LONG Status;
DWORD MaxAdapterName;
- Status = RegQueryInfoKeyA(RegHandle,
- NULL,
- NULL,
- NULL,
- NULL,
- &MaxAdapterName,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
+ Status = RegQueryInfoKeyW(RegHandle,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxAdapterName,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
if (Status == ERROR_SUCCESS)
return MaxAdapterName + 1;
else
}
LONG OpenChildKeyRead( HANDLE RegHandle,
- PCHAR ChildKeyName,
- PHKEY ReturnHandle ) {
- return RegOpenKeyExA( RegHandle,
- ChildKeyName,
- 0,
- KEY_READ,
- ReturnHandle );
+ PWCHAR ChildKeyName,
+ PHKEY ReturnHandle ) {
+ return RegOpenKeyExW( RegHandle,
+ ChildKeyName,
+ 0,
+ KEY_READ,
+ ReturnHandle );
}
/*
* Yields a malloced value that must be freed.
*/
-PCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
+PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
LONG Status;
int MaxAdapterName = GetLongestChildKeyName( RegHandle );
- PCHAR Value;
+ PWCHAR Value;
DWORD ValueLen;
if (MaxAdapterName == -1) {
}
ValueLen = MaxAdapterName;
- Value = (PCHAR)HeapAlloc( GetProcessHeap(), 0, MaxAdapterName );
- Status = RegEnumKeyExA( RegHandle, n, Value, &ValueLen,
- NULL, NULL, NULL, NULL );
+ Value = (PWCHAR)HeapAlloc( GetProcessHeap(), 0, MaxAdapterName );
+ Status = RegEnumKeyExW( RegHandle, n, Value, &ValueLen,
+ NULL, NULL, NULL, NULL );
if (Status != ERROR_SUCCESS)
return 0;
else {
}
}
-void ConsumeChildKeyName( PCHAR Name ) {
+void ConsumeChildKeyName( PWCHAR Name ) {
if (Name) HeapFree( GetProcessHeap(), 0, Name );
}
-PCHAR QueryRegistryValueString( HANDLE RegHandle, PCHAR ValueName ) {
- PCHAR Name;
+PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) {
+ PWCHAR Name;
DWORD ReturnedSize = 0;
- if (RegQueryValueExA( RegHandle, ValueName, NULL, NULL, NULL,
- &ReturnedSize ) != 0)
+ if (RegQueryValueExW( RegHandle, ValueName, NULL, NULL, NULL,
+ &ReturnedSize ) != 0) {
return 0;
- else {
- Name = malloc( (ReturnedSize + 1) * sizeof(WCHAR) );
- RegQueryValueExA( RegHandle, ValueName, NULL, NULL, (PVOID)Name,
- &ReturnedSize );
- Name[ReturnedSize] = 0;
+ } else {
+ Name = malloc( ReturnedSize );
+ RegQueryValueExW( RegHandle, ValueName, NULL, NULL, (PVOID)Name,
+ &ReturnedSize );
return Name;
}
}
-void ConsumeRegValueString( PCHAR Value ) {
+void ConsumeRegValueString( PWCHAR Value ) {
if (Value) free(Value);
}
/*
- * iphlpapi dll implementation -- Auxiliary icmp functions
+ * iphlpapi dll implementation -- Setting and storing route information
*
- * These are stubs for functions that provide a simple ICMP probing API. They
- * will be operating system specific when implemented.
+ * These are stubs for functions that set routing information on the target
+ * operating system. They are grouped here because their implementation will
+ * vary widely by operating system.
*
* Copyright (C) 2004 Art Yerkes
* This library is free software; you can redistribute it and/or
#include "iphlpapi.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
+typedef struct _NAME_SERVER_LIST_PRIVATE {
+ UINT NumServers;
+ UINT CurrentName;
+ PIP_ADDRESS_STRING AddrString;
+} NAME_SERVER_LIST_PRIVATE, *PNAME_SERVER_LIST_PRIVATE;
+
+PVOID STDCALL
+RtlAllocateHeap (
+ HANDLE Heap,
+ ULONG Flags,
+ ULONG Size
+ );
+
+BOOLEAN
+STDCALL
+RtlFreeHeap (
+ HANDLE Heap,
+ ULONG Flags,
+ PVOID Address
+ );
+
+NTSTATUS
+STDCALL
+RtlUnicodeToMultiByteN (
+ PCHAR MbString,
+ ULONG MbSize,
+ PULONG ResultSize,
+ PWCHAR UnicodeString,
+ ULONG UnicodeSize
+ );
+
+typedef VOID (*EnumNameServersFunc)( PWCHAR Interface,
+ PWCHAR NameServer,
+ PVOID Data );
+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, TcpipHandle;
+ HKEY ChildKeyHandle = 0;
+ PWCHAR RegKeyToEnumerate =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
+ PWCHAR RegKeyForTcpip =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
+ 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
+ */
+
+static void EnumNameServers( HANDLE RegHandle, PWCHAR Interface,
+ PVOID Data, EnumNameServersFunc cb ) {
+ PWCHAR NameServerString =
+ QueryRegistryValueString(RegHandle, L"NameServer");
+ /* Now, count the non-empty comma separated */
+ if (NameServerString) {
+ 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);
+ if (NameServer) {
+ memcpy(NameServer,NameServerString + LastNameStart,
+ (ch - LastNameStart));
+ NameServer[ch - LastNameStart] = 0;
+ cb( Interface, NameServer, Data );
+ free(NameServer);
+ }
+ }
+ LastNameStart = ch + 1; /* The first one after the comma */
+ }
+ }
+ if (ch - LastNameStart > 0) { /* A last name? */
+ PWCHAR NameServer = malloc(ch - LastNameStart + 1);
+ memcpy(NameServer,NameServerString + LastNameStart,
+ (ch - LastNameStart));
+ NameServer[ch - LastNameStart] = 0;
+ cb( Interface, NameServer, Data );
+ free(NameServer);
+ }
+ ConsumeRegValueString(NameServerString);
+ }
+}
+
+static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface,
+ PWCHAR Server,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ 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);
+}
+
+static void CreateNameServerListEnumNamesFunc( PWCHAR Interface,
+ PWCHAR Server,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ RtlUnicodeToMultiByteN((PCHAR)&Data->AddrString[Data->CurrentName],
+ sizeof(Data->AddrString[0]),
+ NULL,
+ Server,
+ wcslen(Server));
+ Data->CurrentName++;
+}
+
+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() {
- PIPHLP_RES_INFO InfoPtr =
- (PIPHLP_RES_INFO)HeapAlloc( GetProcessHeap(), 0,
- sizeof(PIPHLP_RES_INFO) );
- if( InfoPtr ) {
- InfoPtr->riCount = 0;
- InfoPtr->riAddressList = NULL;
+ DWORD result = ERROR_SUCCESS, dwSize, i, ServerCount, ExtraServer;
+ HKEY hKey;
+ LONG errCode;
+ PWCHAR Str;
+ IP_ADDR_STRING AddrString;
+ NAME_SERVER_LIST_PRIVATE PrivateNSEnum = { 0 };
+ PIPHLP_RES_INFO ResInfo;
+ struct sockaddr_in *AddrList;
+
+ ServerCount = CountNameServers( &PrivateNSEnum );
+
+ errCode = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\"
+ "Parameters", 0, KEY_READ, &hKey);
+ if (errCode != ERROR_SUCCESS) {
+ RegCloseKey( hKey );
+ return NULL;
+ }
+
+ Str = QueryRegistryValueString( hKey, L"NameServer" );
+ ExtraServer = Str ? 1 : 0;
+
+ ServerCount += ExtraServer;
+
+ PrivateNSEnum.NumServers = ServerCount;
+ PrivateNSEnum.AddrString =
+ (PIP_ADDRESS_STRING)
+ RtlAllocateHeap( GetProcessHeap(), 0,
+ ServerCount * sizeof(IP_ADDRESS_STRING) );
+
+ ResInfo =
+ (PIPHLP_RES_INFO)RtlAllocateHeap
+ ( GetProcessHeap(), 0,
+ sizeof(IPHLP_RES_INFO) +
+ (ServerCount * sizeof(struct sockaddr_in)) );
+
+ if( !ResInfo ) {
+ RtlFreeHeap( GetProcessHeap(), 0, PrivateNSEnum.AddrString );
+ RegCloseKey( hKey );
+ return NULL;
+ }
+
+ ResInfo->riCount = ServerCount;
+ AddrList = (struct sockaddr_in *)
+ (((PCHAR)ResInfo) + sizeof(IPHLP_RES_INFO));
+ ResInfo->riAddressList = AddrList;
+
+ MakeNameServerList( &PrivateNSEnum );
+
+ if( ExtraServer ) {
+ ULONG ResultSize;
+
+ for( ResultSize = 0; Str[ResultSize]; ResultSize++ )
+ ((PCHAR)&AddrString)[ResultSize] = Str[ResultSize];
+
+ ((PCHAR)&AddrString)[ResultSize] = 0;
+ ResInfo->riAddressList[0].sin_family = AF_INET;
+ ResInfo->riAddressList[0].sin_addr.s_addr =
+ inet_addr( (PCHAR)&AddrString );
+ ResInfo->riAddressList[0].sin_port = 0;
+ ConsumeRegValueString( Str );
+ }
+
+ for( i = ExtraServer; i < ServerCount; i++ ) {
+ /* Hmm seems that dns servers are always AF_INET but ... */
+ ResInfo->riAddressList[i].sin_family = AF_INET;
+ ResInfo->riAddressList[i].sin_addr.s_addr =
+ inet_addr( (PCHAR)&PrivateNSEnum.AddrString[i - ExtraServer] );
+ ResInfo->riAddressList[i].sin_port = 0;
}
+
+ RtlFreeHeap( GetProcessHeap(), 0, PrivateNSEnum.AddrString );
+ RegCloseKey( hKey );
- return InfoPtr;
+ return ResInfo;
}
VOID disposeResInfo( PIPHLP_RES_INFO InfoPtr ) {
- HeapFree( GetProcessHeap(), 0, InfoPtr );
+ RtlFreeHeap( GetProcessHeap(), 0, InfoPtr );
}