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);
28 VOID DereferenceProviderByPointer(
29 PCATALOG_ENTRY Provider)
31 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
34 if (Provider->ReferenceCount <= 0) {
35 WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
36 Provider, Provider->ReferenceCount));
40 //EnterCriticalSection(&Provider->Lock);
41 Provider->ReferenceCount--;
42 //LeaveCriticalSection(&Provider->Lock);
44 if (Provider->ReferenceCount == 0) {
45 WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
48 DestroyCatalogEntry(Provider);
53 PCATALOG_ENTRY CreateCatalogEntry(
56 PCATALOG_ENTRY Provider;
58 WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
60 Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
65 ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
67 if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName)) {
68 RtlFreeHeap(GlobalHeap, 0, Provider);
72 Provider->ReferenceCount = 1;
74 InitializeCriticalSection(&Provider->Lock);
75 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
77 Provider->Mapping = NULL;
79 //EnterCriticalSection(&CatalogLock);
81 InsertTailList(&CatalogListHead, &Provider->ListEntry);
83 //LeaveCriticalSection(&CatalogLock);
89 INT DestroyCatalogEntry(
90 PCATALOG_ENTRY Provider)
94 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
96 //EnterCriticalSection(&CatalogLock);
97 RemoveEntryList(&Provider->ListEntry);
98 //LeaveCriticalSection(&CatalogLock);
100 HeapFree(GlobalHeap, 0, Provider->Mapping);
102 if (Provider->hModule) {
103 Status = UnloadProvider(Provider);
108 //DeleteCriticalSection(&Provider->Lock);
110 HeapFree(GlobalHeap, 0, Provider);
116 PCATALOG_ENTRY LocateProvider(
117 LPWSAPROTOCOL_INFOW lpProtocolInfo)
119 PLIST_ENTRY CurrentEntry;
120 PCATALOG_ENTRY Provider;
123 WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
125 //EnterCriticalSection(&CatalogLock);
127 CurrentEntry = CatalogListHead.Flink;
128 while (CurrentEntry != &CatalogListHead) {
129 Provider = CONTAINING_RECORD(CurrentEntry,
133 for (i = 0; i < Provider->Mapping->Rows; i++) {
134 if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) &&
135 (lpProtocolInfo->iSocketType == (INT) Provider->Mapping->Mapping[i].SocketType) &&
136 ((lpProtocolInfo->iProtocol == (INT) Provider->Mapping->Mapping[i].Protocol) ||
137 (lpProtocolInfo->iSocketType == SOCK_RAW))) {
138 //LeaveCriticalSection(&CatalogLock);
139 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
144 CurrentEntry = CurrentEntry->Flink;
147 //LeaveCriticalSection(&CatalogLock);
153 PCATALOG_ENTRY LocateProviderById(
154 DWORD CatalogEntryId)
156 PLIST_ENTRY CurrentEntry;
157 PCATALOG_ENTRY Provider;
159 WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
161 //EnterCriticalSection(&CatalogLock);
162 CurrentEntry = CatalogListHead.Flink;
163 while (CurrentEntry != &CatalogListHead) {
164 Provider = CONTAINING_RECORD(CurrentEntry,
168 if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
169 //LeaveCriticalSection(&CatalogLock);
170 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%wZ).\n",
171 Provider, &Provider->LibraryName));
175 CurrentEntry = CurrentEntry->Flink;
177 //LeaveCriticalSection(&CatalogLock);
179 WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
186 PCATALOG_ENTRY Provider,
187 LPWSAPROTOCOL_INFOW lpProtocolInfo)
191 WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%wZ).\n",
192 Provider, &Provider->LibraryName));
194 if (Provider->hModule == INVALID_HANDLE_VALUE) {
195 /* DLL is not loaded so load it now */
196 Provider->hModule = LoadLibrary(Provider->LibraryName.Buffer);
197 if (Provider->hModule != INVALID_HANDLE_VALUE) {
198 Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(
201 if (Provider->WSPStartup) {
202 WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
203 Provider->WSPStartup));
204 Status = Provider->WSPStartup(
209 &Provider->ProcTable);
211 /* FIXME: Validate the procedure table */
213 Status = ERROR_BAD_PROVIDER;
215 Status = ERROR_DLL_NOT_FOUND;
219 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
226 PCATALOG_ENTRY Provider)
228 INT Status = NO_ERROR;
230 WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
232 if (Provider->hModule) {
233 WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
234 Provider->ProcTable.lpWSPCleanup));
235 Provider->ProcTable.lpWSPCleanup(&Status);
237 WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
238 if (!FreeLibrary(Provider->hModule)) {
239 WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
240 Status = GetLastError();
243 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
246 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
252 VOID CreateCatalog(VOID)
254 PCATALOG_ENTRY Provider;
256 InitializeCriticalSection(&CatalogLock);
258 InitializeListHead(&CatalogListHead);
260 /* FIXME: Read service provider catalog from registry */
262 Provider = CreateCatalogEntry(L"msafd.dll");
264 WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
268 /* Assume one Service Provider with id 1 */
269 Provider->ProtocolInfo.dwCatalogEntryId = 1;
271 Provider->Mapping = HeapAlloc(GlobalHeap,
273 3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
274 if (!Provider->Mapping)
277 Provider->Mapping->Rows = 3;
278 Provider->Mapping->Columns = 3;
280 Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
281 Provider->Mapping->Mapping[0].SocketType = SOCK_STREAM;
282 Provider->Mapping->Mapping[0].Protocol = IPPROTO_TCP;
284 Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
285 Provider->Mapping->Mapping[1].SocketType = SOCK_DGRAM;
286 Provider->Mapping->Mapping[1].Protocol = IPPROTO_UDP;
288 Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
289 Provider->Mapping->Mapping[2].SocketType = SOCK_RAW;
290 Provider->Mapping->Mapping[2].Protocol = 0;
295 VOID DestroyCatalog(VOID)
297 PLIST_ENTRY CurrentEntry;
298 PLIST_ENTRY NextEntry;
299 PCATALOG_ENTRY Provider;
301 CurrentEntry = CatalogListHead.Flink;
302 while (CurrentEntry != &CatalogListHead) {
303 NextEntry = CurrentEntry->Flink;
304 Provider = CONTAINING_RECORD(CurrentEntry,
307 DestroyCatalogEntry(Provider);
308 CurrentEntry = NextEntry;
310 //DeleteCriticalSection(&CatalogLock);