From 617f243c3f9fe4e28f14f2f088a6202b69612b51 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 22 Aug 2010 22:22:27 +0000 Subject: [PATCH] [DHCPCSVC] - Write the DNS servers in a REG_MULTI_SZ value [IPHLPAPI] - Rewrite the registry reading code - Use HeapFree to free memory from the allocated from heap svn path=/trunk/; revision=48593 --- reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c | 11 +- reactos/dll/win32/iphlpapi/iphlpapi_private.h | 1 + reactos/dll/win32/iphlpapi/registry.c | 126 ++++++++++++++++-- reactos/dll/win32/iphlpapi/resinfo_reactos.c | 51 ++----- 4 files changed, 133 insertions(+), 56 deletions(-) diff --git a/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c b/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c index 3b60e1ad95d..120fd6c01e9 100644 --- a/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c +++ b/reactos/dll/win32/dhcpcsvc/dhcp/dhclient.c @@ -507,24 +507,25 @@ void set_name_servers( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) { char *nsbuf; int i, addrs = new_lease->options[DHO_DOMAIN_NAME_SERVERS].len / sizeof(ULONG); + int len = 0; - nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) ); + nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) + 1 ); if( nsbuf) { - nsbuf[0] = 0; + memset(nsbuf, 0, addrs * sizeof(IP_ADDRESS_STRING) + 1); for( i = 0; i < addrs; i++ ) { nameserver.len = sizeof(ULONG); memcpy( nameserver.iabuf, new_lease->options[DHO_DOMAIN_NAME_SERVERS].data + (i * sizeof(ULONG)), sizeof(ULONG) ); strcat( nsbuf, piaddr(nameserver) ); - if( i != addrs-1 ) strcat( nsbuf, "," ); + len += strlen(nsbuf) + 1; } DH_DbgPrint(MID_TRACE,("Setting DhcpNameserver: %s\n", nsbuf)); - RegSetValueExA( RegKey, "DhcpNameServer", 0, REG_SZ, - (LPBYTE)nsbuf, strlen(nsbuf) + 1 ); + RegSetValueExA( RegKey, "DhcpNameServer", 0, REG_MULTI_SZ, + (LPBYTE)nsbuf, len + 1 ); free( nsbuf ); } diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 2cb747f2a80..6ba198a301c 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -139,6 +139,7 @@ LONG OpenChildKeyRead( HANDLE RegHandle, PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ); void ConsumeChildKeyName( PWCHAR Name ); PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ); +PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ); void ConsumeRegValueString( PWCHAR NameServer ); BOOL isInterface( TDIEntityID *if_maybe ); BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ); diff --git a/reactos/dll/win32/iphlpapi/registry.c b/reactos/dll/win32/iphlpapi/registry.c index 64b0f1f98bb..e83fde95281 100644 --- a/reactos/dll/win32/iphlpapi/registry.c +++ b/reactos/dll/win32/iphlpapi/registry.c @@ -66,25 +66,123 @@ void ConsumeChildKeyName( PWCHAR Name ) { if (Name) HeapFree( GetProcessHeap(), 0, Name ); } -PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) { - PWCHAR Name; - DWORD ReturnedSize = 0; +PVOID QueryRegistryValue(HANDLE RegHandle, PWCHAR ValueName, LPDWORD RegistryType, LPDWORD Length) +{ + PVOID ReadValue = NULL; + DWORD Error; - if (RegQueryValueExW( RegHandle, ValueName, NULL, NULL, NULL, - &ReturnedSize ) != 0) { - return 0; - } else { - Name = malloc( ReturnedSize); - RegQueryValueExW( RegHandle, ValueName, NULL, NULL, (PVOID)Name, - &ReturnedSize ); - return Name; - } + *Length = 0; + *RegistryType = REG_NONE; + + while (TRUE) + { + Error = RegQueryValueExW(RegHandle, ValueName, NULL, RegistryType, ReadValue, Length); + if (Error == ERROR_SUCCESS) + { + if (ReadValue) break; + } + else if (Error == ERROR_MORE_DATA) + { + HeapFree(GetProcessHeap(), 0, ReadValue); + } + else break; + + ReadValue = HeapAlloc(GetProcessHeap(), 0, *Length); + if (!ReadValue) return NULL; + } + + if (Error != ERROR_SUCCESS) + { + if (ReadValue) HeapFree(GetProcessHeap(), 0, ReadValue); + + *Length = 0; + *RegistryType = REG_NONE; + ReadValue = NULL; + } + + return ReadValue; +} + +PWCHAR TerminateReadString(PWCHAR String, DWORD Length) +{ + PWCHAR TerminatedString; + + TerminatedString = HeapAlloc(GetProcessHeap(), 0, Length + sizeof(WCHAR)); + if (TerminatedString == NULL) + return NULL; + + memcpy(TerminatedString, String, Length); + + TerminatedString[Length / sizeof(WCHAR)] = UNICODE_NULL; + + return TerminatedString; +} + +PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) +{ + PWCHAR String, TerminatedString; + DWORD Type, Length; + + String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length); + if (!String) return NULL; + if (Type != REG_SZ) + { + DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_SZ); + //HeapFree(GetProcessHeap(), 0, String); + //return NULL; + } + + TerminatedString = TerminateReadString(String, Length); + HeapFree(GetProcessHeap(), 0, String); + if (!TerminatedString) return NULL; + + return TerminatedString; } void ConsumeRegValueString( PWCHAR Value ) { - if (Value) free(Value); + if (Value) HeapFree(GetProcessHeap(), 0, Value); } PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ) { - return 0; /* FIXME if needed */ + PWCHAR String, TerminatedString, Tmp; + PWCHAR *Table; + DWORD Type, Length, i, j; + + String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length); + if (!String) return NULL; + if (Type != REG_MULTI_SZ) + { + DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_MULTI_SZ); + //HeapFree(GetProcessHeap(), 0, String); + //return NULL; + } + + TerminatedString = TerminateReadString(String, Length); + HeapFree(GetProcessHeap(), 0, String); + if (!TerminatedString) return NULL; + + for (Tmp = TerminatedString, i = 0; *Tmp; Tmp++, i++) while (*Tmp) Tmp++; + + Table = HeapAlloc(GetProcessHeap(), 0, (i + 1) * sizeof(PWCHAR)); + if (!Table) + { + HeapFree(GetProcessHeap(), 0, TerminatedString); + return NULL; + } + + for (Tmp = TerminatedString, j = 0; *Tmp; Tmp++, j++) + { + PWCHAR Orig = Tmp; + + for (i = 0; *Tmp; i++, Tmp++); + + Table[j] = HeapAlloc(GetProcessHeap(), 0, i * sizeof(WCHAR)); + memcpy(Table[j], Orig, i * sizeof(WCHAR)); + } + + Table[j] = NULL; + + HeapFree(GetProcessHeap(), 0, TerminatedString); + + return Table; } diff --git a/reactos/dll/win32/iphlpapi/resinfo_reactos.c b/reactos/dll/win32/iphlpapi/resinfo_reactos.c index 02bcb3b9129..154170d0836 100644 --- a/reactos/dll/win32/iphlpapi/resinfo_reactos.c +++ b/reactos/dll/win32/iphlpapi/resinfo_reactos.c @@ -122,47 +122,24 @@ static void EnumInterfaces( PVOID Data, EnumInterfacesFunc cb ) { void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb ) { - PWCHAR NameServerString = - QueryRegistryValueString(RegHandle, L"DhcpNameServer"); + PWCHAR *NameServerString = + QueryRegistryValueStringMulti(RegHandle, L"DhcpNameServer"); + DWORD i; if (!NameServerString) - NameServerString = QueryRegistryValueString(RegHandle, L"NameServer"); - - if (NameServerString) { - /* Now, count the non-empty comma separated */ - DWORD ch; - DWORD LastNameStart = 0; - for (ch = 0; NameServerString[ch]; ch++) { - if (NameServerString[ch] == ',') { - if (ch - LastNameStart > 0) { /* Skip empty entries */ - PWCHAR NameServer = - malloc(((ch - LastNameStart) + 1) * sizeof(WCHAR)); - if (NameServer) { - memcpy(NameServer,NameServerString + LastNameStart, - (ch - LastNameStart) * sizeof(WCHAR)); - NameServer[ch - LastNameStart] = 0; - cb( Interface, NameServer, Data ); - free(NameServer); - LastNameStart = ch +1; - } - } - LastNameStart = ch + 1; /* The first one after the comma */ - } - } - if (ch - LastNameStart > 0) { /* A last name? */ - PWCHAR NameServer = malloc(((ch - LastNameStart) + 1) * sizeof(WCHAR)); - if (NameServer) { - memcpy(NameServer,NameServerString + LastNameStart, - (ch - LastNameStart) * sizeof(WCHAR)); - NameServer[ch - LastNameStart] = 0; - cb( Interface, NameServer, Data ); - free(NameServer); - } - } - ConsumeRegValueString(NameServerString); + NameServerString = QueryRegistryValueStringMulti(RegHandle, L"NameServer"); + + if (!NameServerString) return; + + for (i = 0; NameServerString[i]; i++) + { + cb(Interface, NameServerString[i], Data); + + HeapFree(GetProcessHeap(), 0, NameServerString[i]); } + + HeapFree(GetProcessHeap(), 0, NameServerString); } - static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface, PWCHAR Server, PVOID _Data ) {