From 722bbf4ef395af8d01317b3d6560cc45f9275005 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 11 Oct 2008 19:12:14 +0000 Subject: [PATCH] - Implement GetPerAdapterInfo - Fix multiple bugs in EnumNameServers implementation svn path=/trunk/; revision=36720 --- reactos/dll/win32/iphlpapi/iphlpapi_main.c | 82 +++++++++++++++++-- reactos/dll/win32/iphlpapi/iphlpapi_private.h | 5 ++ reactos/dll/win32/iphlpapi/registry.c | 2 +- reactos/dll/win32/iphlpapi/resinfo_reactos.c | 12 ++- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_main.c b/reactos/dll/win32/iphlpapi/iphlpapi_main.c index f8dc48f7f74..4d506b5f2ba 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_main.c +++ b/reactos/dll/win32/iphlpapi/iphlpapi_main.c @@ -51,6 +51,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); +typedef struct _NAME_SERVER_LIST_CONTEXT { + ULONG uSizeAvailable; + ULONG uSizeRequired; + PIP_PER_ADAPTER_INFO pData; + UINT NumServers; + IP_ADDR_STRING *pLastAddr; +} NAME_SERVER_LIST_CONTEXT, *PNAME_SERVER_LIST_CONTEXT; + BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { @@ -1463,13 +1471,77 @@ DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf) * DWORD * */ +static void CreateNameServerListEnumNamesFunc( PWCHAR Interface, + PWCHAR Server, + PVOID Data ) +{ + IP_ADDR_STRING *pNext; + PNAME_SERVER_LIST_CONTEXT Context = (PNAME_SERVER_LIST_CONTEXT)Data; + + + if (!Context->NumServers) + { + if (Context->uSizeAvailable >= Context->uSizeRequired) + { + WideCharToMultiByte(CP_ACP, 0, Server, -1, Context->pData->DnsServerList.IpAddress.String, 16, NULL, NULL); + Context->pData->DnsServerList.IpAddress.String[15] = '\0'; + Context->pLastAddr = &Context->pData->DnsServerList; + } + } + else + { + Context->uSizeRequired += sizeof(IP_ADDR_STRING); + if (Context->uSizeAvailable >= Context->uSizeRequired) + { + pNext = ((char*)Context->pLastAddr) + sizeof(IP_ADDR_STRING); + WideCharToMultiByte(CP_ACP, 0, Server, -1, pNext->IpAddress.String, 16, NULL, NULL); + pNext->IpAddress.String[15] = '\0'; + Context->pLastAddr->Next = pNext; + Context->pLastAddr = pNext; + pNext->Next = NULL; + } + } + Context->NumServers++; +} + DWORD WINAPI GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen) { - TRACE("IfIndex %ld, pPerAdapterInfo %p, pOutBufLen %p\n", IfIndex, - pPerAdapterInfo, pOutBufLen); - FIXME(":stub\n"); - /* marking Win2K+ functions not supported */ - return ERROR_NOT_SUPPORTED; + HKEY hkey; + const char *ifName; + NAME_SERVER_LIST_CONTEXT Context; + WCHAR keyname[200] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; + + if (!pOutBufLen) + return ERROR_INVALID_PARAMETER; + + ifName = getInterfaceNameByIndex(IfIndex); + if (!ifName) + return ERROR_INVALID_PARAMETER; + + MultiByteToWideChar(CP_ACP, 0, ifName, -1, &keyname[62], sizeof(keyname) - (63 * sizeof(WCHAR))); + HeapFree(GetProcessHeap(), 0, (LPVOID)ifName); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hkey) != ERROR_SUCCESS) + { + return ERROR_NOT_SUPPORTED; + } + Context.NumServers = 0; + Context.uSizeAvailable = *pOutBufLen; + Context.uSizeRequired = sizeof(IP_PER_ADAPTER_INFO); + Context.pData = pPerAdapterInfo; + + if (*pOutBufLen >= sizeof(IP_PER_ADAPTER_INFO)) + ZeroMemory(pPerAdapterInfo, sizeof(IP_PER_ADAPTER_INFO)); + + EnumNameServers(hkey, &keyname[62], &Context, CreateNameServerListEnumNamesFunc); + + if (Context.uSizeRequired > Context.uSizeAvailable) + { + *pOutBufLen = Context.uSizeRequired; + return ERROR_BUFFER_OVERFLOW; + } + + return NOERROR; } diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 00435302941..98d3f732d6b 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -138,6 +138,11 @@ void ConsumeRegValueString( PWCHAR NameServer ); BOOL isInterface( TDIEntityID *if_maybe ); BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ); +typedef VOID (*EnumNameServersFunc)( PWCHAR Interface, + PWCHAR NameServer, + PVOID Data ); +void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb ); + #include /* This is here until we switch to version 2.5 of the mingw headers */ #if (__W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5) diff --git a/reactos/dll/win32/iphlpapi/registry.c b/reactos/dll/win32/iphlpapi/registry.c index 493fd14fabe..6875d038f3b 100644 --- a/reactos/dll/win32/iphlpapi/registry.c +++ b/reactos/dll/win32/iphlpapi/registry.c @@ -73,7 +73,7 @@ PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) { &ReturnedSize ) != 0) { return 0; } else { - Name = malloc( ReturnedSize ); + Name = malloc( ReturnedSize); RegQueryValueExW( RegHandle, ValueName, NULL, NULL, (PVOID)Name, &ReturnedSize ); return Name; diff --git a/reactos/dll/win32/iphlpapi/resinfo_reactos.c b/reactos/dll/win32/iphlpapi/resinfo_reactos.c index c8a8d0d7e57..b7e631f4175 100644 --- a/reactos/dll/win32/iphlpapi/resinfo_reactos.c +++ b/reactos/dll/win32/iphlpapi/resinfo_reactos.c @@ -82,9 +82,7 @@ RtlUnicodeToMultiByteN ( ULONG UnicodeSize ); -typedef VOID (*EnumNameServersFunc)( PWCHAR Interface, - PWCHAR NameServer, - PVOID Data ); + typedef VOID (*EnumInterfacesFunc)( HKEY ChildKeyHandle, PWCHAR ChildKeyName, PVOID Data ); @@ -123,7 +121,7 @@ static void EnumInterfaces( PVOID Data, EnumInterfacesFunc cb ) { * EnumNameServers */ -static void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, +void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb ) { PWCHAR NameServerString = QueryRegistryValueString(RegHandle, L"NameServer"); @@ -135,10 +133,10 @@ static void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, if (NameServerString[ch] == ',') { if (ch - LastNameStart > 0) { /* Skip empty entries */ PWCHAR NameServer = - malloc(ch - LastNameStart + 1); + malloc(((ch - LastNameStart) + 1) * sizeof(WCHAR)); if (NameServer) { memcpy(NameServer,NameServerString + LastNameStart, - (ch - LastNameStart)); + (ch - LastNameStart) * sizeof(WCHAR)); NameServer[ch - LastNameStart] = 0; cb( Interface, NameServer, Data ); free(NameServer); @@ -174,7 +172,7 @@ static void CreateNameServerListEnumIfFuncCount( HKEY RegHandle, CreateNameServerListEnumNamesFuncCount); } -static void CreateNameServerListEnumNamesFunc( PWCHAR Interface, +VOID CreateNameServerListEnumNamesFunc( PWCHAR Interface, PWCHAR Server, PVOID _Data ) { PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;