Author: janderwald Date: Sat Jan 1 21:13:07 2011 New Revision: 50257
URL: http://svn.reactos.org/svn/reactos?rev=50257&view=rev Log: [IPHLPAPI] - Rewrite name server enumeration routines - Check if static dns entries are present before checking for dynamic dns entries - Fixes static dns entries [NETCFGX] - GetPerAdapterInfo requires IP_PER_ADAPTER_INFO struct - Fix reading static dns entries - Delete static name server key, when changing dns servers to automatic (dhcp) - Don't delete DhcpNameServer key yet, as more interaction is needed with dhcp service when changing from static dns to dynamic dhcp - Should finally fix static dns when dhcp is active
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h trunk/reactos/dll/win32/iphlpapi/resinfo_reactos.c trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/iphlpapi... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c [iso-8859-1] Sat Jan 1 21:13:07 2011 @@ -1622,7 +1622,11 @@ return ERROR_BUFFER_OVERFLOW; }
- if(RegQueryValueExW(hkey, L"DHCPNameServer", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS) + if(RegQueryValueExW(hkey, L"NameServer", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS) + { + pPerAdapterInfo->AutoconfigActive = FALSE; + } + else { pPerAdapterInfo->AutoconfigActive = TRUE; }
Modified: trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/iphlpapi... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h [iso-8859-1] Sat Jan 1 21:13:07 2011 @@ -147,7 +147,7 @@ typedef VOID (*EnumNameServersFunc)( PWCHAR Interface, PWCHAR NameServer, PVOID Data ); -void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb ); +LSTATUS EnumNameServers( HKEY RegHandle, LPWSTR Interface, PVOID Data, EnumNameServersFunc cb ); NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile, char *name, DWORD index,
Modified: trunk/reactos/dll/win32/iphlpapi/resinfo_reactos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/resinfo_... ============================================================================== --- trunk/reactos/dll/win32/iphlpapi/resinfo_reactos.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/resinfo_reactos.c [iso-8859-1] Sat Jan 1 21:13:07 2011 @@ -52,197 +52,348 @@ IP_ADDR_STRING * pCurrent; } NAME_SERVER_LIST_PRIVATE, *PNAME_SERVER_LIST_PRIVATE;
-NTSYSAPI -PVOID -NTAPI -RtlAllocateHeap ( - HANDLE Heap, - ULONG Flags, - SIZE_T Size - ); - -NTSYSAPI -BOOLEAN -NTAPI -RtlFreeHeap ( - HANDLE Heap, - ULONG Flags, - PVOID Address - ); - -NTSYSAPI -NTSTATUS -NTAPI -RtlUnicodeToMultiByteN ( - PCHAR MbString, - ULONG MbSize, - PULONG ResultSize, - PWCHAR UnicodeString, - ULONG UnicodeSize - ); - - -typedef VOID (*EnumInterfacesFunc)( HKEY ChildKeyHandle, - PWCHAR ChildKeyName, - PVOID Data ); - -/* - * EnumInterfaces - * - * Call the enumeration function for each name server. - */ - -static void EnumInterfaces( PVOID Data, EnumInterfacesFunc cb ) { - HKEY RegHandle; - HKEY ChildKeyHandle = 0; - PWCHAR RegKeyToEnumerate = - L"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"; - PWCHAR ChildKeyName = 0; - DWORD CurrentInterface; - - if (OpenChildKeyRead(HKEY_LOCAL_MACHINE,RegKeyToEnumerate,&RegHandle)) { - return; - } - - for (CurrentInterface = 0; TRUE; CurrentInterface++) { - ChildKeyName = GetNthChildKeyName( RegHandle, CurrentInterface ); - if (!ChildKeyName) break; - if (OpenChildKeyRead(RegHandle,ChildKeyName, - &ChildKeyHandle) == 0) { - cb( ChildKeyHandle, ChildKeyName, Data ); - RegCloseKey( ChildKeyHandle ); - } - ConsumeChildKeyName( ChildKeyName ); - } -} - -/* - * EnumNameServers - */ - -void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, - PVOID Data, EnumNameServersFunc cb ) { - PWCHAR NameServerString = - QueryRegistryValueString(RegHandle, L"DhcpNameServer"); - - 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); +typedef VOID (*ENUM_INTERFACE_CALLBACK)( + HKEY ChildKeyHandle, + LPWSTR ChildKeyName, + PVOID CallbackContext); + +LSTATUS +QueryNameServer( + IN HKEY hInterface, + IN LPCWSTR NameServerKey, + OUT LPWSTR * OutNameServer) +{ + DWORD dwLength, dwType; + LPWSTR NameServer; + LSTATUS Status; + + /* query ns */ + dwLength = 0; + Status = RegQueryValueExW(hInterface, NameServerKey, NULL, &dwType, NULL, &dwLength); + + if (Status != ERROR_SUCCESS) + { + /* failed to retrieve size */ + DbgPrint("Status %x\n", Status); + return Status; + } + + /* add terminating null */ + dwLength += sizeof(WCHAR); + + /* allocate name server */ + NameServer = HeapAlloc(GetProcessHeap(), 0, dwLength); + + if (!NameServer) + { + /* no memory */ + return ERROR_OUTOFMEMORY; + } + + /* query ns */ + Status = RegQueryValueExW(hInterface, NameServerKey, NULL, &dwType, (LPBYTE)NameServer, &dwLength); + + if (Status != ERROR_SUCCESS || dwType != REG_SZ) + { + /* failed to retrieve ns */ + HeapFree(GetProcessHeap(), 0, NameServer); + return Status; + } + + /* null terminate it */ + NameServer[dwLength / sizeof(WCHAR)] = L'\0'; + + /* store result */ + *OutNameServer = NameServer; + + return STATUS_SUCCESS; +} + + +LSTATUS +EnumNameServers( + IN HKEY hInterface, + IN LPWSTR InterfaceName, + PVOID ServerCallbackContext, + EnumNameServersFunc CallbackRoutine) +{ + LSTATUS Status; + LPWSTR NameServer; + WCHAR Buffer[50]; + DWORD Length; + LPWSTR Start, Comma; + + /* query static assigned name server */ + Status = QueryNameServer(hInterface, L"NameServer", &NameServer); + if (Status != ERROR_SUCCESS) + { + /* query dynamic assigned name server */ + Status = QueryNameServer(hInterface, L"DhcpNameServer", &NameServer); + + if (Status != ERROR_SUCCESS) + { + /* failed to retrieve name servers */ + return Status; + } + } + + /* enumerate all name servers, terminated by comma */ + Start = NameServer; + + do + { + /* find next terminator */ + Comma = wcschr(Start, L','); + + if (Comma) + { + /* calculate length */ + Length = Comma - Start; + + /* copy name server */ + RtlMoveMemory(Buffer, Start, Length * sizeof(WCHAR)); + + /* null terminate it */ + Buffer[Length] = L'\0'; + + /* perform callback */ + CallbackRoutine(InterfaceName, Buffer, ServerCallbackContext); + + } + else + { + /* perform callback */ + CallbackRoutine(InterfaceName, Start, ServerCallbackContext); + + /* last entry */ + break; + } + + /* increment offset */ + Start = Comma + 1; + + }while(TRUE); + + /* free name server string */ + HeapFree(GetProcessHeap(), 0, NameServer); + + /* done */ + return ERROR_SUCCESS; +} + +LSTATUS +EnumInterfaces( + ENUM_INTERFACE_CALLBACK CallbackRoutine, + PVOID InterfaceCallbackContext) +{ + HKEY hKey, hInterface; + LSTATUS Status; + DWORD NumInterfaces, InterfaceNameLen, Index, Length; + LPWSTR InterfaceName; + + /* first open interface key */ + Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces", 0, KEY_READ, &hKey); + + /* check for success */ + if (Status != ERROR_SUCCESS) + { + /* failed to open interface key */ + return Status; + } + + /* now get maximum interface name length and number of interfaces */ + Status = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &NumInterfaces, &InterfaceNameLen, NULL, NULL, NULL, NULL, NULL, NULL); + if (Status != ERROR_SUCCESS) + { + /* failed to get key info */ + RegCloseKey(hKey); + return Status; + } + + /* RegQueryInfoKey does not include terminating null */ + InterfaceNameLen++; + + /* allocate interface name */ + InterfaceName = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, InterfaceNameLen * sizeof(WCHAR)); + + if (!InterfaceName) + { + /* no memory */ + RegCloseKey(hKey); + return ERROR_OUTOFMEMORY; + } + + /* no enumerate all interfaces */ + for(Index = 0; Index < NumInterfaces; Index++) + { + /* query interface name */ + Length = InterfaceNameLen; + Status = RegEnumKeyExW(hKey, Index, InterfaceName, &Length, NULL, NULL, NULL, NULL); + + if (Status == ERROR_SUCCESS) + { + /* make sure it is null terminated */ + InterfaceName[Length] = L'\0'; + + /* now open child key */ + Status = RegOpenKeyExW(hKey, InterfaceName, 0, KEY_READ, &hInterface); + + if (Status == ERROR_SUCCESS) + { + /* perform enumeration callback */ + CallbackRoutine(hInterface, InterfaceName, InterfaceCallbackContext); + + /* close interface key */ + RegCloseKey(hInterface); } - } - ConsumeRegValueString(NameServerString); - } -} - -static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface, - PWCHAR Server, - PVOID _Data ) { - PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data; + } + } + + /* free interface name */ + HeapFree(GetProcessHeap(), 0, InterfaceName); + + /* close root interface key */ + RegCloseKey(hKey); + + /* done */ + return Status; +} + +VOID +CountNameServerCallback( + IN LPWSTR InterfaceName, + IN LPWSTR Server, + IN PVOID CallbackContext) +{ + /* get context */ + PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)CallbackContext; + + /* increment server count */ Data->NumServers++; }
-static void CreateNameServerListEnumIfFuncCount( HKEY RegHandle, - PWCHAR InterfaceName, - PVOID _Data ) { - PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data; - EnumNameServers(RegHandle,InterfaceName,Data, - CreateNameServerListEnumNamesFuncCount); -} - -VOID CreateNameServerListEnumNamesFunc( - PWCHAR Interface, - PWCHAR Server, - PVOID _Data ) -{ - PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data; - +VOID +CountServerCallbackTrampoline( + HKEY ChildKeyHandle, + LPWSTR ChildKeyName, + PVOID CallbackContext) +{ + EnumNameServers(ChildKeyHandle, ChildKeyName, CallbackContext, CountNameServerCallback); +} + +LSTATUS +CountNameServers( + IN PNAME_SERVER_LIST_PRIVATE PrivateData ) +{ + return EnumInterfaces(CountServerCallbackTrampoline, (PVOID)PrivateData); +} + +VOID +CreateNameServerListCallback( + IN LPWSTR InterfaceName, + IN LPWSTR Server, + IN PVOID CallbackContext) +{ + /* get context */ + PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)CallbackContext; + + /* convert to ansi ns string */ if (WideCharToMultiByte(CP_ACP, 0, Server, -1, Data->pCurrent->IpAddress.String, 16, NULL, NULL)) { - Data->pCurrent->Next = (struct _IP_ADDR_STRING*)(char*)Data->pCurrent + sizeof(IP_ADDR_STRING); + /* store offset to next name server struct */ + Data->pCurrent->Next = (struct _IP_ADDR_STRING*)(Data->pCurrent + 1); + + /* move to next entry */ Data->pCurrent = Data->pCurrent->Next; + + /* increment server count */ Data->NumServers++; } else { + /* failed to convert dns server */ Data->pCurrent->IpAddress.String[0] = '\0'; } }
-static void CreateNameServerListEnumIfFunc( HKEY RegHandle, - PWCHAR InterfaceName, - PVOID _Data ) { - PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data; - EnumNameServers(RegHandle,InterfaceName,Data, - CreateNameServerListEnumNamesFunc); -} - -static int CountNameServers( PNAME_SERVER_LIST_PRIVATE PrivateData ) { - EnumInterfaces(PrivateData,CreateNameServerListEnumIfFuncCount); - return PrivateData->NumServers; -} - -static void MakeNameServerList( PNAME_SERVER_LIST_PRIVATE PrivateData ) { - EnumInterfaces(PrivateData,CreateNameServerListEnumIfFunc); -} - -PIPHLP_RES_INFO getResInfo() { - DWORD ServerCount; +VOID +CreateNameServerListCallbackTrampoline( + HKEY ChildKeyHandle, + LPWSTR ChildKeyName, + PVOID CallbackContext) +{ + EnumNameServers(ChildKeyHandle, ChildKeyName, CallbackContext, CreateNameServerListCallback); +} + +LSTATUS +MakeNameServerList( + PNAME_SERVER_LIST_PRIVATE PrivateData ) +{ + return EnumInterfaces(CreateNameServerListCallbackTrampoline, (PVOID)PrivateData); +} + +PIPHLP_RES_INFO +getResInfo() +{ NAME_SERVER_LIST_PRIVATE PrivateNSEnum; PIPHLP_RES_INFO ResInfo; - IP_ADDR_STRING * DnsList; + IP_ADDR_STRING * DnsList = NULL; + LSTATUS Status;
PrivateNSEnum.NumServers = 0; - ServerCount = CountNameServers( &PrivateNSEnum ); - - PrivateNSEnum.NumServers = ServerCount; - DnsList = HeapAlloc(GetProcessHeap(), 0, ServerCount * sizeof(IP_ADDR_STRING)); - if (!DnsList) return NULL; - - ZeroMemory(DnsList, ServerCount * sizeof(IP_ADDR_STRING)); - - ResInfo = (PIPHLP_RES_INFO)RtlAllocateHeap ( GetProcessHeap(), 0, sizeof(IPHLP_RES_INFO)); - if( !ResInfo ) - { - HeapFree( GetProcessHeap(), 0, DnsList ); + + /* count name servers */ + Status = CountNameServers(&PrivateNSEnum); + + if (Status != ERROR_SUCCESS) + { + /* failed to enumerate name servers */ return NULL; }
- PrivateNSEnum.NumServers = 0; - PrivateNSEnum.pCurrent = DnsList; - - MakeNameServerList( &PrivateNSEnum ); - ResInfo->DnsList = DnsList; - ResInfo->riCount = PrivateNSEnum.NumServers; - + /* are there any servers */ + if (PrivateNSEnum.NumServers) + { + /* allocate dns servers */ + DnsList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivateNSEnum.NumServers * sizeof(IP_ADDR_STRING)); + + if (!DnsList) + { + /* no memory */ + return NULL; + } + } + + /* allocate private struct */ + ResInfo = (PIPHLP_RES_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IPHLP_RES_INFO)); + + if(!ResInfo) + { + /* no memory */ + if (DnsList) + { + /* free dns list */ + HeapFree( GetProcessHeap(), 0, DnsList); + } + return NULL; + } + + /* are there any servers */ + if (PrivateNSEnum.NumServers) + { + /* initialize enumeration context */ + PrivateNSEnum.NumServers = 0; + PrivateNSEnum.pCurrent = DnsList; + + /* enumerate servers */ + MakeNameServerList( &PrivateNSEnum ); + + /* store result */ + ResInfo->DnsList = DnsList; + ResInfo->riCount = PrivateNSEnum.NumServers; + } + + /* done */ return ResInfo; }
Modified: trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netcfgx/tcpipconf... ============================================================================== --- trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netcfgx/tcpipconf_notify.c [iso-8859-1] Sat Jan 1 21:13:07 2011 @@ -2765,11 +2765,12 @@ HRESULT Initialize(TcpipConfNotifyImpl * This) { - DWORD dwSize; + DWORD dwSize, Status; WCHAR szBuffer[50]; IP_ADAPTER_INFO * pCurrentAdapter; IP_ADAPTER_INFO * pInfo; PIP_PER_ADAPTER_INFO pPerInfo; + IP_PER_ADAPTER_INFO Info; LPOLESTR pStr; HRESULT hr; BOOL bFound; @@ -2846,13 +2847,17 @@ CopyIpAddrString(&pCurrentAdapter->IpAddressList, &pCurSettings->Ip, SUBMASK, NULL); CopyIpAddrString(&pCurrentAdapter->GatewayList, &pCurSettings->Gw, METRIC, NULL); //FIXME } - uLength = 0; - if (GetPerAdapterInfo(pCurrentAdapter->Index, NULL, &uLength) == ERROR_BUFFER_OVERFLOW) + + uLength = sizeof(IP_PER_ADAPTER_INFO); + ZeroMemory(&Info, sizeof(IP_PER_ADAPTER_INFO)); + + if (GetPerAdapterInfo(pCurrentAdapter->Index, &Info, &uLength) == ERROR_BUFFER_OVERFLOW) { pPerInfo = (PIP_PER_ADAPTER_INFO)CoTaskMemAlloc(uLength); if (pPerInfo) { - if (GetPerAdapterInfo(pCurrentAdapter->Index, pPerInfo, &uLength) == NOERROR) + Status = GetPerAdapterInfo(pCurrentAdapter->Index, pPerInfo, &uLength); + if (Status == NOERROR) { if (!pPerInfo->AutoconfigActive) { @@ -2862,9 +2867,8 @@ } CoTaskMemFree(pPerInfo); } - } - - + + } if (FAILED(LoadFilterSettings(This))) return E_FAIL;
@@ -3284,16 +3288,15 @@
if (!pCurrentConfig->Ns || pCurrentConfig->AutoconfigActive) { - RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR)); + RegDeleteValueW(hKey, L"NameServer"); } else { pStr = CreateMultiSzString(pCurrentConfig->Ns, IPADDR, &dwSize, TRUE); if(pStr) { - RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)pStr, dwSize); - RegDeleteValueW(hKey, L"DhcpNameServer"); + //RegDeleteValueW(hKey, L"DhcpNameServer"); CoTaskMemFree(pStr); } }