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/iphlpap…
==============================================================================
--- 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/iphlpap…
==============================================================================
--- 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/tcpipcon…
==============================================================================
--- 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);
}
}