INT SockGetTdiName( PINT AddressFamily, PINT SocketType, PINT Protocol, GROUP Group, DWORD Flags, PUNICODE_STRING TransportName, PVOID *HelperDllContext, PHELPER_DATA *HelperDllData, PDWORD Events) { PHELPER_DATA HelperData; PWSTR Transports; PWSTR Transport; PWINSOCK_MAPPING Mapping; PLIST_ENTRY Helpers; INT Status; TRACE("AddressFamily %p, SocketType %p, Protocol %p, Group %u, Flags %lx, TransportName %p, HelperDllContext %p, HelperDllData %p, Events %p\n", AddressFamily, SocketType, Protocol, Group, Flags, TransportName, HelperDllContext, HelperDllData, Events); /* Check in our Current Loaded Helpers */ for (Helpers = SockHelpersListHead.Flink; Helpers != &SockHelpersListHead; Helpers = Helpers->Flink ) { HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers); /* See if this Mapping works for us */ if (SockIsTripleInMapping (HelperData->Mapping, *AddressFamily, *SocketType, *Protocol)) { /* Call the Helper Dll function get the Transport Name */ if (HelperData->WSHOpenSocket2 == NULL ) { /* DLL Doesn't support WSHOpenSocket2, call the old one */ HelperData->WSHOpenSocket(AddressFamily, SocketType, Protocol, TransportName, HelperDllContext, Events ); } else { HelperData->WSHOpenSocket2(AddressFamily, SocketType, Protocol, Group, Flags, TransportName, HelperDllContext, Events ); } /* Return the Helper Pointers */ *HelperDllData = HelperData; return NO_ERROR; } } /* Get the Transports available */ Status = SockLoadTransportList(&Transports); /* Check for error */ if (Status) { WARN("Can't get transport list\n"); return Status; } /* Loop through each transport until we find one that can satisfy us */ for (Transport = Transports; *Transports != 0; Transport += wcslen(Transport) + 1) { TRACE("Transport: %S\n", Transports); /* See what mapping this Transport supports */ Status = SockLoadTransportMapping(Transport, &Mapping); /* Check for error */ if (Status) { ERR("Can't get mapping for %S\n", Transports); HeapFree(GlobalHeap, 0, Transports); return Status; } /* See if this Mapping works for us */ if (SockIsTripleInMapping(Mapping, *AddressFamily, *SocketType, *Protocol)) { /* It does, so load the DLL associated with it */ Status = SockLoadHelperDll(Transport, Mapping, &HelperData); /* Check for error */ if (Status) { ERR("Can't load helper DLL for Transport %S.\n", Transport); HeapFree(GlobalHeap, 0, Transports); HeapFree(GlobalHeap, 0, Mapping); return Status; } /* Call the Helper Dll function get the Transport Name */ if (HelperData->WSHOpenSocket2 == NULL) { /* DLL Doesn't support WSHOpenSocket2, call the old one */ HelperData->WSHOpenSocket(AddressFamily, SocketType, Protocol, TransportName, HelperDllContext, Events ); } else { HelperData->WSHOpenSocket2(AddressFamily, SocketType, Protocol, Group, Flags, TransportName, HelperDllContext, Events ); } /* Return the Helper Pointers */ *HelperDllData = HelperData; /* We actually cache these ... the can't be freed yet */ /*HeapFree(GlobalHeap, 0, Transports);*/ /*HeapFree(GlobalHeap, 0, Mapping);*/ return NO_ERROR; } HeapFree(GlobalHeap, 0, Mapping); } HeapFree(GlobalHeap, 0, Transports); return WSAEINVAL; }
INT SockGetTdiName ( IN PINT AddressFamily, IN PINT SocketType, IN PINT Protocol, IN GROUP Group, IN DWORD Flags, OUT PUNICODE_STRING TransportDeviceName, OUT PVOID *HelperDllSocketContext, OUT PWINSOCK_HELPER_DLL_INFO *HelperDll, OUT PDWORD NotificationEvents ) { PLIST_ENTRY listEntry; PWINSOCK_HELPER_DLL_INFO helperDll; INT error; BOOLEAN resourceShared = TRUE; BOOLEAN addressFamilyFound = FALSE; BOOLEAN socketTypeFound = FALSE; BOOLEAN protocolFound = FALSE; BOOLEAN invalidProtocolMatch = FALSE; PWSTR transportList; PWSTR currentTransport; PWINSOCK_MAPPING mapping; // // Acquire lock for shared access and search the list of helper // DLLs for one which supports this combination of address family, // socket type, and protocol. // SockAcquireRwLockShared(&SocketGlobalLock); walkList: for ( listEntry = SockHelperDllListHead.Flink; listEntry != &SockHelperDllListHead; listEntry = listEntry->Flink ) { helperDll = CONTAINING_RECORD( listEntry, WINSOCK_HELPER_DLL_INFO, HelperDllListEntry ); IF_DEBUG(HELPER_DLL) { WS_PRINT(( "SockGetTdiName: examining DLL at %lx for AF %ld, " "ST %ld, Proto %ld\n", helperDll, AddressFamily, SocketType, Protocol )); } // // Check to see whether the DLL supports the socket we're // opening. // if ( SockIsTripleInMapping( helperDll->Mapping, *AddressFamily, &addressFamilyFound, *SocketType, &socketTypeFound, *Protocol, &protocolFound, &invalidProtocolMatch ) ) { // // Found a match. Try to use this DLL. // if( helperDll->WSHOpenSocket2 == NULL ) { // // This helper doesn't support the new WinSock 2 // WSHOpenSocket2 entrypoint. If the application is // creating a "normal" socket, then just call through // to the old WinSock 1 WSHOpenSocket entrypoint. // Otherwise, fail the call. // if( ( Flags & ALL_MULTIPOINT_FLAGS ) == 0 ) { error = helperDll->WSHOpenSocket( AddressFamily, SocketType, Protocol, TransportDeviceName, HelperDllSocketContext, NotificationEvents ); } else { error = WSAEINVAL; } } else { error = helperDll->WSHOpenSocket2( AddressFamily, SocketType, Protocol, Group, Flags, TransportDeviceName, HelperDllSocketContext, NotificationEvents ); } if ( error == NO_ERROR ) { SockReferenceHelper (helperDll); IF_DEBUG(HELPER_DLL) { WS_PRINT(( "WSHOpenSocket by DLL at %lx succeeded, " "context = %lx\n", helperDll, *HelperDllSocketContext )); } // // The DLL accepted the socket. Return a pointer to the // helper DLL info. // if ( resourceShared ) { SockReleaseRwLockShared(&SocketGlobalLock); } else { SockReleaseRwLockExclusive(&SocketGlobalLock); } *HelperDll = helperDll; return NO_ERROR; } if ( (*SocketType == SOCK_RAW) && (TransportDeviceName->Buffer != NULL) ) { RtlFreeHeap( RtlProcessHeap(), 0, TransportDeviceName->Buffer ); TransportDeviceName->Buffer = NULL; } // // The open failed. Continue searching for a matching DLL. // IF_DEBUG(HELPER_DLL) { WS_PRINT(( "WSHOpenSocket by DLL %lx failed: %ld\n", helperDll, error )); } } }