[SETUPLIB][USETUP] Improve disk HW numbering, removable disk support, and "super...
[reactos.git] / base / setup / lib / setuplib.c
index 34eb228..be71e81 100644 (file)
@@ -196,6 +196,16 @@ CheckUnattendedSetup(
        }
     }
 
+    /* Search for FsType in the 'Unattend' section */
+    pSetupData->FsType = 0;
+    if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"FsType", &Context))
+    {
+        if (SpInfGetIntField(&Context, 1, &IntValue))
+        {
+            pSetupData->FsType = IntValue;
+        }
+    }
+
 Quit:
     SpInfCloseInfFile(UnattendInf);
 }
@@ -391,7 +401,7 @@ GetSourcePaths(
     OUT PUNICODE_STRING SourceRootDir)
 {
     NTSTATUS Status;
-    HANDLE Handle;
+    HANDLE LinkHandle;
     OBJECT_ATTRIBUTES ObjectAttributes;
     UCHAR ImageFileBuffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
     PUNICODE_STRING InstallSourcePath = (PUNICODE_STRING)&ImageFileBuffer;
@@ -439,7 +449,7 @@ GetSourcePaths(
                                NULL,
                                NULL);
 
-    Status = NtOpenSymbolicLinkObject(&Handle,
+    Status = NtOpenSymbolicLinkObject(&LinkHandle,
                                       SYMBOLIC_LINK_QUERY,
                                       &ObjectAttributes);
     if (!NT_SUCCESS(Status))
@@ -458,10 +468,11 @@ GetSourcePaths(
                               SystemRootBuffer,
                               sizeof(SystemRootBuffer));
 
-    Status = NtQuerySymbolicLinkObject(Handle,
+    /* Resolve the link and close its handle */
+    Status = NtQuerySymbolicLinkObject(LinkHandle,
                                        &SystemRootPath,
                                        &BufferSize);
-    NtClose(Handle);
+    NtClose(LinkHandle);
 
     if (!NT_SUCCESS(Status))
         return Status; // Unexpected error
@@ -515,7 +526,7 @@ LoadSetupInf(
     pSetupData->SetupInf =
         SpInfOpenInfFile(FileNameBuffer,
                          NULL,
-                         /* INF_STYLE_WIN4 | */ INF_STYLE_OLDNT,
+                         INF_STYLE_WIN4,
                          pSetupData->LanguageId,
                          &ErrorLine);
     if (pSetupData->SetupInf == INVALID_HANDLE_VALUE)
@@ -530,7 +541,8 @@ LoadSetupInf(
         return ERROR_CORRUPT_TXTSETUPSIF;
 
     /* Check 'Signature' string */
-    if (_wcsicmp(Value, L"$ReactOS$") != 0)
+    if (_wcsicmp(Value, L"$ReactOS$") != 0 &&
+        _wcsicmp(Value, L"$Windows NT$") != 0)
     {
         INF_FreeData(Value);
         return ERROR_SIGNATURE_TXTSETUPSIF;
@@ -612,22 +624,35 @@ NTSTATUS
 InitDestinationPaths(
     IN OUT PUSETUP_DATA pSetupData,
     IN PCWSTR InstallationDir,
-    IN PDISKENTRY DiskEntry,    // FIXME: HACK!
     IN PPARTENTRY PartEntry)    // FIXME: HACK!
 {
+    NTSTATUS Status;
+    PDISKENTRY DiskEntry = PartEntry->DiskEntry;
     WCHAR PathBuffer[MAX_PATH];
 
-    //
-    // TODO: Check return status values of the functions!
-    //
+    ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
 
     /* Create 'pSetupData->DestinationRootPath' string */
     RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
-    RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
-            L"\\Device\\Harddisk%lu\\Partition%lu\\",
-            DiskEntry->DiskNumber,
-            PartEntry->PartitionNumber);
-    RtlCreateUnicodeString(&pSetupData->DestinationRootPath, PathBuffer);
+    Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                     L"\\Device\\Harddisk%lu\\Partition%lu\\",
+                     DiskEntry->DiskNumber,
+                     PartEntry->PartitionNumber);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlStringCchPrintfW() failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    Status = RtlCreateUnicodeString(&pSetupData->DestinationRootPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
     DPRINT("DestinationRootPath: %wZ\n", &pSetupData->DestinationRootPath);
 
     // FIXME! Which variable to choose?
@@ -637,23 +662,116 @@ InitDestinationPaths(
 /** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/
     /* Create 'pSetupData->DestinationArcPath' */
     RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
-    RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
-            L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
-            DiskEntry->BiosDiskNumber,
-            PartEntry->PartitionNumber);
-    ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallationDir);
-    RtlCreateUnicodeString(&pSetupData->DestinationArcPath, PathBuffer);
+
+    if (DiskEntry->MediaType == FixedMedia)
+    {
+        if (DiskEntry->BiosFound)
+        {
+#if 1
+            Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                             L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
+                             DiskEntry->HwFixedDiskNumber,
+                             PartEntry->OnDiskPartitionNumber);
+#else
+            Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                             L"multi(%lu)disk(%lu)rdisk(%lu)partition(%lu)\\",
+                             DiskEntry->HwAdapterNumber,
+                             DiskEntry->HwControllerNumber,
+                             DiskEntry->HwFixedDiskNumber,
+                             PartEntry->OnDiskPartitionNumber);
+#endif
+            DPRINT1("Fixed disk found by BIOS, using MULTI ARC path '%S'\n", PathBuffer);
+        }
+        else
+        {
+            Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                             L"scsi(%u)disk(%u)rdisk(%u)partition(%lu)\\",
+                             DiskEntry->Port,
+                             DiskEntry->Bus,
+                             DiskEntry->Id,
+                             PartEntry->OnDiskPartitionNumber);
+            DPRINT1("Fixed disk not found by BIOS, using SCSI ARC path '%S'\n", PathBuffer);
+        }
+    }
+    else // if (DiskEntry->MediaType == RemovableMedia)
+    {
+#if 1
+        Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                         L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
+                         0, 1);
+        DPRINT1("Removable disk, using MULTI ARC path '%S'\n", PathBuffer);
+#else
+        Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+                         L"signature(%08x)disk(%u)rdisk(%u)partition(%lu)\\",
+                         DiskEntry->LayoutBuffer->Signature,
+                         DiskEntry->Bus,
+                         DiskEntry->Id,
+                         PartEntry->OnDiskPartitionNumber);
+        DPRINT1("Removable disk, using SIGNATURE ARC path '%S'\n", PathBuffer);
+#endif
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlStringCchPrintfW() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
+
+    Status = ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallationDir);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("ConcatPaths() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
+
+    Status = RtlCreateUnicodeString(&pSetupData->DestinationArcPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
 
 /** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/
     /* Create 'pSetupData->DestinationPath' string */
     RtlFreeUnicodeString(&pSetupData->DestinationPath);
-    CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
-                 pSetupData->DestinationRootPath.Buffer, InstallationDir);
-    RtlCreateUnicodeString(&pSetupData->DestinationPath, PathBuffer);
+    Status = CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
+                          pSetupData->DestinationRootPath.Buffer, InstallationDir);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CombinePaths() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
+
+    Status = RtlCreateUnicodeString(&pSetupData->DestinationPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
 
 /** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/
     // FIXME: This is only temporary!! Must be removed later!
-    /***/RtlCreateUnicodeString(&pSetupData->InstallPath, InstallationDir);/***/
+    Status = RtlCreateUnicodeString(&pSetupData->InstallPath, InstallationDir) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
+        RtlFreeUnicodeString(&pSetupData->DestinationPath);
+        RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
+        RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
+        return Status;
+    }
 
     return STATUS_SUCCESS;
 }
@@ -674,6 +792,10 @@ InitializeSetup(
         // pSetupData->LayoutList   = NULL;
         // pSetupData->LanguageList = NULL;
 
+        /* Initialize error handling */
+        pSetupData->LastErrorNumber = ERROR_SUCCESS;
+        pSetupData->ErrorRoutine = NULL;
+
         /* Initialize global unicode strings */
         RtlInitUnicodeString(&pSetupData->SourcePath, NULL);
         RtlInitUnicodeString(&pSetupData->SourceRootPath, NULL);
@@ -790,15 +912,11 @@ FinishSetup(
  */
 ERROR_NUMBER
 UpdateRegistry(
-    IN HINF SetupInf,
     IN OUT PUSETUP_DATA pSetupData,
     /**/IN BOOLEAN RepairUpdateFlag,     /* HACK HACK! */
     /**/IN PPARTLIST PartitionList,      /* HACK HACK! */
     /**/IN WCHAR DestinationDriveLetter, /* HACK HACK! */
     /**/IN PCWSTR SelectedLanguageId,    /* HACK HACK! */
-    IN PGENERIC_LIST DisplayList,
-    IN PGENERIC_LIST LayoutList,
-    IN PGENERIC_LIST LanguageList,
     IN PREGISTRY_STATUS_ROUTINE StatusRoutine OPTIONAL)
 {
     ERROR_NUMBER ErrorNumber;
@@ -860,9 +978,9 @@ DoUpdate:
          * "repair" (aka. recreate: ShouldRepairRegistry == TRUE).
          */
 
-        Success = SpInfFindFirstLine(SetupInf, L"HiveInfs.Fresh", NULL, &InfContext);       // Windows-compatible
+        Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Fresh", NULL, &InfContext);       // Windows-compatible
         if (!Success)
-            Success = SpInfFindFirstLine(SetupInf, L"HiveInfs.Install", NULL, &InfContext); // ReactOS-specific
+            Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Install", NULL, &InfContext); // ReactOS-specific
 
         if (!Success)
         {
@@ -879,7 +997,7 @@ DoUpdate:
          * we only update the hives.
          */
 
-        Success = SpInfFindFirstLine(SetupInf, L"HiveInfs.Upgrade", NULL, &InfContext);
+        Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Upgrade", NULL, &InfContext);
         if (!Success)
         {
             /* Nothing to do for update! */
@@ -939,7 +1057,7 @@ DoUpdate:
 
         /* Update display registry settings */
         if (StatusRoutine) StatusRoutine(DisplaySettingsUpdate);
-        if (!ProcessDisplayRegistry(SetupInf, DisplayList))
+        if (!ProcessDisplayRegistry(pSetupData->SetupInf, pSetupData->DisplayList))
         {
             ErrorNumber = ERROR_UPDATE_DISPLAY_SETTINGS;
             goto Cleanup;
@@ -947,7 +1065,7 @@ DoUpdate:
 
         /* Set the locale */
         if (StatusRoutine) StatusRoutine(LocaleSettingsUpdate);
-        if (!ProcessLocaleRegistry(LanguageList))
+        if (!ProcessLocaleRegistry(pSetupData->LanguageList))
         {
             ErrorNumber = ERROR_UPDATE_LOCALESETTINGS;
             goto Cleanup;
@@ -972,7 +1090,7 @@ DoUpdate:
         {
             /* Update keyboard layout settings */
             if (StatusRoutine) StatusRoutine(KeybSettingsUpdate);
-            if (!ProcessKeyboardLayoutRegistry(LayoutList, SelectedLanguageId))
+            if (!ProcessKeyboardLayoutRegistry(pSetupData->LayoutList, SelectedLanguageId))
             {
                 ErrorNumber = ERROR_UPDATE_KBSETTINGS;
                 goto Cleanup;