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 #include <wine/debug.h>
18 WINE_DEFAULT_DEBUG_CHANNEL(msafd
);
20 CRITICAL_SECTION HelperDLLDatabaseLock
;
21 LIST_ENTRY HelperDLLDatabaseListHead
;
31 PUNICODE_STRING TransportName
,
32 PVOID
*HelperDllContext
,
33 PHELPER_DATA
*HelperDllData
,
36 PHELPER_DATA HelperData
;
39 PWINSOCK_MAPPING Mapping
;
43 TRACE("AddressFamily %p, SocketType %p, Protocol %p, Group %u, Flags %lx, TransportName %p, HelperDllContext %p, HelperDllData %p, Events %p\n",
44 AddressFamily
, SocketType
, Protocol
, Group
, Flags
, TransportName
, HelperDllContext
, HelperDllData
, Events
);
46 /* Check in our Current Loaded Helpers */
47 for (Helpers
= SockHelpersListHead
.Flink
;
48 Helpers
!= &SockHelpersListHead
;
49 Helpers
= Helpers
->Flink
) {
51 HelperData
= CONTAINING_RECORD(Helpers
, HELPER_DATA
, Helpers
);
53 /* See if this Mapping works for us */
54 if (SockIsTripleInMapping (HelperData
->Mapping
,
59 /* Call the Helper Dll function get the Transport Name */
60 if (HelperData
->WSHOpenSocket2
== NULL
) {
62 /* DLL Doesn't support WSHOpenSocket2, call the old one */
63 HelperData
->WSHOpenSocket(AddressFamily
,
71 HelperData
->WSHOpenSocket2(AddressFamily
,
82 /* Return the Helper Pointers */
83 *HelperDllData
= HelperData
;
88 /* Get the Transports available */
89 Status
= SockLoadTransportList(&Transports
);
93 WARN("Can't get transport list\n");
97 /* Loop through each transport until we find one that can satisfy us */
98 for (Transport
= Transports
;
100 Transport
+= wcslen(Transport
) + 1) {
101 TRACE("Transport: %S\n", Transports
);
103 /* See what mapping this Transport supports */
104 Status
= SockLoadTransportMapping(Transport
, &Mapping
);
106 /* Check for error */
108 ERR("Can't get mapping for %S\n", Transports
);
109 HeapFree(GlobalHeap
, 0, Transports
);
113 /* See if this Mapping works for us */
114 if (SockIsTripleInMapping(Mapping
, *AddressFamily
, *SocketType
, *Protocol
)) {
116 /* It does, so load the DLL associated with it */
117 Status
= SockLoadHelperDll(Transport
, Mapping
, &HelperData
);
119 /* Check for error */
121 ERR("Can't load helper DLL for Transport %S.\n", Transport
);
122 HeapFree(GlobalHeap
, 0, Transports
);
123 HeapFree(GlobalHeap
, 0, Mapping
);
127 /* Call the Helper Dll function get the Transport Name */
128 if (HelperData
->WSHOpenSocket2
== NULL
) {
129 /* DLL Doesn't support WSHOpenSocket2, call the old one */
130 HelperData
->WSHOpenSocket(AddressFamily
,
138 HelperData
->WSHOpenSocket2(AddressFamily
,
149 /* Return the Helper Pointers */
150 *HelperDllData
= HelperData
;
151 /* We actually cache these ... the can't be freed yet */
152 /*HeapFree(GlobalHeap, 0, Transports);*/
153 /*HeapFree(GlobalHeap, 0, Mapping);*/
157 HeapFree(GlobalHeap
, 0, Mapping
);
159 HeapFree(GlobalHeap
, 0, Transports
);
164 SockLoadTransportMapping(
166 PWINSOCK_MAPPING
*Mapping
)
173 TRACE("TransportName %ws\n", TransportName
);
175 /* Allocate a Buffer */
176 TransportKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
178 /* Check for error */
179 if (TransportKey
== NULL
) {
180 ERR("Buffer allocation failed\n");
184 /* Generate the right key name */
185 wcscpy(TransportKey
, L
"System\\CurrentControlSet\\Services\\");
186 wcscat(TransportKey
, TransportName
);
187 wcscat(TransportKey
, L
"\\Parameters\\Winsock");
190 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, TransportKey
, 0, KEY_READ
, &KeyHandle
);
192 /* We don't need the Transport Key anymore */
193 HeapFree(GlobalHeap
, 0, TransportKey
);
195 /* Check for error */
197 ERR("Error reading transport mapping registry\n");
201 /* Find out how much space we need for the Mapping */
202 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, NULL
, &MappingSize
);
204 /* Check for error */
206 ERR("Error reading transport mapping registry\n");
210 /* Allocate Memory for the Mapping */
211 *Mapping
= HeapAlloc(GlobalHeap
, 0, MappingSize
);
213 /* Check for error */
214 if (*Mapping
== NULL
) {
215 ERR("Buffer allocation failed\n");
219 /* Read the Mapping */
220 Status
= RegQueryValueExW(KeyHandle
, L
"Mapping", NULL
, NULL
, (LPBYTE
)*Mapping
, &MappingSize
);
222 /* Check for error */
224 ERR("Error reading transport mapping registry\n");
225 HeapFree(GlobalHeap
, 0, *Mapping
);
229 /* Close key and return */
230 RegCloseKey(KeyHandle
);
235 SockLoadTransportList(
236 PWSTR
*TransportList
)
238 ULONG TransportListSize
;
244 /* Open the Transports Key */
245 Status
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
246 L
"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
251 /* Check for error */
253 ERR("Error reading transport list registry\n");
257 /* Get the Transport List Size */
258 Status
= RegQueryValueExW(KeyHandle
,
265 /* Check for error */
267 ERR("Error reading transport list registry\n");
271 /* Allocate Memory for the Transport List */
272 *TransportList
= HeapAlloc(GlobalHeap
, 0, TransportListSize
);
274 /* Check for error */
275 if (*TransportList
== NULL
) {
276 ERR("Buffer allocation failed\n");
280 /* Get the Transports */
281 Status
= RegQueryValueExW (KeyHandle
,
285 (LPBYTE
)*TransportList
,
288 /* Check for error */
290 ERR("Error reading transport list registry\n");
291 HeapFree(GlobalHeap
, 0, *TransportList
);
295 /* Close key and return */
296 RegCloseKey(KeyHandle
);
303 PWINSOCK_MAPPING Mapping
,
304 PHELPER_DATA
*HelperDllData
)
306 PHELPER_DATA HelperData
;
308 PWSTR FullHelperDllName
;
314 /* Allocate space for the Helper Structure and TransportName */
315 HelperData
= HeapAlloc(GlobalHeap
, 0, sizeof(*HelperData
) + (wcslen(TransportName
) + 1) * sizeof(WCHAR
));
317 /* Check for error */
318 if (HelperData
== NULL
) {
319 ERR("Buffer allocation failed\n");
323 /* Allocate Space for the Helper DLL Key */
324 HelperKey
= HeapAlloc(GlobalHeap
, 0, (54 + wcslen(TransportName
)) * sizeof(WCHAR
));
326 /* Check for error */
327 if (HelperKey
== NULL
) {
328 ERR("Buffer allocation failed\n");
329 HeapFree(GlobalHeap
, 0, HelperData
);
333 /* Generate the right key name */
334 wcscpy(HelperKey
, L
"System\\CurrentControlSet\\Services\\");
335 wcscat(HelperKey
, TransportName
);
336 wcscat(HelperKey
, L
"\\Parameters\\Winsock");
339 Status
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, HelperKey
, 0, KEY_READ
, &KeyHandle
);
341 HeapFree(GlobalHeap
, 0, HelperKey
);
343 /* Check for error */
345 ERR("Error reading helper DLL parameters\n");
346 HeapFree(GlobalHeap
, 0, HelperData
);
350 /* Read Size of SockAddr Structures */
351 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
352 HelperData
->MinWSAddressLength
= 16;
353 RegQueryValueExW (KeyHandle
,
354 L
"MinSockaddrLength",
357 (LPBYTE
)&HelperData
->MinWSAddressLength
,
359 DataSize
= sizeof(HelperData
->MinWSAddressLength
);
360 HelperData
->MaxWSAddressLength
= 16;
361 RegQueryValueExW (KeyHandle
,
362 L
"MaxSockaddrLength",
365 (LPBYTE
)&HelperData
->MaxWSAddressLength
,
368 /* Size of TDI Structures */
369 HelperData
->MinTDIAddressLength
= HelperData
->MinWSAddressLength
+ 6;
370 HelperData
->MaxTDIAddressLength
= HelperData
->MaxWSAddressLength
+ 6;
372 /* Read Delayed Acceptance Setting */
373 DataSize
= sizeof(DWORD
);
374 HelperData
->UseDelayedAcceptance
= FALSE
;
375 RegQueryValueExW (KeyHandle
,
376 L
"UseDelayedAcceptance",
379 (LPBYTE
)&HelperData
->UseDelayedAcceptance
,
382 /* Allocate Space for the Helper DLL Names */
383 HelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
385 /* Check for error */
386 if (HelperDllName
== NULL
) {
387 ERR("Buffer allocation failed\n");
388 HeapFree(GlobalHeap
, 0, HelperData
);
392 FullHelperDllName
= HeapAlloc(GlobalHeap
, 0, 512);
394 /* Check for error */
395 if (FullHelperDllName
== NULL
) {
396 ERR("Buffer allocation failed\n");
397 HeapFree(GlobalHeap
, 0, HelperDllName
);
398 HeapFree(GlobalHeap
, 0, HelperData
);
402 /* Get the name of the Helper DLL*/
404 Status
= RegQueryValueExW (KeyHandle
,
408 (LPBYTE
)HelperDllName
,
411 /* Check for error */
413 ERR("Error reading helper DLL parameters\n");
414 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
415 HeapFree(GlobalHeap
, 0, HelperDllName
);
416 HeapFree(GlobalHeap
, 0, HelperData
);
420 /* Get the Full name, expanding Environment Strings */
421 ExpandEnvironmentStringsW (HelperDllName
,
426 HelperData
->hInstance
= LoadLibraryW(FullHelperDllName
);
428 HeapFree(GlobalHeap
, 0, HelperDllName
);
429 HeapFree(GlobalHeap
, 0, FullHelperDllName
);
431 if (HelperData
->hInstance
== NULL
) {
432 ERR("Error loading helper DLL\n");
433 HeapFree(GlobalHeap
, 0, HelperData
);
438 RegCloseKey(KeyHandle
);
440 /* Get the Pointers to the Helper Routines */
441 HelperData
->WSHOpenSocket
= (PWSH_OPEN_SOCKET
)
442 GetProcAddress(HelperData
->hInstance
,
444 HelperData
->WSHOpenSocket2
= (PWSH_OPEN_SOCKET2
)
445 GetProcAddress(HelperData
->hInstance
,
447 HelperData
->WSHJoinLeaf
= (PWSH_JOIN_LEAF
)
448 GetProcAddress(HelperData
->hInstance
,
450 HelperData
->WSHNotify
= (PWSH_NOTIFY
)
451 GetProcAddress(HelperData
->hInstance
, "WSHNotify");
452 HelperData
->WSHGetSocketInformation
= (PWSH_GET_SOCKET_INFORMATION
)
453 GetProcAddress(HelperData
->hInstance
,
454 "WSHGetSocketInformation");
455 HelperData
->WSHSetSocketInformation
= (PWSH_SET_SOCKET_INFORMATION
)
456 GetProcAddress(HelperData
->hInstance
,
457 "WSHSetSocketInformation");
458 HelperData
->WSHGetSockaddrType
= (PWSH_GET_SOCKADDR_TYPE
)
459 GetProcAddress(HelperData
->hInstance
,
460 "WSHGetSockaddrType");
461 HelperData
->WSHGetWildcardSockaddr
= (PWSH_GET_WILDCARD_SOCKADDR
)
462 GetProcAddress(HelperData
->hInstance
,
463 "WSHGetWildcardSockaddr");
464 HelperData
->WSHGetBroadcastSockaddr
= (PWSH_GET_BROADCAST_SOCKADDR
)
465 GetProcAddress(HelperData
->hInstance
,
466 "WSHGetBroadcastSockaddr");
467 HelperData
->WSHAddressToString
= (PWSH_ADDRESS_TO_STRING
)
468 GetProcAddress(HelperData
->hInstance
,
469 "WSHAddressToString");
470 HelperData
->WSHStringToAddress
= (PWSH_STRING_TO_ADDRESS
)
471 GetProcAddress(HelperData
->hInstance
,
472 "WSHStringToAddress");
473 HelperData
->WSHIoctl
= (PWSH_IOCTL
)
474 GetProcAddress(HelperData
->hInstance
,
477 /* Save the Mapping Structure and transport name */
478 HelperData
->Mapping
= Mapping
;
479 wcscpy(HelperData
->TransportName
, TransportName
);
481 /* Increment Reference Count */
482 HelperData
->RefCount
= 1;
484 /* Add it to our list */
485 InsertHeadList(&SockHelpersListHead
, &HelperData
->Helpers
);
487 /* Return Pointers */
488 *HelperDllData
= HelperData
;
493 SockIsTripleInMapping(
494 PWINSOCK_MAPPING Mapping
,
499 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
502 TRACE("Called, Mapping rows = %d\n", Mapping
->Rows
);
504 /* Loop through Mapping to Find a matching one */
505 for (Row
= 0; Row
< Mapping
->Rows
; Row
++) {
506 TRACE("Examining: row %d: AF %d type %d proto %d\n",
508 (INT
)Mapping
->Mapping
[Row
].AddressFamily
,
509 (INT
)Mapping
->Mapping
[Row
].SocketType
,
510 (INT
)Mapping
->Mapping
[Row
].Protocol
);
512 /* Check of all three values Match */
513 if (((INT
)Mapping
->Mapping
[Row
].AddressFamily
== AddressFamily
) &&
514 ((INT
)Mapping
->Mapping
[Row
].SocketType
== SocketType
) &&
515 ((INT
)Mapping
->Mapping
[Row
].Protocol
== Protocol
)) {