[NTOSKRNL]
[reactos.git] / ntoskrnl / io / iomgr / driver.c
index f273111..f33a22f 100644 (file)
@@ -239,6 +239,8 @@ IopNormalizeImagePath(
 {
    UNICODE_STRING InputImagePath;
 
+   DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
+
    RtlCopyMemory(
       &InputImagePath,
       ImagePath,
@@ -272,6 +274,8 @@ IopNormalizeImagePath(
       /* Free caller's string */
       ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
    }
+   DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
 
    return STATUS_SUCCESS;
 }
@@ -310,51 +314,65 @@ IopLoadServiceModule(
       return STATUS_UNSUCCESSFUL;
    }
 
-   /* Open CurrentControlSet */
-   RtlInitUnicodeString(&CCSName,
-                        L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
-   Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
-   if (!NT_SUCCESS(Status))
+   if (ExpInTextModeSetup)
    {
-       DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
-       return Status;
-   }
+       /* We have no registry, but luckily we know where all the drivers are */
 
-   /* Open service key */
-   Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
-   if (!NT_SUCCESS(Status))
-   {
-       DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
-       ZwClose(CCSKey);
-       return Status;
+       /* ServiceStart < 4 is all that matters */
+       ServiceStart = 0;
+
+       /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
+       ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0;
+       ServiceImagePath.Buffer = NULL;
    }
+   else
+   {
+       /* Open CurrentControlSet */
+       RtlInitUnicodeString(&CCSName,
+                            L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
+       Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
+       if (!NT_SUCCESS(Status))
+       {
+           DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+           return Status;
+       }
 
-   /*
-    * Get information about the service.
-    */
+       /* Open service key */
+       Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
+       if (!NT_SUCCESS(Status))
+       {
+           DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+           ZwClose(CCSKey);
+           return Status;
+       }
 
-   RtlZeroMemory(QueryTable, sizeof(QueryTable));
+       /*
+        * Get information about the service.
+        */
 
-   RtlInitUnicodeString(&ServiceImagePath, NULL);
+       RtlZeroMemory(QueryTable, sizeof(QueryTable));
 
-   QueryTable[0].Name = L"Start";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[0].EntryContext = &ServiceStart;
+       RtlInitUnicodeString(&ServiceImagePath, NULL);
 
-   QueryTable[1].Name = L"ImagePath";
-   QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[1].EntryContext = &ServiceImagePath;
+       QueryTable[0].Name = L"Start";
+       QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+       QueryTable[0].EntryContext = &ServiceStart;
 
-   Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
-      (PWSTR)ServiceKey, QueryTable, NULL, NULL);
+       QueryTable[1].Name = L"ImagePath";
+       QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+       QueryTable[1].EntryContext = &ServiceImagePath;
 
-   ZwClose(ServiceKey);
-   ZwClose(CCSKey);
+       Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+          (PWSTR)ServiceKey, QueryTable, NULL, NULL);
 
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
-      return Status;
+       ZwClose(ServiceKey);
+       ZwClose(CCSKey);
+
+       if (!NT_SUCCESS(Status))
+       {
+          DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
+          return Status;
+       }
    }
 
    /*
@@ -369,20 +387,24 @@ IopLoadServiceModule(
       return Status;
    }
 
-      /*
-       * Case for disabled drivers
-       */
-
-  if (ServiceStart >= 4)
-  {
-     /* FIXME: Check if it is the right status code */
-     Status = STATUS_PLUGPLAY_NO_DEVICE;
-  }
-  else
-  {
-     DPRINT("Loading module\n");
-     Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
-  }
+   /*
+    * Case for disabled drivers
+    */
+
+   if (ServiceStart >= 4)
+   {
+      /* FIXME: Check if it is the right status code */
+      Status = STATUS_PLUGPLAY_NO_DEVICE;
+   }
+   else
+   {
+      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);
 
@@ -530,7 +552,7 @@ IopAttachFilterDriversCallback(
       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);
@@ -822,7 +844,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;
    }
 
@@ -836,7 +858,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
       DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
       return(Status);
    }
-   DeviceNode->ServiceName = ServiceName;
 
    /*
     * Initialize the driver
@@ -1151,7 +1172,7 @@ 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;
@@ -1820,8 +1841,6 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
       cur--;
    }
 
-   IopDisplayLoadingMessage(&ServiceName);
-
    /*
     * Get service type.
     */
@@ -1868,21 +1887,6 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
    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(
@@ -1897,28 +1901,35 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
         * Load the driver module
         */
 
+       DPRINT("Loading module from %wZ\n", &ImagePath);
        Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
 
        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;
        }
 
-       /*
-        * Set a service name for the device node
-        */
-
-       RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer);
-
        /*
         * Initialize the driver module if it's loaded for the first time
         */
        if (Status != STATUS_IMAGE_ALREADY_LOADED)
        {
+           Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+
+           if (!NT_SUCCESS(Status))
+           {
+               DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+               MmUnloadSystemImage(ModuleObject);
+               LoadParams->Status = Status;
+               (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+               return;
+           }
+
+           IopDisplayLoadingMessage(&DeviceNode->ServiceName);
+
            Status = IopInitializeDriverModule(
                DeviceNode,
                ModuleObject,
@@ -1936,11 +1947,11 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
                (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
                return;
            }
-       }
 
-       /* Initialize and start device */
-       IopInitializeDevice(DeviceNode, DriverObject);
-       Status = IopStartDevice(DeviceNode);
+           /* Initialize and start device */
+           IopInitializeDevice(DeviceNode, DriverObject);
+           Status = IopStartDevice(DeviceNode);
+       }
    }
    else
    {
@@ -1948,9 +1959,6 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
 
       /* IopGetDriverObject references the DriverObject, so dereference it */
       ObDereferenceObject(DriverObject);
-
-      /* Free device node since driver loading failed */
-      IopFreeDeviceNode(DeviceNode);
    }
 
    /* Pass status to the caller and signal the event */