⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helpers.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS Ancillary Function Driver DLL
 * FILE:        misc/helpers.c
 * PURPOSE:     Helper DLL management
 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
 *				Alex Ionescu (alex@relsoft.net)
 * REVISIONS:
 *   CSH 01/09-2000 Created
 *	 Alex 16/07/2004 - Complete Rewrite
 */
#include <msafd.h>

#include <debug.h>

CRITICAL_SECTION HelperDLLDatabaseLock;
LIST_ENTRY HelperDLLDatabaseListHead;


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;

    AFD_DbgPrint(MID_TRACE,("Called\n"));

    /* 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) {
        AFD_DbgPrint(MIN_TRACE, ("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) {
	AFD_DbgPrint(MID_TRACE, ("Transport: %S\n", Transports));

        /* See what mapping this Transport supports */
        Status = SockLoadTransportMapping(Transport, &Mapping);
        
        /* Check for error */
        if (Status) {
            AFD_DbgPrint(MIN_TRACE, ("Can't get mapping\n"));
            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) {
                AFD_DbgPrint(MIN_TRACE, ("Can't load helper DLL\n"));
                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
SockLoadTransportMapping(
    PWSTR TransportName, 
    PWINSOCK_MAPPING *Mapping)
{
    PWSTR               TransportKey;
    HKEY                KeyHandle;
    ULONG               MappingSize;
    LONG                Status;

    AFD_DbgPrint(MID_TRACE,("Called: TransportName %ws\n", TransportName));

    /* Allocate a Buffer */
    TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));

    /* Check for error */
    if (TransportKey == NULL) {
        AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
        return WSAEINVAL;
    }

    /* Generate the right key name */
    wcscpy(TransportKey, L"System\\CurrentControlSet\\Services\\");
    wcscat(TransportKey, TransportName);
    wcscat(TransportKey, L"\\Parameters\\Winsock");

    /* Open the Key */
    Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TransportKey, 0, KEY_READ, &KeyHandle);

    /* We don't need the Transport Key anymore */
    HeapFree(GlobalHeap, 0, TransportKey);

    /* Check for error */
    if (Status) {
        AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
        return WSAEINVAL;
    }

    /* Find out how much space we need for the Mapping */
    Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize);

    /* Check for error */
    if (Status) {
        AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
        return WSAEINVAL;
    }

    /* Allocate Memory for the Mapping */
    *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize);

    /* Check for error */
    if (*Mapping == NULL) {
        AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
        return WSAEINVAL;
    }

    /* Read the Mapping */
    Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, (LPBYTE)*Mapping, &MappingSize);
    
    /* Check for error */
    if (Status) {
        AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
        HeapFree(GlobalHeap, 0, *Mapping);
        return WSAEINVAL;
    }

    /* Close key and return */
    RegCloseKey(KeyHandle);
    return 0;
}

INT 
SockLoadTransportList(
    PWSTR *TransportList)
{
    ULONG	TransportListSize;
    HKEY	KeyHandle;
    LONG	Status;

    AFD_DbgPrint(MID_TRACE,("Called\n"));
    
    /* Open the Transports Key */
    Status = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
                            L"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",  
                            0, 
                            KEY_READ, 
                            &KeyHandle);

    /* Check for error */
    if (Status) {
        AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n"));
        return WSAEINVAL;
    }
    
    /* Get the Transport List Size */
    Status = RegQueryValueExW(KeyHandle,
                              L"Transports",
                              NULL,
                              NULL,
                              NULL,
                              &TransportListSize);

    /* Check for error */
    if (Status) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -