Fix a debug message
[reactos.git] / reactos / ntoskrnl / io / pnpmgr.c
index dc45381..c1fca7e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pnpmgr.c,v 1.36 2004/10/11 18:36:20 navaraf Exp $
+/* $Id: pnpmgr.c,v 1.42 2004/10/22 18:34:11 ekohl Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -18,7 +18,7 @@ DEFINE_GUID(GUID_CLASS_COMPORT,          0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4
 DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
 #endif // DEFINE_GUID
 
-#define NDEBUG
+//#define NDEBUG
 #include <internal/debug.h>
 
 
@@ -77,8 +77,9 @@ IoGetDeviceProperty(
   PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
   ULONG Length;
   PVOID Data;
+  PWSTR Ptr;
 
-  DPRINT("IoGetDeviceProperty called\n");
+  DPRINT("IoGetDeviceProperty(%x %d)\n", DeviceObject, DeviceProperty);
 
   if (DeviceNode == NULL)
     return STATUS_INVALID_DEVICE_REQUEST;
@@ -140,6 +141,10 @@ IoGetDeviceProperty(
     case DevicePropertyDriverKeyName:
     case DevicePropertyManufacturer:
     case DevicePropertyFriendlyName:
+    case DevicePropertyHardwareID:
+    case DevicePropertyCompatibleIDs:
+    case DevicePropertyDeviceDescription:
+    case DevicePropertyLocationInformation:
       {
         LPWSTR RegistryPropertyName, KeyNameBuffer;
         UNICODE_STRING KeyName, ValueName;
@@ -161,18 +166,29 @@ IoGetDeviceProperty(
             RegistryPropertyName = L"Mfg"; break;
           case DevicePropertyFriendlyName:
             RegistryPropertyName = L"FriendlyName"; break;
+          case DevicePropertyHardwareID:
+            RegistryPropertyName = L"HardwareID"; break;
+          case DevicePropertyCompatibleIDs:
+            RegistryPropertyName = L"CompatibleIDs"; break;
+          case DevicePropertyDeviceDescription:
+            RegistryPropertyName = L"DeviceDesc"; break;
+          case DevicePropertyLocationInformation:
+            RegistryPropertyName = L"LocationInformation"; break;
           default:
             RegistryPropertyName = NULL; break;
         }
 
         KeyNameBuffer = ExAllocatePool(PagedPool,
           (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+       
+       DPRINT1("KeyNameBuffer: %x, value %S\n", 
+               KeyNameBuffer, RegistryPropertyName);
+
         if (KeyNameBuffer == NULL)
           return STATUS_INSUFFICIENT_RESOURCES;
 
         wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
         wcscat(KeyNameBuffer, DeviceNode->InstancePath.Buffer);
-        
         RtlInitUnicodeString(&KeyName, KeyNameBuffer);
         InitializeObjectAttributes(&ObjectAttributes, &KeyName,
                                    OBJ_CASE_INSENSITIVE, NULL, NULL);
@@ -218,12 +234,38 @@ IoGetDeviceProperty(
       }
 
     case DevicePropertyBootConfiguration:
+      Length = 0;
+      if (DeviceNode->BootResourceList->Count != 0)
+      {
+       Length = sizeof(CM_RESOURCE_LIST) +
+                ((DeviceNode->BootResourceList->Count - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+      }
+      Data = &DeviceNode->BootResourceList;
+      break;
+
+    /* FIXME: use a translated boot configuration instead */
     case DevicePropertyBootConfigurationTranslated:
-    case DevicePropertyCompatibleIDs:
-    case DevicePropertyDeviceDescription:
-    case DevicePropertyEnumeratorName: 
-    case DevicePropertyHardwareID:
-    case DevicePropertyLocationInformation:
+      Length = 0;
+      if (DeviceNode->BootResourceList->Count != 0)
+      {
+       Length = sizeof(CM_RESOURCE_LIST) +
+                ((DeviceNode->BootResourceList->Count - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+      }
+      Data = &DeviceNode->BootResourceList;
+      break;
+
+    case DevicePropertyEnumeratorName:
+      Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
+      if (Ptr != NULL)
+      {
+       Length = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)DeviceNode->InstancePath.Buffer) + sizeof(WCHAR);
+      }
+      else
+      {
+       Length = 0;
+       Data = NULL;
+      }
+
     case DevicePropertyPhysicalDeviceObjectName:
       return STATUS_NOT_IMPLEMENTED;
 
@@ -236,6 +278,13 @@ IoGetDeviceProperty(
     return STATUS_BUFFER_TOO_SMALL;
   RtlCopyMemory(PropertyBuffer, Data, Length);
 
+  /* Terminate the string */
+  if (DeviceProperty == DevicePropertyEnumeratorName)
+  {
+    Ptr = (PWSTR)PropertyBuffer;
+    Ptr[(Length / sizeof(WCHAR)) - 1] = 0;
+  }
+
   return STATUS_SUCCESS;
 }
 
@@ -485,9 +534,9 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
     ExFreePool(DeviceNode->CmResourceList);
   }
 
-  if (DeviceNode->BootResourcesList)
+  if (DeviceNode->BootResourceList)
   {
-    ExFreePool(DeviceNode->BootResourcesList);
+    ExFreePool(DeviceNode->BootResourceList);
   }
 
   if (DeviceNode->ResourceRequirementsList)
@@ -495,18 +544,6 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
     ExFreePool(DeviceNode->ResourceRequirementsList);
   }
 
-  RtlFreeUnicodeString(&DeviceNode->DeviceID);
-
-  RtlFreeUnicodeString(&DeviceNode->InstanceID);
-
-  RtlFreeUnicodeString(&DeviceNode->HardwareIDs);
-
-  RtlFreeUnicodeString(&DeviceNode->CompatibleIDs);
-
-  RtlFreeUnicodeString(&DeviceNode->DeviceText);
-
-  RtlFreeUnicodeString(&DeviceNode->DeviceTextLocation);
-
   if (DeviceNode->BusInformation)
   {
     ExFreePool(DeviceNode->BusInformation);
@@ -535,22 +572,22 @@ IopInitiatePnpIrp(
 
   KeInitializeEvent(
     &Event,
-         NotificationEvent,
-         FALSE);
-
-  /* PNP IRPs are always initialized with a status code of
-     STATUS_NOT_IMPLEMENTED */
-  IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
-  IoStatusBlock->Information = 0;
+    NotificationEvent,
+    FALSE);
 
   Irp = IoBuildSynchronousFsdRequest(
     IRP_MJ_PNP,
     TopDeviceObject,
-         NULL,
-         0,
-         NULL,
-         &Event,
-         IoStatusBlock);
+    NULL,
+    0,
+    NULL,
+    &Event,
+    IoStatusBlock);
+
+  /* PNP IRPs are always initialized with a status code of
+     STATUS_NOT_IMPLEMENTED */
+  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+  Irp->IoStatus.Information = 0;
 
   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MinorFunction = MinorFunction;
@@ -692,7 +729,8 @@ IopTraverseDeviceTree(
 
 
 static NTSTATUS
-IopCreateDeviceKeyPath(PWSTR Path)
+IopCreateDeviceKeyPath(PWSTR Path,
+                      PHANDLE Handle)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   WCHAR KeyBuffer[MAX_PATH];
@@ -702,6 +740,8 @@ IopCreateDeviceKeyPath(PWSTR Path)
   PWCHAR Current;
   PWCHAR Next;
 
+  *Handle = NULL;
+
   if (_wcsnicmp(Path, L"\\Registry\\", 10) != 0)
     {
       return STATUS_INVALID_PARAMETER;
@@ -715,8 +755,8 @@ IopCreateDeviceKeyPath(PWSTR Path)
   Current = wcschr (Current, '\\') + 1;
   Current = wcschr (Current, '\\') + 1;
 
-  do
-   {
+  while (TRUE)
+    {
       Next = wcschr (Current, '\\');
       if (Next == NULL)
        {
@@ -748,16 +788,92 @@ IopCreateDeviceKeyPath(PWSTR Path)
          return Status;
        }
 
-      NtClose (KeyHandle);
-
-      if (Next != NULL)
+      if (Next == NULL)
        {
+         *Handle = KeyHandle;
+         return STATUS_SUCCESS;
+       }
+      else
+       {
+         NtClose (KeyHandle);
          *Next = L'\\';
        }
 
       Current = Next + 1;
     }
-   while (Next != NULL);
+
+  return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+IopSetDeviceInstanceData(HANDLE InstanceKey,
+                        PDEVICE_NODE DeviceNode)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING KeyName;
+  HANDLE LogConfKey;
+  ULONG ResCount;
+  ULONG ListSize;
+  NTSTATUS Status;
+
+  DPRINT("IopSetDeviceInstanceData() called\n");
+
+  /* Create the 'LogConf' key */
+  RtlInitUnicodeString(&KeyName,
+                      L"LogConf");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &KeyName,
+                            OBJ_CASE_INSENSITIVE,
+                            InstanceKey,
+                            NULL);
+  Status = NtCreateKey(&LogConfKey,
+                      KEY_ALL_ACCESS,
+                      &ObjectAttributes,
+                      0,
+                      NULL,
+                      0,
+                      NULL);
+  if (NT_SUCCESS(Status))
+  {
+    /* Set 'BootConfig' value */
+    if (DeviceNode->BootResourceList != NULL)
+    {
+      ResCount = DeviceNode->BootResourceList->Count;
+      if (ResCount != 0)
+      {
+       ListSize = sizeof(CM_RESOURCE_LIST) +
+                  ((ResCount - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+
+       RtlInitUnicodeString(&KeyName,
+                            L"BootConfig");
+       Status = NtSetValueKey(LogConfKey,
+                              &KeyName,
+                              0,
+                              REG_RESOURCE_LIST,
+                              &DeviceNode->BootResourceList,
+                              ListSize);
+      }
+    }
+
+    /* Set 'BasicConfigVector' value */
+    if (DeviceNode->ResourceRequirementsList != NULL &&
+       DeviceNode->ResourceRequirementsList->ListSize != 0)
+    {
+      RtlInitUnicodeString(&KeyName,
+                          L"BasicConfigVector");
+      Status = NtSetValueKey(LogConfKey,
+                            &KeyName,
+                            0,
+                            REG_RESOURCE_REQUIREMENTS_LIST,
+                            &DeviceNode->ResourceRequirementsList,
+                            DeviceNode->ResourceRequirementsList->ListSize);
+    }
+
+    NtClose(LogConfKey);
+  }
+
+  DPRINT("IopSetDeviceInstanceData() done\n");
 
   return STATUS_SUCCESS;
 }
@@ -796,6 +912,8 @@ IopActionInterrogateDeviceStack(
    PWSTR Ptr;
    USHORT Length;
    USHORT TotalLength;
+   HANDLE InstanceKey = NULL;
+   UNICODE_STRING ValueName;
 
    DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
    DPRINT("PDO %x\n", DeviceNode->Pdo);
@@ -840,9 +958,8 @@ IopActionInterrogateDeviceStack(
       &Stack);
    if (NT_SUCCESS(Status))
    {
-      RtlInitUnicodeString(
-         &DeviceNode->DeviceID,
-         (PWSTR)IoStatusBlock.Information);
+      /* Copy the device id string */
+      wcscpy(InstancePath, (PWSTR)IoStatusBlock.Information);
 
       /*
        * FIXME: Check for valid characters, if there is invalid characters
@@ -852,7 +969,6 @@ IopActionInterrogateDeviceStack(
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->DeviceID, NULL);
    }
 
    DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
@@ -865,9 +981,9 @@ IopActionInterrogateDeviceStack(
       &Stack);
    if (NT_SUCCESS(Status))
    {
-      RtlInitUnicodeString(
-      &DeviceNode->InstanceID,
-      (PWSTR)IoStatusBlock.Information);
+      /* Append the instance id string */
+      wcscat(InstancePath, L"\\");
+      wcscat(InstancePath, (PWSTR)IoStatusBlock.Information);
 
       /*
        * FIXME: Check for valid characters, if there is invalid characters
@@ -877,7 +993,71 @@ IopActionInterrogateDeviceStack(
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->InstanceID, NULL);
+   }
+
+   Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
+   if (NT_SUCCESS(Status))
+   {
+   }
+   else
+   {
+   }
+
+   if (!DeviceNode->CapabilityFlags->UniqueID)
+   {
+      DPRINT("Instance ID is not unique\n");
+      /* FIXME: Add information from parent bus driver to InstancePath */
+   }
+
+   if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool))
+   {
+      DPRINT("No resources\n");
+      /* FIXME: Cleanup and disable device */
+   }
+
+   DPRINT1("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
+
+   /*
+    * Create registry key for the instance id, if it doesn't exist yet
+    */
+   KeyBuffer = ExAllocatePool(
+      PagedPool,
+      (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+   wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+   wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
+   Status = IopCreateDeviceKeyPath(KeyBuffer,
+                                  &InstanceKey);
+   ExFreePool(KeyBuffer);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
+   }
+
+
+   if (DeviceNode->CapabilityFlags != NULL)
+   {
+      /* Set 'Capabilities' value */
+      RtlInitUnicodeString(&ValueName,
+                          L"Capabilities");
+      Status = NtSetValueKey(InstanceKey,
+                            &ValueName,
+                            0,
+                            REG_DWORD,
+                            (PVOID)((ULONG_PTR)&DeviceNode->CapabilityFlags + 4),
+                            sizeof(ULONG));
+
+      /* Set 'UINumber' value */
+      if (DeviceNode->CapabilityFlags->UINumber != (ULONG)-1)
+      {
+         RtlInitUnicodeString(&ValueName,
+                             L"UINumber");
+         Status = NtSetValueKey(InstanceKey,
+                               &ValueName,
+                               0,
+                               REG_DWORD,
+                               &DeviceNode->CapabilityFlags->UINumber,
+                               sizeof(ULONG));
+      }
    }
 
    DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
@@ -908,14 +1088,22 @@ IopActionInterrogateDeviceStack(
       DPRINT("TotalLength: %hu\n", TotalLength);
       DPRINT("\n");
 
-      DeviceNode->HardwareIDs.Length = TotalLength * sizeof(WCHAR);
-      DeviceNode->HardwareIDs.MaximumLength = DeviceNode->HardwareIDs.Length + sizeof(WCHAR);
-      DeviceNode->HardwareIDs.Buffer = (PWSTR)IoStatusBlock.Information;
+      RtlInitUnicodeString(&ValueName,
+                          L"HardwareID");
+      Status = NtSetValueKey(InstanceKey,
+                            &ValueName,
+                            0,
+                            REG_MULTI_SZ,
+                            (PVOID)IoStatusBlock.Information,
+                            (TotalLength + 1) * sizeof(WCHAR));
+      if (!NT_SUCCESS(Status))
+       {
+          DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+       }
    }
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->HardwareIDs, NULL);
    }
 
    DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
@@ -946,23 +1134,24 @@ IopActionInterrogateDeviceStack(
       DPRINT("TotalLength: %hu\n", TotalLength);
       DPRINT("\n");
 
-      DeviceNode->CompatibleIDs.Length = TotalLength * sizeof(WCHAR);
-      DeviceNode->CompatibleIDs.MaximumLength = DeviceNode->CompatibleIDs.Length + sizeof(WCHAR);
-      DeviceNode->CompatibleIDs.Buffer = (PWSTR)IoStatusBlock.Information;
+      RtlInitUnicodeString(&ValueName,
+                          L"CompatibleIDs");
+      Status = NtSetValueKey(InstanceKey,
+                            &ValueName,
+                            0,
+                            REG_MULTI_SZ,
+                            (PVOID)IoStatusBlock.Information,
+                            (TotalLength + 1) * sizeof(WCHAR));
+      if (!NT_SUCCESS(Status))
+       {
+          DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+       }
    }
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->CompatibleIDs, NULL);
    }
 
-   Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
-   if (NT_SUCCESS(Status))
-   {
-   }
-   else
-   {
-   }
 
    DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
 
@@ -975,14 +1164,22 @@ IopActionInterrogateDeviceStack(
       &Stack);
    if (NT_SUCCESS(Status))
    {
-      RtlInitUnicodeString(
-         &DeviceNode->DeviceText,
-         (PWSTR)IoStatusBlock.Information);
+      RtlInitUnicodeString(&ValueName,
+                          L"DeviceDesc");
+      Status = NtSetValueKey(InstanceKey,
+                            &ValueName,
+                            0,
+                            REG_SZ,
+                            (PVOID)IoStatusBlock.Information,
+                            (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+      if (!NT_SUCCESS(Status))
+       {
+          DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+       }
    }
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->DeviceText, NULL);
    }
 
    DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
@@ -996,14 +1193,23 @@ IopActionInterrogateDeviceStack(
       &Stack);
    if (NT_SUCCESS(Status))
    {
-      RtlInitUnicodeString(
-         &DeviceNode->DeviceTextLocation,
-         (PWSTR)IoStatusBlock.Information);
+      DPRINT("LocationInformation: %S\n", (PWSTR)IoStatusBlock.Information);
+      RtlInitUnicodeString(&ValueName,
+                          L"LocationInformation");
+      Status = NtSetValueKey(InstanceKey,
+                            &ValueName,
+                            0,
+                            REG_SZ,
+                            (PVOID)IoStatusBlock.Information,
+                            (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+      if (!NT_SUCCESS(Status))
+       {
+          DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+       }
    }
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      RtlInitUnicodeString(&DeviceNode->DeviceTextLocation, NULL);
    }
 
    DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
@@ -1033,14 +1239,14 @@ IopActionInterrogateDeviceStack(
       NULL);
    if (NT_SUCCESS(Status))
    {
-      DeviceNode->BootResourcesList =
+      DeviceNode->BootResourceList =
          (PCM_RESOURCE_LIST)IoStatusBlock.Information;
       DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
    }
    else
    {
       DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
-      DeviceNode->BootResourcesList = NULL;
+      DeviceNode->BootResourceList = NULL;
    }
 
    DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
@@ -1061,39 +1267,14 @@ IopActionInterrogateDeviceStack(
       DeviceNode->ResourceRequirementsList = NULL;
    }
 
-   /*
-    * Assemble the instance path for the device
-    */
 
-   wcscpy(InstancePath, DeviceNode->DeviceID.Buffer);
-   wcscat(InstancePath, L"\\");
-   wcscat(InstancePath, DeviceNode->InstanceID.Buffer);
-
-   if (!DeviceNode->CapabilityFlags->UniqueID)
+   if (InstanceKey != NULL)
    {
-      DPRINT("Instance ID is not unique\n");
-      /* FIXME: Add information from parent bus driver to InstancePath */
+      IopSetDeviceInstanceData(InstanceKey, DeviceNode);
    }
 
-   if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool))
-   {
-      DPRINT("No resources\n");
-      /* FIXME: Cleanup and disable device */
-   }
-
-   DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
-
-   /*
-    * Create registry key for the instance id, if it doesn't exist yet
-    */
+   NtClose(InstanceKey);
 
-   KeyBuffer = ExAllocatePool(
-      PagedPool,
-      (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
-   wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
-   wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
-   IopCreateDeviceKeyPath(KeyBuffer);
-   ExFreePool(KeyBuffer);
    DeviceNode->Flags |= DNF_PROCESSED;
 
    return STATUS_SUCCESS;