[NTOS:IO]
[reactos.git] / reactos / ntoskrnl / io / iomgr / driver.c
index ba23a12..e623d7b 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
@@ -208,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,
@@ -237,10 +235,12 @@ 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;
 
@@ -338,7 +338,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;
        }
 
@@ -346,7 +347,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;
        }
@@ -434,7 +436,7 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
 /*
  * IopInitializeDriverModule
  *
- * Initalize a loaded driver.
+ * Initialize a loaded driver.
  *
  * Parameters
  *    DeviceNode
@@ -512,6 +514,7 @@ IopInitializeDriverModule(
        DriverName.Length > 0 ? &DriverName : NULL,
        DriverEntry,
        &RegistryKey,
+       ServiceName,
        ModuleObject,
        &Driver);
    RtlFreeUnicodeString(&RegistryKey);
@@ -555,6 +558,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;
@@ -574,18 +581,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;
@@ -641,14 +651,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
@@ -692,9 +711,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;
@@ -703,9 +723,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,
@@ -715,6 +736,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;
@@ -795,6 +825,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 */
@@ -811,14 +846,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;
 
    /*
@@ -862,6 +899,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
     */
@@ -1160,7 +1213,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();
 
@@ -1184,7 +1237,7 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
    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;
 
@@ -1425,6 +1478,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)
 {
@@ -1445,7 +1499,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);
@@ -1496,9 +1550,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)
     {
@@ -1508,21 +1562,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,
@@ -1601,7 +1660,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 */
@@ -1624,7 +1683,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);
 }
 
 /*
@@ -1765,7 +1824,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;
     }
 
@@ -1815,169 +1874,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);
+    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;
 
-       /* Return success and signal the event */
-       LoadParams->Status = STATUS_SUCCESS;
-      (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-       return;
-   }
+    /* Check if it's an unload request */
+    if (LoadParams->DriverObject)
+    {
+        (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
 
-   RtlInitUnicodeString(&ImagePath, NULL);
+        /* Return success and signal the event */
+        LoadParams->Status = STATUS_SUCCESS;
+        KeSetEvent(&LoadParams->Event, 0, FALSE);
+        return;
+    }
 
-   /*
-    * Get the service name from the registry key name.
-    */
-   ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
+    RtlInitUnicodeString(&ImagePath, NULL);
 
-   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 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);
+    RtlInitUnicodeString(&ImagePath, NULL);
 
-   QueryTable[0].Name = L"Type";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-   QueryTable[0].EntryContext = &Type;
+    QueryTable[0].Name = L"Type";
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+    QueryTable[0].EntryContext = &Type;
 
-   QueryTable[1].Name = L"ImagePath";
-   QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[1].EntryContext = &ImagePath;
+    QueryTable[1].Name = L"ImagePath";
+    QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+    QueryTable[1].EntryContext = &ImagePath;
 
-   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;
-      (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);
+    Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
+        LoadParams->Status = Status;
+        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 */));
+    DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
+    DPRINT("Type: %lx\n", Type);
 
-   if (!NT_SUCCESS(Status))
-   {
-       /*
-        * Load the driver module
-        */
+    /*
+     * 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 */));
 
-       DPRINT("Loading module from %wZ\n", &ImagePath);
-       Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        /*
+         * Load the driver module
+         */
 
-       if (!NT_SUCCESS(Status))
-       {
-           DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
-           LoadParams->Status = Status;
-           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-           return;
-       }
+        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
-        */
-       Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
-       if (!NT_SUCCESS(Status))
-       {
-           DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
-           MmUnloadSystemImage(ModuleObject);
-           LoadParams->Status = Status;
-           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-           return;
-       }
+        /*
+         * 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;
+        }
 
-       IopDisplayLoadingMessage(&DeviceNode->ServiceName);
+        IopDisplayLoadingMessage(&DeviceNode->ServiceName);
 
-       Status = IopInitializeDriverModule(DeviceNode,
-                                          ModuleObject,
-                                          &DeviceNode->ServiceName,
-                                          (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
-                                           Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
-                                          &DriverObject);
-       if (!NT_SUCCESS(Status))
-       {
-           DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
-           MmUnloadSystemImage(ModuleObject);
-           IopFreeDeviceNode(DeviceNode);
-           LoadParams->Status = Status;
-           (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
-           return;
-       }
+        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;
+        }
 
-       /* Initialize and start device */
-       IopInitializeDevice(DeviceNode, DriverObject);
-       Status = IopStartDevice(DeviceNode);
-   }
-   else
-   {
-      DPRINT("DriverObject already exist in ObjectManager\n");
-      Status = STATUS_IMAGE_ALREADY_LOADED;
+        /* Initialize and start device */
+        IopInitializeDevice(DeviceNode, DriverObject);
+        Status = IopStartDevice(DeviceNode);
+    }
+    else
+    {
+        DPRINT("DriverObject already exist in ObjectManager\n");
+        Status = STATUS_IMAGE_ALREADY_LOADED;
 
-      /* IopGetDriverObject references the DriverObject, so dereference it */
-      ObDereferenceObject(DriverObject);
-   }
+        /* 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);
 }
 
 /*
@@ -2008,8 +2065,8 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
     PreviousMode = KeGetPreviousMode();
 
     /*
-    * Check security privileges
-    */
+     * Check security privileges
+     */
 
     /* FIXME: Uncomment when privileges will be correctly implemented. */
 #if 0