[WS2_32]
[reactos.git] / reactos / dll / win32 / 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
18 ReferenceProviderByPointer(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 WS_DbgPrint(MAX_TRACE, ("Leaving\n"));
27 }
28
29
30 VOID
31 DereferenceProviderByPointer(PCATALOG_ENTRY Provider)
32 {
33 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
34
35 #if DBG
36 if (Provider->ReferenceCount <= 0)
37 {
38 WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
39 Provider, Provider->ReferenceCount));
40 }
41 #endif
42
43 //EnterCriticalSection(&Provider->Lock);
44 Provider->ReferenceCount--;
45 //LeaveCriticalSection(&Provider->Lock);
46
47 if (Provider->ReferenceCount == 0)
48 {
49 WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
50 Provider));
51
52 DestroyCatalogEntry(Provider);
53 }
54 }
55
56
57 PCATALOG_ENTRY
58 CreateCatalogEntry(LPWSTR LibraryName)
59 {
60 PCATALOG_ENTRY Provider;
61
62 WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
63
64 Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
65 if (!Provider)
66 return NULL;
67
68 ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
69
70 if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName))
71 {
72 RtlFreeHeap(GlobalHeap, 0, Provider);
73 return NULL;
74 }
75
76 Provider->ReferenceCount = 1;
77
78 InitializeCriticalSection(&Provider->Lock);
79 Provider->hModule = NULL;
80
81 Provider->Mapping = NULL;
82
83 //EnterCriticalSection(&CatalogLock);
84
85 InsertTailList(&CatalogListHead, &Provider->ListEntry);
86
87 //LeaveCriticalSection(&CatalogLock);
88
89 return Provider;
90 }
91
92
93 INT
94 DestroyCatalogEntry(PCATALOG_ENTRY Provider)
95 {
96 INT Status;
97
98 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
99
100 //EnterCriticalSection(&CatalogLock);
101 RemoveEntryList(&Provider->ListEntry);
102 //LeaveCriticalSection(&CatalogLock);
103
104 HeapFree(GlobalHeap, 0, Provider->Mapping);
105
106 if (NULL != Provider->hModule)
107 {
108 Status = UnloadProvider(Provider);
109 }
110 else
111 {
112 Status = NO_ERROR;
113 }
114
115 //DeleteCriticalSection(&Provider->Lock);
116
117 HeapFree(GlobalHeap, 0, Provider);
118
119 return Status;
120 }
121
122
123 PCATALOG_ENTRY
124 LocateProvider(LPWSAPROTOCOL_INFOW lpProtocolInfo)
125 {
126 PLIST_ENTRY CurrentEntry;
127 PCATALOG_ENTRY Provider;
128 UINT i;
129
130 WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
131
132 //EnterCriticalSection(&CatalogLock);
133
134 CurrentEntry = CatalogListHead.Flink;
135 while (CurrentEntry != &CatalogListHead)
136 {
137 Provider = CONTAINING_RECORD(CurrentEntry,
138 CATALOG_ENTRY,
139 ListEntry);
140
141 for (i = 0; i < Provider->Mapping->Rows; i++)
142 {
143 if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) &&
144 (lpProtocolInfo->iSocketType == (INT) Provider->Mapping->Mapping[i].SocketType) &&
145 ((lpProtocolInfo->iProtocol == (INT) Provider->Mapping->Mapping[i].Protocol) ||
146 (lpProtocolInfo->iSocketType == SOCK_RAW)))
147 {
148 //LeaveCriticalSection(&CatalogLock);
149 lpProtocolInfo->dwCatalogEntryId = Provider->ProtocolInfo.dwCatalogEntryId;
150 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
151 return Provider;
152 }
153 }
154
155 CurrentEntry = CurrentEntry->Flink;
156 }
157
158 //LeaveCriticalSection(&CatalogLock);
159
160 return NULL;
161 }
162
163
164 PCATALOG_ENTRY
165 LocateProviderById(DWORD CatalogEntryId)
166 {
167 PLIST_ENTRY CurrentEntry;
168 PCATALOG_ENTRY Provider;
169
170 WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
171
172 //EnterCriticalSection(&CatalogLock);
173 CurrentEntry = CatalogListHead.Flink;
174 while (CurrentEntry != &CatalogListHead)
175 {
176 Provider = CONTAINING_RECORD(CurrentEntry,
177 CATALOG_ENTRY,
178 ListEntry);
179
180 if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId)
181 {
182 //LeaveCriticalSection(&CatalogLock);
183 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%wZ).\n",
184 Provider, &Provider->LibraryName));
185 return Provider;
186 }
187
188 CurrentEntry = CurrentEntry->Flink;
189 }
190 //LeaveCriticalSection(&CatalogLock);
191
192 WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
193
194 return NULL;
195 }
196
197
198 INT
199 LoadProvider(PCATALOG_ENTRY Provider,
200 LPWSAPROTOCOL_INFOW lpProtocolInfo)
201 {
202 INT Status;
203
204 WS_DbgPrint(MID_TRACE, ("Loading provider at (0x%X) Name (%wZ).\n",
205 Provider, &Provider->LibraryName));
206
207 if (NULL == Provider->hModule)
208 {
209 /* DLL is not loaded so load it now
210 * UNICODE_STRING objects are not null-terminated, but LoadLibraryW
211 * expects a null-terminated string
212 */
213 Provider->LibraryName.Buffer[Provider->LibraryName.Length / sizeof(WCHAR)] = L'\0';
214 Provider->hModule = LoadLibraryW(Provider->LibraryName.Buffer);
215 if (NULL != Provider->hModule)
216 {
217 Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
218 "WSPStartup");
219 if (Provider->WSPStartup)
220 {
221 WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
222 Provider->WSPStartup));
223 Status = Provider->WSPStartup(MAKEWORD(2, 2),
224 &Provider->WSPData,
225 lpProtocolInfo,
226 UpcallTable,
227 &Provider->ProcTable);
228
229 /* FIXME: Validate the procedure table */
230 }
231 else
232 Status = ERROR_BAD_PROVIDER;
233 }
234 else
235 Status = ERROR_DLL_NOT_FOUND;
236 }
237 else
238 Status = NO_ERROR;
239
240 WS_DbgPrint(MID_TRACE, ("Status (%d).\n", Status));
241
242 return Status;
243 }
244
245
246 INT
247 UnloadProvider(PCATALOG_ENTRY Provider)
248 {
249 INT Status = NO_ERROR;
250
251 WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
252
253 if (NULL != Provider->hModule)
254 {
255 WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
256 Provider->ProcTable.lpWSPCleanup));
257 Provider->ProcTable.lpWSPCleanup(&Status);
258
259 WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
260 if (!FreeLibrary(Provider->hModule))
261 {
262 WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
263 Status = GetLastError();
264 }
265
266 Provider->hModule = NULL;
267 }
268
269 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
270
271 return Status;
272 }
273
274
275 VOID
276 CreateCatalog(VOID)
277 {
278 PCATALOG_ENTRY Provider;
279
280 InitializeCriticalSection(&CatalogLock);
281
282 InitializeListHead(&CatalogListHead);
283
284 /* FIXME: Read service provider catalog from registry
285
286 Catalog info is saved somewhere under
287 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
288 */
289
290 #if 1
291 Provider = CreateCatalogEntry(L"msafd.dll");
292 if (!Provider)
293 {
294 WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
295 return;
296 }
297
298 /* Assume one Service Provider with id 1 */
299 Provider->ProtocolInfo.dwCatalogEntryId = 1;
300
301 Provider->Mapping = HeapAlloc(GlobalHeap,
302 0,
303 6 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
304 if (!Provider->Mapping)
305 return;
306
307 Provider->Mapping->Rows = 6;
308 Provider->Mapping->Columns = 3;
309
310 Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
311 Provider->Mapping->Mapping[0].SocketType = SOCK_STREAM;
312 Provider->Mapping->Mapping[0].Protocol = 0;
313
314 Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
315 Provider->Mapping->Mapping[1].SocketType = SOCK_STREAM;
316 Provider->Mapping->Mapping[1].Protocol = IPPROTO_TCP;
317
318 Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
319 Provider->Mapping->Mapping[2].SocketType = SOCK_DGRAM;
320 Provider->Mapping->Mapping[2].Protocol = 0;
321
322 Provider->Mapping->Mapping[3].AddressFamily = AF_INET;
323 Provider->Mapping->Mapping[3].SocketType = SOCK_DGRAM;
324 Provider->Mapping->Mapping[3].Protocol = IPPROTO_UDP;
325
326 Provider->Mapping->Mapping[4].AddressFamily = AF_INET;
327 Provider->Mapping->Mapping[4].SocketType = SOCK_RAW;
328 Provider->Mapping->Mapping[4].Protocol = IPPROTO_ICMP;
329
330 Provider->Mapping->Mapping[5].AddressFamily = AF_INET;
331 Provider->Mapping->Mapping[5].SocketType = SOCK_RAW;
332 Provider->Mapping->Mapping[5].Protocol = 0;
333 #endif
334 }
335
336
337 VOID DestroyCatalog(VOID)
338 {
339 PLIST_ENTRY CurrentEntry;
340 PLIST_ENTRY NextEntry;
341 PCATALOG_ENTRY Provider;
342
343 CurrentEntry = CatalogListHead.Flink;
344 while (CurrentEntry != &CatalogListHead)
345 {
346 NextEntry = CurrentEntry->Flink;
347 Provider = CONTAINING_RECORD(CurrentEntry,
348 CATALOG_ENTRY,
349 ListEntry);
350 DestroyCatalogEntry(Provider);
351 CurrentEntry = NextEntry;
352 }
353 //DeleteCriticalSection(&CatalogLock);
354 }
355
356 /* EOF */