[NTOS] Remove some hacks that are not needed anymore, since a real registry hive...
[reactos.git] / ntoskrnl / io / pnpmgr / pnpreport.c
index 206fccf..1ef595b 100644 (file)
@@ -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);
@@ -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);