ef077be124f0a6535f0f572be1fb0c897c74487c
[reactos.git] / lib / ws2_32 / misc / catalog.c
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 DLL
4  * FILE:        misc/catalog.c
5  * PURPOSE:     Service Provider Catalog
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  *   CSH 01/09-2000 Created
9  */
10 #include <ws2_32.h>
11 #include <catalog.h>
12
13
14 LIST_ENTRY CatalogListHead;
15 CRITICAL_SECTION CatalogLock;
16
17 VOID ReferenceProviderByPointer(
18     PCATALOG_ENTRY Provider)
19 {
20     WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
21
22     //EnterCriticalSection(&Provider->Lock);
23     Provider->ReferenceCount++;
24     //LeaveCriticalSection(&Provider->Lock);
25 }
26
27
28 VOID DereferenceProviderByPointer(
29     PCATALOG_ENTRY Provider)
30 {
31     WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
32
33 #ifdef DBG
34     if (Provider->ReferenceCount <= 0) {
35         WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
36             Provider, Provider->ReferenceCount));
37     }
38 #endif
39
40     //EnterCriticalSection(&Provider->Lock);
41     Provider->ReferenceCount--;
42     //LeaveCriticalSection(&Provider->Lock);
43
44     if (Provider->ReferenceCount == 0) {
45         WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
46             Provider));
47
48         DestroyCatalogEntry(Provider);
49     }
50 }
51
52
53 PCATALOG_ENTRY CreateCatalogEntry(
54     LPWSTR LibraryName)
55 {
56   PCATALOG_ENTRY Provider;
57
58         WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
59
60   Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
61   if (!Provider) {
62     return NULL;
63         }
64
65   ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
66
67   if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName)) {
68     RtlFreeHeap(GlobalHeap, 0, Provider);
69     return NULL;
70   }
71
72   Provider->ReferenceCount = 1;
73
74         InitializeCriticalSection(&Provider->Lock);
75   Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
76
77   Provider->Mapping = NULL;
78
79   //EnterCriticalSection(&CatalogLock);
80
81   InsertTailList(&CatalogListHead, &Provider->ListEntry);
82
83   //LeaveCriticalSection(&CatalogLock);
84
85   return Provider;
86 }
87
88
89 INT DestroyCatalogEntry(
90     PCATALOG_ENTRY Provider)
91 {
92   INT Status;
93
94   WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
95
96   //EnterCriticalSection(&CatalogLock);
97   RemoveEntryList(&Provider->ListEntry);
98   //LeaveCriticalSection(&CatalogLock);
99
100   HeapFree(GlobalHeap, 0, Provider->Mapping);
101
102   if (Provider->hModule) {
103     Status = UnloadProvider(Provider);
104   } else {
105     Status = NO_ERROR;
106   }
107
108   //DeleteCriticalSection(&Provider->Lock);
109
110   HeapFree(GlobalHeap, 0, Provider);
111
112   return Status;
113 }
114
115
116 PCATALOG_ENTRY LocateProvider(
117     LPWSAPROTOCOL_INFOW lpProtocolInfo)
118 {
119   PLIST_ENTRY CurrentEntry;
120   PCATALOG_ENTRY Provider;
121   UINT i;
122
123   WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
124
125   //EnterCriticalSection(&CatalogLock);
126
127   CurrentEntry = CatalogListHead.Flink;
128   while (CurrentEntry != &CatalogListHead) {
129           Provider = CONTAINING_RECORD(CurrentEntry,
130                                  CATALOG_ENTRY,
131                                  ListEntry);
132
133     for (i = 0; i < Provider->Mapping->Rows; i++) {
134       if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) &&
135         (lpProtocolInfo->iSocketType      == (INT) Provider->Mapping->Mapping[i].SocketType) &&
136         ((lpProtocolInfo->iProtocol       == (INT) Provider->Mapping->Mapping[i].Protocol) ||
137         (lpProtocolInfo->iSocketType      == SOCK_RAW))) {
138         //LeaveCriticalSection(&CatalogLock);
139                                 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
140         return Provider;
141       }
142     }
143
144     CurrentEntry = CurrentEntry->Flink;
145   }
146
147   //LeaveCriticalSection(&CatalogLock);
148
149   return NULL;
150 }
151
152
153 PCATALOG_ENTRY LocateProviderById(
154     DWORD CatalogEntryId)
155 {
156   PLIST_ENTRY CurrentEntry;
157   PCATALOG_ENTRY Provider;
158
159   WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
160
161   //EnterCriticalSection(&CatalogLock);
162   CurrentEntry = CatalogListHead.Flink;
163   while (CurrentEntry != &CatalogListHead) {
164           Provider = CONTAINING_RECORD(CurrentEntry,
165                                  CATALOG_ENTRY,
166                                  ListEntry);
167
168     if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
169       //LeaveCriticalSection(&CatalogLock);
170                   WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X)  Name (%wZ).\n",
171         Provider, &Provider->LibraryName));
172       return Provider;
173     }
174
175     CurrentEntry = CurrentEntry->Flink;
176   }
177   //LeaveCriticalSection(&CatalogLock);
178
179         WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
180
181   return NULL;
182 }
183
184
185 INT LoadProvider(
186     PCATALOG_ENTRY Provider,
187     LPWSAPROTOCOL_INFOW lpProtocolInfo)
188 {
189   INT Status;
190
191   WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X)  Name (%wZ).\n",
192     Provider, &Provider->LibraryName));
193
194   if (Provider->hModule == INVALID_HANDLE_VALUE) {
195     /* DLL is not loaded so load it now */
196     Provider->hModule = LoadLibrary(Provider->LibraryName.Buffer);
197     if (Provider->hModule != INVALID_HANDLE_VALUE) {
198       Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(
199         Provider->hModule,
200         "WSPStartup");
201       if (Provider->WSPStartup) {
202                           WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
203           Provider->WSPStartup));
204         Status = Provider->WSPStartup(
205           MAKEWORD(2, 2),
206           &Provider->WSPData,
207           lpProtocolInfo,
208           UpcallTable,
209           &Provider->ProcTable);
210
211         /* FIXME: Validate the procedure table */
212       } else
213         Status = ERROR_BAD_PROVIDER;
214     } else
215       Status = ERROR_DLL_NOT_FOUND;
216   } else
217     Status = NO_ERROR;
218
219   WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
220
221   return Status;
222 }
223
224
225 INT UnloadProvider(
226     PCATALOG_ENTRY Provider)
227 {
228   INT Status = NO_ERROR;
229
230   WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
231
232   if (Provider->hModule) {
233     WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
234       Provider->ProcTable.lpWSPCleanup));
235       Provider->ProcTable.lpWSPCleanup(&Status);
236
237     WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
238     if (!FreeLibrary(Provider->hModule)) {
239       WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
240       Status = GetLastError();
241     }
242
243     Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
244   }
245
246   WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
247
248   return Status;
249 }
250
251
252 VOID CreateCatalog(VOID)
253 {
254   PCATALOG_ENTRY Provider;
255
256   InitializeCriticalSection(&CatalogLock);
257
258         InitializeListHead(&CatalogListHead);
259
260   /* FIXME: Read service provider catalog from registry */
261 #if 1
262     Provider = CreateCatalogEntry(L"msafd.dll");
263     if (!Provider) {
264                   WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
265       return;
266   }
267         
268   /* Assume one Service Provider with id 1 */
269   Provider->ProtocolInfo.dwCatalogEntryId = 1;
270
271   Provider->Mapping = HeapAlloc(GlobalHeap,
272     0,
273     3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
274   if (!Provider->Mapping)
275     return;
276
277   Provider->Mapping->Rows    = 3;
278   Provider->Mapping->Columns = 3;
279
280   Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
281   Provider->Mapping->Mapping[0].SocketType    = SOCK_STREAM;
282   Provider->Mapping->Mapping[0].Protocol      = IPPROTO_TCP;
283
284   Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
285   Provider->Mapping->Mapping[1].SocketType    = SOCK_DGRAM;
286   Provider->Mapping->Mapping[1].Protocol      = IPPROTO_UDP;
287
288   Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
289   Provider->Mapping->Mapping[2].SocketType    = SOCK_RAW;
290   Provider->Mapping->Mapping[2].Protocol      = 0;
291 #endif
292 }
293
294
295 VOID DestroyCatalog(VOID)
296 {
297   PLIST_ENTRY CurrentEntry;
298         PLIST_ENTRY NextEntry;
299   PCATALOG_ENTRY Provider;
300
301   CurrentEntry = CatalogListHead.Flink;
302   while (CurrentEntry != &CatalogListHead) {
303         NextEntry = CurrentEntry->Flink;
304   Provider = CONTAINING_RECORD(CurrentEntry,
305                                CATALOG_ENTRY,
306                                ListEntry);
307     DestroyCatalogEntry(Provider);
308     CurrentEntry = NextEntry;
309   }
310   //DeleteCriticalSection(&CatalogLock);
311 }
312
313 /* EOF */