ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

helpers.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.