:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 == Provider->Mapping->Mapping[i].AddressFamily) &&
135         (lpProtocolInfo->iSocketType    == Provider->Mapping->Mapping[i].SocketType) &&
136         ((lpProtocolInfo->iProtocol     == 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   UINT i;
159
160   WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
161
162   //EnterCriticalSection(&CatalogLock);
163   CurrentEntry = CatalogListHead.Flink;
164   while (CurrentEntry != &CatalogListHead) {
165           Provider = CONTAINING_RECORD(CurrentEntry,
166                                  CATALOG_ENTRY,
167                                  ListEntry);
168
169     if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
170       //LeaveCriticalSection(&CatalogLock);
171                   WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X)  Name (%wZ).\n",
172         Provider, &Provider->LibraryName));
173       return Provider;
174     }
175
176     CurrentEntry = CurrentEntry->Flink;
177   }
178   //LeaveCriticalSection(&CatalogLock);
179
180         WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
181
182   return NULL;
183 }
184
185
186 INT LoadProvider(
187     PCATALOG_ENTRY Provider,
188     LPWSAPROTOCOL_INFOW lpProtocolInfo)
189 {
190   INT Status;
191
192   WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X)  Name (%wZ).\n",
193     Provider, &Provider->LibraryName));
194
195   if (Provider->hModule == INVALID_HANDLE_VALUE) {
196     /* DLL is not loaded so load it now */
197     Provider->hModule = LoadLibrary(Provider->LibraryName.Buffer);
198     if (Provider->hModule != INVALID_HANDLE_VALUE) {
199       Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(
200         Provider->hModule,
201         "WSPStartup");
202       if (Provider->WSPStartup) {
203                           WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
204           Provider->WSPStartup));
205         Status = Provider->WSPStartup(
206           MAKEWORD(2, 2),
207           &Provider->WSPData,
208           lpProtocolInfo,
209           UpcallTable,
210           &Provider->ProcTable);
211
212         /* FIXME: Validate the procedure table */
213       } else
214         Status = ERROR_BAD_PROVIDER;
215     } else
216       Status = ERROR_DLL_NOT_FOUND;
217   } else
218     Status = NO_ERROR;
219
220   WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
221
222   return Status;
223 }
224
225
226 INT UnloadProvider(
227     PCATALOG_ENTRY Provider)
228 {
229   INT Status = NO_ERROR;
230
231   WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
232
233   if (Provider->hModule) {
234     WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
235       Provider->ProcTable.lpWSPCleanup));
236       Provider->ProcTable.lpWSPCleanup(&Status);
237
238     WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
239     if (!FreeLibrary(Provider->hModule)) {
240       WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
241       Status = GetLastError();
242     }
243
244     Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
245   }
246
247   WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
248
249   return Status;
250 }
251
252
253 VOID CreateCatalog(VOID)
254 {
255   PCATALOG_ENTRY Provider;
256
257   InitializeCriticalSection(&CatalogLock);
258
259         InitializeListHead(&CatalogListHead);
260
261   /* FIXME: Read service provider catalog from registry */
262 #if 1
263     Provider = CreateCatalogEntry(L"msafd.dll");
264     if (!Provider) {
265                   WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
266       return;
267   }
268         
269   /* Assume one Service Provider with id 1 */
270   Provider->ProtocolInfo.dwCatalogEntryId = 1;
271
272   Provider->Mapping = HeapAlloc(GlobalHeap,
273     0,
274     3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
275   if (!Provider->Mapping)
276     return;
277
278   Provider->Mapping->Rows    = 3;
279   Provider->Mapping->Columns = 3;
280
281   Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
282   Provider->Mapping->Mapping[0].SocketType    = SOCK_STREAM;
283   Provider->Mapping->Mapping[0].Protocol      = IPPROTO_TCP;
284
285   Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
286   Provider->Mapping->Mapping[1].SocketType    = SOCK_DGRAM;
287   Provider->Mapping->Mapping[1].Protocol      = IPPROTO_UDP;
288
289   Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
290   Provider->Mapping->Mapping[2].SocketType    = SOCK_RAW;
291   Provider->Mapping->Mapping[2].Protocol      = 0;
292 #endif
293 }
294
295
296 VOID DestroyCatalog(VOID)
297 {
298   PLIST_ENTRY CurrentEntry;
299         PLIST_ENTRY NextEntry;
300   PCATALOG_ENTRY Provider;
301
302   CurrentEntry = CatalogListHead.Flink;
303   while (CurrentEntry != &CatalogListHead) {
304         NextEntry = CurrentEntry->Flink;
305   Provider = CONTAINING_RECORD(CurrentEntry,
306                                CATALOG_ENTRY,
307                                ListEntry);
308     DestroyCatalogEntry(Provider);
309     CurrentEntry = NextEntry;
310   }
311   //DeleteCriticalSection(&CatalogLock);
312 }
313
314 /* EOF */