win-pvdrivers

view xenhide/xenhide.c @ 189:eeeeb6924803

updates preparing for next release
author James Harper <james.harper@bendigoit.com.au>
date Mon Feb 18 22:16:03 2008 +1100 (2008-02-18)
parents a416c66be9c2
children da58a35a8a31
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 }
176 KdPrint((__DRIVER_NAME " Found\n"));
178 status = IoCreateDevice (DriverObject,
179 sizeof(DEVICE_EXTENSION),
180 NULL,
181 FILE_DEVICE_UNKNOWN,
182 FILE_DEVICE_SECURE_OPEN,
183 FALSE,
184 &deviceObject);
186 DeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
188 DeviceExtension->NextLowerDevice = IoAttachDeviceToDeviceStack(
189 deviceObject,
190 PhysicalDeviceObject);
191 deviceObject->Flags |= DeviceExtension->NextLowerDevice->Flags;
193 deviceObject->DeviceType = DeviceExtension->NextLowerDevice->DeviceType;
195 deviceObject->Characteristics =
196 DeviceExtension->NextLowerDevice->Characteristics;
198 DeviceExtension->Self = deviceObject;
200 //INITIALIZE_PNP_STATE(DeviceExtension);
202 if (AutoEnumerate)
203 {
204 status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID)&GUID_XENHIDE_IFACE, NULL, &DeviceExtension->InterfaceName);
205 if (!NT_SUCCESS(status))
206 {
207 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface failed 0x%08x\n", status));
208 return status;
209 }
210 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface complete, SymbolicLinkName = %wZ\n", &DeviceExtension->InterfaceName));
211 status = IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
212 if (!NT_SUCCESS(status))
213 {
214 KdPrint((__DRIVER_NAME " IoSetDeviceInterfaceState failed 0x%08x\n", status));
215 return status;
216 }
217 }
218 else
219 {
220 KdPrint((__DRIVER_NAME " Not registering Interface\n"));
221 }
223 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
225 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
227 return STATUS_SUCCESS;
228 }
230 static int
231 XenHide_StringMatches(PWCHAR String1, PWCHAR String2)
232 {
233 for(;*String1 != 0 && *String2 != 0 && *String1 == *String2; String1++, String2++);
234 return ((*String1 == 0 && *String2 == 0) || (*String1 == 0 && *String2 == L'\n') || (*String1 == L'\n' && *String2 == 0));
235 }
237 static NTSTATUS
238 XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
239 {
240 ULONG i, j;
241 PDEVICE_RELATIONS Relations;
242 WCHAR Buffer[1000];
243 PWCHAR Ptr;
244 ULONG Length;
245 size_t StrLen;
246 int Match;
247 int Offset = 0;
248 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)Context;
250 UNREFERENCED_PARAMETER(DeviceObject);
251 UNREFERENCED_PARAMETER(Context);
253 KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
254 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
256 Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
258 switch (DeviceExtension->InternalState)
259 {
260 case 0:
261 DeviceExtension->InternalState = 1;
262 break;
263 case 1:
264 DeviceExtension->InternalState = 2;
265 for (i = 0; i < Relations->Count; i++)
266 {
267 if (Offset != 0)
268 Relations->Objects[i - Offset] = Relations->Objects[i];
270 Match = 0;
271 for (j = 0; j < 2 && !Match; j++)
272 {
273 Length = sizeof(Buffer);
274 if (j == 0)
275 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
276 else
277 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyHardwareID, Length, Buffer, &Length);
278 StrLen = 0;
279 for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
280 {
281 // Qemu PCI
282 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
283 Match = 1;
284 break;
285 }
286 // Qemu Network
287 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
288 Match = 1;
289 break;
290 }
291 RtlStringCchLengthW(Ptr, Length, &StrLen);
292 }
293 }
294 if (Match)
295 {
296 Offset++;
297 }
298 }
299 Relations->Count -= Offset;
300 break;
301 default:
302 break;
303 }
305 KdPrint((__DRIVER_NAME " <-- IoCompletion\n"));
307 return Irp->IoStatus.Status;
308 }
310 static NTSTATUS
311 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
312 {
313 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
314 NTSTATUS status;
316 IoSkipCurrentIrpStackLocation(Irp);
317 status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
318 return status;
319 }
321 static NTSTATUS
322 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
323 {
324 NTSTATUS Status = STATUS_SUCCESS;
325 PIO_STACK_LOCATION Stack;
326 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
328 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
329 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
331 Stack = IoGetCurrentIrpStackLocation(Irp);
333 switch (Stack->MinorFunction) {
334 case IRP_MN_QUERY_DEVICE_RELATIONS:
335 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS\n"));
336 switch (Stack->Parameters.QueryDeviceRelations.Type)
337 {
338 case BusRelations:
339 KdPrint((__DRIVER_NAME " BusRelations\n"));
340 IoCopyCurrentIrpStackLocationToNext(Irp);
341 IoSetCompletionRoutine(Irp, XenHide_IoCompletion, DeviceExtension, TRUE, TRUE, TRUE);
342 break;
343 default:
344 IoSkipCurrentIrpStackLocation(Irp);
345 break;
346 }
347 break;
348 default:
349 IoSkipCurrentIrpStackLocation(Irp);
350 break;
351 }
353 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
355 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", Status));
357 return Status;
358 }