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
;
17 VOID
ReferenceProviderByPointer(
18 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"));
30 VOID
DereferenceProviderByPointer(
31 PCATALOG_ENTRY Provider
)
33 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
36 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) {
47 WS_DbgPrint(MAX_TRACE
, ("Provider at 0x%X has reference count 0 (unloading).\n",
50 DestroyCatalogEntry(Provider
);
55 PCATALOG_ENTRY
CreateCatalogEntry(
58 PCATALOG_ENTRY Provider
;
60 WS_DbgPrint(MAX_TRACE
, ("LibraryName (%S).\n", LibraryName
));
62 Provider
= HeapAlloc(GlobalHeap
, 0, sizeof(CATALOG_ENTRY
));
67 ZeroMemory(Provider
, sizeof(CATALOG_ENTRY
));
69 if (!RtlCreateUnicodeString(&Provider
->LibraryName
, LibraryName
)) {
70 RtlFreeHeap(GlobalHeap
, 0, Provider
);
74 Provider
->ReferenceCount
= 1;
76 InitializeCriticalSection(&Provider
->Lock
);
77 Provider
->hModule
= NULL
;
79 Provider
->Mapping
= NULL
;
81 //EnterCriticalSection(&CatalogLock);
83 InsertTailList(&CatalogListHead
, &Provider
->ListEntry
);
85 //LeaveCriticalSection(&CatalogLock);
91 INT
DestroyCatalogEntry(
92 PCATALOG_ENTRY Provider
)
96 WS_DbgPrint(MAX_TRACE
, ("Provider (0x%X).\n", Provider
));
98 //EnterCriticalSection(&CatalogLock);
99 RemoveEntryList(&Provider
->ListEntry
);
100 //LeaveCriticalSection(&CatalogLock);
102 HeapFree(GlobalHeap
, 0, Provider
->Mapping
);
104 if (NULL
!= Provider
->hModule
) {
105 Status
= UnloadProvider(Provider
);
110 //DeleteCriticalSection(&Provider->Lock);
112 HeapFree(GlobalHeap
, 0, Provider
);
118 PCATALOG_ENTRY
LocateProvider(
119 LPWSAPROTOCOL_INFOW lpProtocolInfo
)
121 PLIST_ENTRY CurrentEntry
;
122 PCATALOG_ENTRY Provider
;
125 WS_DbgPrint(MAX_TRACE
, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo
));
127 //EnterCriticalSection(&CatalogLock);
129 CurrentEntry
= CatalogListHead
.Flink
;
130 while (CurrentEntry
!= &CatalogListHead
) {
131 Provider
= CONTAINING_RECORD(CurrentEntry
,
135 for (i
= 0; i
< Provider
->Mapping
->Rows
; i
++) {
136 if ((lpProtocolInfo
->iAddressFamily
== (INT
) Provider
->Mapping
->Mapping
[i
].AddressFamily
) &&
137 (lpProtocolInfo
->iSocketType
== (INT
) Provider
->Mapping
->Mapping
[i
].SocketType
) &&
138 ((lpProtocolInfo
->iProtocol
== (INT
) Provider
->Mapping
->Mapping
[i
].Protocol
) ||
139 (lpProtocolInfo
->iSocketType
== SOCK_RAW
))) {
140 //LeaveCriticalSection(&CatalogLock);
141 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X).\n", Provider
));
146 CurrentEntry
= CurrentEntry
->Flink
;
149 //LeaveCriticalSection(&CatalogLock);
155 PCATALOG_ENTRY
LocateProviderById(
156 DWORD CatalogEntryId
)
158 PLIST_ENTRY CurrentEntry
;
159 PCATALOG_ENTRY Provider
;
161 WS_DbgPrint(MAX_TRACE
, ("CatalogEntryId (%d).\n", CatalogEntryId
));
163 //EnterCriticalSection(&CatalogLock);
164 CurrentEntry
= CatalogListHead
.Flink
;
165 while (CurrentEntry
!= &CatalogListHead
) {
166 Provider
= CONTAINING_RECORD(CurrentEntry
,
170 if (Provider
->ProtocolInfo
.dwCatalogEntryId
== CatalogEntryId
) {
171 //LeaveCriticalSection(&CatalogLock);
172 WS_DbgPrint(MID_TRACE
, ("Returning provider at (0x%X) Name (%wZ).\n",
173 Provider
, &Provider
->LibraryName
));
177 CurrentEntry
= CurrentEntry
->Flink
;
179 //LeaveCriticalSection(&CatalogLock);
181 WS_DbgPrint(MID_TRACE
, ("Provider was not found.\n"));
188 PCATALOG_ENTRY Provider
,
189 LPWSAPROTOCOL_INFOW lpProtocolInfo
)
193 WS_DbgPrint(MID_TRACE
, ("Loading provider at (0x%X) Name (%wZ).\n",
194 Provider
, &Provider
->LibraryName
));
196 if (NULL
== Provider
->hModule
)
198 /* DLL is not loaded so load it now
199 * UNICODE_STRING objects are not null-terminated, but LoadLibraryW
200 * expects a null-terminated string
202 Provider
->LibraryName
.Buffer
[Provider
->LibraryName
.Length
/ sizeof(WCHAR
)] = L
'\0';
203 Provider
->hModule
= LoadLibraryW(Provider
->LibraryName
.Buffer
);
204 if (NULL
!= Provider
->hModule
) {
205 Provider
->WSPStartup
= (LPWSPSTARTUP
)GetProcAddress(
208 if (Provider
->WSPStartup
) {
209 WS_DbgPrint(MAX_TRACE
, ("Calling WSPStartup at (0x%X).\n",
210 Provider
->WSPStartup
));
211 Status
= Provider
->WSPStartup(
216 &Provider
->ProcTable
);
218 /* FIXME: Validate the procedure table */
220 Status
= ERROR_BAD_PROVIDER
;
222 Status
= ERROR_DLL_NOT_FOUND
;
226 WS_DbgPrint(MID_TRACE
, ("Status (%d).\n", Status
));
233 PCATALOG_ENTRY Provider
)
235 INT Status
= NO_ERROR
;
237 WS_DbgPrint(MAX_TRACE
, ("Unloading provider at (0x%X)\n", Provider
));
239 if (NULL
!= Provider
->hModule
) {
240 WS_DbgPrint(MAX_TRACE
, ("Calling WSPCleanup at (0x%X).\n",
241 Provider
->ProcTable
.lpWSPCleanup
));
242 Provider
->ProcTable
.lpWSPCleanup(&Status
);
244 WS_DbgPrint(MAX_TRACE
, ("Calling FreeLibrary(0x%X).\n", Provider
->hModule
));
245 if (!FreeLibrary(Provider
->hModule
)) {
246 WS_DbgPrint(MIN_TRACE
, ("Could not free library at (0x%X).\n", Provider
->hModule
));
247 Status
= GetLastError();
250 Provider
->hModule
= NULL
;
253 WS_DbgPrint(MAX_TRACE
, ("Status (%d).\n", Status
));
259 VOID
CreateCatalog(VOID
)
261 PCATALOG_ENTRY Provider
;
263 InitializeCriticalSection(&CatalogLock
);
265 InitializeListHead(&CatalogListHead
);
267 /* FIXME: Read service provider catalog from registry
269 Catalog info is saved somewhere under
270 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
274 Provider
= CreateCatalogEntry(L
"msafd.dll");
276 WS_DbgPrint(MIN_TRACE
, ("Could not create catalog entry.\n"));
280 /* Assume one Service Provider with id 1 */
281 Provider
->ProtocolInfo
.dwCatalogEntryId
= 1;
283 Provider
->Mapping
= HeapAlloc(GlobalHeap
,
285 6 * sizeof(WINSOCK_MAPPING
) + 3 * sizeof(DWORD
));
286 if (!Provider
->Mapping
)
289 Provider
->Mapping
->Rows
= 6;
290 Provider
->Mapping
->Columns
= 3;
292 Provider
->Mapping
->Mapping
[0].AddressFamily
= AF_INET
;
293 Provider
->Mapping
->Mapping
[0].SocketType
= SOCK_STREAM
;
294 Provider
->Mapping
->Mapping
[0].Protocol
= 0;
296 Provider
->Mapping
->Mapping
[1].AddressFamily
= AF_INET
;
297 Provider
->Mapping
->Mapping
[1].SocketType
= SOCK_STREAM
;
298 Provider
->Mapping
->Mapping
[1].Protocol
= IPPROTO_TCP
;
300 Provider
->Mapping
->Mapping
[2].AddressFamily
= AF_INET
;
301 Provider
->Mapping
->Mapping
[2].SocketType
= SOCK_DGRAM
;
302 Provider
->Mapping
->Mapping
[2].Protocol
= 0;
304 Provider
->Mapping
->Mapping
[3].AddressFamily
= AF_INET
;
305 Provider
->Mapping
->Mapping
[3].SocketType
= SOCK_DGRAM
;
306 Provider
->Mapping
->Mapping
[3].Protocol
= IPPROTO_UDP
;
308 Provider
->Mapping
->Mapping
[4].AddressFamily
= AF_INET
;
309 Provider
->Mapping
->Mapping
[4].SocketType
= SOCK_RAW
;
310 Provider
->Mapping
->Mapping
[4].Protocol
= IPPROTO_ICMP
;
312 Provider
->Mapping
->Mapping
[5].AddressFamily
= AF_INET
;
313 Provider
->Mapping
->Mapping
[5].SocketType
= SOCK_RAW
;
314 Provider
->Mapping
->Mapping
[5].Protocol
= 0;
319 VOID
DestroyCatalog(VOID
)
321 PLIST_ENTRY CurrentEntry
;
322 PLIST_ENTRY NextEntry
;
323 PCATALOG_ENTRY Provider
;
325 CurrentEntry
= CatalogListHead
.Flink
;
326 while (CurrentEntry
!= &CatalogListHead
) {
327 NextEntry
= CurrentEntry
->Flink
;
328 Provider
= CONTAINING_RECORD(CurrentEntry
,
331 DestroyCatalogEntry(Provider
);
332 CurrentEntry
= NextEntry
;
334 //DeleteCriticalSection(&CatalogLock);