win-pvdrivers

annotate 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
rev   line source
james@2 1 /*
james@2 2 PV Drivers for Windows Xen HVM Domains
james@2 3 Copyright (C) 2007 James Harper
james@2 4
james@2 5 This program is free software; you can redistribute it and/or
james@2 6 modify it under the terms of the GNU General Public License
james@2 7 as published by the Free Software Foundation; either version 2
james@2 8 of the License, or (at your option) any later version.
james@2 9
james@2 10 This program is distributed in the hope that it will be useful,
james@2 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@2 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@2 13 GNU General Public License for more details.
james@2 14
james@2 15 You should have received a copy of the GNU General Public License
james@2 16 along with this program; if not, write to the Free Software
james@2 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@2 18 */
james@2 19
james@2 20 #include "xenhide.h"
james@2 21 #include <stdlib.h>
james@2 22
james@2 23 DRIVER_INITIALIZE DriverEntry;
james@2 24 static NTSTATUS
james@172 25 XenHide_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject);
james@172 26 static NTSTATUS
james@172 27 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp);
james@172 28 static NTSTATUS
james@172 29 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
james@172 30 static NTSTATUS
james@172 31 XenHide_AddDevice();
james@172 32 //static NTSTATUS
james@172 33 //XenHide_Unload();
james@2 34
james@2 35 #ifdef ALLOC_PRAGMA
james@2 36 #pragma alloc_text (INIT, DriverEntry)
james@2 37 #pragma alloc_text (PAGE, XenHide_AddDevice)
james@2 38 #endif
james@2 39
james@2 40 static BOOLEAN AutoEnumerate;
james@2 41
james@2 42 NTSTATUS
james@2 43 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
james@2 44 {
james@2 45 NTSTATUS status;
james@2 46 UNICODE_STRING RegKeyName;
james@2 47 UNICODE_STRING RegValueName;
james@2 48 HANDLE RegHandle;
james@2 49 OBJECT_ATTRIBUTES RegObjectAttributes;
james@2 50 char Buf[200];
james@2 51 ULONG BufLen = 200;
james@2 52 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
james@2 53 int State = 0;
james@2 54 int StartPos = 0;
james@2 55 WCHAR *SystemStartOptions;
james@2 56 size_t SystemStartOptionsLen;
james@2 57 size_t i;
james@2 58
andy@178 59 UNREFERENCED_PARAMETER(RegistryPath);
andy@178 60
james@2 61 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
james@95 62 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
james@2 63
james@2 64 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
james@2 65 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
james@2 66 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
james@2 67 if(!NT_SUCCESS(status))
james@2 68 {
james@2 69 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
james@2 70 }
james@2 71
james@2 72 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
james@2 73 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
james@2 74 if(!NT_SUCCESS(status))
james@2 75 {
james@2 76 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
james@2 77 }
james@95 78 else
james@95 79 ZwClose(RegHandle);
james@2 80 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
james@2 81 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
james@2 82
james@2 83 AutoEnumerate = FALSE;
james@2 84
james@2 85 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
james@2 86
james@2 87 for (i = 0; i <= SystemStartOptionsLen/2; i++)
james@2 88 {
james@2 89 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
james@2 90
james@2 91 switch (State)
james@2 92 {
james@2 93 case 0:
james@2 94 if (SystemStartOptions[i] == L'G')
james@2 95 {
james@2 96 StartPos = i;
james@2 97 State = 2;
james@2 98 } else if (SystemStartOptions[i] != L' ')
james@2 99 {
james@2 100 State = 1;
james@2 101 }
james@2 102 break;
james@2 103 case 1:
james@2 104 if (SystemStartOptions[i] == L' ')
james@2 105 State = 0;
james@2 106 break;
james@2 107 case 2:
james@2 108 if (SystemStartOptions[i] == L'P')
james@2 109 State = 3;
james@2 110 else
james@2 111 State = 0;
james@2 112 break;
james@2 113 case 3:
james@2 114 if (SystemStartOptions[i] == L'L')
james@2 115 State = 4;
james@2 116 else
james@2 117 State = 0;
james@2 118 break;
james@2 119 case 4:
james@2 120 if (SystemStartOptions[i] == L'P')
james@2 121 State = 5;
james@2 122 else
james@2 123 State = 0;
james@2 124 break;
james@2 125 case 5:
james@2 126 if (SystemStartOptions[i] == L'V')
james@2 127 State = 6;
james@2 128 else
james@2 129 State = 0;
james@2 130 break;
james@2 131 case 6:
james@2 132 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
james@2 133 AutoEnumerate = TRUE;
james@2 134 State = 0;
james@2 135 break;
james@2 136 }
james@2 137 }
james@2 138
james@2 139 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
james@2 140
james@174 141 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
james@172 142 DriverObject->MajorFunction[i] = XenHide_Pass;
james@172 143 if (AutoEnumerate)
james@172 144 DriverObject->MajorFunction[IRP_MJ_PNP] = XenHide_Pnp;
james@172 145 DriverObject->DriverExtension->AddDevice = XenHide_AddDevice;
james@2 146
james@2 147 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
james@2 148
james@2 149 return status;
james@2 150 }
james@2 151
james@2 152 static NTSTATUS
james@172 153 XenHide_AddDevice(
james@172 154 PDRIVER_OBJECT DriverObject,
james@172 155 PDEVICE_OBJECT PhysicalDeviceObject
james@172 156 )
james@159 157 {
james@172 158 NTSTATUS status;
james@189 159 PDEVICE_OBJECT deviceObject = NULL;
james@172 160 PDEVICE_EXTENSION DeviceExtension;
james@184 161 ULONG Length;
james@184 162 WCHAR Buffer[1000];
james@159 163
james@159 164 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@159 165
james@184 166 Length = 1000;
james@184 167 status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDeviceDescription, Length, Buffer, &Length);
james@189 168 KdPrint((__DRIVER_NAME " status = %08x, DevicePropertyDeviceDescription = %ws\n", status, Buffer));
james@184 169
james@184 170 if (!NT_SUCCESS(status) || wcscmp(Buffer, L"PCI bus") != 0)
james@184 171 {
james@184 172 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@184 173 return STATUS_SUCCESS;
james@184 174 }
james@184 175
james@189 176 KdPrint((__DRIVER_NAME " Found\n"));
james@189 177
james@189 178 status = IoCreateDevice (DriverObject,
james@172 179 sizeof(DEVICE_EXTENSION),
james@172 180 NULL,
james@172 181 FILE_DEVICE_UNKNOWN,
james@172 182 FILE_DEVICE_SECURE_OPEN,
james@172 183 FALSE,
james@189 184 &deviceObject);
james@2 185
james@189 186 DeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
james@2 187
james@172 188 DeviceExtension->NextLowerDevice = IoAttachDeviceToDeviceStack(
james@189 189 deviceObject,
james@172 190 PhysicalDeviceObject);
james@189 191 deviceObject->Flags |= DeviceExtension->NextLowerDevice->Flags;
james@2 192
james@189 193 deviceObject->DeviceType = DeviceExtension->NextLowerDevice->DeviceType;
james@159 194
james@189 195 deviceObject->Characteristics =
james@172 196 DeviceExtension->NextLowerDevice->Characteristics;
james@172 197
james@189 198 DeviceExtension->Self = deviceObject;
james@2 199
james@189 200 //INITIALIZE_PNP_STATE(DeviceExtension);
james@189 201
james@159 202 if (AutoEnumerate)
james@159 203 {
james@172 204 status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID)&GUID_XENHIDE_IFACE, NULL, &DeviceExtension->InterfaceName);
james@159 205 if (!NT_SUCCESS(status))
james@159 206 {
james@172 207 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface failed 0x%08x\n", status));
james@172 208 return status;
james@172 209 }
james@172 210 KdPrint((__DRIVER_NAME " IoRegisterDeviceInterface complete, SymbolicLinkName = %wZ\n", &DeviceExtension->InterfaceName));
james@172 211 status = IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
james@172 212 if (!NT_SUCCESS(status))
james@172 213 {
james@172 214 KdPrint((__DRIVER_NAME " IoSetDeviceInterfaceState failed 0x%08x\n", status));
james@159 215 return status;
james@159 216 }
james@159 217 }
james@172 218 else
james@172 219 {
james@172 220 KdPrint((__DRIVER_NAME " Not registering Interface\n"));
james@172 221 }
james@159 222
james@189 223 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
james@2 224
james@172 225 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@172 226
james@172 227 return STATUS_SUCCESS;
james@2 228 }
james@2 229
james@2 230 static int
james@2 231 XenHide_StringMatches(PWCHAR String1, PWCHAR String2)
james@2 232 {
james@2 233 for(;*String1 != 0 && *String2 != 0 && *String1 == *String2; String1++, String2++);
james@2 234 return ((*String1 == 0 && *String2 == 0) || (*String1 == 0 && *String2 == L'\n') || (*String1 == L'\n' && *String2 == 0));
james@2 235 }
james@2 236
james@2 237 static NTSTATUS
james@189 238 XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
james@2 239 {
james@176 240 ULONG i, j;
james@2 241 PDEVICE_RELATIONS Relations;
james@2 242 WCHAR Buffer[1000];
james@2 243 PWCHAR Ptr;
james@2 244 ULONG Length;
james@2 245 size_t StrLen;
james@2 246 int Match;
james@189 247 int Offset = 0;
james@184 248 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)Context;
james@2 249
james@2 250 UNREFERENCED_PARAMETER(DeviceObject);
james@2 251 UNREFERENCED_PARAMETER(Context);
james@2 252
james@189 253 KdPrint((__DRIVER_NAME " --> IoCompletion\n"));
james@95 254 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
james@2 255
james@189 256 Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
james@2 257
james@187 258 switch (DeviceExtension->InternalState)
james@2 259 {
james@184 260 case 0:
james@187 261 DeviceExtension->InternalState = 1;
james@184 262 break;
james@184 263 case 1:
james@189 264 DeviceExtension->InternalState = 2;
james@184 265 for (i = 0; i < Relations->Count; i++)
james@2 266 {
james@189 267 if (Offset != 0)
james@189 268 Relations->Objects[i - Offset] = Relations->Objects[i];
james@189 269
james@184 270 Match = 0;
james@184 271 for (j = 0; j < 2 && !Match; j++)
james@176 272 {
james@184 273 Length = sizeof(Buffer);
james@184 274 if (j == 0)
james@189 275 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
james@184 276 else
james@189 277 IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyHardwareID, Length, Buffer, &Length);
james@189 278 StrLen = 0;
james@184 279 for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
james@184 280 {
james@184 281 // Qemu PCI
james@184 282 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
james@184 283 Match = 1;
james@184 284 break;
james@184 285 }
james@184 286 // Qemu Network
james@184 287 if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
james@184 288 Match = 1;
james@184 289 break;
james@184 290 }
james@184 291 RtlStringCchLengthW(Ptr, Length, &StrLen);
james@176 292 }
james@184 293 }
james@184 294 if (Match)
james@184 295 {
james@189 296 Offset++;
james@2 297 }
james@2 298 }
james@189 299 Relations->Count -= Offset;
james@184 300 break;
james@184 301 default:
james@184 302 break;
james@2 303 }
james@189 304
james@189 305 KdPrint((__DRIVER_NAME " <-- IoCompletion\n"));
james@188 306
james@189 307 return Irp->IoStatus.Status;
james@188 308 }
james@188 309
james@188 310 static NTSTATUS
james@172 311 XenHide_Pass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
james@172 312 {
james@174 313 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
james@189 314 NTSTATUS status;
james@189 315
james@188 316 IoSkipCurrentIrpStackLocation(Irp);
james@189 317 status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
james@189 318 return status;
james@172 319 }
james@172 320
james@172 321 static NTSTATUS
james@172 322 XenHide_Pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
james@2 323 {
james@2 324 NTSTATUS Status = STATUS_SUCCESS;
james@2 325 PIO_STACK_LOCATION Stack;
james@172 326 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
james@2 327
james@159 328 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@95 329 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
james@2 330
james@2 331 Stack = IoGetCurrentIrpStackLocation(Irp);
james@2 332
james@189 333 switch (Stack->MinorFunction) {
james@2 334 case IRP_MN_QUERY_DEVICE_RELATIONS:
james@189 335 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_DEVICE_RELATIONS\n"));
james@189 336 switch (Stack->Parameters.QueryDeviceRelations.Type)
james@189 337 {
james@189 338 case BusRelations:
james@189 339 KdPrint((__DRIVER_NAME " BusRelations\n"));
james@189 340 IoCopyCurrentIrpStackLocationToNext(Irp);
james@189 341 IoSetCompletionRoutine(Irp, XenHide_IoCompletion, DeviceExtension, TRUE, TRUE, TRUE);
james@189 342 break;
james@189 343 default:
james@189 344 IoSkipCurrentIrpStackLocation(Irp);
james@189 345 break;
james@189 346 }
james@184 347 break;
james@187 348 default:
james@189 349 IoSkipCurrentIrpStackLocation(Irp);
james@187 350 break;
james@184 351 }
james@184 352
james@189 353 Status = IoCallDriver(DeviceExtension->NextLowerDevice, Irp);
james@184 354
james@159 355 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", Status));
james@2 356
james@2 357 return Status;
james@2 358 }