Work on winsock stack and indentation corrections.
[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 WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
63 return NULL;
64 }
65
66 ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
67
68 Provider->ReferenceCount = 1;
69
70 InitializeCriticalSection(&Provider->Lock);
71 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
72
73 Provider->Mapping = NULL;
74
75 //EnterCriticalSection(&CatalogLock);
76
77 InsertTailList(&CatalogListHead, &Provider->ListEntry);
78
79 //LeaveCriticalSection(&CatalogLock);
80
81 return Provider;
82 }
83
84
85 INT DestroyCatalogEntry(
86 PCATALOG_ENTRY Provider)
87 {
88 INT Status;
89
90 WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
91
92 //EnterCriticalSection(&CatalogLock);
93 RemoveEntryList(&Provider->ListEntry);
94 //LeaveCriticalSection(&CatalogLock);
95
96 HeapFree(GlobalHeap, 0, Provider->Mapping);
97
98 if (Provider->hModule) {
99 Status = UnloadProvider(Provider);
100 } else {
101 Status = NO_ERROR;
102 }
103
104 //DeleteCriticalSection(&Provider->Lock);
105
106 HeapFree(GlobalHeap, 0, Provider);
107
108 return Status;
109 }
110
111
112 PCATALOG_ENTRY LocateProvider(
113 LPWSAPROTOCOL_INFOW lpProtocolInfo)
114 {
115 PLIST_ENTRY CurrentEntry;
116 PCATALOG_ENTRY Provider;
117 UINT i;
118
119 WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
120
121 //EnterCriticalSection(&CatalogLock);
122
123 CurrentEntry = CatalogListHead.Flink;
124 while (CurrentEntry != &CatalogListHead) {
125 Provider = CONTAINING_RECORD(CurrentEntry,
126 CATALOG_ENTRY,
127 ListEntry);
128
129 for (i = 0; i < Provider->Mapping->Rows; i++) {
130 if ((lpProtocolInfo->iAddressFamily == Provider->Mapping->Mapping[i].AddressFamily) &&
131 (lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) &&
132 ((lpProtocolInfo->iProtocol == Provider->Mapping->Mapping[i].Protocol) ||
133 (lpProtocolInfo->iSocketType == SOCK_RAW))) {
134 //LeaveCriticalSection(&CatalogLock);
135 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
136 return Provider;
137 }
138 }
139
140 CurrentEntry = CurrentEntry->Flink;
141 }
142
143 LeaveCriticalSection(&CatalogLock);
144
145 return NULL;
146 }
147
148
149 PCATALOG_ENTRY LocateProviderById(
150 DWORD CatalogEntryId)
151 {
152 PLIST_ENTRY CurrentEntry;
153 PCATALOG_ENTRY Provider;
154 UINT i;
155
156 WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
157
158 //EnterCriticalSection(&CatalogLock);
159 CurrentEntry = CatalogListHead.Flink;
160 while (CurrentEntry != &CatalogListHead) {
161 Provider = CONTAINING_RECORD(CurrentEntry,
162 CATALOG_ENTRY,
163 ListEntry);
164
165 if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
166 //LeaveCriticalSection(&CatalogLock);
167 WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%s).\n",
168 Provider, Provider->LibraryName));
169 return Provider;
170 }
171
172 CurrentEntry = CurrentEntry->Flink;
173 }
174 //LeaveCriticalSection(&CatalogLock);
175
176 WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
177
178 return NULL;
179 }
180
181
182 INT LoadProvider(
183 PCATALOG_ENTRY Provider,
184 LPWSAPROTOCOL_INFOW lpProtocolInfo)
185 {
186 INT Status;
187
188 WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%S).\n",
189 Provider, Provider->LibraryName));
190
191 if (!Provider->hModule) {
192 /* DLL is not loaded so load it now */
193 Provider->hModule = LoadLibrary(Provider->LibraryName);
194
195 if (Provider->hModule) {
196 Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
197 "WSPStartup");
198 if (Provider->WSPStartup) {
199 WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n", Provider->WSPStartup));
200 Status = Provider->WSPStartup(MAKEWORD(2, 2),
201 &Provider->WSPData,
202 lpProtocolInfo,
203 UpcallTable,
204 &Provider->ProcTable);
205 } else
206 Status = ERROR_BAD_PROVIDER;
207 } else
208 Status = ERROR_DLL_NOT_FOUND;
209 } else
210 Status = NO_ERROR;
211
212 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
213
214 return Status;
215 }
216
217
218 INT UnloadProvider(
219 PCATALOG_ENTRY Provider)
220 {
221 INT Status = NO_ERROR;
222
223 WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
224
225 if (Provider->hModule) {
226 WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
227 Provider->ProcTable.lpWSPCleanup));
228 Provider->ProcTable.lpWSPCleanup(&Status);
229
230 if (!FreeLibrary(Provider->hModule)) {
231 WS_DbgPrint(MIN_TRACE, ("Could not free library.\n"));
232 Status = GetLastError();
233 }
234
235 Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
236 }
237
238 WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
239
240 return Status;
241 }
242
243
244 VOID CreateCatalog(VOID)
245 {
246 PCATALOG_ENTRY Provider;
247
248 InitializeCriticalSection(&CatalogLock);
249
250 InitializeListHead(&CatalogListHead);
251
252 /* FIXME: Read service provider catalog from registry */
253 #if 1
254 Provider = CreateCatalogEntry(L"msafd.dll");
255 if (!Provider) {
256 WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
257 return;
258 }
259
260 /* Assume one Service Provider with id 1 */
261 Provider->ProtocolInfo.dwCatalogEntryId = 1;
262
263 Provider->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
264 if (!Provider->Mapping) {
265 WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
266 return;
267 }
268
269 Provider->Mapping->Rows = 1;
270 Provider->Mapping->Columns = 3;
271 Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
272 Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
273 Provider->Mapping->Mapping[0].Protocol = 0;
274 #endif
275 }
276
277
278 VOID DestroyCatalog(VOID)
279 {
280 PLIST_ENTRY CurrentEntry;
281 PLIST_ENTRY NextEntry;
282 PCATALOG_ENTRY Provider;
283
284 CurrentEntry = CatalogListHead.Flink;
285 while (CurrentEntry != &CatalogListHead) {
286 NextEntry = CurrentEntry->Flink;
287 Provider = CONTAINING_RECORD(CurrentEntry,
288 CATALOG_ENTRY,
289 ListEntry);
290 DestroyCatalogEntry(Provider);
291 CurrentEntry = NextEntry;
292 }
293 //DeleteCriticalSection(&CatalogLock);
294 }
295
296 /* EOF */