- Implement GetPerAdapterInfo
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 11 Oct 2008 19:12:14 +0000 (19:12 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 11 Oct 2008 19:12:14 +0000 (19:12 +0000)
- Fix multiple bugs in EnumNameServers implementation

svn path=/trunk/; revision=36720

reactos/dll/win32/iphlpapi/iphlpapi_main.c
reactos/dll/win32/iphlpapi/iphlpapi_private.h
reactos/dll/win32/iphlpapi/registry.c
reactos/dll/win32/iphlpapi/resinfo_reactos.c

index f8dc48f..4d506b5 100644 (file)
 
 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;
 }
 
 
index 0043530..98d3f73 100644 (file)
@@ -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 <w32api.h>
 /* This is here until we switch to version 2.5 of the mingw headers */
 #if (__W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5)
index 493fd14..6875d03 100644 (file)
@@ -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;
index c8a8d0d..b7e631f 100644 (file)
@@ -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;