* Sync up to trunk head (r64921).
[reactos.git] / ntoskrnl / io / iomgr / driver.c
index 79b4ab7..e0e3bb9 100644 (file)
@@ -58,6 +58,11 @@ IopDeleteDriver(IN PVOID ObjectBody)
     PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
     PAGED_CODE();
 
+    DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
+
+    /* There must be no device objects remaining at this point */
+    ASSERT(!DriverObject->DeviceObject);
+
     /* Get the extension and loop them */
     DriverExtension = IoGetDrvObjExtension(DriverObject)->
                       ClientDriverExtension;
@@ -85,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
@@ -203,7 +206,7 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
     if (!KeLoaderBlock) return;
     RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE);
     snprintf(TextBuffer, sizeof(TextBuffer),
-            "%s%sSystem32\\Drivers\\%wZ%s\n",
+            "%s%sSystem32\\Drivers\\%wZ%s\r\n",
             KeLoaderBlock->ArcBootDeviceName,
             KeLoaderBlock->NtBootPathName,
             ServiceName,
@@ -232,13 +235,17 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
  *    The input image path isn't freed on error.
  */
 
-NTSTATUS FASTCALL
+NTSTATUS
+FASTCALL
 IopNormalizeImagePath(
-   IN OUT PUNICODE_STRING ImagePath,
-   IN PUNICODE_STRING ServiceName)
+   _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
+        PUNICODE_STRING ImagePath,
+   _In_ PUNICODE_STRING ServiceName)
 {
    UNICODE_STRING InputImagePath;
 
+   DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
+
    RtlCopyMemory(
       &InputImagePath,
       ImagePath,
@@ -273,6 +280,8 @@ IopNormalizeImagePath(
       ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
    }
 
+   DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
+
    return STATUS_SUCCESS;
 }
 
@@ -301,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)
    {
@@ -329,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;
        }
 
@@ -337,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;
        }
@@ -389,13 +394,17 @@ IopLoadServiceModule(
 
    if (ServiceStart >= 4)
    {
-      /* FIXME: Check if it is the right status code */
-      Status = STATUS_PLUGPLAY_NO_DEVICE;
+      /* We can't load this */
+      Status = STATUS_DRIVER_UNABLE_TO_LOAD;
    }
    else
    {
-      DPRINT("Loading module\n");
+      DPRINT("Loading module from %wZ\n", &ServiceImagePath);
       Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
+      if (NT_SUCCESS(Status))
+      {
+          IopDisplayLoadingMessage(ServiceName);
+      }
    }
 
    ExFreePool(ServiceImagePath.Buffer);
@@ -414,10 +423,14 @@ IopLoadServiceModule(
    return Status;
 }
 
+VOID
+NTAPI
+MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
+
 /*
  * IopInitializeDriverModule
  *
- * Initalize a loaded driver.
+ * Initialize a loaded driver.
  *
  * Parameters
  *    DeviceNode
@@ -495,6 +508,7 @@ IopInitializeDriverModule(
        DriverName.Length > 0 ? &DriverName : NULL,
        DriverEntry,
        &RegistryKey,
+       ServiceName,
        ModuleObject,
        &Driver);
    RtlFreeUnicodeString(&RegistryKey);
@@ -506,6 +520,8 @@ IopInitializeDriverModule(
       return Status;
    }
 
+   MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection);
+
    /* Set the driver as initialized */
    IopReadyDeviceObjects(Driver);
 
@@ -536,45 +552,44 @@ 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;
         Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
    {
       DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
+
       ServiceName.Buffer = Filters;
       ServiceName.MaximumLength =
-      ServiceName.Length = wcslen(Filters) * sizeof(WCHAR);
+      ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
 
-      /* Load and initialize the filter driver */
-      Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
-      if (Status != STATUS_IMAGE_ALREADY_LOADED)
-      {
-         if (!NT_SUCCESS(Status))
-            continue;
+       Status = IopGetDriverObject(&DriverObject,
+                                   &ServiceName,
+                                   FALSE);
+       if (!NT_SUCCESS(Status))
+       {
+           /* Load and initialize the filter driver */
+           Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
+           if (!NT_SUCCESS(Status))
+               return Status;
 
-         Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
-                                            FALSE, &DriverObject);
-         if (!NT_SUCCESS(Status))
-            continue;
-      }
-      else
-      {
-         /* get existing DriverObject pointer */
-         Status = IopGetDriverObject(
-            &DriverObject,
-            &ServiceName,
-            FALSE);
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT1("IopGetDriverObject() returned status 0x%08x!\n", Status);
-            continue;
-         }
-      }
+           Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
+                                              FALSE, &DriverObject);
+           if (!NT_SUCCESS(Status))
+               return Status;
+       }
 
-      Status = IopInitializeDevice(DeviceNode, DriverObject);
-      if (!NT_SUCCESS(Status))
-         continue;
+       Status = IopInitializeDevice(DeviceNode, DriverObject);
+
+       /* Remove extra reference */
+       ObDereferenceObject(DriverObject);
+
+       if (!NT_SUCCESS(Status))
+           return Status;
    }
 
    return STATUS_SUCCESS;
@@ -630,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
@@ -681,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;
@@ -692,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,
@@ -704,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;
@@ -784,6 +819,11 @@ LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
                                       &MissingApiName,
                                       &MissingDriverName,
                                       &LoadedImports);
+
+    /* Free the temporary buffer */
+    ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);
+
+    /* Check the result of the imports resolution */
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Return */
@@ -800,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;
 
    /*
@@ -836,7 +878,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
    FileExtension = wcsrchr(ServiceName.Buffer, '.');
    if (FileExtension != NULL)
    {
-      ServiceName.Length -= wcslen(FileExtension) * sizeof(WCHAR);
+      ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
       FileExtension[0] = 0;
    }
 
@@ -850,7 +892,22 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
       DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
       return(Status);
    }
-   DeviceNode->ServiceName = ServiceName;
+
+   /* 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
@@ -870,6 +927,9 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
       Status = IopStartDevice(DeviceNode);
    }
 
+   /* Remove extra reference from IopInitializeDriverModule */
+   ObDereferenceObject(DriverObject);
+
    return Status;
 }
 
@@ -931,6 +991,7 @@ IopInitializeBootDrivers(VOID)
     {
         /* Fail */
         IopFreeDeviceNode(DeviceNode);
+        ObDereferenceObject(DriverObject);
         return;
     }
 
@@ -940,6 +1001,7 @@ IopInitializeBootDrivers(VOID)
     {
         /* Fail */
         IopFreeDeviceNode(DeviceNode);
+        ObDereferenceObject(DriverObject);
         return;
     }
 
@@ -1145,7 +1207,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
    LPWSTR Start;
    BOOLEAN SafeToUnload = TRUE;
 
-   DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers);
+   DPRINT("IopUnloadDriver('%wZ', %u)\n", DriverServiceName, UnloadPnpDrivers);
 
    PAGED_CODE();
 
@@ -1165,11 +1227,11 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
     * Construct the driver object name
     */
 
-   ObjectName.Length = (wcslen(Start) + 8) * sizeof(WCHAR);
+   ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
    ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
    ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
    if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
-   wcscpy(ObjectName.Buffer, L"\\Driver\\");
+   wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME);
    memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
    ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0;
 
@@ -1251,7 +1313,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
     */
 
     /* Call the load/unload routine, depending on current process */
-   if (DriverObject->DriverUnload && DriverObject->DriverSection)
+   if (DriverObject->DriverUnload && DriverObject->DriverSection &&
+       (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
    {
       /* Loop through each device object of the driver
          and set DOE_UNLOAD_PENDING flag */
@@ -1281,6 +1344,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
          return STATUS_SUCCESS;
       }
 
+      DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
+
       /* Set the unload invoked flag */
       DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
 
@@ -1320,6 +1385,8 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
    }
    else
    {
+      DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
+
       /* Dereference one time (refd inside this function) */
       ObDereferenceObject(DriverObject);
 
@@ -1405,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)
 {
@@ -1425,7 +1493,7 @@ try_again:
     {
         /* Create a random name and set up the string*/
         NameLength = (USHORT)swprintf(NameBuffer,
-                                      L"\\Driver\\%08u",
+                                      DRIVER_ROOT_NAME L"%08u",
                                       KeTickCount);
         LocalDriverName.Length = NameLength * sizeof(WCHAR);
         LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
@@ -1463,7 +1531,7 @@ try_again:
     RtlZeroMemory(DriverObject, ObjectSize);
     DriverObject->Type = IO_TYPE_DRIVER;
     DriverObject->Size = sizeof(DRIVER_OBJECT);
-    DriverObject->Flags = DRVO_LEGACY_DRIVER;//DRVO_BUILTIN_DRIVER;
+    DriverObject->Flags = DRVO_LEGACY_DRIVER;
     DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
     DriverObject->DriverExtension->DriverObject = DriverObject;
     DriverObject->DriverInit = InitializationFunction;
@@ -1476,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)
     {
@@ -1488,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,
@@ -1529,6 +1602,10 @@ try_again:
                                        KernelMode,
                                        (PVOID*)&DriverObject,
                                        NULL);
+
+    /* Close the extra handle */
+    ZwClose(hDriver);
+
     if (!NT_SUCCESS(Status))
     {
         /* Fail */
@@ -1537,9 +1614,6 @@ try_again:
         return Status;
     }
 
-    /* Close the extra handle */
-    ZwClose(hDriver);
-
     DriverObject->HardwareDatabase = &IopHardwareDatabaseKey;
     DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
     DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
@@ -1555,6 +1629,7 @@ try_again:
         DriverObject->DriverSection = NULL;
         ObMakeTemporaryObject(DriverObject);
         ObDereferenceObject(DriverObject);
+        return Status;
     }
     else
     {
@@ -1562,6 +1637,10 @@ try_again:
         *pDriverObject = DriverObject;
     }
 
+    /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
+     * Other parts of the I/O manager depend on this behavior */
+    if (!DriverObject->DeviceObject) DriverObject->Flags &= ~DRVO_LEGACY_DRIVER;
+
     /* Loop all Major Functions */
     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
     {
@@ -1575,7 +1654,7 @@ try_again:
         if (!DriverObject->MajorFunction[i])
         {
             /* Print a warning in the debug log */
-            DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%d] to NULL!\n",
+            DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
                     &DriverObject->DriverName, i);
 
             /* Fix it up */
@@ -1598,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);
 }
 
 /*
@@ -1739,7 +1818,7 @@ IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
     if (!Inserted)
     {
         /* Free the entry and fail */
-        ExFreePool(NewDriverExtension);
+        ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
         return STATUS_OBJECT_NAME_COLLISION;
     }
 
@@ -1789,187 +1868,167 @@ IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
 VOID NTAPI
 IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
 {
-   RTL_QUERY_REGISTRY_TABLE QueryTable[3];
-   UNICODE_STRING ImagePath;
-   UNICODE_STRING ServiceName;
-   NTSTATUS Status;
-   ULONG Type;
-   PDEVICE_NODE DeviceNode;
-   PDRIVER_OBJECT DriverObject;
-   PLDR_DATA_TABLE_ENTRY ModuleObject;
-   PVOID BaseAddress;
-   WCHAR *cur;
-
-   /* Check if it's an unload request */
-   if (LoadParams->DriverObject)
-   {
-       (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
-
-       /* Return success and signal the event */
-       LoadParams->Status = STATUS_SUCCESS;
-      (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-       return;
-   }
+    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+    UNICODE_STRING ImagePath;
+    UNICODE_STRING ServiceName;
+    NTSTATUS Status;
+    ULONG Type;
+    PDEVICE_NODE DeviceNode;
+    PDRIVER_OBJECT DriverObject;
+    PLDR_DATA_TABLE_ENTRY ModuleObject;
+    PVOID BaseAddress;
+    WCHAR *cur;
 
-   RtlInitUnicodeString(&ImagePath, NULL);
+    /* Check if it's an unload request */
+    if (LoadParams->DriverObject)
+    {
+        (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
 
-   /*
-    * Get the service name from the registry key name.
-    */
-   ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
+        /* Return success and signal the event */
+        LoadParams->Status = STATUS_SUCCESS;
+        KeSetEvent(&LoadParams->Event, 0, FALSE);
+        return;
+    }
 
-   ServiceName = *LoadParams->ServiceName;
-   cur = LoadParams->ServiceName->Buffer +
-       (LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1;
-   while (LoadParams->ServiceName->Buffer != cur)
-   {
-      if(*cur == L'\\')
-      {
-         ServiceName.Buffer = cur + 1;
-         ServiceName.Length = LoadParams->ServiceName->Length -
-                              (USHORT)((ULONG_PTR)ServiceName.Buffer -
-                                       (ULONG_PTR)LoadParams->ServiceName->Buffer);
-         break;
-      }
-      cur--;
-   }
+    RtlInitUnicodeString(&ImagePath, NULL);
 
-   IopDisplayLoadingMessage(&ServiceName);
+    /*
+     * Get the service name from the registry key name.
+     */
+    ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
+
+    ServiceName = *LoadParams->ServiceName;
+    cur = LoadParams->ServiceName->Buffer +
+         (LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1;
+    while (LoadParams->ServiceName->Buffer != cur)
+    {
+        if (*cur == L'\\')
+        {
+            ServiceName.Buffer = cur + 1;
+            ServiceName.Length = LoadParams->ServiceName->Length -
+                                 (USHORT)((ULONG_PTR)ServiceName.Buffer -
+                                          (ULONG_PTR)LoadParams->ServiceName->Buffer);
+            break;
+        }
+        cur--;
+    }
 
-   /*
+    /*
     * Get service type.
     */
 
-   RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+    RtlZeroMemory(&QueryTable, sizeof(QueryTable));
 
-   RtlInitUnicodeString(&ImagePath, NULL);
-
-   QueryTable[0].Name = L"Type";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-   QueryTable[0].EntryContext = &Type;
+    RtlInitUnicodeString(&ImagePath, NULL);
 
-   QueryTable[1].Name = L"ImagePath";
-   QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[1].EntryContext = &ImagePath;
+    QueryTable[0].Name = L"Type";
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+    QueryTable[0].EntryContext = &Type;
 
-   Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-      LoadParams->ServiceName->Buffer, QueryTable, NULL, NULL);
+    QueryTable[1].Name = L"ImagePath";
+    QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+    QueryTable[1].EntryContext = &ImagePath;
 
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
-      if (ImagePath.Buffer)
-         ExFreePool(ImagePath.Buffer);
-      LoadParams->Status = Status;
-      (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-      return;
-   }
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+                                    LoadParams->ServiceName->Buffer,
+                                    QueryTable, NULL, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+        if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
+        LoadParams->Status = Status;
+        KeSetEvent(&LoadParams->Event, 0, FALSE);
+        return;
+    }
 
-   /*
+    /*
     * Normalize the image path for all later processing.
     */
 
-   Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
-      LoadParams->Status = Status;
-      (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-      return;
-   }
-
-   DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
-   DPRINT("Type: %lx\n", Type);
-
-   /*
-    * Create device node
-    */
-
-   /* Use IopRootDeviceNode for now */
-   Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
-      LoadParams->Status = Status;
-      (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-      return;
-   }
-
-   /* Get existing DriverObject pointer (in case the driver has
-      already been loaded and initialized) */
-   Status = IopGetDriverObject(
-       &DriverObject,
-       &ServiceName,
-       (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
-        Type == 8 /* SERVICE_RECOGNIZER_DRIVER */));
-
-   if (!NT_SUCCESS(Status))
-   {
-       /*
-        * Load the driver module
-        */
+    Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
+        LoadParams->Status = Status;
+        KeSetEvent(&LoadParams->Event, 0, FALSE);
+        return;
+    }
 
-       Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+    DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
+    DPRINT("Type: %lx\n", Type);
 
-       if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED)
-       {
-           DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
-           IopFreeDeviceNode(DeviceNode);
-           LoadParams->Status = Status;
-           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-           return;
-       }
+    /*
+     * Get existing DriverObject pointer (in case the driver
+     * has already been loaded and initialized).
+     */
+    Status = IopGetDriverObject(&DriverObject,
+                                &ServiceName,
+                                (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
+                                 Type == 8 /* SERVICE_RECOGNIZER_DRIVER */));
 
-       /*
-        * Set a service name for the device node
-        */
+    if (!NT_SUCCESS(Status))
+    {
+        /*
+         * Load the driver module
+         */
 
-       RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer);
+        DPRINT("Loading module from %wZ\n", &ImagePath);
+        Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
+            LoadParams->Status = Status;
+            KeSetEvent(&LoadParams->Event, 0, FALSE);
+            return;
+        }
 
-       /*
-        * Initialize the driver module if it's loaded for the first time
-        */
-       if (Status != STATUS_IMAGE_ALREADY_LOADED)
-       {
-           Status = IopInitializeDriverModule(
-               DeviceNode,
-               ModuleObject,
-               &DeviceNode->ServiceName,
-               (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
-               Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
-               &DriverObject);
+        /*
+         * Initialize the driver module if it's loaded for the first time
+         */
+        Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+            MmUnloadSystemImage(ModuleObject);
+            LoadParams->Status = Status;
+            KeSetEvent(&LoadParams->Event, 0, FALSE);
+            return;
+        }
 
-           if (!NT_SUCCESS(Status))
-           {
-               DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status);
-               MmUnloadSystemImage(ModuleObject);
-               IopFreeDeviceNode(DeviceNode);
-               LoadParams->Status = Status;
-               (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-               return;
-           }
-       }
+        IopDisplayLoadingMessage(&DeviceNode->ServiceName);
 
-       /* Initialize and start device */
-       IopInitializeDevice(DeviceNode, DriverObject);
-       Status = IopStartDevice(DeviceNode);
-   }
-   else
-   {
-      DPRINT("DriverObject already exist in ObjectManager\n");
+        Status = IopInitializeDriverModule(DeviceNode,
+                                           ModuleObject,
+                                           &DeviceNode->ServiceName,
+                                           (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
+                                            Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
+                                           &DriverObject);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
+            MmUnloadSystemImage(ModuleObject);
+            IopFreeDeviceNode(DeviceNode);
+            LoadParams->Status = Status;
+            KeSetEvent(&LoadParams->Event, 0, FALSE);
+            return;
+        }
 
-      /* IopGetDriverObject references the DriverObject, so dereference it */
-      ObDereferenceObject(DriverObject);
+        /* Initialize and start device */
+        IopInitializeDevice(DeviceNode, DriverObject);
+        Status = IopStartDevice(DeviceNode);
+    }
+    else
+    {
+        DPRINT("DriverObject already exist in ObjectManager\n");
+        Status = STATUS_IMAGE_ALREADY_LOADED;
 
-      /* Free device node since driver loading failed */
-      IopFreeDeviceNode(DeviceNode);
-   }
+        /* IopGetDriverObject references the DriverObject, so dereference it */
+        ObDereferenceObject(DriverObject);
+    }
 
-   /* Pass status to the caller and signal the event */
-   LoadParams->Status = Status;
-   (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+    /* Pass status to the caller and signal the event */
+    LoadParams->Status = Status;
+    KeSetEvent(&LoadParams->Event, 0, FALSE);
 }
 
 /*
@@ -2000,8 +2059,8 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
     PreviousMode = KeGetPreviousMode();
 
     /*
-    * Check security privileges
-    */
+     * Check security privileges
+     */
 
     /* FIXME: Uncomment when privileges will be correctly implemented. */
 #if 0