2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: dll/win32/msafd/misc/helpers.c
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 TRACE("AddressFamily %p, SocketType %p, Protocol %p, Group %u, Flags %lx, TransportName %p, HelperDllContext %p, HelperDllData %p, Events %p\n",
41 AddressFamily
, SocketType
, Protocol
, Group
, Flags
, TransportName
, HelperDllContext
, HelperDllData
, Events
);
43 /* Check in our Current Loaded Helpers */
44 for (Helpers
= SockHelpersListHead
.Flink
;
45 Helpers
!= &SockHelpersListHead
;
46 Helpers
= Helpers
->Flink
) {
48 HelperData
= CONTAINING_RECORD(Helpers
, HELPER_DATA
, Helpers
);
50 /* See if this Mapping works for us */
51 if (SockIsTripleInMapping (HelperData
->Mapping
,
56 /* Call the Helper Dll function get the Transport Name */
57 if (HelperData
->WSHOpenSocket2
== NULL
) {
59 /* DLL Doesn't support WSHOpenSocket2, call the old one */
60 HelperData
->WSHOpenSocket(AddressFamily
,
68 HelperData
->WSHOpenSocket2(AddressFamily
,
79 /* Return the Helper Pointers */
80 *HelperDllData
= HelperData
;
85 /* Get the Transports available */
86 Status
= SockLoadTransportList(&Transports
);
90 WARN("Can't get transport list\n");
94 /* Loop through each transport until we find one that can satisfy us */
95 for (Transport
= Transports
;
97 Transport
+= wcslen(Transport
) + 1) {
98 TRACE("Transport: %S\n", Transports
);
100 /* See what mapping this Transport supports */
101 Status
= SockLoadTransportMapping(Transport
, &Mapping
);
103 /* Check for error */
105 ERR("Can't get mapping for %S\n", Transports
);
106 HeapFree(GlobalHeap
, 0, Transports
);
110 /* See if this Mapping works for us */
111 if (SockIsTripleInMapping(Mapping
, *AddressFamily
, *SocketType
, *Protocol
)) {
113 /* It does, so load the DLL associated with it */
114 Status
= SockLoadHelperDll(Transport
, Mapping
, &HelperData
);
116 /* Check for error */
118 ERR("Can't load helper DLL for Transport %S.\n", Transport
);
119 HeapFree(GlobalHeap
, 0, Transports
);
120 HeapFree(GlobalHeap
, 0, Mapping
);
124 /* Call the Helper Dll function get the Transport Name */
125 if (HelperData
->WSHOpenSocket2
== NULL
) {
126 /* DLL Doesn't support WSHOpenSocket2, call the old one */
127 HelperData
->WSHOpenSocket(AddressFamily
,
135 HelperData
->WSHOpenSocket2(AddressFamily
,
146 /* Return the Helper Pointers */
147 *HelperDllData
= HelperData
;
148 /* We actually cache these ... the can't be freed yet */
149 /*HeapFree(GlobalHeap, 0, Transports);*/
150 /*HeapFree(GlobalHeap, 0, Mapping);*/
154 HeapFree(GlobalHeap
, 0, Mapping
);
156 HeapFree(GlobalHeap
, 0, Transports
);
161 SockLoadTransportMapping(
163 PWINSOCK_MAPPING
*Mapping
)
170 TRACE("TransportName %ws\n", TransportName
);
172 /* Allocate a Buffer */
173 TransportKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
175 /* Check for error */
176 if (TransportKey
== NULL
) {
177 ERR("Buffer allocation failed\n");
181 /* Generate the right key name */
182 wcscpy(TransportKey
, L
"System\\CurrentControlSet\\Services\\");
183 wcscat(TransportKey
, TransportName
);
184 wcscat(TransportKey
, L
"\\Parameters\\Winsock");
187 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, TransportKey
, 0, KEY_READ
, &KeyHandle
);
189 /* We don't need the Transport Key anymore */
190 HeapFree(GlobalHeap
, 0, TransportKey
);
192 /* Check for error */
194 ERR("Error reading transport mapping registry\n");
198 /* Find out how much space we need for the Mapping */
199 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, NULL
, &MappingSize
);
201 /* Check for error */
203 ERR("Error reading transport mapping registry\n");
207 /* Allocate Memory for the Mapping */
208 *Mapping
= HeapAlloc(GlobalHeap
, 0, MappingSize
);
210 /* Check for error */
211 if (*Mapping
== NULL
) {
212 ERR("Buffer allocation failed\n");
216 /* Read the Mapping */
217 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, (LPBYTE
)*Mapping
, &MappingSize
);
219 /* Check for error */
221 ERR("Error reading transport mapping registry\n");
222 HeapFree(GlobalHeap
, 0, *Mapping
);
226 /* Close key and return */
227 RegCloseKey(KeyHandle
);
232 SockLoadTransportList(
233 PWSTR
*TransportList
)
235 ULONG TransportListSize
;
241 /* Open the Transports Key */
242 Status
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
243 L
"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
248 /* Check for error */
250 ERR("Error reading transport list registry\n");
254 /* Get the Transport List Size */
255 Status
= RegQueryValueExW(KeyHandle
,
262 /* Check for error */
264 ERR("Error reading transport list registry\n");
268 /* Allocate Memory for the Transport List */
269 *TransportList
= HeapAlloc(GlobalHeap
, 0, TransportListSize
);
271 /* Check for error */
272 if (*TransportList
== NULL
) {
273 ERR("Buffer allocation failed\n");
277 /* Get the Transports */
278 Status
= RegQueryValueExW (KeyHandle
,
282 (LPBYTE
)*TransportList
,
285 /* Check for error */
287 ERR("Error reading transport list registry\n");
288 HeapFree(GlobalHeap
, 0, *TransportList
);
292 /* Close key and return */
293 RegCloseKey(KeyHandle
);
300 PWINSOCK_MAPPING Mapping
,
301 PHELPER_DATA
*HelperDllData
)
303 PHELPER_DATA HelperData
;
305 PWSTR FullHelperDllName
;
311 /* Allocate space for the Helper Structure and TransportName */
312 HelperData
= HeapAlloc(GlobalHeap
, 0, sizeof(*HelperData
) + (wcslen(TransportName
) + 1) * sizeof(WCHAR
));
314 /* Check for error */
315 if (HelperData
== NULL
) {
316 ERR("Buffer allocation failed\n");
320 /* Allocate Space for the Helper DLL Key */
321 HelperKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
323 /* Check for error */
324 if (HelperKey
== NULL
) {
325 ERR("Buffer allocation failed\n");
326 HeapFree(GlobalHeap
, 0, HelperData
);
330 /* Generate the right key name */
331 wcscpy(HelperKey
, L
"System\\CurrentControlSet\\Services\\");
332 wcscat(HelperKey
, TransportName
);
333 wcscat(HelperKey
, L
"\\Parameters\\Winsock");
336 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, HelperKey
, 0, KEY_READ
, &KeyHandle
);
338 HeapFree(GlobalHeap
, 0, HelperKey
);
340 /* Check for error */
342 ERR("Error reading helper DLL parameters\n");
343 HeapFree(GlobalHeap
, 0, HelperData
);
347 /* Read Size of SockAddr Structures */
348 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
349 HelperData
->MinWSAddressLength
= 16;
350 RegQueryValueExW (KeyHandle
,
351 L
"MinSockaddrLength",
354 (LPBYTE
)&HelperData
->MinWSAddressLength
,
356 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
357 HelperData
->MaxWSAddressLength
= 16;
358 RegQueryValueExW (KeyHandle
,
359 L
"MaxSockaddrLength",
362 (LPBYTE
)&HelperData
->MaxWSAddressLength
,
365 /* Size of TDI Structures */
366 HelperData
->MinTDIAddressLength
= HelperData
->MinWSAddressLength
+ 6;
367 HelperData
->MaxTDIAddressLength
= HelperData
->MaxWSAddressLength
+ 6;
369 /* Read Delayed Acceptance Setting */
370 DataSize
= sizeof(DWORD
);
371 HelperData
->UseDelayedAcceptance
= FALSE
;
372 RegQueryValueExW (KeyHandle
,
373 L
"UseDelayedAcceptance",
376 (LPBYTE
)&HelperData
->UseDelayedAcceptance
,
379 /* Allocate Space for the Helper DLL Names */
380 HelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
382 /* Check for error */
383 if (HelperDllName
== NULL
) {
384 ERR("Buffer allocation failed\n");
385 HeapFree(GlobalHeap
, 0, HelperData
);
389 FullHelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
391 /* Check for error */
392 if (FullHelperDllName
== NULL
) {
393 ERR("Buffer allocation failed\n");
394 HeapFree(GlobalHeap
, 0, HelperDllName
);
395 HeapFree(GlobalHeap
, 0, HelperData
);
399 /* Get the name of the Helper DLL*/
401 Status
= RegQueryValueExW (KeyHandle
,
405 (LPBYTE
)HelperDllName
,
408 /* Check for error */
410 ERR("Error reading helper DLL parameters\n");
411 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
412 HeapFree(GlobalHeap
, 0, HelperDllName
);
413 HeapFree(GlobalHeap
, 0, HelperData
);
417 /* Get the Full name, expanding Environment Strings */
418 ExpandEnvironmentStringsW (HelperDllName
,
423 HelperData
->hInstance
= LoadLibraryW(FullHelperDllName
);
425 HeapFree(GlobalHeap
, 0, HelperDllName
);
426 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
428 if (HelperData
->hInstance
== NULL
) {
429 ERR("Error loading helper DLL\n");
430 HeapFree(GlobalHeap
, 0, HelperData
);
435 RegCloseKey(KeyHandle
);
437 /* Get the Pointers to the Helper Routines */
438 HelperData
->WSHOpenSocket
= (PWSH_OPEN_SOCKET
)
439 GetProcAddress(HelperData
->hInstance
,
441 HelperData
->WSHOpenSocket2
= (PWSH_OPEN_SOCKET2
)
442 GetProcAddress(HelperData
->hInstance
,
444 HelperData
->WSHJoinLeaf
= (PWSH_JOIN_LEAF
)
445 GetProcAddress(HelperData
->hInstance
,
447 HelperData
->WSHNotify
= (PWSH_NOTIFY
)
448 GetProcAddress(HelperData
->hInstance
, "WSHNotify");
449 HelperData
->WSHGetSocketInformation
= (PWSH_GET_SOCKET_INFORMATION
)
450 GetProcAddress(HelperData
->hInstance
,
451 "WSHGetSocketInformation");
452 HelperData
->WSHSetSocketInformation
= (PWSH_SET_SOCKET_INFORMATION
)
453 GetProcAddress(HelperData
->hInstance
,
454 "WSHSetSocketInformation");
455 HelperData
->WSHGetSockaddrType
= (PWSH_GET_SOCKADDR_TYPE
)
456 GetProcAddress(HelperData
->hInstance
,
457 "WSHGetSockaddrType");
458 HelperData
->WSHGetWildcardSockaddr
= (PWSH_GET_WILDCARD_SOCKADDR
)
459 GetProcAddress(HelperData
->hInstance
,
460 "WSHGetWildcardSockaddr");
461 HelperData
->WSHGetBroadcastSockaddr
= (PWSH_GET_BROADCAST_SOCKADDR
)
462 GetProcAddress(HelperData
->hInstance
,
463 "WSHGetBroadcastSockaddr");
464 HelperData
->WSHAddressToString
= (PWSH_ADDRESS_TO_STRING
)
465 GetProcAddress(HelperData
->hInstance
,
466 "WSHAddressToString");
467 HelperData
->WSHStringToAddress
= (PWSH_STRING_TO_ADDRESS
)
468 GetProcAddress(HelperData
->hInstance
,
469 "WSHStringToAddress");
470 HelperData
->WSHIoctl
= (PWSH_IOCTL
)
471 GetProcAddress(HelperData
->hInstance
,
474 /* Save the Mapping Structure and transport name */
475 HelperData
->Mapping
= Mapping
;
476 wcscpy(HelperData
->TransportName
, TransportName
);
478 /* Increment Reference Count */
479 HelperData
->RefCount
= 1;
481 /* Add it to our list */
482 InsertHeadList(&SockHelpersListHead
, &HelperData
->Helpers
);
484 /* Return Pointers */
485 *HelperDllData
= HelperData
;
490 SockIsTripleInMapping(
491 PWINSOCK_MAPPING Mapping
,
496 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
499 TRACE("Called, Mapping rows = %d\n", Mapping
->Rows
);
501 /* Loop through Mapping to Find a matching one */
502 for (Row
= 0; Row
< Mapping
->Rows
; Row
++) {
503 TRACE("Examining: row %d: AF %d type %d proto %d\n",
505 (INT
)Mapping
->Mapping
[Row
].AddressFamily
,
506 (INT
)Mapping
->Mapping
[Row
].SocketType
,
507 (INT
)Mapping
->Mapping
[Row
].Protocol
);
509 /* Check of all three values Match */
510 if (((INT
)Mapping
->Mapping
[Row
].AddressFamily
== AddressFamily
) &&
511 ((INT
)Mapping
->Mapping
[Row
].SocketType
== SocketType
) &&
512 ((INT
)Mapping
->Mapping
[Row
].Protocol
== Protocol
)) {