Detect devices using the NULL driver, and set the STARTED flag
[reactos.git] / reactos / ntoskrnl / io / pnpmgr.c
index bc30f00..064eb7f 100644 (file)
@@ -322,13 +322,13 @@ IoGetDeviceProperty(
         *ResultLength = ValueInformation->DataLength;
         ZwClose(KeyHandle);
 
-        if (ValueInformation->DataLength > BufferLength)
-          Status = STATUS_BUFFER_TOO_SMALL;
-
         if (!NT_SUCCESS(Status))
         {
           ExFreePool(ValueInformation);
-          return Status;
+          if (Status == STATUS_BUFFER_OVERFLOW)
+            return STATUS_BUFFER_TOO_SMALL;
+          else
+            return Status;
         }
 
         /* FIXME: Verify the value (NULL-terminated, correct format). */
@@ -437,7 +437,7 @@ IoOpenDeviceRegistryKey(
       L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
    static WCHAR ClassKeyName[] = L"Control\\Class\\";
    static WCHAR EnumKeyName[] = L"Enum\\";
-   static WCHAR DeviceParametersKeyName[] = L"Device Parameters\\";
+   static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
    ULONG KeyNameLength;
    LPWSTR KeyNameBuffer;
    UNICODE_STRING KeyName;
@@ -1406,21 +1406,29 @@ IopGetParentIdPrefix(
    {
       if (ParentIdPrefixInformation->Type != REG_SZ)
          Status = STATUS_UNSUCCESSFUL;
+      else
+      {
+         KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+         KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
+      }
       goto cleanup;
    }
    if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+   {
+      KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+      KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
       goto cleanup;
+   }
 
    /* 2. Create the ParentIdPrefix value */
-   currentByte = (PBYTE)DeviceNode->Parent;
-   for (i = 0; i < sizeof(DEVICE_NODE); i++, currentByte++)
+   currentByte = (PBYTE)DeviceNode->Parent->InstancePath.Buffer;
+   for (i = 0; i < DeviceNode->Parent->InstancePath.Length; i++, currentByte++)
       crc32 = (crc32 >> 8) ^ crc32Table[*currentByte ^ (crc32 & 0xff)];
    crc32 = ~crc32;
-   KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
-   swprintf(KeyValue.Buffer, L"%lx&%lx", DeviceNode->Parent->Level, crc32);
+   swprintf((PWSTR)ParentIdPrefixInformation->Data, L"%lx&%lx", DeviceNode->Parent->Level, crc32);
+   RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation->Data);
 
    /* 3. Try to write the ParentIdPrefix to registry */
-   RtlInitUnicodeString(&KeyValue, KeyValue.Buffer);
    Status = ZwSetValueKey(
       hKey, &ValueName,
       0, REG_SZ,
@@ -1431,8 +1439,6 @@ cleanup:
    if (NT_SUCCESS(Status))
    {
       /* Duplicate the string to return it */
-      KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
-      KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
       Status = RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &KeyValue, ParentIdPrefix);
    }
    ExFreePool(ParentIdPrefixInformation);
@@ -1916,9 +1922,11 @@ IopActionConfigureChildServices(
   PDEVICE_NODE DeviceNode,
   PVOID Context)
 {
-   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+   RTL_QUERY_REGISTRY_TABLE QueryTable[3];
    PDEVICE_NODE ParentDeviceNode;
    PUNICODE_STRING Service;
+   UNICODE_STRING ClassGUID;
+   UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
    NTSTATUS Status;
 
    DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context);
@@ -1963,11 +1971,19 @@ IopActionConfigureChildServices(
 
       RtlZeroMemory(QueryTable, sizeof(QueryTable));
       RtlInitUnicodeString(Service, NULL);
+      RtlInitUnicodeString(&ClassGUID, NULL);
 
       QueryTable[0].Name = L"Service";
       QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
       QueryTable[0].EntryContext = Service;
 
+      QueryTable[1].Name = L"ClassGUID";
+      QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+      QueryTable[1].EntryContext = &ClassGUID;
+      QueryTable[1].DefaultType = REG_SZ;
+      QueryTable[1].DefaultData = &NullString;
+      QueryTable[1].DefaultLength = 0;
+
       RtlAppendUnicodeToString(&RegKey, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
       RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath);
 
@@ -1987,6 +2003,15 @@ IopActionConfigureChildServices(
       if (Service->Buffer == NULL)
       {
          IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
+
+         if (ClassGUID.Length != 0)
+         {
+            /* Device has a ClassGUID value, but no Service value.
+             * Suppose it is using the NULL driver, so state the
+             * device is started */
+            DPRINT("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
+            IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
+         }
          return STATUS_SUCCESS;
       }