xref: /reactos/dll/win32/msafd/misc/helpers.c (revision f6108f31)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:   See COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:     ReactOS Ancillary Function Driver DLL
4*c2c66affSColin Finck  * FILE:        dll/win32/msafd/misc/helpers.c
5*c2c66affSColin Finck  * PURPOSE:     Helper DLL management
6*c2c66affSColin Finck  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7*c2c66affSColin Finck  *				Alex Ionescu (alex@relsoft.net)
8*c2c66affSColin Finck  * REVISIONS:
9*c2c66affSColin Finck  *   CSH 01/09-2000 Created
10*c2c66affSColin Finck  *	 Alex 16/07/2004 - Complete Rewrite
11*c2c66affSColin Finck  */
12*c2c66affSColin Finck 
13*c2c66affSColin Finck #include <msafd.h>
14*c2c66affSColin Finck 
15*c2c66affSColin Finck #include <winreg.h>
16*c2c66affSColin Finck 
17*c2c66affSColin Finck CRITICAL_SECTION HelperDLLDatabaseLock;
18*c2c66affSColin Finck LIST_ENTRY HelperDLLDatabaseListHead;
19*c2c66affSColin Finck 
20*c2c66affSColin Finck 
21*c2c66affSColin Finck INT
SockGetTdiName(PINT AddressFamily,PINT SocketType,PINT Protocol,GROUP Group,DWORD Flags,PUNICODE_STRING TransportName,PVOID * HelperDllContext,PHELPER_DATA * HelperDllData,PDWORD Events)22*c2c66affSColin Finck SockGetTdiName(
23*c2c66affSColin Finck     PINT AddressFamily,
24*c2c66affSColin Finck     PINT SocketType,
25*c2c66affSColin Finck     PINT Protocol,
26*c2c66affSColin Finck     GROUP Group,
27*c2c66affSColin Finck     DWORD Flags,
28*c2c66affSColin Finck     PUNICODE_STRING TransportName,
29*c2c66affSColin Finck     PVOID *HelperDllContext,
30*c2c66affSColin Finck     PHELPER_DATA *HelperDllData,
31*c2c66affSColin Finck     PDWORD Events)
32*c2c66affSColin Finck {
33*c2c66affSColin Finck     PHELPER_DATA        HelperData;
34*c2c66affSColin Finck     PWSTR               Transports;
35*c2c66affSColin Finck     PWSTR               Transport;
36*c2c66affSColin Finck     PWINSOCK_MAPPING	Mapping;
37*c2c66affSColin Finck     PLIST_ENTRY	        Helpers;
38*c2c66affSColin Finck     INT                 Status;
39*c2c66affSColin Finck 
40*c2c66affSColin Finck     TRACE("AddressFamily %p, SocketType %p, Protocol %p, Group %u, Flags %lx, TransportName %p, HelperDllContext %p, HelperDllData %p, Events %p\n",
41*c2c66affSColin Finck         AddressFamily, SocketType, Protocol, Group, Flags, TransportName, HelperDllContext, HelperDllData, Events);
42*c2c66affSColin Finck 
43*c2c66affSColin Finck     /* Check in our Current Loaded Helpers */
44*c2c66affSColin Finck     for (Helpers = SockHelpersListHead.Flink;
45*c2c66affSColin Finck          Helpers != &SockHelpersListHead;
46*c2c66affSColin Finck          Helpers = Helpers->Flink ) {
47*c2c66affSColin Finck 
48*c2c66affSColin Finck         HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers);
49*c2c66affSColin Finck 
50*c2c66affSColin Finck         /* See if this Mapping works for us */
51*c2c66affSColin Finck         if (SockIsTripleInMapping (HelperData->Mapping,
52*c2c66affSColin Finck                                    *AddressFamily,
53*c2c66affSColin Finck                                    *SocketType,
54*c2c66affSColin Finck                                    *Protocol)) {
55*c2c66affSColin Finck 
56*c2c66affSColin Finck             /* Call the Helper Dll function get the Transport Name */
57*c2c66affSColin Finck             if (HelperData->WSHOpenSocket2 == NULL ) {
58*c2c66affSColin Finck 
59*c2c66affSColin Finck                 /* DLL Doesn't support WSHOpenSocket2, call the old one */
60*c2c66affSColin Finck                 HelperData->WSHOpenSocket(AddressFamily,
61*c2c66affSColin Finck                                           SocketType,
62*c2c66affSColin Finck                                           Protocol,
63*c2c66affSColin Finck                                           TransportName,
64*c2c66affSColin Finck                                           HelperDllContext,
65*c2c66affSColin Finck                                           Events
66*c2c66affSColin Finck                                           );
67*c2c66affSColin Finck             } else {
68*c2c66affSColin Finck                 HelperData->WSHOpenSocket2(AddressFamily,
69*c2c66affSColin Finck                                            SocketType,
70*c2c66affSColin Finck                                            Protocol,
71*c2c66affSColin Finck                                            Group,
72*c2c66affSColin Finck                                            Flags,
73*c2c66affSColin Finck                                            TransportName,
74*c2c66affSColin Finck                                            HelperDllContext,
75*c2c66affSColin Finck                                            Events
76*c2c66affSColin Finck                                            );
77*c2c66affSColin Finck             }
78*c2c66affSColin Finck 
79*c2c66affSColin Finck             /* Return the Helper Pointers */
80*c2c66affSColin Finck             *HelperDllData = HelperData;
81*c2c66affSColin Finck             return NO_ERROR;
82*c2c66affSColin Finck         }
83*c2c66affSColin Finck     }
84*c2c66affSColin Finck 
85*c2c66affSColin Finck     /* Get the Transports available */
86*c2c66affSColin Finck     Status = SockLoadTransportList(&Transports);
87*c2c66affSColin Finck 
88*c2c66affSColin Finck     /* Check for error */
89*c2c66affSColin Finck     if (Status) {
90*c2c66affSColin Finck         WARN("Can't get transport list\n");
91*c2c66affSColin Finck         return Status;
92*c2c66affSColin Finck     }
93*c2c66affSColin Finck 
94*c2c66affSColin Finck     /* Loop through each transport until we find one that can satisfy us */
95*c2c66affSColin Finck     for (Transport = Transports;
96*c2c66affSColin Finck          *Transports != 0;
97*c2c66affSColin Finck          Transport += wcslen(Transport) + 1) {
98*c2c66affSColin Finck         TRACE("Transport: %S\n", Transports);
99*c2c66affSColin Finck 
100*c2c66affSColin Finck         /* See what mapping this Transport supports */
101*c2c66affSColin Finck         Status = SockLoadTransportMapping(Transport, &Mapping);
102*c2c66affSColin Finck 
103*c2c66affSColin Finck         /* Check for error */
104*c2c66affSColin Finck         if (Status) {
105*c2c66affSColin Finck             ERR("Can't get mapping for %S\n", Transports);
106*c2c66affSColin Finck             HeapFree(GlobalHeap, 0, Transports);
107*c2c66affSColin Finck             return Status;
108*c2c66affSColin Finck         }
109*c2c66affSColin Finck 
110*c2c66affSColin Finck         /* See if this Mapping works for us */
111*c2c66affSColin Finck         if (SockIsTripleInMapping(Mapping, *AddressFamily, *SocketType, *Protocol)) {
112*c2c66affSColin Finck 
113*c2c66affSColin Finck             /* It does, so load the DLL associated with it */
114*c2c66affSColin Finck             Status = SockLoadHelperDll(Transport, Mapping, &HelperData);
115*c2c66affSColin Finck 
116*c2c66affSColin Finck             /* Check for error */
117*c2c66affSColin Finck             if (Status) {
118*c2c66affSColin Finck                 ERR("Can't load helper DLL for Transport %S.\n", Transport);
119*c2c66affSColin Finck                 HeapFree(GlobalHeap, 0, Transports);
120*c2c66affSColin Finck                 HeapFree(GlobalHeap, 0, Mapping);
121*c2c66affSColin Finck                 return Status;
122*c2c66affSColin Finck             }
123*c2c66affSColin Finck 
124*c2c66affSColin Finck             /* Call the Helper Dll function get the Transport Name */
125*c2c66affSColin Finck             if (HelperData->WSHOpenSocket2 == NULL) {
126*c2c66affSColin Finck                 /* DLL Doesn't support WSHOpenSocket2, call the old one */
127*c2c66affSColin Finck                 HelperData->WSHOpenSocket(AddressFamily,
128*c2c66affSColin Finck                                           SocketType,
129*c2c66affSColin Finck                                           Protocol,
130*c2c66affSColin Finck                                           TransportName,
131*c2c66affSColin Finck                                           HelperDllContext,
132*c2c66affSColin Finck                                           Events
133*c2c66affSColin Finck                                           );
134*c2c66affSColin Finck             } else {
135*c2c66affSColin Finck                 HelperData->WSHOpenSocket2(AddressFamily,
136*c2c66affSColin Finck                                            SocketType,
137*c2c66affSColin Finck                                            Protocol,
138*c2c66affSColin Finck                                            Group,
139*c2c66affSColin Finck                                            Flags,
140*c2c66affSColin Finck                                            TransportName,
141*c2c66affSColin Finck                                            HelperDllContext,
142*c2c66affSColin Finck                                            Events
143*c2c66affSColin Finck                                            );
144*c2c66affSColin Finck             }
145*c2c66affSColin Finck 
146*c2c66affSColin Finck             /* Return the Helper Pointers */
147*c2c66affSColin Finck             *HelperDllData = HelperData;
148*c2c66affSColin Finck             /* We actually cache these ... the can't be freed yet */
149*c2c66affSColin Finck             /*HeapFree(GlobalHeap, 0, Transports);*/
150*c2c66affSColin Finck             /*HeapFree(GlobalHeap, 0, Mapping);*/
151*c2c66affSColin Finck             return NO_ERROR;
152*c2c66affSColin Finck         }
153*c2c66affSColin Finck 
154*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, Mapping);
155*c2c66affSColin Finck     }
156*c2c66affSColin Finck     HeapFree(GlobalHeap, 0, Transports);
157*c2c66affSColin Finck     return WSAEINVAL;
158*c2c66affSColin Finck }
159*c2c66affSColin Finck 
160*c2c66affSColin Finck INT
SockLoadTransportMapping(PWSTR TransportName,PWINSOCK_MAPPING * Mapping)161*c2c66affSColin Finck SockLoadTransportMapping(
162*c2c66affSColin Finck     PWSTR TransportName,
163*c2c66affSColin Finck     PWINSOCK_MAPPING *Mapping)
164*c2c66affSColin Finck {
165*c2c66affSColin Finck     PWSTR               TransportKey;
166*c2c66affSColin Finck     HKEY                KeyHandle;
167*c2c66affSColin Finck     ULONG               MappingSize;
168*c2c66affSColin Finck     LONG                Status;
169*c2c66affSColin Finck 
170*c2c66affSColin Finck     TRACE("TransportName %ws\n", TransportName);
171*c2c66affSColin Finck 
172*c2c66affSColin Finck     /* Allocate a Buffer */
173*c2c66affSColin Finck     TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
174*c2c66affSColin Finck 
175*c2c66affSColin Finck     /* Check for error */
176*c2c66affSColin Finck     if (TransportKey == NULL) {
177*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
178*c2c66affSColin Finck         return WSAEINVAL;
179*c2c66affSColin Finck     }
180*c2c66affSColin Finck 
181*c2c66affSColin Finck     /* Generate the right key name */
182*c2c66affSColin Finck     wcscpy(TransportKey, L"System\\CurrentControlSet\\Services\\");
183*c2c66affSColin Finck     wcscat(TransportKey, TransportName);
184*c2c66affSColin Finck     wcscat(TransportKey, L"\\Parameters\\Winsock");
185*c2c66affSColin Finck 
186*c2c66affSColin Finck     /* Open the Key */
187*c2c66affSColin Finck     Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TransportKey, 0, KEY_READ, &KeyHandle);
188*c2c66affSColin Finck 
189*c2c66affSColin Finck     /* We don't need the Transport Key anymore */
190*c2c66affSColin Finck     HeapFree(GlobalHeap, 0, TransportKey);
191*c2c66affSColin Finck 
192*c2c66affSColin Finck     /* Check for error */
193*c2c66affSColin Finck     if (Status) {
194*c2c66affSColin Finck         ERR("Error reading transport mapping registry\n");
195*c2c66affSColin Finck         return WSAEINVAL;
196*c2c66affSColin Finck     }
197*c2c66affSColin Finck 
198*c2c66affSColin Finck     /* Find out how much space we need for the Mapping */
199*c2c66affSColin Finck     Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize);
200*c2c66affSColin Finck 
201*c2c66affSColin Finck     /* Check for error */
202*c2c66affSColin Finck     if (Status) {
203*c2c66affSColin Finck         ERR("Error reading transport mapping registry\n");
204*c2c66affSColin Finck         return WSAEINVAL;
205*c2c66affSColin Finck     }
206*c2c66affSColin Finck 
207*c2c66affSColin Finck     /* Allocate Memory for the Mapping */
208*c2c66affSColin Finck     *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize);
209*c2c66affSColin Finck 
210*c2c66affSColin Finck     /* Check for error */
211*c2c66affSColin Finck     if (*Mapping == NULL) {
212*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
213*c2c66affSColin Finck         return WSAEINVAL;
214*c2c66affSColin Finck     }
215*c2c66affSColin Finck 
216*c2c66affSColin Finck     /* Read the Mapping */
217*c2c66affSColin Finck     Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, (LPBYTE)*Mapping, &MappingSize);
218*c2c66affSColin Finck 
219*c2c66affSColin Finck     /* Check for error */
220*c2c66affSColin Finck     if (Status) {
221*c2c66affSColin Finck         ERR("Error reading transport mapping registry\n");
222*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, *Mapping);
223*c2c66affSColin Finck         return WSAEINVAL;
224*c2c66affSColin Finck     }
225*c2c66affSColin Finck 
226*c2c66affSColin Finck     /* Close key and return */
227*c2c66affSColin Finck     RegCloseKey(KeyHandle);
228*c2c66affSColin Finck     return 0;
229*c2c66affSColin Finck }
230*c2c66affSColin Finck 
231*c2c66affSColin Finck INT
SockLoadTransportList(PWSTR * TransportList)232*c2c66affSColin Finck SockLoadTransportList(
233*c2c66affSColin Finck     PWSTR *TransportList)
234*c2c66affSColin Finck {
235*c2c66affSColin Finck     ULONG	TransportListSize;
236*c2c66affSColin Finck     HKEY	KeyHandle;
237*c2c66affSColin Finck     LONG	Status;
238*c2c66affSColin Finck 
239*c2c66affSColin Finck     TRACE("Called\n");
240*c2c66affSColin Finck 
241*c2c66affSColin Finck     /* Open the Transports Key */
242*c2c66affSColin Finck     Status = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
243*c2c66affSColin Finck                             L"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
244*c2c66affSColin Finck                             0,
245*c2c66affSColin Finck                             KEY_READ,
246*c2c66affSColin Finck                             &KeyHandle);
247*c2c66affSColin Finck 
248*c2c66affSColin Finck     /* Check for error */
249*c2c66affSColin Finck     if (Status) {
250*c2c66affSColin Finck         ERR("Error reading transport list registry\n");
251*c2c66affSColin Finck         return WSAEINVAL;
252*c2c66affSColin Finck     }
253*c2c66affSColin Finck 
254*c2c66affSColin Finck     /* Get the Transport List Size */
255*c2c66affSColin Finck     Status = RegQueryValueExW(KeyHandle,
256*c2c66affSColin Finck                               L"Transports",
257*c2c66affSColin Finck                               NULL,
258*c2c66affSColin Finck                               NULL,
259*c2c66affSColin Finck                               NULL,
260*c2c66affSColin Finck                               &TransportListSize);
261*c2c66affSColin Finck 
262*c2c66affSColin Finck     /* Check for error */
263*c2c66affSColin Finck     if (Status) {
264*c2c66affSColin Finck         ERR("Error reading transport list registry\n");
265*c2c66affSColin Finck         return WSAEINVAL;
266*c2c66affSColin Finck     }
267*c2c66affSColin Finck 
268*c2c66affSColin Finck     /* Allocate Memory for the Transport List */
269*c2c66affSColin Finck     *TransportList = HeapAlloc(GlobalHeap, 0, TransportListSize);
270*c2c66affSColin Finck 
271*c2c66affSColin Finck     /* Check for error */
272*c2c66affSColin Finck     if (*TransportList == NULL) {
273*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
274*c2c66affSColin Finck         return WSAEINVAL;
275*c2c66affSColin Finck     }
276*c2c66affSColin Finck 
277*c2c66affSColin Finck     /* Get the Transports */
278*c2c66affSColin Finck     Status = RegQueryValueExW (KeyHandle,
279*c2c66affSColin Finck                                L"Transports",
280*c2c66affSColin Finck                                NULL,
281*c2c66affSColin Finck                                NULL,
282*c2c66affSColin Finck                                (LPBYTE)*TransportList,
283*c2c66affSColin Finck                                &TransportListSize);
284*c2c66affSColin Finck 
285*c2c66affSColin Finck     /* Check for error */
286*c2c66affSColin Finck     if (Status) {
287*c2c66affSColin Finck         ERR("Error reading transport list registry\n");
288*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, *TransportList);
289*c2c66affSColin Finck         return WSAEINVAL;
290*c2c66affSColin Finck     }
291*c2c66affSColin Finck 
292*c2c66affSColin Finck     /* Close key and return */
293*c2c66affSColin Finck     RegCloseKey(KeyHandle);
294*c2c66affSColin Finck     return 0;
295*c2c66affSColin Finck }
296*c2c66affSColin Finck 
297*c2c66affSColin Finck INT
SockLoadHelperDll(PWSTR TransportName,PWINSOCK_MAPPING Mapping,PHELPER_DATA * HelperDllData)298*c2c66affSColin Finck SockLoadHelperDll(
299*c2c66affSColin Finck     PWSTR TransportName,
300*c2c66affSColin Finck     PWINSOCK_MAPPING Mapping,
301*c2c66affSColin Finck     PHELPER_DATA *HelperDllData)
302*c2c66affSColin Finck {
303*c2c66affSColin Finck     PHELPER_DATA        HelperData;
304*c2c66affSColin Finck     PWSTR               HelperDllName;
305*c2c66affSColin Finck     PWSTR               FullHelperDllName;
306*c2c66affSColin Finck     PWSTR               HelperKey;
307*c2c66affSColin Finck     HKEY                KeyHandle;
308*c2c66affSColin Finck     ULONG               DataSize;
309*c2c66affSColin Finck     LONG                Status;
310*c2c66affSColin Finck 
311*c2c66affSColin Finck     /* Allocate space for the Helper Structure and TransportName */
312*c2c66affSColin Finck     HelperData = HeapAlloc(GlobalHeap, 0, sizeof(*HelperData) + (wcslen(TransportName) + 1) * sizeof(WCHAR));
313*c2c66affSColin Finck 
314*c2c66affSColin Finck     /* Check for error */
315*c2c66affSColin Finck     if (HelperData == NULL) {
316*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
317*c2c66affSColin Finck         return WSAEINVAL;
318*c2c66affSColin Finck     }
319*c2c66affSColin Finck 
320*c2c66affSColin Finck     /* Allocate Space for the Helper DLL Key */
321*c2c66affSColin Finck     HelperKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
322*c2c66affSColin Finck 
323*c2c66affSColin Finck     /* Check for error */
324*c2c66affSColin Finck     if (HelperKey == NULL) {
325*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
326*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
327*c2c66affSColin Finck         return WSAEINVAL;
328*c2c66affSColin Finck     }
329*c2c66affSColin Finck 
330*c2c66affSColin Finck     /* Generate the right key name */
331*c2c66affSColin Finck     wcscpy(HelperKey, L"System\\CurrentControlSet\\Services\\");
332*c2c66affSColin Finck     wcscat(HelperKey, TransportName);
333*c2c66affSColin Finck     wcscat(HelperKey, L"\\Parameters\\Winsock");
334*c2c66affSColin Finck 
335*c2c66affSColin Finck     /* Open the Key */
336*c2c66affSColin Finck     Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, HelperKey, 0, KEY_READ, &KeyHandle);
337*c2c66affSColin Finck 
338*c2c66affSColin Finck     HeapFree(GlobalHeap, 0, HelperKey);
339*c2c66affSColin Finck 
340*c2c66affSColin Finck     /* Check for error */
341*c2c66affSColin Finck     if (Status) {
342*c2c66affSColin Finck         ERR("Error reading helper DLL parameters\n");
343*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
344*c2c66affSColin Finck         return WSAEINVAL;
345*c2c66affSColin Finck     }
346*c2c66affSColin Finck 
347*c2c66affSColin Finck     /* Read Size of SockAddr Structures */
348*c2c66affSColin Finck     DataSize = sizeof(HelperData->MinWSAddressLength);
349*c2c66affSColin Finck     HelperData->MinWSAddressLength = 16;
350*c2c66affSColin Finck     RegQueryValueExW (KeyHandle,
351*c2c66affSColin Finck                       L"MinSockaddrLength",
352*c2c66affSColin Finck                       NULL,
353*c2c66affSColin Finck                       NULL,
354*c2c66affSColin Finck                       (LPBYTE)&HelperData->MinWSAddressLength,
355*c2c66affSColin Finck                       &DataSize);
356*c2c66affSColin Finck     DataSize = sizeof(HelperData->MinWSAddressLength);
357*c2c66affSColin Finck     HelperData->MaxWSAddressLength = 16;
358*c2c66affSColin Finck     RegQueryValueExW (KeyHandle,
359*c2c66affSColin Finck                       L"MaxSockaddrLength",
360*c2c66affSColin Finck                       NULL,
361*c2c66affSColin Finck                       NULL,
362*c2c66affSColin Finck                       (LPBYTE)&HelperData->MaxWSAddressLength,
363*c2c66affSColin Finck                       &DataSize);
364*c2c66affSColin Finck 
365*c2c66affSColin Finck     /* Size of TDI Structures */
366*c2c66affSColin Finck     HelperData->MinTDIAddressLength = HelperData->MinWSAddressLength + 6;
367*c2c66affSColin Finck     HelperData->MaxTDIAddressLength = HelperData->MaxWSAddressLength + 6;
368*c2c66affSColin Finck 
369*c2c66affSColin Finck     /* Read Delayed Acceptance Setting */
370*c2c66affSColin Finck     DataSize = sizeof(DWORD);
371*c2c66affSColin Finck     HelperData->UseDelayedAcceptance = FALSE;
372*c2c66affSColin Finck     RegQueryValueExW (KeyHandle,
373*c2c66affSColin Finck                       L"UseDelayedAcceptance",
374*c2c66affSColin Finck                       NULL,
375*c2c66affSColin Finck                       NULL,
376*c2c66affSColin Finck                       (LPBYTE)&HelperData->UseDelayedAcceptance,
377*c2c66affSColin Finck                       &DataSize);
378*c2c66affSColin Finck 
379*c2c66affSColin Finck     /* Allocate Space for the Helper DLL Names */
380*c2c66affSColin Finck     HelperDllName = HeapAlloc(GlobalHeap, 0, 512);
381*c2c66affSColin Finck 
382*c2c66affSColin Finck     /* Check for error */
383*c2c66affSColin Finck     if (HelperDllName == NULL) {
384*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
385*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
386*c2c66affSColin Finck         return WSAEINVAL;
387*c2c66affSColin Finck     }
388*c2c66affSColin Finck 
389*c2c66affSColin Finck     FullHelperDllName = HeapAlloc(GlobalHeap, 0, 512);
390*c2c66affSColin Finck 
391*c2c66affSColin Finck     /* Check for error */
392*c2c66affSColin Finck     if (FullHelperDllName == NULL) {
393*c2c66affSColin Finck         ERR("Buffer allocation failed\n");
394*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperDllName);
395*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
396*c2c66affSColin Finck         return WSAEINVAL;
397*c2c66affSColin Finck     }
398*c2c66affSColin Finck 
399*c2c66affSColin Finck     /* Get the name of the Helper DLL*/
400*c2c66affSColin Finck     DataSize = 512;
401*c2c66affSColin Finck     Status = RegQueryValueExW (KeyHandle,
402*c2c66affSColin Finck                                L"HelperDllName",
403*c2c66affSColin Finck                                NULL,
404*c2c66affSColin Finck                                NULL,
405*c2c66affSColin Finck                                (LPBYTE)HelperDllName,
406*c2c66affSColin Finck                                &DataSize);
407*c2c66affSColin Finck 
408*c2c66affSColin Finck     /* Check for error */
409*c2c66affSColin Finck     if (Status) {
410*c2c66affSColin Finck         ERR("Error reading helper DLL parameters\n");
411*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, FullHelperDllName);
412*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperDllName);
413*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
414*c2c66affSColin Finck         return WSAEINVAL;
415*c2c66affSColin Finck     }
416*c2c66affSColin Finck 
417*c2c66affSColin Finck     /* Get the Full name, expanding Environment Strings */
418*c2c66affSColin Finck     ExpandEnvironmentStringsW (HelperDllName,
419*c2c66affSColin Finck                                FullHelperDllName,
420*c2c66affSColin Finck                                256);
421*c2c66affSColin Finck 
422*c2c66affSColin Finck     /* Load the DLL */
423*c2c66affSColin Finck     HelperData->hInstance = LoadLibraryW(FullHelperDllName);
424*c2c66affSColin Finck 
425*c2c66affSColin Finck     HeapFree(GlobalHeap, 0, HelperDllName);
426*c2c66affSColin Finck     HeapFree(GlobalHeap, 0, FullHelperDllName);
427*c2c66affSColin Finck 
428*c2c66affSColin Finck     if (HelperData->hInstance == NULL) {
429*c2c66affSColin Finck         ERR("Error loading helper DLL\n");
430*c2c66affSColin Finck         HeapFree(GlobalHeap, 0, HelperData);
431*c2c66affSColin Finck         return WSAEINVAL;
432*c2c66affSColin Finck     }
433*c2c66affSColin Finck 
434*c2c66affSColin Finck     /* Close Key */
435*c2c66affSColin Finck     RegCloseKey(KeyHandle);
436*c2c66affSColin Finck 
437*c2c66affSColin Finck     /* Get the Pointers to the Helper Routines */
438*c2c66affSColin Finck     HelperData->WSHOpenSocket =	(PWSH_OPEN_SOCKET)
439*c2c66affSColin Finck 									GetProcAddress(HelperData->hInstance,
440*c2c66affSColin Finck 									"WSHOpenSocket");
441*c2c66affSColin Finck     HelperData->WSHOpenSocket2 = (PWSH_OPEN_SOCKET2)
442*c2c66affSColin Finck 									GetProcAddress(HelperData->hInstance,
443*c2c66affSColin Finck 									"WSHOpenSocket2");
444*c2c66affSColin Finck     HelperData->WSHJoinLeaf = (PWSH_JOIN_LEAF)
445*c2c66affSColin Finck 								GetProcAddress(HelperData->hInstance,
446*c2c66affSColin Finck 								"WSHJoinLeaf");
447*c2c66affSColin Finck     HelperData->WSHNotify = (PWSH_NOTIFY)
448*c2c66affSColin Finck 								GetProcAddress(HelperData->hInstance, "WSHNotify");
449*c2c66affSColin Finck     HelperData->WSHGetSocketInformation = (PWSH_GET_SOCKET_INFORMATION)
450*c2c66affSColin Finck 											GetProcAddress(HelperData->hInstance,
451*c2c66affSColin Finck 											"WSHGetSocketInformation");
452*c2c66affSColin Finck     HelperData->WSHSetSocketInformation = (PWSH_SET_SOCKET_INFORMATION)
453*c2c66affSColin Finck 											GetProcAddress(HelperData->hInstance,
454*c2c66affSColin Finck 											"WSHSetSocketInformation");
455*c2c66affSColin Finck     HelperData->WSHGetSockaddrType = (PWSH_GET_SOCKADDR_TYPE)
456*c2c66affSColin Finck 										GetProcAddress(HelperData->hInstance,
457*c2c66affSColin Finck 										"WSHGetSockaddrType");
458*c2c66affSColin Finck     HelperData->WSHGetWildcardSockaddr = (PWSH_GET_WILDCARD_SOCKADDR)
459*c2c66affSColin Finck 											GetProcAddress(HelperData->hInstance,
460*c2c66affSColin Finck 											"WSHGetWildcardSockaddr");
461*c2c66affSColin Finck     HelperData->WSHGetBroadcastSockaddr = (PWSH_GET_BROADCAST_SOCKADDR)
462*c2c66affSColin Finck 											GetProcAddress(HelperData->hInstance,
463*c2c66affSColin Finck 											"WSHGetBroadcastSockaddr");
464*c2c66affSColin Finck     HelperData->WSHAddressToString = (PWSH_ADDRESS_TO_STRING)
465*c2c66affSColin Finck 										GetProcAddress(HelperData->hInstance,
466*c2c66affSColin Finck 										"WSHAddressToString");
467*c2c66affSColin Finck     HelperData->WSHStringToAddress = (PWSH_STRING_TO_ADDRESS)
468*c2c66affSColin Finck 										GetProcAddress(HelperData->hInstance,
469*c2c66affSColin Finck 										"WSHStringToAddress");
470*c2c66affSColin Finck     HelperData->WSHIoctl = (PWSH_IOCTL)
471*c2c66affSColin Finck 							GetProcAddress(HelperData->hInstance,
472*c2c66affSColin Finck 							"WSHIoctl");
473*c2c66affSColin Finck 
474*c2c66affSColin Finck     /* Save the Mapping Structure and transport name */
475*c2c66affSColin Finck     HelperData->Mapping = Mapping;
476*c2c66affSColin Finck     wcscpy(HelperData->TransportName, TransportName);
477*c2c66affSColin Finck 
478*c2c66affSColin Finck     /* Increment Reference Count */
479*c2c66affSColin Finck     HelperData->RefCount = 1;
480*c2c66affSColin Finck 
481*c2c66affSColin Finck     /* Add it to our list */
482*c2c66affSColin Finck     InsertHeadList(&SockHelpersListHead, &HelperData->Helpers);
483*c2c66affSColin Finck 
484*c2c66affSColin Finck     /* Return Pointers */
485*c2c66affSColin Finck     *HelperDllData = HelperData;
486*c2c66affSColin Finck     return 0;
487*c2c66affSColin Finck }
488*c2c66affSColin Finck 
489*c2c66affSColin Finck BOOL
SockIsTripleInMapping(PWINSOCK_MAPPING Mapping,INT AddressFamily,INT SocketType,INT Protocol)490*c2c66affSColin Finck SockIsTripleInMapping(
491*c2c66affSColin Finck     PWINSOCK_MAPPING Mapping,
492*c2c66affSColin Finck     INT AddressFamily,
493*c2c66affSColin Finck     INT SocketType,
494*c2c66affSColin Finck     INT Protocol)
495*c2c66affSColin Finck {
496*c2c66affSColin Finck     /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
497*c2c66affSColin Finck     ULONG    Row;
498*c2c66affSColin Finck 
499*c2c66affSColin Finck     TRACE("Called, Mapping rows = %d\n", Mapping->Rows);
500*c2c66affSColin Finck 
501*c2c66affSColin Finck     /* Loop through Mapping to Find a matching one */
502*c2c66affSColin Finck     for (Row = 0; Row < Mapping->Rows; Row++) {
503*c2c66affSColin Finck         TRACE("Examining: row %d: AF %d type %d proto %d\n",
504*c2c66affSColin Finck 				Row,
505*c2c66affSColin Finck 				(INT)Mapping->Mapping[Row].AddressFamily,
506*c2c66affSColin Finck 				(INT)Mapping->Mapping[Row].SocketType,
507*c2c66affSColin Finck 				(INT)Mapping->Mapping[Row].Protocol);
508*c2c66affSColin Finck 
509*c2c66affSColin Finck         /* Check of all three values Match */
510*c2c66affSColin Finck         if (((INT)Mapping->Mapping[Row].AddressFamily == AddressFamily) &&
511*c2c66affSColin Finck             ((INT)Mapping->Mapping[Row].SocketType == SocketType) &&
512*c2c66affSColin Finck             ((INT)Mapping->Mapping[Row].Protocol == Protocol)) {
513*c2c66affSColin Finck             TRACE("Found\n");
514*c2c66affSColin Finck             return TRUE;
515*c2c66affSColin Finck         }
516*c2c66affSColin Finck     }
517*c2c66affSColin Finck     WARN("Not found\n");
518*c2c66affSColin Finck     return FALSE;
519*c2c66affSColin Finck }
520*c2c66affSColin Finck 
521*c2c66affSColin Finck /* EOF */
522