Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhelpers.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Ancillary Function Driver DLL 00004 * FILE: misc/helpers.c 00005 * PURPOSE: Helper DLL management 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Alex Ionescu (alex@relsoft.net) 00008 * REVISIONS: 00009 * CSH 01/09-2000 Created 00010 * Alex 16/07/2004 - Complete Rewrite 00011 */ 00012 #include <msafd.h> 00013 00014 CRITICAL_SECTION HelperDLLDatabaseLock; 00015 LIST_ENTRY HelperDLLDatabaseListHead; 00016 00017 00018 INT 00019 SockGetTdiName( 00020 PINT AddressFamily, 00021 PINT SocketType, 00022 PINT Protocol, 00023 GROUP Group, 00024 DWORD Flags, 00025 PUNICODE_STRING TransportName, 00026 PVOID *HelperDllContext, 00027 PHELPER_DATA *HelperDllData, 00028 PDWORD Events) 00029 { 00030 PHELPER_DATA HelperData; 00031 PWSTR Transports; 00032 PWSTR Transport; 00033 PWINSOCK_MAPPING Mapping; 00034 PLIST_ENTRY Helpers; 00035 INT Status; 00036 00037 AFD_DbgPrint(MID_TRACE,("Called\n")); 00038 00039 /* Check in our Current Loaded Helpers */ 00040 for (Helpers = SockHelpersListHead.Flink; 00041 Helpers != &SockHelpersListHead; 00042 Helpers = Helpers->Flink ) { 00043 00044 HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers); 00045 00046 /* See if this Mapping works for us */ 00047 if (SockIsTripleInMapping (HelperData->Mapping, 00048 *AddressFamily, 00049 *SocketType, 00050 *Protocol)) { 00051 00052 /* Call the Helper Dll function get the Transport Name */ 00053 if (HelperData->WSHOpenSocket2 == NULL ) { 00054 00055 /* DLL Doesn't support WSHOpenSocket2, call the old one */ 00056 HelperData->WSHOpenSocket(AddressFamily, 00057 SocketType, 00058 Protocol, 00059 TransportName, 00060 HelperDllContext, 00061 Events 00062 ); 00063 } else { 00064 HelperData->WSHOpenSocket2(AddressFamily, 00065 SocketType, 00066 Protocol, 00067 Group, 00068 Flags, 00069 TransportName, 00070 HelperDllContext, 00071 Events 00072 ); 00073 } 00074 00075 /* Return the Helper Pointers */ 00076 *HelperDllData = HelperData; 00077 return NO_ERROR; 00078 } 00079 } 00080 00081 /* Get the Transports available */ 00082 Status = SockLoadTransportList(&Transports); 00083 00084 /* Check for error */ 00085 if (Status) { 00086 AFD_DbgPrint(MIN_TRACE, ("Can't get transport list\n")); 00087 return Status; 00088 } 00089 00090 /* Loop through each transport until we find one that can satisfy us */ 00091 for (Transport = Transports; 00092 *Transports != 0; 00093 Transport += wcslen(Transport) + 1) { 00094 AFD_DbgPrint(MID_TRACE, ("Transport: %S\n", Transports)); 00095 00096 /* See what mapping this Transport supports */ 00097 Status = SockLoadTransportMapping(Transport, &Mapping); 00098 00099 /* Check for error */ 00100 if (Status) { 00101 AFD_DbgPrint(MIN_TRACE, ("Can't get mapping\n")); 00102 HeapFree(GlobalHeap, 0, Transports); 00103 return Status; 00104 } 00105 00106 /* See if this Mapping works for us */ 00107 if (SockIsTripleInMapping(Mapping, *AddressFamily, *SocketType, *Protocol)) { 00108 00109 /* It does, so load the DLL associated with it */ 00110 Status = SockLoadHelperDll(Transport, Mapping, &HelperData); 00111 00112 /* Check for error */ 00113 if (Status) { 00114 AFD_DbgPrint(MIN_TRACE, ("Can't load helper DLL\n")); 00115 HeapFree(GlobalHeap, 0, Transports); 00116 HeapFree(GlobalHeap, 0, Mapping); 00117 return Status; 00118 } 00119 00120 /* Call the Helper Dll function get the Transport Name */ 00121 if (HelperData->WSHOpenSocket2 == NULL) { 00122 /* DLL Doesn't support WSHOpenSocket2, call the old one */ 00123 HelperData->WSHOpenSocket(AddressFamily, 00124 SocketType, 00125 Protocol, 00126 TransportName, 00127 HelperDllContext, 00128 Events 00129 ); 00130 } else { 00131 HelperData->WSHOpenSocket2(AddressFamily, 00132 SocketType, 00133 Protocol, 00134 Group, 00135 Flags, 00136 TransportName, 00137 HelperDllContext, 00138 Events 00139 ); 00140 } 00141 00142 /* Return the Helper Pointers */ 00143 *HelperDllData = HelperData; 00144 /* We actually cache these ... the can't be freed yet */ 00145 /*HeapFree(GlobalHeap, 0, Transports);*/ 00146 /*HeapFree(GlobalHeap, 0, Mapping);*/ 00147 return NO_ERROR; 00148 } 00149 00150 HeapFree(GlobalHeap, 0, Mapping); 00151 } 00152 HeapFree(GlobalHeap, 0, Transports); 00153 return WSAEINVAL; 00154 } 00155 00156 INT 00157 SockLoadTransportMapping( 00158 PWSTR TransportName, 00159 PWINSOCK_MAPPING *Mapping) 00160 { 00161 PWSTR TransportKey; 00162 HKEY KeyHandle; 00163 ULONG MappingSize; 00164 LONG Status; 00165 00166 AFD_DbgPrint(MID_TRACE,("Called: TransportName %ws\n", TransportName)); 00167 00168 /* Allocate a Buffer */ 00169 TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR)); 00170 00171 /* Check for error */ 00172 if (TransportKey == NULL) { 00173 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00174 return WSAEINVAL; 00175 } 00176 00177 /* Generate the right key name */ 00178 wcscpy(TransportKey, L"System\\CurrentControlSet\\Services\\"); 00179 wcscat(TransportKey, TransportName); 00180 wcscat(TransportKey, L"\\Parameters\\Winsock"); 00181 00182 /* Open the Key */ 00183 Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TransportKey, 0, KEY_READ, &KeyHandle); 00184 00185 /* We don't need the Transport Key anymore */ 00186 HeapFree(GlobalHeap, 0, TransportKey); 00187 00188 /* Check for error */ 00189 if (Status) { 00190 AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n")); 00191 return WSAEINVAL; 00192 } 00193 00194 /* Find out how much space we need for the Mapping */ 00195 Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize); 00196 00197 /* Check for error */ 00198 if (Status) { 00199 AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n")); 00200 return WSAEINVAL; 00201 } 00202 00203 /* Allocate Memory for the Mapping */ 00204 *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize); 00205 00206 /* Check for error */ 00207 if (*Mapping == NULL) { 00208 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00209 return WSAEINVAL; 00210 } 00211 00212 /* Read the Mapping */ 00213 Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, (LPBYTE)*Mapping, &MappingSize); 00214 00215 /* Check for error */ 00216 if (Status) { 00217 AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n")); 00218 HeapFree(GlobalHeap, 0, *Mapping); 00219 return WSAEINVAL; 00220 } 00221 00222 /* Close key and return */ 00223 RegCloseKey(KeyHandle); 00224 return 0; 00225 } 00226 00227 INT 00228 SockLoadTransportList( 00229 PWSTR *TransportList) 00230 { 00231 ULONG TransportListSize; 00232 HKEY KeyHandle; 00233 LONG Status; 00234 00235 AFD_DbgPrint(MID_TRACE,("Called\n")); 00236 00237 /* Open the Transports Key */ 00238 Status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, 00239 L"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters", 00240 0, 00241 KEY_READ, 00242 &KeyHandle); 00243 00244 /* Check for error */ 00245 if (Status) { 00246 AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n")); 00247 return WSAEINVAL; 00248 } 00249 00250 /* Get the Transport List Size */ 00251 Status = RegQueryValueExW(KeyHandle, 00252 L"Transports", 00253 NULL, 00254 NULL, 00255 NULL, 00256 &TransportListSize); 00257 00258 /* Check for error */ 00259 if (Status) { 00260 AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n")); 00261 return WSAEINVAL; 00262 } 00263 00264 /* Allocate Memory for the Transport List */ 00265 *TransportList = HeapAlloc(GlobalHeap, 0, TransportListSize); 00266 00267 /* Check for error */ 00268 if (*TransportList == NULL) { 00269 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00270 return WSAEINVAL; 00271 } 00272 00273 /* Get the Transports */ 00274 Status = RegQueryValueExW (KeyHandle, 00275 L"Transports", 00276 NULL, 00277 NULL, 00278 (LPBYTE)*TransportList, 00279 &TransportListSize); 00280 00281 /* Check for error */ 00282 if (Status) { 00283 AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n")); 00284 HeapFree(GlobalHeap, 0, *TransportList); 00285 return WSAEINVAL; 00286 } 00287 00288 /* Close key and return */ 00289 RegCloseKey(KeyHandle); 00290 return 0; 00291 } 00292 00293 INT 00294 SockLoadHelperDll( 00295 PWSTR TransportName, 00296 PWINSOCK_MAPPING Mapping, 00297 PHELPER_DATA *HelperDllData) 00298 { 00299 PHELPER_DATA HelperData; 00300 PWSTR HelperDllName; 00301 PWSTR FullHelperDllName; 00302 PWSTR HelperKey; 00303 HKEY KeyHandle; 00304 ULONG DataSize; 00305 LONG Status; 00306 00307 /* Allocate space for the Helper Structure and TransportName */ 00308 HelperData = HeapAlloc(GlobalHeap, 0, sizeof(*HelperData) + (wcslen(TransportName) + 1) * sizeof(WCHAR)); 00309 00310 /* Check for error */ 00311 if (HelperData == NULL) { 00312 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00313 return WSAEINVAL; 00314 } 00315 00316 /* Allocate Space for the Helper DLL Key */ 00317 HelperKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR)); 00318 00319 /* Check for error */ 00320 if (HelperKey == NULL) { 00321 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00322 HeapFree(GlobalHeap, 0, HelperData); 00323 return WSAEINVAL; 00324 } 00325 00326 /* Generate the right key name */ 00327 wcscpy(HelperKey, L"System\\CurrentControlSet\\Services\\"); 00328 wcscat(HelperKey, TransportName); 00329 wcscat(HelperKey, L"\\Parameters\\Winsock"); 00330 00331 /* Open the Key */ 00332 Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, HelperKey, 0, KEY_READ, &KeyHandle); 00333 00334 HeapFree(GlobalHeap, 0, HelperKey); 00335 00336 /* Check for error */ 00337 if (Status) { 00338 AFD_DbgPrint(MIN_TRACE, ("Error reading helper DLL parameters\n")); 00339 HeapFree(GlobalHeap, 0, HelperData); 00340 return WSAEINVAL; 00341 } 00342 00343 /* Read Size of SockAddr Structures */ 00344 DataSize = sizeof(HelperData->MinWSAddressLength); 00345 HelperData->MinWSAddressLength = 16; 00346 RegQueryValueExW (KeyHandle, 00347 L"MinSockaddrLength", 00348 NULL, 00349 NULL, 00350 (LPBYTE)&HelperData->MinWSAddressLength, 00351 &DataSize); 00352 DataSize = sizeof(HelperData->MinWSAddressLength); 00353 HelperData->MaxWSAddressLength = 16; 00354 RegQueryValueExW (KeyHandle, 00355 L"MaxSockaddrLength", 00356 NULL, 00357 NULL, 00358 (LPBYTE)&HelperData->MaxWSAddressLength, 00359 &DataSize); 00360 00361 /* Size of TDI Structures */ 00362 HelperData->MinTDIAddressLength = HelperData->MinWSAddressLength + 6; 00363 HelperData->MaxTDIAddressLength = HelperData->MaxWSAddressLength + 6; 00364 00365 /* Read Delayed Acceptance Setting */ 00366 DataSize = sizeof(DWORD); 00367 HelperData->UseDelayedAcceptance = FALSE; 00368 RegQueryValueExW (KeyHandle, 00369 L"UseDelayedAcceptance", 00370 NULL, 00371 NULL, 00372 (LPBYTE)&HelperData->UseDelayedAcceptance, 00373 &DataSize); 00374 00375 /* Allocate Space for the Helper DLL Names */ 00376 HelperDllName = HeapAlloc(GlobalHeap, 0, 512); 00377 00378 /* Check for error */ 00379 if (HelperDllName == NULL) { 00380 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00381 HeapFree(GlobalHeap, 0, HelperData); 00382 return WSAEINVAL; 00383 } 00384 00385 FullHelperDllName = HeapAlloc(GlobalHeap, 0, 512); 00386 00387 /* Check for error */ 00388 if (FullHelperDllName == NULL) { 00389 AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); 00390 HeapFree(GlobalHeap, 0, HelperDllName); 00391 HeapFree(GlobalHeap, 0, HelperData); 00392 return WSAEINVAL; 00393 } 00394 00395 /* Get the name of the Helper DLL*/ 00396 DataSize = 512; 00397 Status = RegQueryValueExW (KeyHandle, 00398 L"HelperDllName", 00399 NULL, 00400 NULL, 00401 (LPBYTE)HelperDllName, 00402 &DataSize); 00403 00404 /* Check for error */ 00405 if (Status) { 00406 AFD_DbgPrint(MIN_TRACE, ("Error reading helper DLL parameters\n")); 00407 HeapFree(GlobalHeap, 0, FullHelperDllName); 00408 HeapFree(GlobalHeap, 0, HelperDllName); 00409 HeapFree(GlobalHeap, 0, HelperData); 00410 return WSAEINVAL; 00411 } 00412 00413 /* Get the Full name, expanding Environment Strings */ 00414 ExpandEnvironmentStringsW (HelperDllName, 00415 FullHelperDllName, 00416 256); 00417 00418 /* Load the DLL */ 00419 HelperData->hInstance = LoadLibraryW(FullHelperDllName); 00420 00421 HeapFree(GlobalHeap, 0, HelperDllName); 00422 HeapFree(GlobalHeap, 0, FullHelperDllName); 00423 00424 if (HelperData->hInstance == NULL) { 00425 AFD_DbgPrint(MIN_TRACE, ("Error loading helper DLL\n")); 00426 HeapFree(GlobalHeap, 0, HelperData); 00427 return WSAEINVAL; 00428 } 00429 00430 /* Close Key */ 00431 RegCloseKey(KeyHandle); 00432 00433 /* Get the Pointers to the Helper Routines */ 00434 HelperData->WSHOpenSocket = (PWSH_OPEN_SOCKET) 00435 GetProcAddress(HelperData->hInstance, 00436 "WSHOpenSocket"); 00437 HelperData->WSHOpenSocket2 = (PWSH_OPEN_SOCKET2) 00438 GetProcAddress(HelperData->hInstance, 00439 "WSHOpenSocket2"); 00440 HelperData->WSHJoinLeaf = (PWSH_JOIN_LEAF) 00441 GetProcAddress(HelperData->hInstance, 00442 "WSHJoinLeaf"); 00443 HelperData->WSHNotify = (PWSH_NOTIFY) 00444 GetProcAddress(HelperData->hInstance, "WSHNotify"); 00445 HelperData->WSHGetSocketInformation = (PWSH_GET_SOCKET_INFORMATION) 00446 GetProcAddress(HelperData->hInstance, 00447 "WSHGetSocketInformation"); 00448 HelperData->WSHSetSocketInformation = (PWSH_SET_SOCKET_INFORMATION) 00449 GetProcAddress(HelperData->hInstance, 00450 "WSHSetSocketInformation"); 00451 HelperData->WSHGetSockaddrType = (PWSH_GET_SOCKADDR_TYPE) 00452 GetProcAddress(HelperData->hInstance, 00453 "WSHGetSockaddrType"); 00454 HelperData->WSHGetWildcardSockaddr = (PWSH_GET_WILDCARD_SOCKADDR) 00455 GetProcAddress(HelperData->hInstance, 00456 "WSHGetWildcardSockaddr"); 00457 HelperData->WSHGetBroadcastSockaddr = (PWSH_GET_BROADCAST_SOCKADDR) 00458 GetProcAddress(HelperData->hInstance, 00459 "WSHGetBroadcastSockaddr"); 00460 HelperData->WSHAddressToString = (PWSH_ADDRESS_TO_STRING) 00461 GetProcAddress(HelperData->hInstance, 00462 "WSHAddressToString"); 00463 HelperData->WSHStringToAddress = (PWSH_STRING_TO_ADDRESS) 00464 GetProcAddress(HelperData->hInstance, 00465 "WSHStringToAddress"); 00466 HelperData->WSHIoctl = (PWSH_IOCTL) 00467 GetProcAddress(HelperData->hInstance, 00468 "WSHIoctl"); 00469 00470 /* Save the Mapping Structure and transport name */ 00471 HelperData->Mapping = Mapping; 00472 wcscpy(HelperData->TransportName, TransportName); 00473 00474 /* Increment Reference Count */ 00475 HelperData->RefCount = 1; 00476 00477 /* Add it to our list */ 00478 InsertHeadList(&SockHelpersListHead, &HelperData->Helpers); 00479 00480 /* Return Pointers */ 00481 *HelperDllData = HelperData; 00482 return 0; 00483 } 00484 00485 BOOL 00486 SockIsTripleInMapping( 00487 PWINSOCK_MAPPING Mapping, 00488 INT AddressFamily, 00489 INT SocketType, 00490 INT Protocol) 00491 { 00492 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */ 00493 ULONG Row; 00494 00495 AFD_DbgPrint(MID_TRACE,("Called, Mapping rows = %d\n", Mapping->Rows)); 00496 00497 /* Loop through Mapping to Find a matching one */ 00498 for (Row = 0; Row < Mapping->Rows; Row++) { 00499 AFD_DbgPrint(MID_TRACE,("Examining: row %d: AF %d type %d proto %d\n", 00500 Row, 00501 (INT)Mapping->Mapping[Row].AddressFamily, 00502 (INT)Mapping->Mapping[Row].SocketType, 00503 (INT)Mapping->Mapping[Row].Protocol)); 00504 00505 /* Check of all three values Match */ 00506 if (((INT)Mapping->Mapping[Row].AddressFamily == AddressFamily) && 00507 ((INT)Mapping->Mapping[Row].SocketType == SocketType) && 00508 ((INT)Mapping->Mapping[Row].Protocol == Protocol)) { 00509 AFD_DbgPrint(MID_TRACE,("Found\n")); 00510 return TRUE; 00511 } 00512 } 00513 AFD_DbgPrint(MID_TRACE,("Not found\n")); 00514 return FALSE; 00515 } 00516 00517 /* EOF */ Generated on Thu May 24 2012 04:25:05 for ReactOS by
1.7.6.1
|