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
17 CRITICAL_SECTION HelperDLLDatabaseLock
;
18 LIST_ENTRY HelperDLLDatabaseListHead
;
28 PUNICODE_STRING TransportName
,
29 PVOID
*HelperDllContext
,
30 PHELPER_DATA
*HelperDllData
,
33 PHELPER_DATA HelperData
;
36 PWINSOCK_MAPPING Mapping
;
40 AFD_DbgPrint(MID_TRACE
,("Called\n"));
42 /* Check in our Current Loaded Helpers */
43 for (Helpers
= SockHelpersListHead
.Flink
;
44 Helpers
!= &SockHelpersListHead
;
45 Helpers
= Helpers
->Flink
) {
47 HelperData
= CONTAINING_RECORD(Helpers
, HELPER_DATA
, Helpers
);
49 /* See if this Mapping works for us */
50 if (SockIsTripleInMapping (HelperData
->Mapping
,
55 /* Call the Helper Dll function get the Transport Name */
56 if (HelperData
->WSHOpenSocket2
== NULL
) {
58 /* DLL Doesn't support WSHOpenSocket2, call the old one */
59 HelperData
->WSHOpenSocket(AddressFamily
,
67 HelperData
->WSHOpenSocket2(AddressFamily
,
78 /* Return the Helper Pointers */
79 *HelperDllData
= HelperData
;
84 /* Get the Transports available */
85 Status
= SockLoadTransportList(&Transports
);
89 AFD_DbgPrint(MIN_TRACE
, ("Can't get transport list\n"));
93 /* Loop through each transport until we find one that can satisfy us */
94 for (Transport
= Transports
;
96 Transport
+= wcslen(Transport
) + 1) {
97 AFD_DbgPrint(MID_TRACE
, ("Transport: %S\n", Transports
));
99 /* See what mapping this Transport supports */
100 Status
= SockLoadTransportMapping(Transport
, &Mapping
);
102 /* Check for error */
104 AFD_DbgPrint(MIN_TRACE
, ("Can't get mapping\n"));
105 HeapFree(GlobalHeap
, 0, Transports
);
109 /* See if this Mapping works for us */
110 if (SockIsTripleInMapping(Mapping
, *AddressFamily
, *SocketType
, *Protocol
)) {
112 /* It does, so load the DLL associated with it */
113 Status
= SockLoadHelperDll(Transport
, Mapping
, &HelperData
);
115 /* Check for error */
117 AFD_DbgPrint(MIN_TRACE
, ("Can't load helper DLL\n"));
118 HeapFree(GlobalHeap
, 0, Transports
);
119 HeapFree(GlobalHeap
, 0, Mapping
);
123 /* Call the Helper Dll function get the Transport Name */
124 if (HelperData
->WSHOpenSocket2
== NULL
) {
125 /* DLL Doesn't support WSHOpenSocket2, call the old one */
126 HelperData
->WSHOpenSocket(AddressFamily
,
134 HelperData
->WSHOpenSocket2(AddressFamily
,
145 /* Return the Helper Pointers */
146 *HelperDllData
= HelperData
;
147 /* We actually cache these ... the can't be freed yet */
148 /*HeapFree(GlobalHeap, 0, Transports);*/
149 /*HeapFree(GlobalHeap, 0, Mapping);*/
153 HeapFree(GlobalHeap
, 0, Mapping
);
155 HeapFree(GlobalHeap
, 0, Transports
);
160 SockLoadTransportMapping(
162 PWINSOCK_MAPPING
*Mapping
)
169 AFD_DbgPrint(MID_TRACE
,("Called: TransportName %ws\n", TransportName
));
171 /* Allocate a Buffer */
172 TransportKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
174 /* Check for error */
175 if (TransportKey
== NULL
) {
176 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
180 /* Generate the right key name */
181 wcscpy(TransportKey
, L
"System\\CurrentControlSet\\Services\\");
182 wcscat(TransportKey
, TransportName
);
183 wcscat(TransportKey
, L
"\\Parameters\\Winsock");
186 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, TransportKey
, 0, KEY_READ
, &KeyHandle
);
188 /* We don't need the Transport Key anymore */
189 HeapFree(GlobalHeap
, 0, TransportKey
);
191 /* Check for error */
193 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
197 /* Find out how much space we need for the Mapping */
198 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, NULL
, &MappingSize
);
200 /* Check for error */
202 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
206 /* Allocate Memory for the Mapping */
207 *Mapping
= HeapAlloc(GlobalHeap
, 0, MappingSize
);
209 /* Check for error */
210 if (*Mapping
== NULL
) {
211 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
215 /* Read the Mapping */
216 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, (LPBYTE
)*Mapping
, &MappingSize
);
218 /* Check for error */
220 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
221 HeapFree(GlobalHeap
, 0, *Mapping
);
225 /* Close key and return */
226 RegCloseKey(KeyHandle
);
231 SockLoadTransportList(
232 PWSTR
*TransportList
)
234 ULONG TransportListSize
;
238 AFD_DbgPrint(MID_TRACE
,("Called\n"));
240 /* Open the Transports Key */
241 Status
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
242 L
"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
247 /* Check for error */
249 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
253 /* Get the Transport List Size */
254 Status
= RegQueryValueExW(KeyHandle
,
261 /* Check for error */
263 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
267 /* Allocate Memory for the Transport List */
268 *TransportList
= HeapAlloc(GlobalHeap
, 0, TransportListSize
);
270 /* Check for error */
271 if (*TransportList
== NULL
) {
272 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
276 /* Get the Transports */
277 Status
= RegQueryValueExW (KeyHandle
,
281 (LPBYTE
)*TransportList
,
284 /* Check for error */
286 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
287 HeapFree(GlobalHeap
, 0, *TransportList
);
291 /* Close key and return */
292 RegCloseKey(KeyHandle
);
299 PWINSOCK_MAPPING Mapping
,
300 PHELPER_DATA
*HelperDllData
)
302 PHELPER_DATA HelperData
;
304 PWSTR FullHelperDllName
;
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 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_SOCKADDR
)
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"));