[IPHLPAPI]
authorPierre Schweitzer <pierre@reactos.org>
Sun, 22 Nov 2015 14:47:42 +0000 (14:47 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 22 Nov 2015 14:47:42 +0000 (14:47 +0000)
- Implement TCPSendIoctl() to issue IOCTLs to network stack. We should use global handles to \Device\Ip & such, but as iphlpapi doesn't have such feature yet, a hack is here to workaround.
- Implement SendARP() using the TCPSendIoctl() function. So far, it doesn't work, as tcpip.sys is missing appropriate code path.

svn path=/trunk/; revision=70025

reactos/dll/win32/iphlpapi/CMakeLists.txt
reactos/dll/win32/iphlpapi/iphlpapi_main.c
reactos/dll/win32/iphlpapi/iphlpapi_private.h
reactos/dll/win32/iphlpapi/iphlpapi_reactos.c [new file with mode: 0644]

index 79d7525..11cc683 100644 (file)
@@ -12,6 +12,7 @@ list(APPEND SOURCE
     dhcp_reactos.c
     ifenum_reactos.c
     ipstats_reactos.c
+    iphlpapi_reactos.c
     iphlpapi_main.c
     media.c
     registry.c
index 10ce459..babb458 100644 (file)
@@ -2047,7 +2047,6 @@ DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
   return ERROR_NOT_SUPPORTED;
 }
 
-
 /******************************************************************
  *    SendARP (IPHLPAPI.@)
  *
@@ -2062,15 +2061,19 @@ DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
  * RETURNS
  *  Success: NO_ERROR
  *  Failure: error code from winerror.h
- *
- * FIXME
- *  Stub, returns ERROR_NOT_SUPPORTED.
  */
 DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
 {
-  FIXME("(DestIP 0x%08x, SrcIP 0x%08x, pMacAddr %p, PhyAddrLen %p): stub\n",
-   DestIP, SrcIP, pMacAddr, PhyAddrLen);
-  return ERROR_NOT_SUPPORTED;
+  IPAddr IPs[2];
+  ULONG Size;
+
+  if (IsBadWritePtr(pMacAddr, sizeof(ULONG)) || IsBadWritePtr(PhyAddrLen, sizeof(ULONG)))
+    return ERROR_INVALID_PARAMETER;
+
+  IPs[0] = DestIP;
+  IPs[1] = SrcIP;
+  Size = sizeof(IPs);
+  return TCPSendIoctl(INVALID_HANDLE_VALUE, IOCTL_QUERY_IP_HW_ADDRESS, IPs, &Size, pMacAddr, PhyAddrLen);
 }
 
 
index 42fef45..2b37e30 100644 (file)
@@ -164,6 +164,7 @@ NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile,
                              char *name,
                              DWORD index,
                              IFInfo *ifInfo);
+DWORD TCPSendIoctl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, PULONG pInBufferSize, LPVOID lpOutBuffer, PULONG pOutBufferSize);
 
 #include <w32api.h>
 /* This is here until we switch to version 2.5 of the mingw headers */
diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_reactos.c b/reactos/dll/win32/iphlpapi/iphlpapi_reactos.c
new file mode 100644 (file)
index 0000000..91aeaad
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * PROJECT:     ReactOS Networking
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        dll/win32/iphlpapi/iphlpapi_reactos.c
+ * PURPOSE:     DHCP helper functions for ReactOS
+ * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include "iphlpapi_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
+
+DWORD TCPSendIoctl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, PULONG pInBufferSize, LPVOID lpOutBuffer, PULONG pOutBufferSize)
+{
+    BOOL Hack = FALSE;
+    HANDLE Event;
+    IO_STATUS_BLOCK IoStatusBlock;
+    NTSTATUS Status;
+
+    /* FIXME: We don't have a global handle opened to \Device\Ip, so open one each time
+     * we need. In a future, it would be cool, just to pass it to TCPSendIoctl using the first arg
+     */
+    if (hDevice == INVALID_HANDLE_VALUE)
+    {
+        UNICODE_STRING DevName = RTL_CONSTANT_STRING(L"\\Device\\Ip");
+        OBJECT_ATTRIBUTES ObjectAttributes;
+
+        FIXME("Using the handle hack\n");
+        Hack = TRUE;
+
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &DevName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+
+        Status = NtCreateFile(&hDevice, GENERIC_EXECUTE, &ObjectAttributes,
+                              &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF,
+                              0, NULL, 0);
+        if (!NT_SUCCESS(Status))
+        {
+          return RtlNtStatusToDosError(Status);
+        }
+    }
+
+    /* Sync event */
+    Event = CreateEventW(NULL, TRUE, FALSE, NULL);
+    if (Event == NULL)
+    {
+        /* FIXME: See upper */
+        if (Hack)
+        {
+            CloseHandle(hDevice);
+        }
+        return GetLastError();
+    }
+
+    /* Reinit, and call the networking stack */
+    IoStatusBlock.Status = STATUS_SUCCESS;
+    IoStatusBlock.Information = 0;
+    Status = NtDeviceIoControlFile(hDevice, Event, NULL, NULL, &IoStatusBlock, dwIoControlCode, lpInBuffer, *pInBufferSize, lpOutBuffer, *pOutBufferSize);
+    if (Status == STATUS_PENDING)
+    {
+        NtWaitForSingleObject(Event, FALSE, NULL);
+        Status = IoStatusBlock.Status;
+    }
+
+    /* Close & return size info */
+    CloseHandle(Event);
+    *pOutBufferSize = IoStatusBlock.Information;
+
+    /* FIXME: See upper */
+    if (Hack)
+    {
+        CloseHandle(hDevice);
+    }
+
+    /* Return result */
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    return ERROR_SUCCESS;
+}