win-pvdrivers

view xenhide/xenhide.c @ 185:e13475347e4a

Merge with head
author James Harper <james.harper@bendigoit.com.au>
date Wed Feb 13 23:27:00 2008 +1100 (2008-02-13)
parents 524ffdb246b6 f4c428c040ea
children 145b318c367c
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenhide.h"
21 #include <stdlib.h>
23 DRIVER_INITIALIZE DriverEntry;
24 static NTSTATUS
25 XenHide_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject);
26 static NTSTATUS
27 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp);
28 static NTSTATUS
29 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
30 static NTSTATUS
31 XenHide_AddDevice();
32 //static NTSTATUS
33 //XenHide_Unload();
35 #ifdef ALLOC_PRAGMA
36 #pragma alloc_text (INIT, DriverEntry)
37 #pragma alloc_text (PAGE, XenHide_AddDevice)
38 #endif
40 static BOOLEAN AutoEnumerate;
42 NTSTATUS
43 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
44 {
45 NTSTATUS status;
46 UNICODE_STRING RegKeyName;
47 UNICODE_STRING RegValueName;
48 HANDLE RegHandle;
49 OBJECT_ATTRIBUTES RegObjectAttributes;
50 char Buf[200];
51 ULONG BufLen = 200;
52 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
53 int State = 0;
54 int StartPos = 0;
55 WCHAR *SystemStartOptions;
56 size_t SystemStartOptionsLen;
57 size_t i;
59 UNREFERENCED_PARAMETER(RegistryPath);
61 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
62 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
64 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
65 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
66 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
67 if(!NT_SUCCESS(status))
68 {
69 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
70 }
72 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
73 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
74 if(!NT_SUCCESS(status))
75 {
76 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
77 }
78 else
79 ZwClose(RegHandle);
80 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
81 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
83 AutoEnumerate = FALSE;
85 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
87 for (i = 0; i <= SystemStartOptionsLen/2; i++)
88 {
89 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
91 switch (State)
92 {
93 case 0:
94 if (SystemStartOptions[i] == L'G')
95 {
96 StartPos = i;
97 State = 2;
98 } else if (SystemStartOptions[i] != L' ')
99 {
100 State = 1;
101 }
102 break;
103 case 1:
104 if (SystemStartOptions[i] == L' ')
105 State = 0;
106 break;
107 case 2:
108 if (SystemStartOptions[i] == L'P')
109 State = 3;
110 else
111 State = 0;
112 break;
113 case 3:
114 if (SystemStartOptions[i] == L'L')
115 State = 4;
116 else
117 State = 0;
118 break;
119 case 4:
120 if (SystemStartOptions[i] == L'P')
121 State = 5;
122 else
123 State = 0;
124 break;
125 case 5:
126 if (SystemStartOptions[i] == L'V')
127 State = 6;
128 else
129 State = 0;
130 break;
131 case 6:
132 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
133 AutoEnumerate = TRUE;
134 State = 0;
135 break;
136 }
137 }
139 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
141 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
142 DriverObject->MajorFunction[i] = XenHide_Pass;
143 if (AutoEnumerate)
144 DriverObject->MajorFunction[IRP_MJ_PNP] = XenHide_Pnp;
145 DriverObject->DriverExtension->AddDevice = XenHide_AddDevice;
147 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
149 return status;
150 }
152 static NTSTATUS
153 XenHide_AddDevice(
154 PDRIVER_OBJECT DriverObject,
155 PDEVICE_OBJECT PhysicalDeviceObject
156 )
157 {
158 NTSTATUS status;
159 PDEVICE_OBJECT DeviceObject = NULL;
160 PDEVICE_EXTENSION DeviceExtension;
161 ULONG Length;
162 WCHAR Buffer[1000];
164 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
166 Length = 1000;
167 status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDeviceDescription, Length, Buffer, &Length);
168 KdPrint((__DRIVER_NAME " status = %08x, DevicePropertyDeviceDescription = %ws\n", status, Buffer));
170 if (!NT_SUCCESS(status) || wcscmp(Buffer, L"PCI bus") != 0)
171 {
172 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
173 return STATUS_SUCCESS;
174 }
175 KdPrint((__DRIVER_NAME " Found\n"));
177 status = IoCreateDevice(DriverObject,
178 sizeof(DEVICE_EXTENSION),
179 NULL,
180 FILE_DEVICE_UNKNOWN,
181 FILE_DEVICE_SECURE_OPEN,
182 FALSE,
183 &DeviceObject);
184 if (!NT_SUCCESS(status))
185 {
186 KdPrint((__DRIVER_NAME " IoCreateDevice failed 0x%08x\n", status));
187 return status;
188 }
190 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
192 DeviceExtension->Self = DeviceObject;
193 DeviceExtension->DriverObject = DriverObject;
194 DeviceExtension->Type = XENHIDE_TYPE_PCI;
195 DeviceExtension->CallCount = 0;
197 DeviceExtension->NextLowerDevice = IoAttachDeviceToDeviceStack(
198 DeviceObject,
199 PhysicalDeviceObject);
201 DeviceObject->Flags |= DeviceExtension->NextLowerDevice->Flags;
203 DeviceObject->DeviceType = DeviceExtension->NextLowerDevice->DeviceType;
205 DeviceObject->Characteristics =
206 DeviceExtension->NextLowerDevice->Characteristics;
208 //INITIALIZE_PNP_STATE(DeviceExtension);
210 if (AutoEnumerate)
211 {
212 status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID)&GUID_XENHIDE_IFACE, NULL, &DeviceExtension->InterfaceName);
213 if (!NT_SUCCESS(status))
214 {
215 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface failed 0x%08x\n", status));
216 return status;
217 }
218 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface complete, SymbolicLinkName = %wZ\n", &DeviceExtension->InterfaceName));
219 status = IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
220 if (!NT_SUCCESS(status))
221 {
222 KdPrint((__DRIVER_NAME " IoSetDeviceInterfaceState failed 0x%08x\n", status));
223 return status;
224 }
225 }
226 else
227 {
228 KdPrint((__DRIVER_NAME " Not registering Interface\n"));
229 }
231 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
233 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
235 return STATUS_SUCCESS;
236 }
238 static int
239 XenHide_StringMatches(PWCHAR String1, PWCHAR String2)
240 {
241 for(;*String1 != 0 && *String2 != 0 && *String1 == *String2; String1++, String2++);
242 return ((*String1 == 0 && *String2 == 0) || (*String1 == 0 && *String2 == L'\n') || (*String1 == L'\n' && *String2 == 0));
243 }
245 static NTSTATUS
246 XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
247 {
248 ULONG i, j;
249 PDEVICE_RELATIONS Relations;
250 WCHAR Buffer[1000];
251 PWCHAR Ptr;
252 ULONG Length;
253 size_t StrLen;
254 int Match;
255 NTSTATUS status;
256 PDEVICE_OBJECT deviceObject = NULL;
257 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)Context;
258 PDEVICE_EXTENSION NewDeviceExtension;
260 UNREFERENCED_PARAMETER(DeviceObject);
261 UNREFERENCED_PARAMETER(Context);
263 KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
264 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
265 KdPrint((__DRIVER_NAME " CallCount = %d\n", DeviceExtension->CallCount));
267 if (Irp->PendingReturned)
268 IoMarkIrpPending(Irp);
270 switch (DeviceExtension->CallCount)
271 {
272 case 0:
273 DeviceExtension->CallCount = 1;
274 break;
275 case 1:
276 DeviceExtension->CallCount = 2;
277 /*
278 break;
279 case 2:
280 DeviceExtension->CallCount = 3;
281 */
282 Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
284 for (i = 0; i < Relations->Count; i++)
285 {
286 Match = 0;
287 for (j = 0; j < 2 && !Match; j++)
288 {
289 Length = sizeof(Buffer);
290 if (j == 0)
291 IoGetDeviceProperty(Relations->Objects[i], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
292 else
293 IoGetDeviceProperty(Relations->Objects[i], DevicePropertyHardwareID, Length, Buffer, &Length);
294 StrLen = 0;
295 for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
296 {
297 // Qemu PCI
298 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
299 KdPrint((__DRIVER_NAME " %ws\n", Ptr));
300 Match = 1;
301 break;
302 }
303 // Qemu Network
304 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
305 KdPrint((__DRIVER_NAME " %ws\n", Ptr));
306 Match = 1;
307 break;
308 }
309 RtlStringCchLengthW(Ptr, Length, &StrLen);
310 }
311 }
312 if (Match)
313 {
314 KdPrint((__DRIVER_NAME " Creating and attaching Device\n"));
315 deviceObject = NULL;
316 status = IoCreateDevice(DeviceExtension->DriverObject,
317 sizeof(DEVICE_EXTENSION),
318 NULL,
319 FILE_DEVICE_UNKNOWN,
320 FILE_DEVICE_SECURE_OPEN,
321 FALSE,
322 &deviceObject);
323 if (!NT_SUCCESS(status))
324 {
325 KdPrint((__DRIVER_NAME " IoCreateDevice failed 0x%08x\n", status));
326 continue;
327 }
329 NewDeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
331 NewDeviceExtension->NextLowerDevice = IoAttachDeviceToDeviceStack(
332 deviceObject,
333 Relations->Objects[i]);
334 deviceObject->Flags |= NewDeviceExtension->NextLowerDevice->Flags;
336 deviceObject->DeviceType = NewDeviceExtension->NextLowerDevice->DeviceType;
338 deviceObject->Characteristics =
339 NewDeviceExtension->NextLowerDevice->Characteristics;
341 NewDeviceExtension->Self = deviceObject;
342 NewDeviceExtension->Type = XENHIDE_TYPE_HIDE;
344 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
345 }
346 }
347 break;
348 default:
349 break;
350 }
352 KdPrint((__DRIVER_NAME " <-- IoCompletion\n"));
354 return STATUS_SUCCESS; //Irp->IoStatus.Status;
355 }
357 static NTSTATUS
358 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
359 {
360 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
361 NTSTATUS Status;
363 if (DeviceExtension->Type == XENHIDE_TYPE_HIDE)
364 {
365 Irp->IoStatus.Status = Status = STATUS_UNSUCCESSFUL;
366 Irp->IoStatus.Information = 0;
367 IoCompleteRequest(Irp, IO_NO_INCREMENT);
368 }
369 else
370 {
371 IoSkipCurrentIrpStackLocation(Irp);
372 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
373 }
374 return Status;
375 }
377 static NTSTATUS
378 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
379 {
380 NTSTATUS Status = STATUS_SUCCESS;
381 PIO_STACK_LOCATION Stack;
382 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
384 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
385 KdPrint((__DRIVER_NAME " DeviceObject = %p\n", DeviceObject));
386 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
388 Stack = IoGetCurrentIrpStackLocation(Irp);
390 switch (Stack->MinorFunction)
391 {
392 case IRP_MN_START_DEVICE:
393 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_START_DEVICE\n"));
394 break;
395 case IRP_MN_QUERY_STOP_DEVICE:
396 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_STOP_DEVICE\n"));
397 break;
398 case IRP_MN_STOP_DEVICE:
399 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_STOP_DEVICE\n"));
400 break;
401 case IRP_MN_CANCEL_STOP_DEVICE:
402 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_CANCEL_STOP_DEVICE\n"));
403 break;
404 case IRP_MN_QUERY_REMOVE_DEVICE:
405 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_REMOVE_DEVICE\n"));
406 break;
407 case IRP_MN_REMOVE_DEVICE:
408 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_REMOVE_DEVICEE\n"));
409 break;
410 case IRP_MN_CANCEL_REMOVE_DEVICE:
411 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_CANCEL_REMOVE_DEVICE\n"));
412 break;
413 case IRP_MN_SURPRISE_REMOVAL:
414 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_SURPRISE_REMOVAL\n"));
415 break;
416 case IRP_MN_QUERY_CAPABILITIES:
417 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_CAPABILITIES\n"));
418 break;
419 case IRP_MN_QUERY_PNP_DEVICE_STATE:
420 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE\n"));
421 break;
422 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
423 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"));
424 break;
425 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
426 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
427 break;
428 case IRP_MN_QUERY_DEVICE_RELATIONS:
429 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS\n"));
430 break;
431 case IRP_MN_QUERY_RESOURCES:
432 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_RESOURCES\n"));
433 break;
434 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
435 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"));
436 break;
437 case IRP_MN_QUERY_ID:
438 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_ID\n"));
439 break;
440 case IRP_MN_QUERY_DEVICE_TEXT:
441 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_DEVICE_TEXT\n"));
442 break;
443 case IRP_MN_QUERY_BUS_INFORMATION:
444 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_BUS_INFORMATION\n"));
445 break;
446 case IRP_MN_QUERY_INTERFACE:
447 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_QUERY_INTERFACE\n"));
448 break;
449 case IRP_MN_READ_CONFIG:
450 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_READ_CONFIG\n"));
451 break;
452 case IRP_MN_WRITE_CONFIG:
453 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_WRITE_CONFIG\n"));
454 break;
455 case IRP_MN_EJECT:
456 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_EJECT\n"));
457 break;
458 case IRP_MN_SET_LOCK:
459 KdPrint((__DRIVER_NAME " MinorFunction = IRP_MN_SET_LOCK\n"));
460 break;
461 }
463 switch (DeviceExtension->Type)
464 {
465 case XENHIDE_TYPE_PCI:
466 KdPrint((__DRIVER_NAME " As PCI\n"));
468 switch (Stack->MinorFunction) {
469 case IRP_MN_QUERY_DEVICE_RELATIONS:
470 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS\n"));
471 switch (Stack->Parameters.QueryDeviceRelations.Type)
472 {
473 case BusRelations:
474 KdPrint((__DRIVER_NAME " BusRelations\n"));
475 IoCopyCurrentIrpStackLocationToNext(Irp);
476 IoSetCompletionRoutine(Irp, XenHide_IoCompletion, DeviceExtension, TRUE, TRUE, TRUE);
477 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
478 break;
479 default:
480 IoSkipCurrentIrpStackLocation(Irp);
481 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
482 break;
483 }
484 break;
485 default:
486 IoSkipCurrentIrpStackLocation(Irp);
487 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
488 break;
489 }
490 break;
491 case XENHIDE_TYPE_HIDE:
492 KdPrint((__DRIVER_NAME " As Hide\n"));
493 Irp->IoStatus.Information = 0;
494 switch (Stack->MinorFunction)
495 {
496 case IRP_MN_START_DEVICE:
497 case IRP_MN_STOP_DEVICE:
498 Irp->IoStatus.Status = Status = STATUS_SUCCESS;
499 break;
500 case IRP_MN_QUERY_PNP_DEVICE_STATE:
501 Irp->IoStatus.Status = Status = STATUS_SUCCESS;
502 Irp->IoStatus.Information = PNP_DEVICE_DONT_DISPLAY_IN_UI;
503 break;
504 default:
505 Irp->IoStatus.Status = Status = STATUS_UNSUCCESSFUL;
506 break;
507 }
508 IoCompleteRequest(Irp, IO_NO_INCREMENT);
510 /*
511 switch (Stack->MinorFunction)
512 {
513 case IRP_MN_START_DEVICE:
514 IoCopyCurrentIrpStackLocationToNext(Irp);
515 Stack = IoGetNextIrpStackLocation(Irp);
516 Stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList.Count = 0;
517 Stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList.Count = 0;
518 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
519 break;
520 default:
521 IoSkipCurrentIrpStackLocation(Irp);
522 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
523 break;
524 }
525 IoCompleteRequest(Irp, IO_NO_INCREMENT);
526 */
527 break;
528 }
530 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", Status));
532 return Status;
533 }