* Sync up to trunk head (r64921).
[reactos.git] / ntoskrnl / io / iomgr / driver.c
index d3e749b..e0e3bb9 100644 (file)
@@ -90,14 +90,12 @@ IopDeleteDriver(IN PVOID ObjectBody)
         ExFreePool(DriverObject->DriverName.Buffer);
     }
 
-#if 0 /* See a bit of hack in IopCreateDriver */
     /* Check if it has a service key name */
     if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
     {
         /* Free it */
         ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
     }
-#endif
 }
 
 NTSTATUS FASTCALL
@@ -312,14 +310,8 @@ IopLoadServiceModule(
    HANDLE CCSKey, ServiceKey;
    PVOID BaseAddress;
 
-   DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
-
-   /* FIXME: This check may be removed once the bug is fixed */
-   if (ServiceName->Buffer == NULL)
-   {
-       DPRINT1("If you see this, please report to Fireball or hpoussin!\n");
-      return STATUS_UNSUCCESSFUL;
-   }
+    ASSERT(ServiceName->Length);
+    DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
 
    if (ExpInTextModeSetup)
    {
@@ -340,7 +332,8 @@ IopLoadServiceModule(
        Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
        if (!NT_SUCCESS(Status))
        {
-           DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+           DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n",
+                   &CCSName, Status);
            return Status;
        }
 
@@ -348,7 +341,8 @@ IopLoadServiceModule(
        Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
        if (!NT_SUCCESS(Status))
        {
-           DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+           DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n",
+                   ServiceName, Status);
            ZwClose(CCSKey);
            return Status;
        }
@@ -514,6 +508,7 @@ IopInitializeDriverModule(
        DriverName.Length > 0 ? &DriverName : NULL,
        DriverEntry,
        &RegistryKey,
+       ServiceName,
        ModuleObject,
        &Driver);
    RtlFreeUnicodeString(&RegistryKey);
@@ -557,6 +552,10 @@ IopAttachFilterDriversCallback(
    PDRIVER_OBJECT DriverObject;
    NTSTATUS Status;
 
+   /* No filter value present */
+   if (ValueType == REG_NONE)
+       return STATUS_SUCCESS;
+
    for (Filters = ValueData;
         ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
         *Filters != 0;
@@ -576,18 +575,21 @@ IopAttachFilterDriversCallback(
            /* Load and initialize the filter driver */
            Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
            if (!NT_SUCCESS(Status))
-               continue;
+               return Status;
 
            Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
                                               FALSE, &DriverObject);
            if (!NT_SUCCESS(Status))
-               continue;
+               return Status;
        }
 
        Status = IopInitializeDevice(DeviceNode, DriverObject);
 
        /* Remove extra reference */
        ObDereferenceObject(DriverObject);
+
+       if (!NT_SUCCESS(Status))
+           return Status;
    }
 
    return STATUS_SUCCESS;
@@ -643,14 +645,23 @@ IopAttachFilterDrivers(
      QueryTable[0].Name = L"LowerFilters";
    else
      QueryTable[0].Name = L"UpperFilters";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+   QueryTable[0].Flags = 0;
+   QueryTable[0].DefaultType = REG_NONE;
 
-   RtlQueryRegistryValues(
+   Status = RtlQueryRegistryValues(
       RTL_REGISTRY_HANDLE,
       (PWSTR)SubKey,
       QueryTable,
       DeviceNode,
       NULL);
+   if (!NT_SUCCESS(Status))
+   {
+       DPRINT1("Failed to load device %s filters: %08X\n",
+         Lower ? "lower" : "upper", Status);
+       ZwClose(SubKey);
+       ZwClose(EnumRootKey);
+       return Status;
+   }
 
    /*
     * Now get the class GUID
@@ -694,9 +705,10 @@ IopAttachFilterDrivers(
            &Class, KEY_READ);
        if (!NT_SUCCESS(Status))
        {
+           /* It's okay if there's no class key */
            DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
            ZwClose(EnumRootKey);
-           return Status;
+           return STATUS_SUCCESS;
        }
 
       QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
@@ -705,9 +717,10 @@ IopAttachFilterDrivers(
       else
          QueryTable[0].Name = L"UpperFilters";
       QueryTable[0].EntryContext = NULL;
-      QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+      QueryTable[0].Flags = 0;
+      QueryTable[0].DefaultType = REG_NONE;
 
-      RtlQueryRegistryValues(
+      Status = RtlQueryRegistryValues(
          RTL_REGISTRY_HANDLE,
          (PWSTR)SubKey,
          QueryTable,
@@ -717,6 +730,15 @@ IopAttachFilterDrivers(
       /* Clean up */
       ZwClose(SubKey);
       ZwClose(EnumRootKey);
+
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("Failed to load class %s filters: %08X\n",
+            Lower ? "lower" : "upper", Status);
+         ZwClose(SubKey);
+         ZwClose(EnumRootKey);
+         return Status;
+      }
    }
 
    return STATUS_SUCCESS;
@@ -818,14 +840,16 @@ LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
 NTSTATUS
 NTAPI
 INIT_FUNCTION
-IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
 {
     PDEVICE_NODE DeviceNode;
     PDRIVER_OBJECT DriverObject;
     NTSTATUS Status;
     PWCHAR FileNameWithoutPath;
     LPWSTR FileExtension;
-    PUNICODE_STRING ModuleName = &LdrEntry->BaseDllName;
+    PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
+    PLDR_DATA_TABLE_ENTRY LdrEntry;
+    PLIST_ENTRY NextEntry;
     UNICODE_STRING ServiceName;
 
    /*
@@ -869,6 +893,22 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
       return(Status);
    }
 
+   /* Lookup the new Ldr entry in PsLoadedModuleList */
+   NextEntry = PsLoadedModuleList.Flink;
+   while (NextEntry != &PsLoadedModuleList)
+   {
+      LdrEntry = CONTAINING_RECORD(NextEntry,
+                                   LDR_DATA_TABLE_ENTRY,
+                                   InLoadOrderLinks);
+      if (RtlEqualUnicodeString(ModuleName, &LdrEntry->BaseDllName, TRUE))
+      {
+            break;
+      }
+
+      NextEntry = NextEntry->Flink;
+   }
+   NT_ASSERT(NextEntry != &PsLoadedModuleList);
+
    /*
     * Initialize the driver
     */
@@ -1432,6 +1472,7 @@ NTAPI
 IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
                 IN PDRIVER_INITIALIZE InitializationFunction,
                 IN PUNICODE_STRING RegistryPath,
+                IN PCUNICODE_STRING ServiceName,
                 PLDR_DATA_TABLE_ENTRY ModuleObject,
                 OUT PDRIVER_OBJECT *pDriverObject)
 {
@@ -1503,9 +1544,9 @@ try_again:
     }
 
     /* Set up the service key name buffer */
-    ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool,
-                                                  LocalDriverName.Length +
-                                                  sizeof(WCHAR),
+    ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
+    ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                                  ServiceKeyName.MaximumLength,
                                                   TAG_IO);
     if (!ServiceKeyName.Buffer)
     {
@@ -1515,21 +1556,26 @@ try_again:
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    /* Fill out the key data and copy the buffer */
-    ServiceKeyName.Length = LocalDriverName.Length;
-    ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength;
-    RtlCopyMemory(ServiceKeyName.Buffer,
-                  LocalDriverName.Buffer,
-                  LocalDriverName.Length);
-
-    /* Null-terminate it and set it */
-    ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+    /* Copy the name and set it in the driver extension */
+    RtlCopyUnicodeString(&ServiceKeyName,
+                         ServiceName);
     DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
 
-    /* Also store it in the Driver Object. This is a bit of a hack. */
-    RtlCopyMemory(&DriverObject->DriverName,
-                  &ServiceKeyName,
-                  sizeof(UNICODE_STRING));
+    /* Make a copy of the driver name to store in the driver object */
+    DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
+    DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                            DriverObject->DriverName.MaximumLength,
+                                                            TAG_IO);
+    if (!DriverObject->DriverName.Buffer)
+    {
+        /* Fail */
+        ObMakeTemporaryObject(DriverObject);
+        ObDereferenceObject(DriverObject);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    RtlCopyUnicodeString(&DriverObject->DriverName,
+                         &LocalDriverName);
 
     /* Add the Object and get its handle */
     Status = ObInsertObject(DriverObject,
@@ -1631,7 +1677,7 @@ IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
                IN PDRIVER_INITIALIZE InitializationFunction)
 {
    PDRIVER_OBJECT DriverObject;
-   return IopCreateDriver(DriverName, InitializationFunction, NULL, NULL, &DriverObject);
+   return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
 }
 
 /*