1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         User mode part of the TcpIp.sys test suite
5  * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
6  */
7 
8 #include <apitest.h>
9 
10 #include <ipexport.h>
11 #include <winioctl.h>
12 #include <tcpioctl.h>
13 #include <tcpip_undoc.h>
14 
START_TEST(InterfaceInfo)15 START_TEST(InterfaceInfo)
16 {
17     IP_INTERFACE_INFO* pInterfaceInfo;
18     IP_INTERFACE_INFO InterfaceInfo;
19     HANDLE FileHandle;
20     DWORD BufferSize;
21     BOOL Result;
22     DWORD Error;
23     ULONG i;
24 
25     /* Open a control channel file for TCP */
26     FileHandle = CreateFileW(
27         L"\\\\.\\Tcp",
28         FILE_READ_DATA | FILE_WRITE_DATA,
29         FILE_SHARE_READ | FILE_SHARE_WRITE,
30         NULL,
31         OPEN_EXISTING,
32         FILE_FLAG_OVERLAPPED,
33         NULL);
34     ok(FileHandle != INVALID_HANDLE_VALUE, "CreateFile failed, GLE %lu\n", GetLastError());
35 
36     /* Try the IOCTL */
37     BufferSize = 0;
38     pInterfaceInfo = &InterfaceInfo;
39     Result = DeviceIoControl(
40         FileHandle,
41         IOCTL_IP_INTERFACE_INFO,
42         NULL,
43         0,
44         pInterfaceInfo,
45         sizeof(InterfaceInfo),
46         &BufferSize,
47         NULL);
48     Error = GetLastError();
49     ok(!Result, "DeviceIoControl succeeded.\n");
50     ok_long(Error, ERROR_INVALID_FUNCTION);
51     ok_long(BufferSize, 0);
52 
53     CloseHandle(FileHandle);
54 
55     /* This IOCTL only works with \Device\Ip */
56     FileHandle = CreateFileW(
57         L"\\\\.\\Ip",
58         FILE_READ_DATA | FILE_WRITE_DATA,
59         FILE_SHARE_READ | FILE_SHARE_WRITE,
60         NULL,
61         OPEN_EXISTING,
62         FILE_FLAG_OVERLAPPED,
63         NULL);
64     ok(FileHandle != INVALID_HANDLE_VALUE, "CreateFile failed, GLE %lu\n", GetLastError());
65 
66     /* Get the buffer size. */
67     BufferSize = 0;
68     pInterfaceInfo = &InterfaceInfo;
69     Result = DeviceIoControl(
70         FileHandle,
71         IOCTL_IP_INTERFACE_INFO,
72         NULL,
73         0,
74         pInterfaceInfo,
75         sizeof(InterfaceInfo),
76         &BufferSize,
77         NULL);
78     ok(Result, "DeviceIoControl failed, GLE %lu.\n", GetLastError());
79     ok(BufferSize != 0, "Buffer size is zero.\n");
80     trace("Buffer size is %lu.\n", BufferSize);
81 
82     if (BufferSize > sizeof(InterfaceInfo))
83     {
84         pInterfaceInfo = HeapAlloc(GetProcessHeap(), 0, BufferSize);
85         ok(pInterfaceInfo != NULL, "HeapAlloc failed.\n");
86 
87         /* Send IOCTL to fill the buffer in. */
88         Result = DeviceIoControl(
89                 FileHandle,
90                 IOCTL_IP_INTERFACE_INFO,
91                 NULL,
92                 0,
93                 pInterfaceInfo,
94                 BufferSize,
95                 &BufferSize,
96                 NULL);
97         ok(Result, "DeviceIoControl failed, GLE %lu.\n", GetLastError());
98     }
99 
100     if (Result && BufferSize >= RTL_SIZEOF_THROUGH_FIELD(IP_INTERFACE_INFO, NumAdapters))
101     {
102         /* Nothing much to test. Just print out the adapters we got */
103         trace("We got %ld adapters.\n", pInterfaceInfo->NumAdapters);
104         for (i = 0; i < pInterfaceInfo->NumAdapters; i++)
105         {
106             trace("\tIndex %lu, name %S\n", pInterfaceInfo->Adapter[i].Index, pInterfaceInfo->Adapter[i].Name);
107         }
108     }
109 
110     if (pInterfaceInfo != &InterfaceInfo)
111         HeapFree(GetProcessHeap(), 0, pInterfaceInfo);
112     CloseHandle(FileHandle);
113 }
114