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
14 CRITICAL_SECTION HelperDLLDatabaseLock
;
15 LIST_ENTRY HelperDLLDatabaseListHead
;
25 PUNICODE_STRING TransportName
,
26 PVOID
*HelperDllContext
,
27 PHELPER_DATA
*HelperDllData
,
30 PHELPER_DATA HelperData
;
33 PWINSOCK_MAPPING Mapping
;
37 AFD_DbgPrint(MID_TRACE
,("Called\n"));
39 /* Check in our Current Loaded Helpers */
40 for (Helpers
= SockHelpersListHead
.Flink
;
41 Helpers
!= &SockHelpersListHead
;
42 Helpers
= Helpers
->Flink
) {
44 HelperData
= CONTAINING_RECORD(Helpers
, HELPER_DATA
, Helpers
);
46 /* See if this Mapping works for us */
47 if (SockIsTripleInMapping (HelperData
->Mapping
,
52 /* Call the Helper Dll function get the Transport Name */
53 if (HelperData
->WSHOpenSocket2
== NULL
) {
55 /* DLL Doesn't support WSHOpenSocket2, call the old one */
56 HelperData
->WSHOpenSocket(AddressFamily
,
64 HelperData
->WSHOpenSocket2(AddressFamily
,
75 /* Return the Helper Pointers */
76 *HelperDllData
= HelperData
;
81 /* Get the Transports available */
82 Status
= SockLoadTransportList(&Transports
);
86 AFD_DbgPrint(MIN_TRACE
, ("Can't get transport list\n"));
90 /* Loop through each transport until we find one that can satisfy us */
91 for (Transport
= Transports
;
93 Transport
+= wcslen(Transport
) + 1) {
94 AFD_DbgPrint(MID_TRACE
, ("Transport: %S\n", Transports
));
96 /* See what mapping this Transport supports */
97 Status
= SockLoadTransportMapping(Transport
, &Mapping
);
101 AFD_DbgPrint(MIN_TRACE
, ("Can't get mapping\n"));
102 HeapFree(GlobalHeap
, 0, Transports
);
106 /* See if this Mapping works for us */
107 if (SockIsTripleInMapping(Mapping
, *AddressFamily
, *SocketType
, *Protocol
)) {
109 /* It does, so load the DLL associated with it */
110 Status
= SockLoadHelperDll(Transport
, Mapping
, &HelperData
);
112 /* Check for error */
114 AFD_DbgPrint(MIN_TRACE
, ("Can't load helper DLL\n"));
115 HeapFree(GlobalHeap
, 0, Transports
);
116 HeapFree(GlobalHeap
, 0, Mapping
);
120 /* Call the Helper Dll function get the Transport Name */
121 if (HelperData
->WSHOpenSocket2
== NULL
) {
122 /* DLL Doesn't support WSHOpenSocket2, call the old one */
123 HelperData
->WSHOpenSocket(AddressFamily
,
131 HelperData
->WSHOpenSocket2(AddressFamily
,
142 /* Return the Helper Pointers */
143 *HelperDllData
= HelperData
;
144 /* We actually cache these ... the can't be freed yet */
145 /*HeapFree(GlobalHeap, 0, Transports);*/
146 /*HeapFree(GlobalHeap, 0, Mapping);*/
150 HeapFree(GlobalHeap
, 0, Mapping
);
152 HeapFree(GlobalHeap
, 0, Transports
);
157 SockLoadTransportMapping(
159 PWINSOCK_MAPPING
*Mapping
)
166 AFD_DbgPrint(MID_TRACE
,("Called: TransportName %ws\n", TransportName
));
168 /* Allocate a Buffer */
169 TransportKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
171 /* Check for error */
172 if (TransportKey
== NULL
) {
173 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
177 /* Generate the right key name */
178 wcscpy(TransportKey
, L
"System\\CurrentControlSet\\Services\\");
179 wcscat(TransportKey
, TransportName
);
180 wcscat(TransportKey
, L
"\\Parameters\\Winsock");
183 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, TransportKey
, 0, KEY_READ
, &KeyHandle
);
185 /* We don't need the Transport Key anymore */
186 HeapFree(GlobalHeap
, 0, TransportKey
);
188 /* Check for error */
190 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
194 /* Find out how much space we need for the Mapping */
195 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, NULL
, &MappingSize
);
197 /* Check for error */
199 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
203 /* Allocate Memory for the Mapping */
204 *Mapping
= HeapAlloc(GlobalHeap
, 0, MappingSize
);
206 /* Check for error */
207 if (*Mapping
== NULL
) {
208 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
212 /* Read the Mapping */
213 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, (LPBYTE
)*Mapping
, &MappingSize
);
215 /* Check for error */
217 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport mapping registry\n"));
218 HeapFree(GlobalHeap
, 0, *Mapping
);
222 /* Close key and return */
223 RegCloseKey(KeyHandle
);
228 SockLoadTransportList(
229 PWSTR
*TransportList
)
231 ULONG TransportListSize
;
235 AFD_DbgPrint(MID_TRACE
,("Called\n"));
237 /* Open the Transports Key */
238 Status
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
239 L
"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
244 /* Check for error */
246 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
250 /* Get the Transport List Size */
251 Status
= RegQueryValueExW(KeyHandle
,
258 /* Check for error */
260 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
264 /* Allocate Memory for the Transport List */
265 *TransportList
= HeapAlloc(GlobalHeap
, 0, TransportListSize
);
267 /* Check for error */
268 if (*TransportList
== NULL
) {
269 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
273 /* Get the Transports */
274 Status
= RegQueryValueExW (KeyHandle
,
278 (LPBYTE
)*TransportList
,
281 /* Check for error */
283 AFD_DbgPrint(MIN_TRACE
, ("Error reading transport list registry\n"));
284 HeapFree(GlobalHeap
, 0, *TransportList
);
288 /* Close key and return */
289 RegCloseKey(KeyHandle
);
296 PWINSOCK_MAPPING Mapping
,
297 PHELPER_DATA
*HelperDllData
)
299 PHELPER_DATA HelperData
;
301 PWSTR FullHelperDllName
;
307 /* Allocate space for the Helper Structure and TransportName */
308 HelperData
= HeapAlloc(GlobalHeap
, 0, sizeof(*HelperData
) + (wcslen(TransportName
) + 1) * sizeof(WCHAR
));
310 /* Check for error */
311 if (HelperData
== NULL
) {
312 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
316 /* Allocate Space for the Helper DLL Key */
317 HelperKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
319 /* Check for error */
320 if (HelperKey
== NULL
) {
321 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
322 HeapFree(GlobalHeap
, 0, HelperData
);
326 /* Generate the right key name */
327 wcscpy(HelperKey
, L
"System\\CurrentControlSet\\Services\\");
328 wcscat(HelperKey
, TransportName
);
329 wcscat(HelperKey
, L
"\\Parameters\\Winsock");
332 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, HelperKey
, 0, KEY_READ
, &KeyHandle
);
334 HeapFree(GlobalHeap
, 0, HelperKey
);
336 /* Check for error */
338 AFD_DbgPrint(MIN_TRACE
, ("Error reading helper DLL parameters\n"));
339 HeapFree(GlobalHeap
, 0, HelperData
);
343 /* Read Size of SockAddr Structures */
344 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
345 HelperData
->MinWSAddressLength
= 16;
346 RegQueryValueExW (KeyHandle
,
347 L
"MinSockaddrLength",
350 (LPBYTE
)&HelperData
->MinWSAddressLength
,
352 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
353 HelperData
->MaxWSAddressLength
= 16;
354 RegQueryValueExW (KeyHandle
,
355 L
"MaxSockaddrLength",
358 (LPBYTE
)&HelperData
->MaxWSAddressLength
,
361 /* Size of TDI Structures */
362 HelperData
->MinTDIAddressLength
= HelperData
->MinWSAddressLength
+ 6;
363 HelperData
->MaxTDIAddressLength
= HelperData
->MaxWSAddressLength
+ 6;
365 /* Read Delayed Acceptance Setting */
366 DataSize
= sizeof(DWORD
);
367 HelperData
->UseDelayedAcceptance
= FALSE
;
368 RegQueryValueExW (KeyHandle
,
369 L
"UseDelayedAcceptance",
372 (LPBYTE
)&HelperData
->UseDelayedAcceptance
,
375 /* Allocate Space for the Helper DLL Names */
376 HelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
378 /* Check for error */
379 if (HelperDllName
== NULL
) {
380 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
381 HeapFree(GlobalHeap
, 0, HelperData
);
385 FullHelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
387 /* Check for error */
388 if (FullHelperDllName
== NULL
) {
389 AFD_DbgPrint(MIN_TRACE
, ("Buffer allocation failed\n"));
390 HeapFree(GlobalHeap
, 0, HelperDllName
);
391 HeapFree(GlobalHeap
, 0, HelperData
);
395 /* Get the name of the Helper DLL*/
397 Status
= RegQueryValueExW (KeyHandle
,
401 (LPBYTE
)HelperDllName
,
404 /* Check for error */
406 AFD_DbgPrint(MIN_TRACE
, ("Error reading helper DLL parameters\n"));
407 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
408 HeapFree(GlobalHeap
, 0, HelperDllName
);
409 HeapFree(GlobalHeap
, 0, HelperData
);
413 /* Get the Full name, expanding Environment Strings */
414 ExpandEnvironmentStringsW (HelperDllName
,
419 HelperData
->hInstance
= LoadLibraryW(FullHelperDllName
);
421 HeapFree(GlobalHeap
, 0, HelperDllName
);
422 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
424 if (HelperData
->hInstance
== NULL
) {
425 AFD_DbgPrint(MIN_TRACE
, ("Error loading helper DLL\n"));
426 HeapFree(GlobalHeap
, 0, HelperData
);
431 RegCloseKey(KeyHandle
);
433 /* Get the Pointers to the Helper Routines */
434 HelperData
->WSHOpenSocket
= (PWSH_OPEN_SOCKET
)
435 GetProcAddress(HelperData
->hInstance
,
437 HelperData
->WSHOpenSocket2
= (PWSH_OPEN_SOCKET2
)
438 GetProcAddress(HelperData
->hInstance
,
440 HelperData
->WSHJoinLeaf
= (PWSH_JOIN_LEAF
)
441 GetProcAddress(HelperData
->hInstance
,
443 HelperData
->WSHNotify
= (PWSH_NOTIFY
)
444 GetProcAddress(HelperData
->hInstance
, "WSHNotify");
445 HelperData
->WSHGetSocketInformation
= (PWSH_GET_SOCKET_INFORMATION
)
446 GetProcAddress(HelperData
->hInstance
,
447 "WSHGetSocketInformation");
448 HelperData
->WSHSetSocketInformation
= (PWSH_SET_SOCKET_INFORMATION
)
449 GetProcAddress(HelperData
->hInstance
,
450 "WSHSetSocketInformation");
451 HelperData
->WSHGetSockaddrType
= (PWSH_GET_SOCKADDR_TYPE
)
452 GetProcAddress(HelperData
->hInstance
,
453 "WSHGetSockaddrType");
454 HelperData
->WSHGetWildcardSockaddr
= (PWSH_GET_WILDCARD_SOCKADDR
)
455 GetProcAddress(HelperData
->hInstance
,
456 "WSHGetWildcardSockaddr");
457 HelperData
->WSHGetBroadcastSockaddr
= (PWSH_GET_BROADCAST_SOCKADDR
)
458 GetProcAddress(HelperData
->hInstance
,
459 "WSHGetBroadcastSockaddr");
460 HelperData
->WSHAddressToString
= (PWSH_ADDRESS_TO_STRING
)
461 GetProcAddress(HelperData
->hInstance
,
462 "WSHAddressToString");
463 HelperData
->WSHStringToAddress
= (PWSH_STRING_TO_ADDRESS
)
464 GetProcAddress(HelperData
->hInstance
,
465 "WSHStringToAddress");
466 HelperData
->WSHIoctl
= (PWSH_IOCTL
)
467 GetProcAddress(HelperData
->hInstance
,
470 /* Save the Mapping Structure and transport name */
471 HelperData
->Mapping
= Mapping
;
472 wcscpy(HelperData
->TransportName
, TransportName
);
474 /* Increment Reference Count */
475 HelperData
->RefCount
= 1;
477 /* Add it to our list */
478 InsertHeadList(&SockHelpersListHead
, &HelperData
->Helpers
);
480 /* Return Pointers */
481 *HelperDllData
= HelperData
;
486 SockIsTripleInMapping(
487 PWINSOCK_MAPPING Mapping
,
492 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
495 AFD_DbgPrint(MID_TRACE
,("Called, Mapping rows = %d\n", Mapping
->Rows
));
497 /* Loop through Mapping to Find a matching one */
498 for (Row
= 0; Row
< Mapping
->Rows
; Row
++) {
499 AFD_DbgPrint(MID_TRACE
,("Examining: row %d: AF %d type %d proto %d\n",
501 (INT
)Mapping
->Mapping
[Row
].AddressFamily
,
502 (INT
)Mapping
->Mapping
[Row
].SocketType
,
503 (INT
)Mapping
->Mapping
[Row
].Protocol
));
505 /* Check of all three values Match */
506 if (((INT
)Mapping
->Mapping
[Row
].AddressFamily
== AddressFamily
) &&
507 ((INT
)Mapping
->Mapping
[Row
].SocketType
== SocketType
) &&
508 ((INT
)Mapping
->Mapping
[Row
].Protocol
== Protocol
)) {
509 AFD_DbgPrint(MID_TRACE
,("Found\n"));
513 AFD_DbgPrint(MID_TRACE
,("Not found\n"));