diff --git a/reactos/dll/win32/iphlpapi/CMakeLists.txt b/reactos/dll/win32/iphlpapi/CMakeLists.txt index 79d7525aa4c..11cc68354c6 100644 --- a/reactos/dll/win32/iphlpapi/CMakeLists.txt +++ b/reactos/dll/win32/iphlpapi/CMakeLists.txt @@ -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 diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_main.c b/reactos/dll/win32/iphlpapi/iphlpapi_main.c index 10ce459d50b..babb4582bb5 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_main.c +++ b/reactos/dll/win32/iphlpapi/iphlpapi_main.c @@ -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); } diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 42fef454ee1..2b37e300062 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -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 /* 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 index 00000000000..91aeaada63a --- /dev/null +++ b/reactos/dll/win32/iphlpapi/iphlpapi_reactos.c @@ -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 + */ + +#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; +}