2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 DLL
5 * PURPOSE: Service Provider Catalog
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
13 LIST_ENTRY CatalogListHead
;
14 CRITICAL_SECTION CatalogLock
;
17 ReferenceProviderByPointer(PCATALOG_ENTRY Provider
)
19 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
21 //EnterCriticalSection(&Provider->Lock);
22 Provider
->ReferenceCount
++;
23 //LeaveCriticalSection(&Provider->Lock);
25 WS_DbgPrint(MAX_TRACE
, ("Leaving\n"));
30 DereferenceProviderByPointer(PCATALOG_ENTRY Provider
)
32 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
35 if (Provider
->ReferenceCount
<= 0)
37 WS_DbgPrint(MIN_TRACE
, ("Provider at 0x%X has invalid reference count (%ld).\n",
38 Provider
, Provider
->ReferenceCount
));
42 //EnterCriticalSection(&Provider->Lock);
43 Provider
->ReferenceCount
--;
44 //LeaveCriticalSection(&Provider->Lock);
46 if (Provider
->ReferenceCount
== 0)
48 WS_DbgPrint(MAX_TRACE
, ("Provider at 0x%X has reference count 0 (unloading).\n",
51 DestroyCatalogEntry(Provider
);
57 CreateCatalogEntry(LPWSTR LibraryName
)
59 PCATALOG_ENTRY Provider
;
61 WS_DbgPrint(MAX_TRACE
, ("LibraryName (%S).\n", LibraryName
));
63 Provider
= HeapAlloc(GlobalHeap
, 0, sizeof(CATALOG_ENTRY
));
67 ZeroMemory(Provider
, sizeof(CATALOG_ENTRY
));
69 if (!RtlCreateUnicodeString(&Provider
->LibraryName
, LibraryName
))
71 HeapFree(GlobalHeap
, 0, Provider
);
75 Provider
->ReferenceCount
= 1;
77 InitializeCriticalSection(&Provider
->Lock
);
78 Provider
->hModule
= NULL
;
80 Provider
->Mapping
= NULL
;
82 //EnterCriticalSection(&CatalogLock);
84 InsertTailList(&CatalogListHead
, &Provider
->ListEntry
);
86 //LeaveCriticalSection(&CatalogLock);
93 DestroyCatalogEntry(PCATALOG_ENTRY Provider
)
97 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
99 //EnterCriticalSection(&CatalogLock);
100 RemoveEntryList(&Provider
->ListEntry
);
101 //LeaveCriticalSection(&CatalogLock);
103 HeapFree(GlobalHeap
, 0, Provider
->Mapping
);
105 if (NULL
!= Provider
->hModule
)
107 Status
= UnloadProvider(Provider
);
114 //DeleteCriticalSection(&Provider->Lock);
116 HeapFree(GlobalHeap
, 0, Provider
);
123 LocateProvider(LPWSAPROTOCOL_INFOW lpProtocolInfo
)
125 PLIST_ENTRY CurrentEntry
;
126 PCATALOG_ENTRY Provider
;
129 WS_DbgPrint(MAX_TRACE
, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo
));
131 //EnterCriticalSection(&CatalogLock);
133 CurrentEntry
= CatalogListHead
.Flink
;
134 while (CurrentEntry
!= &CatalogListHead
)
136 Provider
= CONTAINING_RECORD(CurrentEntry
,
140 for (i
= 0; i
< Provider
->Mapping
->Rows
; i
++)
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
)))
147 //LeaveCriticalSection(&CatalogLock);
148 lpProtocolInfo
->dwCatalogEntryId
= Provider
->ProtocolInfo
.dwCatalogEntryId
;
149 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X).\n", Provider
));
154 CurrentEntry
= CurrentEntry
->Flink
;
157 //LeaveCriticalSection(&CatalogLock);
164 LocateProviderById(DWORD CatalogEntryId
)
166 PLIST_ENTRY CurrentEntry
;
167 PCATALOG_ENTRY Provider
;
169 WS_DbgPrint(MAX_TRACE
, ("CatalogEntryId (%d).\n", CatalogEntryId
));
171 //EnterCriticalSection(&CatalogLock);
172 CurrentEntry
= CatalogListHead
.Flink
;
173 while (CurrentEntry
!= &CatalogListHead
)
175 Provider
= CONTAINING_RECORD(CurrentEntry
,
179 if (Provider
->ProtocolInfo
.dwCatalogEntryId
== CatalogEntryId
)
181 //LeaveCriticalSection(&CatalogLock);
182 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X) Name (%wZ).\n",
183 Provider
, &Provider
->LibraryName
));
187 CurrentEntry
= CurrentEntry
->Flink
;
189 //LeaveCriticalSection(&CatalogLock);
191 WS_DbgPrint(MID_TRACE
, ("Provider was not found.\n"));
198 LoadProvider(PCATALOG_ENTRY Provider
,
199 LPWSAPROTOCOL_INFOW lpProtocolInfo
)
203 WS_DbgPrint(MID_TRACE
, ("Loading provider at (0x%X) Name (%wZ).\n",
204 Provider
, &Provider
->LibraryName
));
206 if (NULL
== Provider
->hModule
)
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
212 Provider
->LibraryName
.Buffer
[Provider
->LibraryName
.Length
/ sizeof(WCHAR
)] = L
'\0';
213 Provider
->hModule
= LoadLibraryW(Provider
->LibraryName
.Buffer
);
214 if (NULL
!= Provider
->hModule
)
216 Provider
->WSPStartup
= (LPWSPSTARTUP
)GetProcAddress(Provider
->hModule
,
218 if (Provider
->WSPStartup
)
220 WS_DbgPrint(MAX_TRACE
, ("Calling WSPStartup at (0x%X).\n",
221 Provider
->WSPStartup
));
222 Status
= Provider
->WSPStartup(MAKEWORD(2, 2),
226 &Provider
->ProcTable
);
228 /* FIXME: Validate the procedure table */
231 Status
= ERROR_BAD_PROVIDER
;
234 Status
= ERROR_DLL_NOT_FOUND
;
239 WS_DbgPrint(MID_TRACE
, ("Status (%d).\n", Status
));
246 UnloadProvider(PCATALOG_ENTRY Provider
)
248 INT Status
= NO_ERROR
;
250 WS_DbgPrint(MAX_TRACE
, ("Unloading provider at (0x%X)\n", Provider
));
252 if (NULL
!= Provider
->hModule
)
254 WS_DbgPrint(MAX_TRACE
, ("Calling WSPCleanup at (0x%X).\n",
255 Provider
->ProcTable
.lpWSPCleanup
));
256 Provider
->ProcTable
.lpWSPCleanup(&Status
);
258 WS_DbgPrint(MAX_TRACE
, ("Calling FreeLibrary(0x%X).\n", Provider
->hModule
));
259 if (!FreeLibrary(Provider
->hModule
))
261 WS_DbgPrint(MIN_TRACE
, ("Could not free library at (0x%X).\n", Provider
->hModule
));
262 Status
= GetLastError();
265 Provider
->hModule
= NULL
;
268 WS_DbgPrint(MAX_TRACE
, ("Status (%d).\n", Status
));
277 PCATALOG_ENTRY Provider
;
279 InitializeCriticalSection(&CatalogLock
);
281 InitializeListHead(&CatalogListHead
);
283 /* FIXME: Read service provider catalog from registry
285 Catalog info is saved somewhere under
286 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
290 Provider
= CreateCatalogEntry(L
"msafd.dll");
293 WS_DbgPrint(MIN_TRACE
, ("Could not create catalog entry.\n"));
297 /* Assume one Service Provider with id 1 */
298 Provider
->ProtocolInfo
.dwCatalogEntryId
= 1;
300 Provider
->Mapping
= HeapAlloc(GlobalHeap
,
302 6 * sizeof(WINSOCK_MAPPING
) + 3 * sizeof(DWORD
));
303 if (!Provider
->Mapping
)
306 Provider
->Mapping
->Rows
= 6;
307 Provider
->Mapping
->Columns
= 3;
309 Provider
->Mapping
->Mapping
[0].AddressFamily
= AF_INET
;
310 Provider
->Mapping
->Mapping
[0].SocketType
= SOCK_STREAM
;
311 Provider
->Mapping
->Mapping
[0].Protocol
= 0;
313 Provider
->Mapping
->Mapping
[1].AddressFamily
= AF_INET
;
314 Provider
->Mapping
->Mapping
[1].SocketType
= SOCK_STREAM
;
315 Provider
->Mapping
->Mapping
[1].Protocol
= IPPROTO_TCP
;
317 Provider
->Mapping
->Mapping
[2].AddressFamily
= AF_INET
;
318 Provider
->Mapping
->Mapping
[2].SocketType
= SOCK_DGRAM
;
319 Provider
->Mapping
->Mapping
[2].Protocol
= 0;
321 Provider
->Mapping
->Mapping
[3].AddressFamily
= AF_INET
;
322 Provider
->Mapping
->Mapping
[3].SocketType
= SOCK_DGRAM
;
323 Provider
->Mapping
->Mapping
[3].Protocol
= IPPROTO_UDP
;
325 Provider
->Mapping
->Mapping
[4].AddressFamily
= AF_INET
;
326 Provider
->Mapping
->Mapping
[4].SocketType
= SOCK_RAW
;
327 Provider
->Mapping
->Mapping
[4].Protocol
= IPPROTO_ICMP
;
329 Provider
->Mapping
->Mapping
[5].AddressFamily
= AF_INET
;
330 Provider
->Mapping
->Mapping
[5].SocketType
= SOCK_RAW
;
331 Provider
->Mapping
->Mapping
[5].Protocol
= 0;
336 VOID
DestroyCatalog(VOID
)
338 PLIST_ENTRY CurrentEntry
;
339 PLIST_ENTRY NextEntry
;
340 PCATALOG_ENTRY Provider
;
342 CurrentEntry
= CatalogListHead
.Flink
;
343 while (CurrentEntry
!= &CatalogListHead
)
345 NextEntry
= CurrentEntry
->Flink
;
346 Provider
= CONTAINING_RECORD(CurrentEntry
,
349 DestroyCatalogEntry(Provider
);
350 CurrentEntry
= NextEntry
;
352 //DeleteCriticalSection(&CatalogLock);