2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
5 * PURPOSE: Helper DLL management
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
9 * CSH 01/09-2000 Created
10 * Alex 16/07/2004 - Complete Rewrite
16 CRITICAL_SECTION HelperDLLDatabaseLock
;
17 LIST_ENTRY HelperDLLDatabaseListHead
;
27 PUNICODE_STRING TransportName
,
28 PVOID
*HelperDllContext
,
29 PHELPER_DATA
*HelperDllData
,
32 PHELPER_DATA HelperData
;
35 PWINSOCK_MAPPING Mapping
;
39 AFD_DbgPrint(MID_TRACE
,("Called\n"));
41 /* Check in our Current Loaded Helpers */
42 for (Helpers
= SockHelpersListHead
.Flink
;
43 Helpers
!= &SockHelpersListHead
;
44 Helpers
= Helpers
->Flink
) {
46 HelperData
= CONTAINING_RECORD(Helpers
, HELPER_DATA
, Helpers
);
48 /* See if this Mapping works for us */
49 if (SockIsTripleInMapping (HelperData
->Mapping
,
54 /* Call the Helper Dll function get the Transport Name */
55 if (HelperData
->WSHOpenSocket2
== NULL
) {
57 /* DLL Doesn't support WSHOpenSocket2, call the old one */
58 HelperData
->WSHOpenSocket(AddressFamily
,
66 HelperData
->WSHOpenSocket2(AddressFamily
,
77 /* Return the Helper Pointers */
78 *HelperDllData
= HelperData
;
83 /* Get the Transports available */
84 Status
= SockLoadTransportList(&Transports
);
88 AFD_DbgPrint(MIN_TRACE
, ("Can't get transport list\n"));
92 /* Loop through each transport until we find one that can satisfy us */
93 for (Transport
= Transports
;
95 Transport
+= wcslen(Transport
) + 1) {
96 AFD_DbgPrint(MID_TRACE
, ("Transport: %S\n", Transports
));
98 /* See what mapping this Transport supports */
99 Status
= SockLoadTransportMapping(Transport
, &Mapping
);
101 /* Check for error */
103 AFD_DbgPrint(MIN_TRACE
, ("Can't get mapping\n"));
104 HeapFree(GlobalHeap
, 0, Transports
);
108 /* See if this Mapping works for us */
109 if (SockIsTripleInMapping(Mapping
, *AddressFamily
, *SocketType
, *Protocol
)) {
111 /* It does, so load the DLL associated with it */
112 Status
= SockLoadHelperDll(Transport
, Mapping
, &HelperData
);
114 /* Check for error */
116 AFD_DbgPrint(MIN_TRACE
, ("Can't load helper DLL\n"));
117 HeapFree(GlobalHeap
, 0, Transports
);
118 HeapFree(GlobalHeap
, 0, Mapping
);
122 /* Call the Helper Dll function get the Transport Name */
123 if (HelperData
->WSHOpenSocket2
== NULL
) {
124 /* DLL Doesn't support WSHOpenSocket2, call the old one */
125 HelperData
->WSHOpenSocket(AddressFamily
,
133 HelperData
->WSHOpenSocket2(AddressFamily
,
144 /* Return the Helper Pointers */
145 *HelperDllData
= HelperData
;
146 /* We actually cache these ... the can't be freed yet */
147 /*HeapFree(GlobalHeap, 0, Transports);*/
148 /*HeapFree(GlobalHeap, 0, Mapping);*/
152 HeapFree(GlobalHeap
, 0, Mapping
);
154 HeapFree(GlobalHeap
, 0, Transports
);
159 SockLoadTransportMapping(
161 PWINSOCK_MAPPING
*Mapping
)
168 AFD_DbgPrint(MID_TRACE
,("Called: TransportName %ws\n", TransportName
));
170 /* Allocate a Buffer */
171 TransportKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
173 /* Check for error */
174 if (TransportKey
== NULL
) {
175 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
179 /* Generate the right key name */
180 wcscpy(TransportKey
, L
"System\\CurrentControlSet\\Services\\");
181 wcscat(TransportKey
, TransportName
);
182 wcscat(TransportKey
, L
"\\Parameters\\Winsock");
185 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, TransportKey
, 0, KEY_READ
, &KeyHandle
);
187 /* We don't need the Transport Key anymore */
188 HeapFree(GlobalHeap
, 0, TransportKey
);
190 /* Check for error */
192 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
196 /* Find out how much space we need for the Mapping */
197 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, NULL
, &MappingSize
);
199 /* Check for error */
201 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
205 /* Allocate Memory for the Mapping */
206 *Mapping
= HeapAlloc(GlobalHeap
, 0, MappingSize
);
208 /* Check for error */
209 if (*Mapping
== NULL
) {
210 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
214 /* Read the Mapping */
215 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, (LPBYTE
)*Mapping
, &MappingSize
);
217 /* Check for error */
219 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
220 HeapFree(GlobalHeap
, 0, *Mapping
);
224 /* Close key and return */
225 RegCloseKey(KeyHandle
);
230 SockLoadTransportList(
231 PWSTR
*TransportList
)
233 ULONG TransportListSize
;
237 AFD_DbgPrint(MID_TRACE
,("Called\n"));
239 /* Open the Transports Key */
240 Status
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
241 L
"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
246 /* Check for error */
248 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
252 /* Get the Transport List Size */
253 Status
= RegQueryValueExW(KeyHandle
,
260 /* Check for error */
262 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
266 /* Allocate Memory for the Transport List */
267 *TransportList
= HeapAlloc(GlobalHeap
, 0, TransportListSize
);
269 /* Check for error */
270 if (*TransportList
== NULL
) {
271 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
275 /* Get the Transports */
276 Status
= RegQueryValueExW (KeyHandle
,
280 (LPBYTE
)*TransportList
,
283 /* Check for error */
285 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
286 HeapFree(GlobalHeap
, 0, *TransportList
);
290 /* Close key and return */
291 RegCloseKey(KeyHandle
);
298 PWINSOCK_MAPPING Mapping
,
299 PHELPER_DATA
*HelperDllData
)
301 PHELPER_DATA HelperData
;
303 PWSTR FullHelperDllName
;
304 ULONG HelperDllNameSize
;
310 /* Allocate space for the Helper Structure and TransportName */
311 HelperData
= HeapAlloc(GlobalHeap
, 0, sizeof(*HelperData
) + (wcslen(TransportName
) + 1) * sizeof(WCHAR
));
313 /* Check for error */
314 if (HelperData
== NULL
) {
315 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
319 /* Allocate Space for the Helper DLL Key */
320 HelperKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
322 /* Check for error */
323 if (HelperKey
== NULL
) {
324 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
325 HeapFree(GlobalHeap
, 0, HelperData
);
329 /* Generate the right key name */
330 wcscpy(HelperKey
, L
"System\\CurrentControlSet\\Services\\");
331 wcscat(HelperKey
, TransportName
);
332 wcscat(HelperKey
, L
"\\Parameters\\Winsock");
335 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, HelperKey
, 0, KEY_READ
, &KeyHandle
);
337 HeapFree(GlobalHeap
, 0, HelperKey
);
339 /* Check for error */
341 AFD_DbgPrint(MIN_TRACE
, ("Error reading helper DLL parameters\n"));
342 HeapFree(GlobalHeap
, 0, HelperData
);
346 /* Read Size of SockAddr Structures */
347 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
348 HelperData
->MinWSAddressLength
= 16;
349 RegQueryValueExW (KeyHandle
,
350 L
"MinSockaddrLength",
353 (LPBYTE
)&HelperData
->MinWSAddressLength
,
355 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
356 HelperData
->MaxWSAddressLength
= 16;
357 RegQueryValueExW (KeyHandle
,
358 L
"MaxSockaddrLength",
361 (LPBYTE
)&HelperData
->MaxWSAddressLength
,
364 /* Size of TDI Structures */
365 HelperData
->MinTDIAddressLength
= HelperData
->MinWSAddressLength
+ 6;
366 HelperData
->MaxTDIAddressLength
= HelperData
->MaxWSAddressLength
+ 6;
368 /* Read Delayed Acceptance Setting */
369 DataSize
= sizeof(DWORD
);
370 HelperData
->UseDelayedAcceptance
= FALSE
;
371 RegQueryValueExW (KeyHandle
,
372 L
"UseDelayedAcceptance",
375 (LPBYTE
)&HelperData
->UseDelayedAcceptance
,
378 /* Allocate Space for the Helper DLL Names */
379 HelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
381 /* Check for error */
382 if (HelperDllName
== NULL
) {
383 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
384 HeapFree(GlobalHeap
, 0, HelperData
);
388 FullHelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
390 /* Check for error */
391 if (FullHelperDllName
== NULL
) {
392 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
393 HeapFree(GlobalHeap
, 0, HelperDllName
);
394 HeapFree(GlobalHeap
, 0, HelperData
);
398 /* Get the name of the Helper DLL*/
400 Status
= RegQueryValueExW (KeyHandle
,
404 (LPBYTE
)HelperDllName
,
407 /* Check for error */
409 AFD_DbgPrint(MIN_TRACE
, ("Error reading helper DLL parameters\n"));
410 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
411 HeapFree(GlobalHeap
, 0, HelperDllName
);
412 HeapFree(GlobalHeap
, 0, HelperData
);
416 /* Get the Full name, expanding Environment Strings */
417 HelperDllNameSize
= ExpandEnvironmentStringsW (HelperDllName
,
422 HelperData
->hInstance
= LoadLibraryW(FullHelperDllName
);
424 HeapFree(GlobalHeap
, 0, HelperDllName
);
425 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
427 if (HelperData
->hInstance
== NULL
) {
428 AFD_DbgPrint(MIN_TRACE
, ("Error loading helper DLL\n"));
429 HeapFree(GlobalHeap
, 0, HelperData
);
434 RegCloseKey(KeyHandle
);
436 /* Get the Pointers to the Helper Routines */
437 HelperData
->WSHOpenSocket
= (PWSH_OPEN_SOCKET
)
438 GetProcAddress(HelperData
->hInstance
,
440 HelperData
->WSHOpenSocket2
= (PWSH_OPEN_SOCKET2
)
441 GetProcAddress(HelperData
->hInstance
,
443 HelperData
->WSHJoinLeaf
= (PWSH_JOIN_LEAF
)
444 GetProcAddress(HelperData
->hInstance
,
446 HelperData
->WSHNotify
= (PWSH_NOTIFY
)
447 GetProcAddress(HelperData
->hInstance
, "WSHNotify");
448 HelperData
->WSHGetSocketInformation
= (PWSH_GET_SOCKET_INFORMATION
)
449 GetProcAddress(HelperData
->hInstance
,
450 "WSHGetSocketInformation");
451 HelperData
->WSHSetSocketInformation
= (PWSH_SET_SOCKET_INFORMATION
)
452 GetProcAddress(HelperData
->hInstance
,
453 "WSHSetSocketInformation");
454 HelperData
->WSHGetSockaddrType
= (PWSH_GET_SOCKADDR_TYPE
)
455 GetProcAddress(HelperData
->hInstance
,
456 "WSHGetSockaddrType");
457 HelperData
->WSHGetWildcardSockaddr
= (PWSH_GET_WILDCARD_SOCKEADDR
)
458 GetProcAddress(HelperData
->hInstance
,
459 "WSHGetWildcardSockaddr");
460 HelperData
->WSHGetBroadcastSockaddr
= (PWSH_GET_BROADCAST_SOCKADDR
)
461 GetProcAddress(HelperData
->hInstance
,
462 "WSHGetBroadcastSockaddr");
463 HelperData
->WSHAddressToString
= (PWSH_ADDRESS_TO_STRING
)
464 GetProcAddress(HelperData
->hInstance
,
465 "WSHAddressToString");
466 HelperData
->WSHStringToAddress
= (PWSH_STRING_TO_ADDRESS
)
467 GetProcAddress(HelperData
->hInstance
,
468 "WSHStringToAddress");
469 HelperData
->WSHIoctl
= (PWSH_IOCTL
)
470 GetProcAddress(HelperData
->hInstance
,
473 /* Save the Mapping Structure and transport name */
474 HelperData
->Mapping
= Mapping
;
475 wcscpy(HelperData
->TransportName
, TransportName
);
477 /* Increment Reference Count */
478 HelperData
->RefCount
= 1;
480 /* Add it to our list */
481 InsertHeadList(&SockHelpersListHead
, &HelperData
->Helpers
);
483 /* Return Pointers */
484 *HelperDllData
= HelperData
;
489 SockIsTripleInMapping(
490 PWINSOCK_MAPPING Mapping
,
495 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
498 AFD_DbgPrint(MID_TRACE
,("Called, Mapping rows = %d\n", Mapping
->Rows
));
500 /* Loop through Mapping to Find a matching one */
501 for (Row
= 0; Row
< Mapping
->Rows
; Row
++) {
502 AFD_DbgPrint(MID_TRACE
,("Examining: row %d: AF %d type %d proto %d\n",
504 (INT
)Mapping
->Mapping
[Row
].AddressFamily
,
505 (INT
)Mapping
->Mapping
[Row
].SocketType
,
506 (INT
)Mapping
->Mapping
[Row
].Protocol
));
508 /* Check of all three values Match */
509 if (((INT
)Mapping
->Mapping
[Row
].AddressFamily
== AddressFamily
) &&
510 ((INT
)Mapping
->Mapping
[Row
].SocketType
== SocketType
) &&
511 ((INT
)Mapping
->Mapping
[Row
].Protocol
== Protocol
)) {
512 AFD_DbgPrint(MID_TRACE
,("Found\n"));
516 AFD_DbgPrint(MID_TRACE
,("Not found\n"));