- Implement GetPerAdapterInfo

- Fix multiple bugs in EnumNameServers implementation

svn path=/trunk/; revision=36720
This commit is contained in:
Johannes Anderwald 2008-10-11 19:12:14 +00:00
parent 33e3938bb1
commit 722bbf4ef3
4 changed files with 88 additions and 13 deletions

View file

@ -51,6 +51,14 @@
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;
}

View 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)

View 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;

View 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;