1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// OEM sample: enumerates supported device services, then sends "Hello, My Driver"
// to the WiFiCx sample driver via WlanDeviceServiceCommand and prints the
// driver's "Nice to meet you, My OEM".
#define NOMINMAX // use std::min/std::max instead of the windows.h min/max macros
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h> // StringFromGUID2
#include <algorithm> // std::min
#include <cstdio>
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib") // StringFromGUID2
// WlanGetSupportedDeviceServices, WlanDeviceServiceCommand and
// WLAN_DEVICE_SERVICE_GUID_LIST are all declared by wlanapi.h.
// This GUID/opcode pair MUST match the driver (drivercode\SharedTypes.h).
// {2d6f9a14-3a1d-4f0a-9b7e-1c2e3a4b5c6d}
static const GUID GUID_OEM_SAMPLE_DEVICE_SERVICE =
{ 0x2d6f9a14, 0x3a1d, 0x4f0a, { 0x9b, 0x7e, 0x1c, 0x2e, 0x3a, 0x4b, 0x5c, 0x6d } };
#define OEM_DEVICE_SERVICE_OPCODE_HELLO 0x00000001
#define OEM_DEVICE_SERVICE_REQUEST_STRING "Hello, My Driver"
static void PrintGuid(const GUID& g)
{
wchar_t buf[64] = { 0 };
StringFromGUID2(g, buf, ARRAYSIZE(buf));
wprintf(L"%s", buf);
}
// Enumerate the device services the driver advertises (via WDI_GET_SUPPORTED_DEVICE_SERVICES).
static bool QuerySupportedServices(HANDLE hClient, const GUID& interfaceGuid)
{
PWLAN_DEVICE_SERVICE_GUID_LIST pList = nullptr;
DWORD result = WlanGetSupportedDeviceServices(hClient, &interfaceGuid, &pList);
if (result != ERROR_SUCCESS || pList == nullptr)
{
printf("WlanGetSupportedDeviceServices failed with error %u\n", result);
return false;
}
bool found = false;
printf("Supported device services: %u\n", pList->dwNumberOfItems);
for (DWORD i = 0; i < pList->dwNumberOfItems; i++)
{
printf(" [%u] ", i);
PrintGuid(pList->DeviceService[i]);
if (IsEqualGUID(pList->DeviceService[i], GUID_OEM_SAMPLE_DEVICE_SERVICE))
{
found = true;
printf(" <-- OEM sample service");
}
printf("\n");
}
WlanFreeMemory(pList);
return found;
}
static void SendHelloToInterface(HANDLE hClient, const GUID& interfaceGuid)
{
char inBuffer[] = OEM_DEVICE_SERVICE_REQUEST_STRING; // includes null terminator
DWORD inBufferSize = static_cast<DWORD>(sizeof(inBuffer));
BYTE outBuffer[256] = { 0 };
DWORD outBufferSize = static_cast<DWORD>(sizeof(outBuffer));
DWORD bytesReturned = 0;
printf("Sending device service command: \"%s\"\n", inBuffer);
DWORD result = WlanDeviceServiceCommand(
hClient,
&interfaceGuid,
const_cast<LPGUID>(&GUID_OEM_SAMPLE_DEVICE_SERVICE),
OEM_DEVICE_SERVICE_OPCODE_HELLO,
inBufferSize,
inBuffer,
outBufferSize,
outBuffer,
&bytesReturned);
if (result != ERROR_SUCCESS)
{
printf("WlanDeviceServiceCommand failed with error %u\n", result);
return;
}
if (bytesReturned > 0)
{
outBuffer[std::min(bytesReturned, static_cast<DWORD>(sizeof(outBuffer) - 1))] = '\0';
printf("Driver responded: \"%s\" (%u bytes)\n", reinterpret_cast<char*>(outBuffer), bytesReturned);
}
else
{
printf("Driver returned no data.\n");
}
}
int __cdecl main()
{
HANDLE hClient = nullptr;
DWORD negotiatedVersion = 0;
PWLAN_INTERFACE_INFO_LIST pIfList = nullptr;
// 1) WlanOpenHandle
DWORD result = WlanOpenHandle(WLAN_API_VERSION_2_0, nullptr, &negotiatedVersion, &hClient);
if (result != ERROR_SUCCESS)
{
printf("WlanOpenHandle failed with error %u\n", result);
return 1;
}
// 2) WlanEnumInterfaces
result = WlanEnumInterfaces(hClient, nullptr, &pIfList);
if (result != ERROR_SUCCESS)
{
printf("WlanEnumInterfaces failed with error %u\n", result);
WlanCloseHandle(hClient, nullptr);
return 1;
}
printf("Found %u WLAN interface(s).\n", pIfList->dwNumberOfItems);
for (DWORD i = 0; i < pIfList->dwNumberOfItems; i++)
{
const WLAN_INTERFACE_INFO& ifInfo = pIfList->InterfaceInfo[i];
printf("\nInterface[%u]: %ws\n", i, ifInfo.strInterfaceDescription);
// Enumerate supported device services first.
bool supported = QuerySupportedServices(hClient, ifInfo.InterfaceGuid);
// 3) WlanDeviceServiceCommand (only if our service is advertised)
if (supported)
{
SendHelloToInterface(hClient, ifInfo.InterfaceGuid);
}
else
{
printf("OEM sample device service not advertised on this interface; skipping command.\n");
}
}
// 4) WlanFreeMemory(pIfList);
if (pIfList != nullptr)
{
WlanFreeMemory(pIfList);
pIfList = nullptr;
}
// 5) WlanCloseHandle(hClient, nullptr);
WlanCloseHandle(hClient, nullptr);
return 0;
}
|