win-pvdrivers

view xenhide/xenhide.c @ 174:02a14f8e0298

Fixed a stupid off by one error which was preventing booting when /gplpv was not specified
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 05 22:18:20 2008 +1100 (2008-02-05)
parents 4d23c0381767
children 09f1c620ba55
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 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
60 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
62 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
63 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
64 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
65 if(!NT_SUCCESS(status))
66 {
67 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
68 }
70 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
71 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
72 if(!NT_SUCCESS(status))
73 {
74 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
75 }
76 else
77 ZwClose(RegHandle);
78 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
79 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
81 AutoEnumerate = FALSE;
83 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
85 for (i = 0; i <= SystemStartOptionsLen/2; i++)
86 {
87 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
89 switch (State)
90 {
91 case 0:
92 if (SystemStartOptions[i] == L'G')
93 {
94 StartPos = i;
95 State = 2;
96 } else if (SystemStartOptions[i] != L' ')
97 {
98 State = 1;
99 }
100 break;
101 case 1:
102 if (SystemStartOptions[i] == L' ')
103 State = 0;
104 break;
105 case 2:
106 if (SystemStartOptions[i] == L'P')
107 State = 3;
108 else
109 State = 0;
110 break;
111 case 3:
112 if (SystemStartOptions[i] == L'L')
113 State = 4;
114 else
115 State = 0;
116 break;
117 case 4:
118 if (SystemStartOptions[i] == L'P')
119 State = 5;
120 else
121 State = 0;
122 break;
123 case 5:
124 if (SystemStartOptions[i] == L'V')
125 State = 6;
126 else
127 State = 0;
128 break;
129 case 6:
130 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
131 AutoEnumerate = TRUE;
132 State = 0;
133 break;
134 }
135 }
137 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
139 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
140 DriverObject->MajorFunction[i] = XenHide_Pass;
141 if (AutoEnumerate)
142 DriverObject->MajorFunction[IRP_MJ_PNP] = XenHide_Pnp;
143 DriverObject->DriverExtension->AddDevice = XenHide_AddDevice;
145 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
147 return status;
148 }
150 static NTSTATUS
151 XenHide_AddDevice(
152 PDRIVER_OBJECT DriverObject,
153 PDEVICE_OBJECT PhysicalDeviceObject
154 )
155 {
156 NTSTATUS status;
157 PDEVICE_OBJECT deviceObject = NULL;
158 PDEVICE_EXTENSION DeviceExtension;
160 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
162 status = IoCreateDevice (DriverObject,
163 sizeof(DEVICE_EXTENSION),
164 NULL,
165 FILE_DEVICE_UNKNOWN,
166 FILE_DEVICE_SECURE_OPEN,
167 FALSE,
168 &deviceObject);
170 DeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
172 DeviceExtension->NextLowerDevice = IoAttachDeviceToDeviceStack(
173 deviceObject,
174 PhysicalDeviceObject);
175 deviceObject->Flags |= DeviceExtension->NextLowerDevice->Flags;
177 deviceObject->DeviceType = DeviceExtension->NextLowerDevice->DeviceType;
179 deviceObject->Characteristics =
180 DeviceExtension->NextLowerDevice->Characteristics;
182 DeviceExtension->Self = deviceObject;
184 //INITIALIZE_PNP_STATE(DeviceExtension);
186 if (AutoEnumerate)
187 {
188 status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID)&GUID_XENHIDE_IFACE, NULL, &DeviceExtension->InterfaceName);
189 if (!NT_SUCCESS(status))
190 {
191 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface failed 0x%08x\n", status));
192 return status;
193 }
194 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface complete, SymbolicLinkName = %wZ\n", &DeviceExtension->InterfaceName));
195 status = IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
196 if (!NT_SUCCESS(status))
197 {
198 KdPrint((__DRIVER_NAME " IoSetDeviceInterfaceState failed 0x%08x\n", status));
199 return status;
200 }
201 }
202 else
203 {
204 KdPrint((__DRIVER_NAME " Not registering Interface\n"));
205 }
207 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
209 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
211 return STATUS_SUCCESS;
212 }
214 static int
215 XenHide_StringMatches(PWCHAR String1, PWCHAR String2)
216 {
217 for(;*String1 != 0 && *String2 != 0 && *String1 == *String2; String1++, String2++);
218 return ((*String1 == 0 && *String2 == 0) || (*String1 == 0 && *String2 == L'\n') || (*String1 == L'\n' && *String2 == 0));
219 }
221 static NTSTATUS
222 XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
223 {
224 ULONG i;
225 PDEVICE_RELATIONS Relations;
226 WCHAR Buffer[1000];
227 PWCHAR Ptr;
228 ULONG Length;
229 size_t StrLen;
230 int Match;
231 int Offset = 0;
233 UNREFERENCED_PARAMETER(DeviceObject);
234 UNREFERENCED_PARAMETER(Context);
236 KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
237 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
239 Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
241 for (i = 0; i < Relations->Count; i++)
242 {
243 if (Offset != 0)
244 Relations->Objects[i - Offset] = Relations->Objects[i];
246 // Length = sizeof(Buffer);
247 // IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyDeviceDescription, Length, Buffer, &Length);
248 // KdPrint((__DRIVER_NAME " %3d - %ws\n", i, Buffer));
250 // Length = sizeof(Buffer);
251 // IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyPhysicalDeviceObjectName, Length, Buffer, &Length);
252 // KdPrint((__DRIVER_NAME " %3d - %ws\n", i, Buffer));
254 Length = sizeof(Buffer);
255 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
256 Match = 0;
257 StrLen = 0;
258 for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
259 {
260 // KdPrint((__DRIVER_NAME " - %ws\n", Ptr));
261 // Qemu PCI
262 // if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010&SUBSYS_00015853")) {
263 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
264 Match = 1;
265 break;
266 }
267 // Qemu Network
268 // if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139&SUBSYS_00015853")) {
269 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
270 Match = 1;
271 break;
272 }
273 RtlStringCchLengthW(Ptr, Length, &StrLen);
274 }
275 if (Match)
276 {
277 // KdPrint((__DRIVER_NAME " (Match)\n"));
278 Offset++;
279 }
280 }
281 Relations->Count -= Offset;
283 KdPrint((__DRIVER_NAME " <-- IoCompletion\n"));
285 return Irp->IoStatus.Status;
286 }
288 static NTSTATUS
289 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
290 {
291 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
292 NTSTATUS status;
294 IoSkipCurrentIrpStackLocation(Irp);
295 status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
296 return status;
297 }
299 static NTSTATUS
300 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
301 {
302 NTSTATUS Status = STATUS_SUCCESS;
303 PIO_STACK_LOCATION Stack;
304 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
306 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
307 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
309 Stack = IoGetCurrentIrpStackLocation(Irp);
311 switch (Stack->MinorFunction) {
312 case IRP_MN_QUERY_DEVICE_RELATIONS:
313 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS\n"));
314 switch (Stack->Parameters.QueryDeviceRelations.Type)
315 {
316 case BusRelations:
317 KdPrint((__DRIVER_NAME " BusRelations\n"));
318 IoCopyCurrentIrpStackLocationToNext(Irp);
319 IoSetCompletionRoutine(Irp, XenHide_IoCompletion, NULL, TRUE, TRUE, TRUE);
320 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
321 break;
322 default:
323 IoSkipCurrentIrpStackLocation(Irp);
324 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
325 break;
326 }
327 break;
328 default:
329 IoSkipCurrentIrpStackLocation(Irp);
330 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
331 break;
332 }
334 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", Status));
336 return Status;
337 }