win-pvdrivers

view xenhide/xenhide.c @ 117:92aea8738afb

Added error checking into xenhide
author James Harper <james.harper@bendigoit.com.au>
date Mon Jan 14 23:10:27 2008 +1100 (2008-01-14)
parents b55f4ed508b0
children f3f156c524ee
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(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
26 static VOID
27 XenHide_IoInternalDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode);
29 #ifdef ALLOC_PRAGMA
30 #pragma alloc_text (INIT, DriverEntry)
31 #pragma alloc_text (PAGE, XenHide_AddDevice)
32 #endif
34 static BOOLEAN AutoEnumerate;
36 static WDFDEVICE Device;
38 NTSTATUS
39 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
40 {
41 WDF_DRIVER_CONFIG config;
42 NTSTATUS status;
43 UNICODE_STRING RegKeyName;
44 UNICODE_STRING RegValueName;
45 HANDLE RegHandle;
46 OBJECT_ATTRIBUTES RegObjectAttributes;
47 char Buf[200];
48 ULONG BufLen = 200;
49 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
50 int State = 0;
51 int StartPos = 0;
52 WCHAR *SystemStartOptions;
53 size_t SystemStartOptionsLen;
54 size_t i;
56 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
57 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
59 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
60 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
61 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
62 if(!NT_SUCCESS(status))
63 {
64 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
65 }
67 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
68 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
69 if(!NT_SUCCESS(status))
70 {
71 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
72 }
73 else
74 ZwClose(RegHandle);
75 KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
76 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
77 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
78 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
80 AutoEnumerate = FALSE;
82 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
84 for (i = 0; i <= SystemStartOptionsLen/2; i++)
85 {
86 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
88 switch (State)
89 {
90 case 0:
91 if (SystemStartOptions[i] == L'G')
92 {
93 StartPos = i;
94 State = 2;
95 } else if (SystemStartOptions[i] != L' ')
96 {
97 State = 1;
98 }
99 break;
100 case 1:
101 if (SystemStartOptions[i] == L' ')
102 State = 0;
103 break;
104 case 2:
105 if (SystemStartOptions[i] == L'P')
106 State = 3;
107 else
108 State = 0;
109 break;
110 case 3:
111 if (SystemStartOptions[i] == L'L')
112 State = 4;
113 else
114 State = 0;
115 break;
116 case 4:
117 if (SystemStartOptions[i] == L'P')
118 State = 5;
119 else
120 State = 0;
121 break;
122 case 5:
123 if (SystemStartOptions[i] == L'V')
124 State = 6;
125 else
126 State = 0;
127 break;
128 case 6:
129 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
130 AutoEnumerate = TRUE;
131 State = 0;
132 break;
133 }
134 }
136 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
139 WDF_DRIVER_CONFIG_INIT(&config, XenHide_AddDevice);
140 status = WdfDriverCreate(
141 DriverObject,
142 RegistryPath,
143 WDF_NO_OBJECT_ATTRIBUTES,
144 &config,
145 WDF_NO_HANDLE);
146 if(!NT_SUCCESS(status))
147 {
148 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
149 }
151 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
153 return status;
154 }
156 static NTSTATUS
157 XenHide_PreprocessWdmIrpPNP(WDFDEVICE Device, PIRP Irp);
159 static NTSTATUS
160 XenHide_AddDevice(
161 IN WDFDRIVER Driver,
162 IN PWDFDEVICE_INIT DeviceInit
163 )
164 {
165 NTSTATUS status;
166 WDF_OBJECT_ATTRIBUTES attributes;
167 UCHAR MinorFunctions[1] = { IRP_MN_QUERY_DEVICE_RELATIONS };
169 UNREFERENCED_PARAMETER(Driver);
171 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
172 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
174 WdfFdoInitSetFilter(DeviceInit);
176 WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
178 status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit, XenHide_PreprocessWdmIrpPNP, IRP_MJ_PNP, MinorFunctions, 1);
179 if(!NT_SUCCESS(status))
180 {
181 KdPrint((__DRIVER_NAME " WdfDeviceInitAssignWdmIrpPreprocessCallback failed with status 0x%08x\n", status));
182 return status;
183 }
185 status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
186 if(!NT_SUCCESS(status))
187 {
188 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with status 0x%08x\n", status));
189 return status;
190 }
192 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
194 return status;
195 }
197 static int
198 XenHide_StringMatches(PWCHAR String1, PWCHAR String2)
199 {
200 for(;*String1 != 0 && *String2 != 0 && *String1 == *String2; String1++, String2++);
201 return ((*String1 == 0 && *String2 == 0) || (*String1 == 0 && *String2 == L'\n') || (*String1 == L'\n' && *String2 == 0));
202 }
204 static NTSTATUS
205 XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
206 {
207 ULONG i;
208 PDEVICE_RELATIONS Relations;
209 WCHAR Buffer[1000];
210 PWCHAR Ptr;
211 ULONG Length;
212 size_t StrLen;
213 int Match;
214 int Offset = 0;
216 UNREFERENCED_PARAMETER(DeviceObject);
217 UNREFERENCED_PARAMETER(Context);
219 KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
220 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
222 Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
224 for (i = 0; i < Relations->Count; i++)
225 {
226 if (Offset != 0)
227 Relations->Objects[i - Offset] = Relations->Objects[i];
229 Length = sizeof(Buffer);
230 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyDeviceDescription, Length, Buffer, &Length);
231 KdPrint((__DRIVER_NAME " %3d - %ws\n", i, Buffer));
233 Length = sizeof(Buffer);
234 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyPhysicalDeviceObjectName, Length, Buffer, &Length);
235 KdPrint((__DRIVER_NAME " %3d - %ws\n", i, Buffer));
237 Length = sizeof(Buffer);
238 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyHardwareID, Length, Buffer, &Length);
239 Match = 0;
240 StrLen = 0;
241 for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
242 {
243 KdPrint((__DRIVER_NAME " - %ws\n", Ptr));
244 // Qemu PCI
245 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010&SUBSYS_00015853")) {
246 Match = 1;
247 break;
248 }
249 // Qemu Network
250 #if 0 // we don't need this because we can specify type=netfront instead of type=ioemu
251 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139&SUBSYS_00015853")) {
252 Match = 1;
253 break;
254 }
255 #endif
256 RtlStringCchLengthW(Ptr, Length, &StrLen);
257 }
258 if (Match)
259 {
260 KdPrint((__DRIVER_NAME " (Match)\n"));
261 Offset++;
262 }
263 }
264 Relations->Count -= Offset;
266 KdPrint((__DRIVER_NAME " <-- IoCompletion\n"));
268 return Irp->IoStatus.Status;
269 }
271 static NTSTATUS
272 XenHide_PreprocessWdmIrpPNP(WDFDEVICE Device, PIRP Irp)
273 {
274 NTSTATUS Status = STATUS_SUCCESS;
275 PIO_STACK_LOCATION Stack;
277 KdPrint((__DRIVER_NAME " --> WdmIrpPreprocessPNP\n"));
278 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
280 Stack = IoGetCurrentIrpStackLocation(Irp);
282 switch (Stack->MinorFunction) {
283 case IRP_MN_QUERY_DEVICE_RELATIONS:
284 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS Device = %08x Irp = %08x, Stack = %08x\n", Device, Irp, Stack));
285 switch (Stack->Parameters.QueryDeviceRelations.Type)
286 {
287 case BusRelations:
288 KdPrint((__DRIVER_NAME " BusRelations\n"));
289 if (AutoEnumerate)
290 {
291 IoCopyCurrentIrpStackLocationToNext(Irp);
292 IoSetCompletionRoutine(Irp, XenHide_IoCompletion, NULL, TRUE, TRUE, TRUE);
293 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
294 }
295 else
296 {
297 IoSkipCurrentIrpStackLocation(Irp);
298 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
299 }
300 break;
301 case EjectionRelations:
302 IoSkipCurrentIrpStackLocation(Irp);
303 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
304 KdPrint((__DRIVER_NAME " EjectionRelations\n"));
305 break;
306 case RemovalRelations:
307 IoSkipCurrentIrpStackLocation(Irp);
308 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
309 KdPrint((__DRIVER_NAME " RemovalRelations\n"));
310 break;
311 case TargetDeviceRelation:
312 IoSkipCurrentIrpStackLocation(Irp);
313 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
314 KdPrint((__DRIVER_NAME " TargetDeviceRelation\n"));
315 break;
316 default:
317 IoSkipCurrentIrpStackLocation(Irp);
318 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
319 KdPrint((__DRIVER_NAME " Unknown Type %d\n", Stack->Parameters.QueryDeviceRelations.Type));
320 break;
321 }
322 break;
323 default:
324 IoSkipCurrentIrpStackLocation(Irp);
325 Status = WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
326 KdPrint((__DRIVER_NAME " Unknown Minor %d\n", Stack->MinorFunction));
327 break;
328 }
330 KdPrint((__DRIVER_NAME " <-- WdmIrpPreprocessPNP (returning with status %08x\n", Status));
332 return Status;
333 }