Author: cgutman
Date: Fri May 14 03:30:37 2010
New Revision: 47195
URL:
http://svn.reactos.org/svn/reactos?rev=47195&view=rev
Log:
[IPHLPAPI]
- Implement GetAdaptersAddresses
- Fixes the last iphlpapi winetest
Modified:
trunk/reactos/dll/win32/iphlpapi/iphlpapi_main.c
trunk/reactos/dll/win32/iphlpapi/iphlpapi_private.h
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] Fri May 14 03:30:37
2010
@@ -2301,17 +2301,196 @@
}
/*
- * @unimplemented
+ * @implemented
*/
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 (!pAdapterAddresses || *pOutBufLen == 0)
- return ERROR_BUFFER_OVERFLOW;
if (Reserved) return ERROR_INVALID_PARAMETER;
- FIXME(":stub\n");
- return ERROR_NO_DATA;
+ indexTable = getNonLoopbackInterfaceIndexTable(); //I think we want non-loopback
here
+ 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;
}
/*
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] Fri May 14 03:30:37
2010
@@ -59,6 +59,15 @@
#define TCP_REQUEST_QUERY_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
@@ -138,6 +147,10 @@
PWCHAR NameServer,
PVOID Data );
void EnumNameServers( HANDLE RegHandle, PWCHAR Interface, PVOID Data, EnumNameServersFunc
cb );
+NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile,
+ char *name,
+ DWORD index,
+ IFInfo *ifInfo);
#include <w32api.h>
/* This is here until we switch to version 2.5 of the mingw headers */