[NTOS:PNP] Refactor PnpRootCreateDevice

- Remove unused "DriverObject" argument
- Make "FullInstancePath" mandatory
- Extract the PDO creation into separate function, it will be used later
This commit is contained in:
Victor Perevertkin 2023-06-29 19:24:51 +03:00
parent bbf64c0cc4
commit 6cac5b8c9e
No known key found for this signature in database
GPG key ID: C750B7222E9C7830
3 changed files with 46 additions and 38 deletions

View file

@ -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

View file

@ -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);

View file

@ -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\<service_name>"
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);