X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fio%2Fpnpmgr%2Fpnpreport.c;h=1ef595b682a2649e05dd869c925f90f8bebb250c;hp=8b919a124b794d3a5b3cc0b97c8b8af8b05fe928;hb=e2cb7b50b45e67575bcb44971425b3090e7a56f6;hpb=e4155c95c72474bab3db9873fbb0f4548305026a diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 8b919a124b7..1ef595b682a 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -108,6 +108,7 @@ IopGetInterfaceTypeString(INTERFACE_TYPE IfType) } VOID +NTAPI IopReportTargetDeviceChangeAsyncWorker(PVOID Context) { PINTERNAL_WORK_QUEUE_ITEM Item; @@ -172,20 +173,17 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, NTSTATUS Status; HANDLE InstanceKey; ULONG RequiredLength; - UNICODE_STRING ValueName, ServiceName; + UNICODE_STRING ValueName, ServiceLongName, ServiceName; WCHAR HardwareId[256]; PWCHAR IfString; ULONG IdLength; + ULONG LegacyValue; DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n", - DeviceObject, DeviceObject ? *DeviceObject : NULL); + DeviceObject, DeviceObject ? *DeviceObject : NULL); - /* Create the service name (eg. ACPI_HAL) */ - ServiceName.Buffer = DriverObject->DriverName.Buffer + - sizeof(DRIVER_ROOT_NAME) / sizeof(WCHAR) - 1; - ServiceName.Length = DriverObject->DriverName.Length - - sizeof(DRIVER_ROOT_NAME) + sizeof(WCHAR); - ServiceName.MaximumLength = ServiceName.Length; + ServiceLongName = DriverObject->DriverExtension->ServiceKeyName; + ServiceName = ServiceLongName; /* If the interface type is unknown, treat it as internal */ if (LegacyBusType == InterfaceTypeUndefined) @@ -198,6 +196,42 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, if (!IfString) return STATUS_INVALID_PARAMETER; + /* + * Drivers that have been created via a direct IoCreateDriver() call + * have their ServiceKeyName set to \Driver\DriverName. We need to + * strip everything up to the last path separator and keep what remains. + */ + if (DriverObject->Flags & DRVO_BUILTIN_DRIVER) + { + /* + * Find the last path separator. + * NOTE: Since ServiceName is not necessarily NULL-terminated, + * we cannot use wcsrchr(). + */ + if (ServiceName.Buffer && ServiceName.Length >= sizeof(WCHAR)) + { + ValueName.Length = 1; + ValueName.Buffer = ServiceName.Buffer + (ServiceName.Length / sizeof(WCHAR)) - 1; + + while ((ValueName.Buffer > ServiceName.Buffer) && (*ValueName.Buffer != L'\\')) + { + --ValueName.Buffer; + ++ValueName.Length; + } + if (*ValueName.Buffer == L'\\') + { + ++ValueName.Buffer; + --ValueName.Length; + } + ValueName.Length *= sizeof(WCHAR); + + /* Shorten the string */ + ServiceName.MaximumLength -= (ServiceName.Length - ValueName.Length); + ServiceName.Length = ValueName.Length; + ServiceName.Buffer = ValueName.Buffer; + } + } + /* We use the caller's PDO if they supplied one */ if (DeviceObject && *DeviceObject) { @@ -222,7 +256,6 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, Pdo, NULL, &DeviceNode); - if (!NT_SUCCESS(Status)) { DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status); @@ -231,7 +264,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, /* We're enumerated already */ IopDeviceNodeSetFlag(DeviceNode, DNF_ENUMERATED); - + /* We don't call AddDevice for devices reported this way */ IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED); @@ -251,11 +284,27 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent); /* Open a handle to the instance path key */ - /* REG_OPTION_VOLATILE is a HACK!!! */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_VOLATILE, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey); if (!NT_SUCCESS(Status)) return Status; + /* Save the driver name */ + RtlInitUnicodeString(&ValueName, L"Service"); + Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_SZ, ServiceLongName.Buffer, ServiceLongName.Length + sizeof(UNICODE_NULL)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write the Service name value: 0x%x\n", Status); + } + + /* Report as non-legacy driver */ + RtlInitUnicodeString(&ValueName, L"Legacy"); + LegacyValue = 0; + Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write the Legacy value: 0x%x\n", Status); + } + /* Add DETECTEDInterfaceType\DriverName */ IdLength = 0; IdLength += swprintf(&HardwareId[IdLength], @@ -278,33 +327,33 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_MULTI_SZ, HardwareId, IdLength * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { - DPRINT("Failed to write the compatible IDs: 0x%x\n", Status); - ZwClose(InstanceKey); - return Status; + DPRINT("Failed to write the compatible IDs: 0x%x\n", Status); + ZwClose(InstanceKey); + return Status; } /* Add a hardware ID if the driver didn't report one */ RtlInitUnicodeString(&ValueName, L"HardwareID"); if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND) { - /* Just use our most specific compatible ID */ - IdLength = 0; - IdLength += swprintf(&HardwareId[IdLength], - L"DETECTED%ls\\%wZ", - IfString, - &ServiceName); - IdLength++; - - HardwareId[IdLength++] = UNICODE_NULL; - - /* Write the value to the registry */ - Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_MULTI_SZ, HardwareId, IdLength * sizeof(WCHAR)); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed to write the hardware ID: 0x%x\n", Status); - ZwClose(InstanceKey); - return Status; - } + /* Just use our most specific compatible ID */ + IdLength = 0; + IdLength += swprintf(&HardwareId[IdLength], + L"DETECTED%ls\\%wZ", + IfString, + &ServiceName); + IdLength++; + + HardwareId[IdLength++] = UNICODE_NULL; + + /* Write the value to the registry */ + Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_MULTI_SZ, HardwareId, IdLength * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write the hardware ID: 0x%x\n", Status); + ZwClose(InstanceKey); + return Status; + } } /* Assign the resources to the device node */ @@ -313,10 +362,10 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, /* Set appropriate flags */ if (DeviceNode->BootResources) - IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG); + IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG); if (!DeviceNode->ResourceRequirements && !DeviceNode->BootResources) - IopDeviceNodeSetFlag(DeviceNode, DNF_NO_RESOURCE_REQUIRED); + IopDeviceNodeSetFlag(DeviceNode, DNF_NO_RESOURCE_REQUIRED); /* Write the resource information to the registry */ IopSetDeviceInstanceData(InstanceKey, DeviceNode); @@ -324,15 +373,15 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, /* If the caller didn't get the resources assigned for us, do it now */ if (!ResourceAssigned) { - Status = IopAssignDeviceResources(DeviceNode); - - /* See if we failed */ - if (!NT_SUCCESS(Status)) - { - DPRINT("Assigning resources failed: 0x%x\n", Status); - ZwClose(InstanceKey); - return Status; - } + Status = IopAssignDeviceResources(DeviceNode); + + /* See if we failed */ + if (!NT_SUCCESS(Status)) + { + DPRINT("Assigning resources failed: 0x%x\n", Status); + ZwClose(InstanceKey); + return Status; + } } /* Close the instance key handle */ @@ -350,7 +399,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, &DeviceNode->InstancePath); - DPRINT1("Reported device: %S (%wZ)\n", HardwareId, &DeviceNode->InstancePath); + DPRINT("Reported device: %S (%wZ)\n", HardwareId, &DeviceNode->InstancePath); /* Return the PDO */ if (DeviceObject) *DeviceObject = Pdo; @@ -429,7 +478,7 @@ IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject, /* Check for valid PDO */ if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)) { - KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0); + KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)PhysicalDeviceObject, 0, 0); } /* FileObject must be null. PnP will fill in it */ @@ -480,7 +529,7 @@ IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, /* Check for valid PDO */ if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)) { - KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0); + KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)PhysicalDeviceObject, 0, 0); } /* FileObject must be null. PnP will fill in it */ @@ -509,7 +558,7 @@ IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, Item->PhysicalDeviceObject = PhysicalDeviceObject; Item->Callback = Callback; Item->Context = Context; - ExInitializeWorkItem(&(Item->WorkItem), (PWORKER_THREAD_ROUTINE)IopReportTargetDeviceChangeAsyncWorker, Item); + ExInitializeWorkItem(&(Item->WorkItem), IopReportTargetDeviceChangeAsyncWorker, Item); /* Finally, queue the item, our work here is done */ ExQueueWorkItem(&(Item->WorkItem), DelayedWorkQueue);