summaryrefslogtreecommitdiff
path: root/wireless.c
diff options
context:
space:
mode:
Diffstat (limited to 'wireless.c')
-rw-r--r--wireless.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/wireless.c b/wireless.c
new file mode 100644
index 0000000..0132824
--- /dev/null
+++ b/wireless.c
@@ -0,0 +1,338 @@
1/*
2 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
3 *
4 * Module Name:
5 *
6 * wireless.c
7 *
8 * Abstract:
9 *
10 * This module deals with wireless cards.
11 *
12 * Author:
13 *
14 * Eugene Tsyrklevich 12-Oct-2004
15 */
16
17
18#include <NTDDK.h>
19
20#undef DEFINE_GUID
21#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name \
22 = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
23
24#include <ntddstor.h>
25#include <wdmguid.h>
26#include "wireless.h"
27#include "pathproc.h"
28#include "policy.h"
29
30
31#ifdef ALLOC_PRAGMA
32#pragma alloc_text (INIT, InitWirelessHooks)
33#pragma alloc_text (PAGE, RemoveWirelessHooks)
34#endif
35
36
37PVOID WirelessNotificationEntry = NULL;
38
39/* removable wireless flags defined in drive.h (READONLY, etc) */
40UCHAR WirelessRemovableFlags = 0;
41
42
43typedef struct _WORK_CONTEXT
44{
45 PIO_WORKITEM Item;
46 UNICODE_STRING SymbolicLinkName;
47
48} WORK_CONTEXT, *PWORK_CONTEXT;
49
50
51
52/*
53 * AddDrive()
54 *
55 * Description:
56 * .
57 *
58 * Parameters:
59 * pusDriveName - .
60 * DriveLetter - .
61 *
62 * Returns:
63 * Nothing.
64 */
65
66VOID
67AddDrive(PUNICODE_STRING pusDriveName, CHAR DriveLetter)
68{
69 PDEVICE_OBJECT pDeviceObject;
70 STORAGE_HOTPLUG_INFO HotplugInfo;
71
72
73 pDeviceObject = GetDriveHotplugInformation(pusDriveName, &HotplugInfo);
74 if (pDeviceObject == NULL)
75 return;
76
77
78 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: %c:\\ drive: %d %d %d %d %d\n", DriveLetter, HotplugInfo.Size, HotplugInfo.WirelessRemovable, HotplugInfo.WirelessHotplug, HotplugInfo.DeviceHotplug, HotplugInfo.WriteCacheEnableOverride));
79
80
81 //XXX remove
82 if (HotplugInfo.WirelessRemovable == FALSE && HotplugInfo.WirelessHotplug == TRUE)
83 {
84 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: hotpluggable but not removable drive! %c: %S\n", DriveLetter, pusDriveName->Buffer));
85 }
86
87 if (HotplugInfo.WirelessRemovable)
88 {
89 CHAR rule[MAX_PATH];
90
91
92 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: removable drive! %c: %S\n", DriveLetter, pusDriveName->Buffer));
93
94
95 /* Create a new global policy rule */
96
97 if (IS_REMOVABLE_WIRELESS_DISABLED())
98 {
99 sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny");
100
101 PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "all", rule);
102
103 /* no need to process other rules, this one denies everything already */
104 return;
105 }
106
107 if (IS_REMOVABLE_WIRELESS_READONLY())
108 {
109 sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny");
110
111 PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "write", rule);
112 }
113
114 if (IS_REMOVABLE_WIRELESS_NOEXECUTE())
115 {
116 sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny");
117
118 PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "execute", rule);
119 }
120 }
121
122
123 return;
124}
125
126
127
128/*
129 * RemoveDrive()
130 *
131 * Description:
132 * .
133 *
134 * Parameters:
135 * pusDriveName - .
136 *
137 * Returns:
138 * Nothing.
139 */
140
141VOID
142RemoveDrive(PUNICODE_STRING pusDriveName)
143{
144 PDEVICE_OBJECT pDeviceObject;
145 STORAGE_HOTPLUG_INFO HotplugInfo;
146 NTSTATUS rc;
147
148
149 pDeviceObject = GetDriveHotplugInformation(pusDriveName, &HotplugInfo);
150 if (pDeviceObject == NULL)
151 return;
152
153// KdPrint(("success %d %d %d %d %d\n", info.Size, info.WirelessRemovable, info.WirelessHotplug, info.DeviceHotplug, info.WriteCacheEnableOverride));
154
155 if (HotplugInfo.WirelessRemovable)
156 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveDrive: removable drive! %S\n", pusDriveName->Buffer));
157
158
159 rc = RtlVolumeDeviceToDosName(pDeviceObject, pusDriveName);
160 if (NT_SUCCESS(rc))
161 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveDrive: IoVolumeDeviceToDosName returned %S\n", pusDriveName->Buffer));
162
163 return;
164}
165
166
167
168/*
169 * PnpWorker()
170 *
171 * Description:
172 * A work item routine that runs at PASSIVE_LEVEL irql. The routine is scheduled by PnpCallback
173 * which is not allowed to block.
174 *
175 * PnpWorker calls RemoveDrive() with a drive name setup by PnpCallback.
176 *
177 * Parameters:
178 * pDeviceObject - .
179 * Context - .
180 *
181 * Returns:
182 * Nothing.
183 */
184
185VOID
186PnpWorker(IN PDEVICE_OBJECT pDeviceObject, IN PVOID Context)
187{
188 PWORK_CONTEXT WorkContext = (PWORK_CONTEXT) Context;
189
190
191 if (WorkContext == NULL)
192 {
193 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("PnpWorker: WorkContext = NULL\n"));
194 return;
195 }
196
197 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("PnpWorker: %S\n", WorkContext->SymbolicLinkName.Buffer));
198
199
200 RemoveDrive(&WorkContext->SymbolicLinkName);
201
202
203 IoFreeWorkItem(WorkContext->Item);
204
205 ExFreePoolWithTag(WorkContext, _POOL_TAG);
206}
207
208
209
210/*
211 * PnpCallback()
212 *
213 * Description:
214 * Plug-and-Play callback. Gets called when a p-n-p drive/cdrom interface is modified
215 * (i.e. when a removable drive is added or removed from the system).
216 *
217 * Parameters:
218 * NotificationStructure - DEVICE_INTERFACE_CHANGE_NOTIFICATION indicating which interface changed.
219 * Context - the driver's device context.
220 *
221 * Returns:
222 * STATUS_SUCCESS.
223 */
224
225NTSTATUS
226PnpCallback(IN PVOID NotificationStructure, IN PVOID Context)
227{
228 PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notify = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION) NotificationStructure;
229 PDEVICE_OBJECT pDeviceObject = (PDEVICE_OBJECT) Context;
230 PIO_WORKITEM WorkItem;
231 PWORK_CONTEXT WorkContext;
232
233
234 if (IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_REMOVAL))
235 {
236 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("GUID_DEVICE_INTERFACE_REMOVAL %S\n", Notify->SymbolicLinkName->Buffer));
237/*
238 }
239
240
241 if (IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_ARRIVAL) ||
242 IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_REMOVAL))
243 {
244 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("GUID_DEVICE_INTERFACE_ARRIVAL %x %S\n", Notify->SymbolicLinkName, Notify->SymbolicLinkName->Buffer));
245*/
246
247 /*
248 * Schedule a work item to process this request. Cannot block in this callback function.
249 */
250
251 WorkItem = IoAllocateWorkItem(pDeviceObject);
252
253 WorkContext = (PWORK_CONTEXT) ExAllocatePoolWithTag(PagedPool,
254 sizeof(WORK_CONTEXT) + Notify->SymbolicLinkName->Length,
255 _POOL_TAG);
256 if (!WorkContext)
257 {
258 IoFreeWorkItem(WorkItem);
259 return(STATUS_SUCCESS);
260 }
261
262 WorkContext->SymbolicLinkName.Buffer = (PWSTR) ((PCHAR) &WorkContext->SymbolicLinkName + sizeof(UNICODE_STRING));
263 WorkContext->SymbolicLinkName.MaximumLength = Notify->SymbolicLinkName->Length;
264 WorkContext->SymbolicLinkName.Length = 0;
265
266 WorkContext->Item = WorkItem;
267 RtlCopyUnicodeString(&WorkContext->SymbolicLinkName, Notify->SymbolicLinkName);
268
269 IoQueueWorkItem(WorkItem, PnpWorker, DelayedWorkQueue, WorkContext);
270 }
271
272
273 return STATUS_SUCCESS;
274}
275
276
277
278/*
279 * InitWirelessHooks()
280 *
281 * Description:
282 * Process any existing wireless cards and register Plug-and-Play notifications for future drive additions/removals.
283 *
284 * NOTE: Called once during driver initialization (DriverEntry()).
285 *
286 * Parameters:
287 * None.
288 *
289 * Returns:
290 * TRUE to indicate success, FALSE if failed.
291 */
292
293BOOLEAN
294InitWirelessHooks(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT pDeviceObject)
295{
296 NTSTATUS rc;
297
298
299 rc = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
300 /*0,*/PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
301 (LPGUID) &GUID_DEVINTERFACE_DISK,
302 pDriverObject,
303 PnpCallback,
304 pDeviceObject,
305 &WirelessNotificationEntry);
306
307 if (! NT_SUCCESS(rc))
308 {
309 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("InitWirelessHooks: IoRegisterPlugPlayNotification failed with status %x\n", rc));
310 return FALSE;
311 }
312
313
314 return TRUE;
315}
316
317
318
319/*
320 * RemoveWirelessHooks()
321 *
322 * Description:
323 * Unregister Plug-and-Play notifications.
324 *
325 * Parameters:
326 * None.
327 *
328 * Returns:
329 * Nothing.
330 */
331
332VOID
333RemoveWirelessHooks()
334{
335 if (WirelessNotificationEntry)
336 if (! NT_SUCCESS(IoUnregisterPlugPlayNotification(WirelessNotificationEntry)))
337 LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveWirelessHooks: IoUnregisterPlugPlayNotification failed\n"));
338}