diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index c4cb5c366cb..680e20ef4e0 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -1063,12 +1063,15 @@ PnpRootDriverEntry( IN PUNICODE_STRING RegistryPath ); +NTSTATUS +PnpRootCreateDeviceObject( + OUT PDEVICE_OBJECT *DeviceObject); + NTSTATUS PnpRootCreateDevice( IN PUNICODE_STRING ServiceName, - IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, - OUT OPTIONAL PUNICODE_STRING FullInstancePath + OUT PUNICODE_STRING FullInstancePath ); NTSTATUS diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 9f6f06688bd..735760f8c4f 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -223,7 +223,7 @@ IoReportDetectedDevice( } /* We use the caller's PDO if they supplied one */ - UNICODE_STRING instancePath; + UNICODE_STRING instancePath = {0}; if (DeviceObject && *DeviceObject) { Pdo = *DeviceObject; @@ -231,7 +231,7 @@ IoReportDetectedDevice( else { /* Create the PDO */ - Status = PnpRootCreateDevice(&ServiceName, NULL, &Pdo, &instancePath); + Status = PnpRootCreateDevice(&ServiceName, &Pdo, &instancePath); if (!NT_SUCCESS(Status)) { DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status); @@ -247,7 +247,8 @@ IoReportDetectedDevice( return STATUS_INSUFFICIENT_RESOURCES; } - Status = RtlDuplicateUnicodeString(0, &instancePath, &DeviceNode->InstancePath); + // The string comes from PnpRootCreateDevice, so it can be used right away + DeviceNode->InstancePath = instancePath; /* Open a handle to the instance path key */ Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey); diff --git a/ntoskrnl/io/pnpmgr/pnproot.c b/ntoskrnl/io/pnpmgr/pnproot.c index 4a9ae6607b5..b0948da4882 100644 --- a/ntoskrnl/io/pnpmgr/pnproot.c +++ b/ntoskrnl/io/pnpmgr/pnproot.c @@ -108,6 +108,7 @@ PnpRootRegisterDevice( IN PDEVICE_OBJECT DeviceObject) { PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension = &PnpRootDOExtension; + PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension; PPNPROOT_DEVICE Device; PDEVICE_NODE DeviceNode; PWSTR InstancePath; @@ -147,6 +148,10 @@ PnpRootRegisterDevice( Device->Pdo = DeviceObject; + PdoDeviceExtension = DeviceObject->DeviceExtension; + RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION)); + PdoDeviceExtension->DeviceInfo = Device; + KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock); InsertTailList(&DeviceExtension->DeviceListHead, &Device->ListEntry); @@ -158,13 +163,28 @@ PnpRootRegisterDevice( return STATUS_SUCCESS; } +NTSTATUS +PnpRootCreateDeviceObject( + OUT PDEVICE_OBJECT *DeviceObject) +{ + NTSTATUS status = IoCreateDevice( + IopRootDriverObject, + sizeof(PNPROOT_PDO_DEVICE_EXTENSION), + NULL, + FILE_DEVICE_CONTROLLER, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, + DeviceObject); + + return status; +} + /* Creates a new PnP device for a legacy driver */ NTSTATUS PnpRootCreateDevice( IN PUNICODE_STRING ServiceName, - IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, - OUT OPTIONAL PUNICODE_STRING FullInstancePath) + OUT PUNICODE_STRING FullInstancePath) { PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension; @@ -172,7 +192,6 @@ PnpRootCreateDevice( WCHAR InstancePath[5]; PPNPROOT_DEVICE Device = NULL; NTSTATUS Status; - UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); ULONG NextInstance; UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM); HANDLE EnumHandle, DeviceKeyHandle = NULL, InstanceKeyHandle; @@ -207,7 +226,7 @@ PnpRootCreateDevice( goto cleanup; } RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE)); - Device->DeviceID = DevicePath; + Device->DeviceID = DevicePath; // "Root\" RtlInitEmptyUnicodeString(&DevicePath, NULL, 0); Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ); @@ -278,6 +297,7 @@ tryagain: goto cleanup; } + // "0000" or higher if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath)) { Status = STATUS_NO_MEMORY; @@ -300,31 +320,22 @@ tryagain: /* Just close the handle */ ObCloseHandle(InstanceKeyHandle, KernelMode); - if (FullInstancePath) + // generate the full device instance path + FullInstancePath->MaximumLength = Device->DeviceID.Length + sizeof(L'\\') + Device->InstanceID.Length; + FullInstancePath->Length = 0; + FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength); + if (!FullInstancePath->Buffer) { - FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length; - FullInstancePath->Length = 0; - FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength); - if (!FullInstancePath->Buffer) - { - Status = STATUS_NO_MEMORY; - goto cleanup; - } - - RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID); - RtlAppendUnicodeStringToString(FullInstancePath, &PathSep); - RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID); + Status = STATUS_NO_MEMORY; + goto cleanup; } + RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID); + RtlAppendUnicodeToString(FullInstancePath, L"\\"); + RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID); + /* Initialize a device object */ - Status = IoCreateDevice( - DriverObject ? DriverObject : IopRootDeviceNode->PhysicalDeviceObject->DriverObject, - sizeof(PNPROOT_PDO_DEVICE_EXTENSION), - NULL, - FILE_DEVICE_CONTROLLER, - FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, - &Device->Pdo); + Status = PnpRootCreateDeviceObject(&Device->Pdo); if (!NT_SUCCESS(Status)) { DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); @@ -923,14 +934,7 @@ PnpRootQueryDeviceRelations( { /* Create a physical device object for the * device as it does not already have one */ - Status = IoCreateDevice( - DeviceObject->DriverObject, - sizeof(PNPROOT_PDO_DEVICE_EXTENSION), - NULL, - FILE_DEVICE_CONTROLLER, - FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, - &Device->Pdo); + Status = PnpRootCreateDeviceObject(&Device->Pdo); if (!NT_SUCCESS(Status)) { DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);