mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:42:56 +00:00
[IPHLPAPI]
- Implement GetAdaptersAddresses - Fixes the last iphlpapi winetest svn path=/trunk/; revision=47195
This commit is contained in:
parent
0ca885a586
commit
ebb491824a
2 changed files with 197 additions and 5 deletions
|
@ -2301,17 +2301,196 @@ PIP_ADAPTER_ORDER_MAP WINAPI GetAdapterOrderMap(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen)
|
DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen)
|
||||||
{
|
{
|
||||||
|
InterfaceIndexTable *indexTable;
|
||||||
|
IFInfo ifInfo;
|
||||||
|
int i;
|
||||||
|
ULONG ret, requiredSize = 0;
|
||||||
|
PIP_ADAPTER_ADDRESSES currentAddress;
|
||||||
|
PUCHAR currentLocation;
|
||||||
|
HANDLE tcpFile;
|
||||||
|
|
||||||
if (!pOutBufLen) return ERROR_INVALID_PARAMETER;
|
if (!pOutBufLen) return ERROR_INVALID_PARAMETER;
|
||||||
if (!pAdapterAddresses || *pOutBufLen == 0)
|
|
||||||
return ERROR_BUFFER_OVERFLOW;
|
|
||||||
if (Reserved) return ERROR_INVALID_PARAMETER;
|
if (Reserved) return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
FIXME(":stub\n");
|
indexTable = getNonLoopbackInterfaceIndexTable(); //I think we want non-loopback here
|
||||||
return ERROR_NO_DATA;
|
if (!indexTable)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
|
ret = openTcpFile(&tcpFile);
|
||||||
|
if (!NT_SUCCESS(ret))
|
||||||
|
return ERROR_NO_DATA;
|
||||||
|
|
||||||
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile,
|
||||||
|
NULL,
|
||||||
|
indexTable->indexes[i],
|
||||||
|
&ifInfo)))
|
||||||
|
{
|
||||||
|
/* The whole struct */
|
||||||
|
requiredSize += sizeof(IP_ADAPTER_ADDRESSES);
|
||||||
|
|
||||||
|
/* Friendly name */
|
||||||
|
if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||||
|
requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; //FIXME
|
||||||
|
|
||||||
|
/* Adapter name */
|
||||||
|
requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||||
|
|
||||||
|
/* Unicast address */
|
||||||
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||||
|
requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||||
|
|
||||||
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||||
|
|
||||||
|
/* FIXME: Implement dns suffix and description */
|
||||||
|
requiredSize += 2 * sizeof(WCHAR);
|
||||||
|
|
||||||
|
/* We're only going to implement what's required for XP SP0 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pOutBufLen < requiredSize)
|
||||||
|
{
|
||||||
|
*pOutBufLen = requiredSize;
|
||||||
|
closeTcpFile(tcpFile);
|
||||||
|
free(indexTable);
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(pAdapterAddresses, requiredSize);
|
||||||
|
|
||||||
|
/* Let's set up the pointers */
|
||||||
|
currentAddress = pAdapterAddresses;
|
||||||
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile,
|
||||||
|
NULL,
|
||||||
|
indexTable->indexes[i],
|
||||||
|
&ifInfo)))
|
||||||
|
{
|
||||||
|
currentLocation = (PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES);
|
||||||
|
|
||||||
|
/* FIXME: Friendly name */
|
||||||
|
if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||||
|
{
|
||||||
|
currentAddress->FriendlyName = (PVOID)currentLocation;
|
||||||
|
currentLocation += sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adapter name */
|
||||||
|
currentAddress->AdapterName = (PVOID)currentLocation;
|
||||||
|
currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||||
|
|
||||||
|
/* Unicast address */
|
||||||
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||||
|
{
|
||||||
|
currentAddress->FirstUnicastAddress = (PVOID)currentLocation;
|
||||||
|
currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||||
|
currentAddress->FirstUnicastAddress->Address.lpSockaddr = (PVOID)currentLocation;
|
||||||
|
currentLocation += sizeof(struct sockaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||||
|
|
||||||
|
/* FIXME: Implement dns suffix and description */
|
||||||
|
currentAddress->DnsSuffix = (PVOID)currentLocation;
|
||||||
|
currentLocation += sizeof(WCHAR);
|
||||||
|
|
||||||
|
currentAddress->Description = (PVOID)currentLocation;
|
||||||
|
currentLocation += sizeof(WCHAR);
|
||||||
|
|
||||||
|
currentAddress->Next = (PVOID)currentLocation;
|
||||||
|
|
||||||
|
/* We're only going to implement what's required for XP SP0 */
|
||||||
|
|
||||||
|
currentAddress = currentAddress->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the last address correctly */
|
||||||
|
if (currentAddress)
|
||||||
|
currentAddress->Next = NULL;
|
||||||
|
|
||||||
|
/* Now again, for real this time */
|
||||||
|
|
||||||
|
currentAddress = pAdapterAddresses;
|
||||||
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile,
|
||||||
|
NULL,
|
||||||
|
indexTable->indexes[i],
|
||||||
|
&ifInfo)))
|
||||||
|
{
|
||||||
|
/* Make sure we're not looping more than we hoped for */
|
||||||
|
ASSERT(currentAddress);
|
||||||
|
|
||||||
|
/* Alignment information */
|
||||||
|
currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES);
|
||||||
|
currentAddress->IfIndex = indexTable->indexes[i];
|
||||||
|
|
||||||
|
/* Adapter name */
|
||||||
|
strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr);
|
||||||
|
|
||||||
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||||
|
{
|
||||||
|
currentAddress->FirstUnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||||
|
currentAddress->FirstUnicastAddress->Flags = 0; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->Next = NULL; //FIXME: Support more than one address per adapter
|
||||||
|
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family = AF_INET;
|
||||||
|
memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data,
|
||||||
|
&ifInfo.ip_addr.iae_addr,
|
||||||
|
sizeof(ifInfo.ip_addr.iae_addr));
|
||||||
|
currentAddress->FirstUnicastAddress->Address.iSockaddrLength = sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT);
|
||||||
|
currentAddress->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->SuffixOrigin = IpPrefixOriginOther; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->DadState = IpDadStatePreferred; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->ValidLifetime = 0xFFFFFFFF; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->PreferredLifetime = 0xFFFFFFFF; //FIXME
|
||||||
|
currentAddress->FirstUnicastAddress->LeaseLifetime = 0xFFFFFFFF; //FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||||
|
currentAddress->FirstAnycastAddress = NULL;
|
||||||
|
currentAddress->FirstMulticastAddress = NULL;
|
||||||
|
currentAddress->FirstDnsServerAddress = NULL;
|
||||||
|
|
||||||
|
/* FIXME: Implement dns suffix, description, and friendly name */
|
||||||
|
currentAddress->DnsSuffix[0] = UNICODE_NULL;
|
||||||
|
currentAddress->Description[0] = UNICODE_NULL;
|
||||||
|
currentAddress->FriendlyName[0] = UNICODE_NULL;
|
||||||
|
|
||||||
|
/* Physical Address */
|
||||||
|
memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr, ifInfo.if_info.ent.if_physaddrlen);
|
||||||
|
currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen;
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
currentAddress->Flags = 0; //FIXME
|
||||||
|
|
||||||
|
/* MTU */
|
||||||
|
currentAddress->Mtu = ifInfo.if_info.ent.if_mtu;
|
||||||
|
|
||||||
|
/* Interface type */
|
||||||
|
currentAddress->IfType = ifInfo.if_info.ent.if_type;
|
||||||
|
|
||||||
|
/* Operational status */
|
||||||
|
currentAddress->OperStatus = ifInfo.if_info.ent.if_operstatus;
|
||||||
|
|
||||||
|
/* We're only going to implement what's required for XP SP0 */
|
||||||
|
|
||||||
|
/* Move to the next address */
|
||||||
|
currentAddress = currentAddress->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeTcpFile(tcpFile);
|
||||||
|
free(indexTable);
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -60,6 +60,15 @@
|
||||||
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } }
|
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } }
|
||||||
#define TCP_REQUEST_SET_INFORMATION_INIT { { 0 } }
|
#define TCP_REQUEST_SET_INFORMATION_INIT { { 0 } }
|
||||||
|
|
||||||
|
/* FIXME: ROS headers suck */
|
||||||
|
#ifndef GAA_FLAG_SKIP_UNICAST
|
||||||
|
#define GAA_FLAG_SKIP_UNICAST 0x0001
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GAA_FLAG_SKIP_FRIENDLY_NAME
|
||||||
|
#define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020
|
||||||
|
#endif
|
||||||
|
|
||||||
// As in the mib from RFC 1213
|
// As in the mib from RFC 1213
|
||||||
|
|
||||||
typedef struct _IPRouteEntry {
|
typedef struct _IPRouteEntry {
|
||||||
|
@ -138,6 +147,10 @@ typedef VOID (*EnumNameServersFunc)( PWCHAR Interface,
|
||||||
PWCHAR NameServer,
|
PWCHAR NameServer,
|
||||||
PVOID Data );
|
PVOID Data );
|
||||||
void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb );
|
void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc cb );
|
||||||
|
NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile,
|
||||||
|
char *name,
|
||||||
|
DWORD index,
|
||||||
|
IFInfo *ifInfo);
|
||||||
|
|
||||||
#include <w32api.h>
|
#include <w32api.h>
|
||||||
/* This is here until we switch to version 2.5 of the mingw headers */
|
/* This is here until we switch to version 2.5 of the mingw headers */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue