1 /*
2  * PROJECT:     ReactOS Networking
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/iphlpapi/iphlpapi_reactos.c
5  * PURPOSE:     DHCP helper functions for ReactOS
6  * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 #include "iphlpapi_private.h"
10 
11 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
12 
13 DWORD TCPSendIoctl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, PULONG pInBufferSize, LPVOID lpOutBuffer, PULONG pOutBufferSize)
14 {
15     BOOL Hack = FALSE;
16     HANDLE Event;
17     IO_STATUS_BLOCK IoStatusBlock;
18     NTSTATUS Status;
19 
20     /* FIXME: We don't have a global handle opened to \Device\Ip, so open one each time
21      * we need. In a future, it would be cool, just to pass it to TCPSendIoctl using the first arg
22      */
23     if (hDevice == INVALID_HANDLE_VALUE)
24     {
25         UNICODE_STRING DevName = RTL_CONSTANT_STRING(L"\\Device\\Ip");
26         OBJECT_ATTRIBUTES ObjectAttributes;
27 
28         FIXME("Using the handle hack\n");
29         Hack = TRUE;
30 
31         InitializeObjectAttributes(&ObjectAttributes,
32                                    &DevName,
33                                    OBJ_CASE_INSENSITIVE,
34                                    NULL,
35                                    NULL);
36 
37         Status = NtCreateFile(&hDevice, GENERIC_EXECUTE, &ObjectAttributes,
38                               &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF,
39                               0, NULL, 0);
40         if (!NT_SUCCESS(Status))
41         {
42           return RtlNtStatusToDosError(Status);
43         }
44     }
45 
46     /* Sync event */
47     Event = CreateEventW(NULL, TRUE, FALSE, NULL);
48     if (Event == NULL)
49     {
50         /* FIXME: See upper */
51         if (Hack)
52         {
53             CloseHandle(hDevice);
54         }
55         return GetLastError();
56     }
57 
58     /* Reinit, and call the networking stack */
59     IoStatusBlock.Status = STATUS_SUCCESS;
60     IoStatusBlock.Information = 0;
61     Status = NtDeviceIoControlFile(hDevice, Event, NULL, NULL, &IoStatusBlock, dwIoControlCode, lpInBuffer, *pInBufferSize, lpOutBuffer, *pOutBufferSize);
62     if (Status == STATUS_PENDING)
63     {
64         NtWaitForSingleObject(Event, FALSE, NULL);
65         Status = IoStatusBlock.Status;
66     }
67 
68     /* Close & return size info */
69     CloseHandle(Event);
70     *pOutBufferSize = IoStatusBlock.Information;
71 
72     /* FIXME: See upper */
73     if (Hack)
74     {
75         CloseHandle(hDevice);
76     }
77 
78     /* Return result */
79     if (!NT_SUCCESS(Status))
80     {
81         return RtlNtStatusToDosError(Status);
82     }
83 
84     return ERROR_SUCCESS;
85 }
86