Raw IP and ICMP fixes
[reactos.git] / reactos / lib / 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
27
28 VOID DereferenceProviderByPointer(
29 PCATALOG_ENTRY Provider)
30 {
31 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
32
33 #ifdef DBG
34 if (Provider->ReferenceCount <= 0) {
35 WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
36 Provider, Provider->ReferenceCount));
37 }
38 #endif
39
40 //EnterCriticalSection(&Provider->Lock);
41 Provider->ReferenceCount--;
42 //LeaveCriticalSection(&Provider->Lock);
43
44 if (Provider->ReferenceCount == 0) {
45 WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
46 Provider));
47
48 DestroyCatalogEntry(Provider);
49 }
50 }
51
52
53 PCATALOG_ENTRY CreateCatalogEntry(
54 LPWSTR LibraryName)
55 {
56 PCATALOG_ENTRY Provider;
57
58 WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
59
60 Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
61 if (!Provider) {
62 return NULL;
63 }
64
65 ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
66
67 if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName)) {
68 RtlFreeHeap(GlobalHeap, 0, Provider);
69 return NULL;
70 }
71
72 Provider->ReferenceCount = 1;
73
74 InitializeCriticalSection(&Provider->Lock);
75 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
76
77 Provider->Mapping = NULL;
78
79 //EnterCriticalSection(&CatalogLock);
80
81 InsertTailList(&CatalogListHead, &Provider->ListEntry);
82
83 //LeaveCriticalSection(&CatalogLock);
84
85 return Provider;
86 }
87
88
89 INT DestroyCatalogEntry(
90 PCATALOG_ENTRY Provider)
91 {
92 INT Status;
93
94 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
95
96 //EnterCriticalSection(&CatalogLock);
97 RemoveEntryList(&Provider->ListEntry);
98 //LeaveCriticalSection(&CatalogLock);
99
100 HeapFree(GlobalHeap, 0, Provider->Mapping);
101
102 if (Provider->hModule) {
103 Status = UnloadProvider(Provider);
104 } else {
105 Status = NO_ERROR;
106 }
107
108 //DeleteCriticalSection(&Provider->Lock);
109
110 HeapFree(GlobalHeap, 0, Provider);
111
112 return Status;
113 }
114
115
116 PCATALOG_ENTRY LocateProvider(
117 LPWSAPROTOCOL_INFOW lpProtocolInfo)
118 {
119 PLIST_ENTRY CurrentEntry;
120 PCATALOG_ENTRY Provider;
121 UINT i;
122
123 WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
124
125 //EnterCriticalSection(&CatalogLock);
126
127 CurrentEntry = CatalogListHead.Flink;
128 while (CurrentEntry != &CatalogListHead) {
129 Provider = CONTAINING_RECORD(CurrentEntry,
130 CATALOG_ENTRY,
131 ListEntry);
132
133 for (i = 0; i < Provider->Mapping->Rows; i++) {
134 if ((lpProtocolInfo->iAddressFamily == Provider->Mapping->Mapping[i].AddressFamily) &&
135 (lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) &&
136 ((lpProtocolInfo->iProtocol == 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));
140 return Provider;
141 }
142 }
143
144 CurrentEntry = CurrentEntry->Flink;
145 }
146
147 LeaveCriticalSection(&CatalogLock);
148
149 return NULL;
150 }
151
152
153 PCATALOG_ENTRY LocateProviderById(
154 DWORD CatalogEntryId)
155 {
156 PLIST_ENTRY CurrentEntry;
157 PCATALOG_ENTRY Provider;
158 UINT i;
159
160 WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
161
162 //EnterCriticalSection(&CatalogLock);
163 CurrentEntry = CatalogListHead.Flink;
164 while (CurrentEntry != &CatalogListHead) {
165 Provider = CONTAINING_RECORD(CurrentEntry,
166 CATALOG_ENTRY,
167 ListEntry);
168
169 if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
170 //LeaveCriticalSection(&CatalogLock);
171 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%wZ).\n",
172 Provider, &Provider->LibraryName));
173 return Provider;
174 }
175
176 CurrentEntry = CurrentEntry->Flink;
177 }
178 //LeaveCriticalSection(&CatalogLock);
179
180 WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
181
182 return NULL;
183 }
184
185
186 INT LoadProvider(
187 PCATALOG_ENTRY Provider,
188 LPWSAPROTOCOL_INFOW lpProtocolInfo)
189 {
190 INT Status;
191
192 WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%wZ).\n",
193 Provider, &Provider->LibraryName));
194
195 if (Provider->hModule == INVALID_HANDLE_VALUE) {
196 /* DLL is not loaded so load it now */
197 Provider->hModule = LoadLibrary(Provider->LibraryName.Buffer);
198 if (Provider->hModule != INVALID_HANDLE_VALUE) {
199 Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(
200 Provider->hModule,
201 "WSPStartup");
202 if (Provider->WSPStartup) {
203 WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
204 Provider->WSPStartup));
205 Status = Provider->WSPStartup(
206 MAKEWORD(2, 2),
207 &Provider->WSPData,
208 lpProtocolInfo,
209 UpcallTable,
210 &Provider->ProcTable);
211
212 /* FIXME: Validate the procedure table */
213
214 WS_DbgPrint(MAX_TRACE, ("OFFSET2 (0x%X)\n",
215 FIELD_OFFSET(WSPPROC_TABLE, lpWSPSocket)));
216
217 assert(Provider->ProcTable.lpWSPSocket);
218
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(MAX_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 (Provider->hModule) {
240 WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
241 Provider->ProcTable.lpWSPCleanup));
242 Provider->ProcTable.lpWSPCleanup(&Status);
243
244 if (!FreeLibrary(Provider->hModule)) {
245 WS_DbgPrint(MIN_TRACE, ("Could not free library.\n"));
246 Status = GetLastError();
247 }
248
249 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
250 }
251
252 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
253
254 return Status;
255 }
256
257
258 VOID CreateCatalog(VOID)
259 {
260 PCATALOG_ENTRY Provider;
261
262 InitializeCriticalSection(&CatalogLock);
263
264 InitializeListHead(&CatalogListHead);
265
266 /* FIXME: Read service provider catalog from registry */
267 #if 1
268 Provider = CreateCatalogEntry(L"msafd.dll");
269 if (!Provider) {
270 WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
271 return;
272 }
273
274 /* Assume one Service Provider with id 1 */
275 Provider->ProtocolInfo.dwCatalogEntryId = 1;
276
277 Provider->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
278 if (!Provider->Mapping) {
279 WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
280 return;
281 }
282
283 Provider->Mapping->Rows = 1;
284 Provider->Mapping->Columns = 3;
285 Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
286 Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
287 Provider->Mapping->Mapping[0].Protocol = 0;
288 #endif
289 }
290
291
292 VOID DestroyCatalog(VOID)
293 {
294 PLIST_ENTRY CurrentEntry;
295 PLIST_ENTRY NextEntry;
296 PCATALOG_ENTRY Provider;
297
298 CurrentEntry = CatalogListHead.Flink;
299 while (CurrentEntry != &CatalogListHead) {
300 NextEntry = CurrentEntry->Flink;
301 Provider = CONTAINING_RECORD(CurrentEntry,
302 CATALOG_ENTRY,
303 ListEntry);
304 DestroyCatalogEntry(Provider);
305 CurrentEntry = NextEntry;
306 }
307 //DeleteCriticalSection(&CatalogLock);
308 }
309
310 /* EOF */