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