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