📄 helpers.c
字号:
/*
* 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 + -