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