Sync with trunk (r48545)
[reactos.git] / dll / win32 / iphlpapi / iphlpapi_main.c
index 6d27ce6..717fd2d 100644 (file)
@@ -49,7 +49,7 @@
 #include "route.h"
 #include "wine/debug.h"
 #include "dhcpcsdk.h"
-#include "dhcp/rosdhcp_public.h"
+#include "dhcpcapi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
 
@@ -789,6 +789,32 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
   return ret;
 }
 
+/******************************************************************
+ *    GetExtendedTcpTable (IPHLPAPI.@)
+ *
+ * Get the table of TCP endpoints available to the application.
+ *
+ * PARAMS
+ *  pTcpTable [Out]    table struct with the filtered TCP endpoints available to application
+ *  pdwSize   [In/Out] estimated size of the structure returned in pTcpTable, in bytes
+ *  bOrder    [In]     whether to order the table
+ *  ulAf       [in]    version of IP used by the TCP endpoints
+ *  TableClass [in]    type of the TCP table structure from TCP_TABLE_CLASS
+ *  Reserved [in]      reserved - this value must be zero
+ *
+ * RETURNS
+ *  Success: NO_ERROR
+ *  Failure: either ERROR_INSUFFICIENT_BUFFER or ERROR_INVALID_PARAMETER
+ *
+ * NOTES
+ */
+DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved)
+{
+       DWORD ret = NO_ERROR;
+       UNIMPLEMENTED;
+       return ret;     
+}
+
 
 /******************************************************************
  *    GetFriendlyIfIndex (IPHLPAPI.@)
@@ -1479,6 +1505,33 @@ DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf)
 }
 
 
+/******************************************************************
+ *    GetOwnerModuleFromTcpEntry (IPHLPAPI.@)
+ *
+ * Get data about the module that issued the context bind for a specific IPv4 TCP endpoint in a MIB table row
+ *
+ * PARAMS
+ *  pTcpEntry [in]    pointer to a MIB_TCPROW_OWNER_MODULE structure
+ *  Class [in]         TCPIP_OWNER_MODULE_INFO_CLASS enumeration value
+ *  Buffer [out]       pointer a buffer containing a TCPIP_OWNER_MODULE_BASIC_INFO structure with the owner module data. 
+ *  pdwSize [in, out]  estimated size of the structure returned in Buffer, in bytes
+ *
+ * RETURNS
+ *  Success: NO_ERROR
+ *  Failure: ERROR_INSUFFICIENT_BUFFER, ERROR_INVALID_PARAMETER, ERROR_NOT_ENOUGH_MEMORY
+ *            ERROR_NOT_FOUND or ERROR_PARTIAL_COPY
+ *
+ * NOTES
+ * The type of data returned in Buffer is indicated by the value of the Class parameter.
+ */
+DWORD WINAPI GetOwnerModuleFromTcpEntry( PMIB_TCPROW_OWNER_MODULE pTcpEntry, TCPIP_OWNER_MODULE_INFO_CLASS Class, PVOID Buffer, PDWORD pdwSize)
+{
+       DWORD ret = NO_ERROR;
+       UNIMPLEMENTED;
+       return ret;     
+}
+
+
 /******************************************************************
  *    GetPerAdapterInfo (IPHLPAPI.@)
  *
@@ -1891,30 +1944,23 @@ DWORD WINAPI GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIP
  */
 DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
 {
-  COMM_DHCP_REPLY Reply;
-  COMM_DHCP_REQ Request;
-  DWORD BytesRead;
+  DWORD Status, Version = 0;
 
-  Request.AdapterIndex = AdapterInfo->Index;
-  Request.Type = DhcpReqReleaseIpAddress;
+  if (!AdapterInfo || !AdapterInfo->Name)
+      return ERROR_INVALID_PARAMETER;
 
-  TRACE("AdapterInfo %p\n", AdapterInfo);
+  /* Maybe we should do this in DllMain */
+  if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS)
+      return ERROR_PROC_NOT_FOUND;
 
-  if (CallNamedPipe(DHCP_PIPE_NAME,
-                    &Request,
-                    sizeof(Request),
-                    &Reply,
-                    sizeof(Reply),
-                    &BytesRead,
-                    NMPWAIT_USE_DEFAULT_WAIT))
-  {
-      if (Reply.Reply)
-          return NO_ERROR;
+  if (DhcpReleaseIpAddressLease(AdapterInfo->Index))
+      Status = ERROR_SUCCESS;
+  else
+      Status = ERROR_PROC_NOT_FOUND;
 
-      return ERROR_INVALID_PARAMETER;
-  }
+  DhcpCApiCleanup();
 
-  return ERROR_PROC_NOT_FOUND;
+  return Status;
 }
 
 
@@ -1932,30 +1978,23 @@ DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
  */
 DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
 {
-  COMM_DHCP_REPLY Reply;
-  COMM_DHCP_REQ Request;
-  DWORD BytesRead;
+  DWORD Status, Version = 0;
 
-  Request.AdapterIndex = AdapterInfo->Index;
-  Request.Type = DhcpReqRenewIpAddress;
+  if (!AdapterInfo || !AdapterInfo->Name)
+      return ERROR_INVALID_PARAMETER;
 
-  TRACE("AdapterInfo %p\n", AdapterInfo);
+  /* Maybe we should do this in DllMain */
+  if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS)
+      return ERROR_PROC_NOT_FOUND;
 
-  if (CallNamedPipe(DHCP_PIPE_NAME,
-                    &Request,
-                    sizeof(Request),
-                    &Reply,
-                    sizeof(Reply),
-                    &BytesRead,
-                    NMPWAIT_USE_DEFAULT_WAIT))
-  {
-      if (Reply.Reply)
-          return NO_ERROR;
+  if (DhcpRenewIpAddressLease(AdapterInfo->Index))
+      Status = ERROR_SUCCESS;
+  else
+      Status = ERROR_PROC_NOT_FOUND;
 
-      return ERROR_INVALID_PARAMETER;
-  }
+  DhcpCApiCleanup();
 
-  return ERROR_PROC_NOT_FOUND;
+  return Status;
 }
 
 
@@ -2248,10 +2287,198 @@ PIP_ADAPTER_ORDER_MAP WINAPI GetAdapterOrderMap(VOID)
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen)
 {
+#if 0
+    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 (Reserved) return ERROR_INVALID_PARAMETER;
+
+    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;
+#else
     if (!pOutBufLen) return ERROR_INVALID_PARAMETER;
     if (!pAdapterAddresses || *pOutBufLen == 0)
       return ERROR_BUFFER_OVERFLOW;
@@ -2259,6 +2486,7 @@ DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_AD
 
     FIXME(":stub\n");
     return ERROR_NO_DATA;
+#endif
 }
 
 /*