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
14 LIST_ENTRY CatalogListHead
;
15 CRITICAL_SECTION CatalogLock
;
18 ReferenceProviderByPointer(PCATALOG_ENTRY Provider
)
20 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
22 //EnterCriticalSection(&Provider->Lock);
23 Provider
->ReferenceCount
++;
24 //LeaveCriticalSection(&Provider->Lock);
26 WS_DbgPrint(MAX_TRACE
, ("Leaving\n"));
31 DereferenceProviderByPointer(PCATALOG_ENTRY Provider
)
33 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
36 if (Provider
->ReferenceCount
<= 0)
38 WS_DbgPrint(MIN_TRACE
, ("Provider at 0x%X has invalid reference count (%ld).\n",
39 Provider
, Provider
->ReferenceCount
));
43 //EnterCriticalSection(&Provider->Lock);
44 Provider
->ReferenceCount
--;
45 //LeaveCriticalSection(&Provider->Lock);
47 if (Provider
->ReferenceCount
== 0)
49 WS_DbgPrint(MAX_TRACE
, ("Provider at 0x%X has reference count 0 (unloading).\n",
52 DestroyCatalogEntry(Provider
);
58 CreateCatalogEntry(LPWSTR LibraryName
)
60 PCATALOG_ENTRY Provider
;
62 WS_DbgPrint(MAX_TRACE
, ("LibraryName (%S).\n", LibraryName
));
64 Provider
= HeapAlloc(GlobalHeap
, 0, sizeof(CATALOG_ENTRY
));
68 ZeroMemory(Provider
, sizeof(CATALOG_ENTRY
));
70 if (!RtlCreateUnicodeString(&Provider
->LibraryName
, LibraryName
))
72 RtlFreeHeap(GlobalHeap
, 0, Provider
);
76 Provider
->ReferenceCount
= 1;
78 InitializeCriticalSection(&Provider
->Lock
);
79 Provider
->hModule
= NULL
;
81 Provider
->Mapping
= NULL
;
83 //EnterCriticalSection(&CatalogLock);
85 InsertTailList(&CatalogListHead
, &Provider
->ListEntry
);
87 //LeaveCriticalSection(&CatalogLock);
94 DestroyCatalogEntry(PCATALOG_ENTRY Provider
)
98 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
100 //EnterCriticalSection(&CatalogLock);
101 RemoveEntryList(&Provider
->ListEntry
);
102 //LeaveCriticalSection(&CatalogLock);
104 HeapFree(GlobalHeap
, 0, Provider
->Mapping
);
106 if (NULL
!= Provider
->hModule
)
108 Status
= UnloadProvider(Provider
);
115 //DeleteCriticalSection(&Provider->Lock);
117 HeapFree(GlobalHeap
, 0, Provider
);
124 LocateProvider(LPWSAPROTOCOL_INFOW lpProtocolInfo
)
126 PLIST_ENTRY CurrentEntry
;
127 PCATALOG_ENTRY Provider
;
130 WS_DbgPrint(MAX_TRACE
, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo
));
132 //EnterCriticalSection(&CatalogLock);
134 CurrentEntry
= CatalogListHead
.Flink
;
135 while (CurrentEntry
!= &CatalogListHead
)
137 Provider
= CONTAINING_RECORD(CurrentEntry
,
141 for (i
= 0; i
< Provider
->Mapping
->Rows
; i
++)
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
)))
148 //LeaveCriticalSection(&CatalogLock);
149 lpProtocolInfo
->dwCatalogEntryId
= Provider
->ProtocolInfo
.dwCatalogEntryId
;
150 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X).\n", Provider
));
155 CurrentEntry
= CurrentEntry
->Flink
;
158 //LeaveCriticalSection(&CatalogLock);
165 LocateProviderById(DWORD CatalogEntryId
)
167 PLIST_ENTRY CurrentEntry
;
168 PCATALOG_ENTRY Provider
;
170 WS_DbgPrint(MAX_TRACE
, ("CatalogEntryId (%d).\n", CatalogEntryId
));
172 //EnterCriticalSection(&CatalogLock);
173 CurrentEntry
= CatalogListHead
.Flink
;
174 while (CurrentEntry
!= &CatalogListHead
)
176 Provider
= CONTAINING_RECORD(CurrentEntry
,
180 if (Provider
->ProtocolInfo
.dwCatalogEntryId
== CatalogEntryId
)
182 //LeaveCriticalSection(&CatalogLock);
183 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X) Name (%wZ).\n",
184 Provider
, &Provider
->LibraryName
));
188 CurrentEntry
= CurrentEntry
->Flink
;
190 //LeaveCriticalSection(&CatalogLock);
192 WS_DbgPrint(MID_TRACE
, ("Provider was not found.\n"));
199 LoadProvider(PCATALOG_ENTRY Provider
,
200 LPWSAPROTOCOL_INFOW lpProtocolInfo
)
204 WS_DbgPrint(MID_TRACE
, ("Loading provider at (0x%X) Name (%wZ).\n",
205 Provider
, &Provider
->LibraryName
));
207 if (NULL
== Provider
->hModule
)
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
213 Provider
->LibraryName
.Buffer
[Provider
->LibraryName
.Length
/ sizeof(WCHAR
)] = L
'\0';
214 Provider
->hModule
= LoadLibraryW(Provider
->LibraryName
.Buffer
);
215 if (NULL
!= Provider
->hModule
)
217 Provider
->WSPStartup
= (LPWSPSTARTUP
)GetProcAddress(Provider
->hModule
,
219 if (Provider
->WSPStartup
)
221 WS_DbgPrint(MAX_TRACE
, ("Calling WSPStartup at (0x%X).\n",
222 Provider
->WSPStartup
));
223 Status
= Provider
->WSPStartup(MAKEWORD(2, 2),
227 &Provider
->ProcTable
);
229 /* FIXME: Validate the procedure table */
232 Status
= ERROR_BAD_PROVIDER
;
235 Status
= ERROR_DLL_NOT_FOUND
;
240 WS_DbgPrint(MID_TRACE
, ("Status (%d).\n", Status
));
247 UnloadProvider(PCATALOG_ENTRY Provider
)
249 INT Status
= NO_ERROR
;
251 WS_DbgPrint(MAX_TRACE
, ("Unloading provider at (0x%X)\n", Provider
));
253 if (NULL
!= Provider
->hModule
)
255 WS_DbgPrint(MAX_TRACE
, ("Calling WSPCleanup at (0x%X).\n",
256 Provider
->ProcTable
.lpWSPCleanup
));
257 Provider
->ProcTable
.lpWSPCleanup(&Status
);
259 WS_DbgPrint(MAX_TRACE
, ("Calling FreeLibrary(0x%X).\n", Provider
->hModule
));
260 if (!FreeLibrary(Provider
->hModule
))
262 WS_DbgPrint(MIN_TRACE
, ("Could not free library at (0x%X).\n", Provider
->hModule
));
263 Status
= GetLastError();
266 Provider
->hModule
= NULL
;
269 WS_DbgPrint(MAX_TRACE
, ("Status (%d).\n", Status
));
278 PCATALOG_ENTRY Provider
;
280 InitializeCriticalSection(&CatalogLock
);
282 InitializeListHead(&CatalogListHead
);
284 /* FIXME: Read service provider catalog from registry
286 Catalog info is saved somewhere under
287 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
291 Provider
= CreateCatalogEntry(L
"msafd.dll");
294 WS_DbgPrint(MIN_TRACE
, ("Could not create catalog entry.\n"));
298 /* Assume one Service Provider with id 1 */
299 Provider
->ProtocolInfo
.dwCatalogEntryId
= 1;
301 Provider
->Mapping
= HeapAlloc(GlobalHeap
,
303 6 * sizeof(WINSOCK_MAPPING
) + 3 * sizeof(DWORD
));
304 if (!Provider
->Mapping
)
307 Provider
->Mapping
->Rows
= 6;
308 Provider
->Mapping
->Columns
= 3;
310 Provider
->Mapping
->Mapping
[0].AddressFamily
= AF_INET
;
311 Provider
->Mapping
->Mapping
[0].SocketType
= SOCK_STREAM
;
312 Provider
->Mapping
->Mapping
[0].Protocol
= 0;
314 Provider
->Mapping
->Mapping
[1].AddressFamily
= AF_INET
;
315 Provider
->Mapping
->Mapping
[1].SocketType
= SOCK_STREAM
;
316 Provider
->Mapping
->Mapping
[1].Protocol
= IPPROTO_TCP
;
318 Provider
->Mapping
->Mapping
[2].AddressFamily
= AF_INET
;
319 Provider
->Mapping
->Mapping
[2].SocketType
= SOCK_DGRAM
;
320 Provider
->Mapping
->Mapping
[2].Protocol
= 0;
322 Provider
->Mapping
->Mapping
[3].AddressFamily
= AF_INET
;
323 Provider
->Mapping
->Mapping
[3].SocketType
= SOCK_DGRAM
;
324 Provider
->Mapping
->Mapping
[3].Protocol
= IPPROTO_UDP
;
326 Provider
->Mapping
->Mapping
[4].AddressFamily
= AF_INET
;
327 Provider
->Mapping
->Mapping
[4].SocketType
= SOCK_RAW
;
328 Provider
->Mapping
->Mapping
[4].Protocol
= IPPROTO_ICMP
;
330 Provider
->Mapping
->Mapping
[5].AddressFamily
= AF_INET
;
331 Provider
->Mapping
->Mapping
[5].SocketType
= SOCK_RAW
;
332 Provider
->Mapping
->Mapping
[5].Protocol
= 0;
337 VOID
DestroyCatalog(VOID
)
339 PLIST_ENTRY CurrentEntry
;
340 PLIST_ENTRY NextEntry
;
341 PCATALOG_ENTRY Provider
;
343 CurrentEntry
= CatalogListHead
.Flink
;
344 while (CurrentEntry
!= &CatalogListHead
)
346 NextEntry
= CurrentEntry
->Flink
;
347 Provider
= CONTAINING_RECORD(CurrentEntry
,
350 DestroyCatalogEntry(Provider
);
351 CurrentEntry
= NextEntry
;
353 //DeleteCriticalSection(&CatalogLock);