[USETUP] Improvements for the File-queues code.
[reactos.git] / base / setup / usetup / usetup.c
index 1461528..929a4dc 100644 (file)
 /* GLOBALS & LOCALS *********************************************************/
 
 HANDLE ProcessHeap;
-
 BOOLEAN IsUnattendedSetup = FALSE;
-static USETUP_DATA USetupData;
 
-/*
- * NOTE: Technically only used for the COPYCONTEXT InstallPath member
- * for the filequeue functionality.
- */
-static UNICODE_STRING InstallPath;
+static USETUP_DATA USetupData;
 
 // FIXME: Is it really useful?? Just used for SetDefaultPagefile...
 static WCHAR DestinationDriveLetter;
@@ -71,18 +65,23 @@ static FORMATMACHINESTATE FormatState = Start;
 
 /*****************************************************/
 
-static HINF SetupInf;
-
-static HSPFILEQ SetupFileQueue = NULL;
-
 static PNTOS_INSTALLATION CurrentInstallation = NULL;
 static PGENERIC_LIST NtOsInstallsList = NULL;
 
-static PGENERIC_LIST ComputerList = NULL;
-static PGENERIC_LIST DisplayList  = NULL;
-static PGENERIC_LIST KeyboardList = NULL;
-static PGENERIC_LIST LayoutList   = NULL;
-static PGENERIC_LIST LanguageList = NULL;
+
+// HACK: Temporary compatibility code.
+#if 1
+    #define SetupQueueCopy SetupQueueCopyWithCab
+
+    static CABINET_CONTEXT CabinetContext;
+    #define CabinetInitialize() (CabinetInitialize(&CabinetContext))
+    #define CabinetSetEventHandlers(a,b,c) (CabinetSetEventHandlers(&CabinetContext,(a),(b),(c)))
+    #define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a)))
+    #define CabinetOpen() (CabinetOpen(&CabinetContext))
+    #define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext))
+    #define CabinetGetCabinetReservedArea(a) (CabinetGetCabinetReservedArea(&CabinetContext,(a)))
+    #define CabinetCleanup() (CabinetCleanup(&CabinetContext))
+#endif
 
 
 /* FUNCTIONS ****************************************************************/
@@ -404,10 +403,10 @@ UpdateKBLayout(VOID)
 
     pszNewLayout = MUIDefaultKeyboardLayout(SelectedLanguageId);
 
-    if (LayoutList == NULL)
+    if (USetupData.LayoutList == NULL)
     {
-        LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout);
-        if (LayoutList == NULL)
+        USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout);
+        if (USetupData.LayoutList == NULL)
         {
             /* FIXME: Handle error! */
             return;
@@ -417,12 +416,12 @@ UpdateKBLayout(VOID)
     /* Search for default layout (if provided) */
     if (pszNewLayout != NULL)
     {
-        for (ListEntry = GetFirstListEntry(LayoutList); ListEntry;
+        for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
              ListEntry = GetNextListEntry(ListEntry))
         {
             if (!wcscmp(pszNewLayout, ((PGENENTRY)GetListEntryData(ListEntry))->Id))
             {
-                SetCurrentListEntry(LayoutList, ListEntry);
+                SetCurrentListEntry(USetupData.LayoutList, ListEntry);
                 break;
             }
         }
@@ -491,10 +490,10 @@ LanguagePage(PINPUT_RECORD Ir)
     BOOL RefreshPage = FALSE;
 
     /* Initialize the computer settings list */
-    if (LanguageList == NULL)
+    if (USetupData.LanguageList == NULL)
     {
-        LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
-        if (LanguageList == NULL)
+        USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage);
+        if (USetupData.LanguageList == NULL)
         {
            PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE);
            return WELCOME_PAGE;
@@ -512,13 +511,13 @@ LanguagePage(PINPUT_RECORD Ir)
      * If there is no language or just a single one in the list,
      * skip the language selection process altogether.
      */
-    if (GetNumberOfListEntries(LanguageList) <= 1)
+    if (GetNumberOfListEntries(USetupData.LanguageList) <= 1)
     {
         USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
         return WELCOME_PAGE;
     }
 
-    InitGenericListUi(&ListUi, LanguageList, GetSettingDescription);
+    InitGenericListUi(&ListUi, USetupData.LanguageList, GetSettingDescription);
     DrawGenericList(&ListUi,
                     2, 18,
                     xScreen - 3,
@@ -566,10 +565,10 @@ LanguagePage(PINPUT_RECORD Ir)
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)  /* ENTER */
         {
-            ASSERT(GetNumberOfListEntries(LanguageList) >= 1);
+            ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1);
 
             SelectedLanguageId =
-                ((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id;
+                ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id;
 
             USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
 
@@ -592,10 +591,10 @@ LanguagePage(PINPUT_RECORD Ir)
 
         if (RefreshPage)
         {
-            ASSERT(GetNumberOfListEntries(LanguageList) >= 1);
+            ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1);
 
             NewLanguageId =
-                ((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id;
+                ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id;
 
             if (wcscmp(SelectedLanguageId, NewLanguageId))
             {
@@ -632,7 +631,7 @@ LanguagePage(PINPUT_RECORD Ir)
  *  Init USetupData.SourcePath
  *  Init USetupData.SourceRootPath
  *  Init USetupData.SourceRootDir
- *  Init SetupInf
+ *  Init USetupData.SetupInf
  *  Init USetupData.RequiredPartitionDiskSpace
  *  Init IsUnattendedSetup
  *  If unattended, init *List and sets the Codepage
@@ -645,29 +644,14 @@ LanguagePage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 SetupStartPage(PINPUT_RECORD Ir)
 {
-    NTSTATUS Status;
     ULONG Error;
     PGENERIC_LIST_ENTRY ListEntry;
     PCWSTR LocaleId;
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
-    /* Get the source path and source root path */
-    Status = GetSourcePaths(&USetupData.SourcePath,
-                            &USetupData.SourceRootPath,
-                            &USetupData.SourceRootDir);
-    if (!NT_SUCCESS(Status))
-    {
-        CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status);
-        MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
-        return QUIT_PAGE;
-    }
-    DPRINT1("SourcePath: '%wZ'\n", &USetupData.SourcePath);
-    DPRINT1("SourceRootPath: '%wZ'\n", &USetupData.SourceRootPath);
-    DPRINT1("SourceRootDir: '%wZ'\n", &USetupData.SourceRootDir);
-
-    /* Load 'txtsetup.sif' from the installation media */
-    Error = LoadSetupInf(&SetupInf, &USetupData);
+    /* Initialize Setup, phase 1 */
+    Error = InitializeSetup(&USetupData, 1);
     if (Error != ERROR_SUCCESS)
     {
         MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER);
@@ -688,41 +672,41 @@ SetupStartPage(PINPUT_RECORD Ir)
         // TODO: Read options from inf
         /* Load the hardware, language and keyboard layout lists */
 
-        ComputerList = CreateComputerTypeList(SetupInf);
-        DisplayList = CreateDisplayDriverList(SetupInf);
-        KeyboardList = CreateKeyboardDriverList(SetupInf);
+        USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf);
+        USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf);
+        USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf);
 
-        LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
+        USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage);
 
         /* new part */
         SelectedLanguageId = DefaultLanguage;
         wcscpy(DefaultLanguage, USetupData.LocaleID);
         USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
 
-        LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout);
+        USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout);
 
         /* first we hack LanguageList */
-        for (ListEntry = GetFirstListEntry(LanguageList); ListEntry;
+        for (ListEntry = GetFirstListEntry(USetupData.LanguageList); ListEntry;
              ListEntry = GetNextListEntry(ListEntry))
         {
             LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
             if (!wcsicmp(USetupData.LocaleID, LocaleId))
             {
                 DPRINT("found %S in LanguageList\n", LocaleId);
-                SetCurrentListEntry(LanguageList, ListEntry);
+                SetCurrentListEntry(USetupData.LanguageList, ListEntry);
                 break;
             }
         }
 
         /* now LayoutList */
-        for (ListEntry = GetFirstListEntry(LayoutList); ListEntry;
+        for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry;
              ListEntry = GetNextListEntry(ListEntry))
         {
             LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
             if (!wcsicmp(USetupData.LocaleID, LocaleId))
             {
                 DPRINT("found %S in LayoutList\n", LocaleId);
-                SetCurrentListEntry(LayoutList, ListEntry);
+                SetCurrentListEntry(USetupData.LayoutList, ListEntry);
                 break;
             }
         }
@@ -1131,10 +1115,10 @@ OemDriverPage(PINPUT_RECORD Ir)
  *  QuitPage
  *
  * SIDEEFFECTS
- *  Init ComputerList
- *  Init DisplayList
- *  Init KeyboardList
- *  Init LayoutList
+ *  Init USetupData.ComputerList
+ *  Init USetupData.DisplayList
+ *  Init USetupData.KeyboardList
+ *  Init USetupData.LayoutList
  *
  * RETURNS
  *   Number of the next page.
@@ -1145,10 +1129,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
     static ULONG Line = 16;
 
     /* Initialize the computer settings list */
-    if (ComputerList == NULL)
+    if (USetupData.ComputerList == NULL)
     {
-        ComputerList = CreateComputerTypeList(SetupInf);
-        if (ComputerList == NULL)
+        USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf);
+        if (USetupData.ComputerList == NULL)
         {
             MUIDisplayError(ERROR_LOAD_COMPUTER, Ir, POPUP_WAIT_ENTER);
             return QUIT_PAGE;
@@ -1156,10 +1140,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
     }
 
     /* Initialize the display settings list */
-    if (DisplayList == NULL)
+    if (USetupData.DisplayList == NULL)
     {
-        DisplayList = CreateDisplayDriverList(SetupInf);
-        if (DisplayList == NULL)
+        USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf);
+        if (USetupData.DisplayList == NULL)
         {
             MUIDisplayError(ERROR_LOAD_DISPLAY, Ir, POPUP_WAIT_ENTER);
             return QUIT_PAGE;
@@ -1167,10 +1151,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
     }
 
     /* Initialize the keyboard settings list */
-    if (KeyboardList == NULL)
+    if (USetupData.KeyboardList == NULL)
     {
-        KeyboardList = CreateKeyboardDriverList(SetupInf);
-        if (KeyboardList == NULL)
+        USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf);
+        if (USetupData.KeyboardList == NULL)
         {
             MUIDisplayError(ERROR_LOAD_KEYBOARD, Ir, POPUP_WAIT_ENTER);
             return QUIT_PAGE;
@@ -1178,10 +1162,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
     }
 
     /* Initialize the keyboard layout list */
-    if (LayoutList == NULL)
+    if (USetupData.LayoutList == NULL)
     {
-        LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout);
-        if (LayoutList == NULL)
+        USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout);
+        if (USetupData.LayoutList == NULL)
         {
             /* FIXME: report error */
             MUIDisplayError(ERROR_LOAD_KBLAYOUT, Ir, POPUP_WAIT_ENTER);
@@ -1197,10 +1181,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
 
     MUIDisplayPage(DEVICE_SETTINGS_PAGE);
 
-    DrawGenericListCurrentItem(ComputerList, GetSettingDescription, 25, 11);
-    DrawGenericListCurrentItem(DisplayList , GetSettingDescription, 25, 12);
-    DrawGenericListCurrentItem(KeyboardList, GetSettingDescription, 25, 13);
-    DrawGenericListCurrentItem(LayoutList  , GetSettingDescription, 25, 14);
+    DrawGenericListCurrentItem(USetupData.ComputerList, GetSettingDescription, 25, 11);
+    DrawGenericListCurrentItem(USetupData.DisplayList , GetSettingDescription, 25, 12);
+    DrawGenericListCurrentItem(USetupData.KeyboardList, GetSettingDescription, 25, 13);
+    DrawGenericListCurrentItem(USetupData.LayoutList  , GetSettingDescription, 25, 14);
 
     CONSOLE_InvertTextXY(24, Line, 48, 1);
 
@@ -1343,7 +1327,7 @@ ComputerSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(COMPUTER_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, ComputerList, GetSettingDescription);
+    InitGenericListUi(&ListUi, USetupData.ComputerList, GetSettingDescription);
     DrawGenericList(&ListUi,
                     2, 18,
                     xScreen - 3,
@@ -1369,7 +1353,7 @@ DisplaySettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(DISPLAY_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, DisplayList, GetSettingDescription);
+    InitGenericListUi(&ListUi, USetupData.DisplayList, GetSettingDescription);
     DrawGenericList(&ListUi,
                     2, 18,
                     xScreen - 3,
@@ -1395,7 +1379,7 @@ KeyboardSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(KEYBOARD_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, KeyboardList, GetSettingDescription);
+    InitGenericListUi(&ListUi, USetupData.KeyboardList, GetSettingDescription);
     DrawGenericList(&ListUi,
                     2, 18,
                     xScreen - 3,
@@ -1421,7 +1405,7 @@ LayoutSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(LAYOUT_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, LayoutList, GetSettingDescription);
+    InitGenericListUi(&ListUi, USetupData.LayoutList, GetSettingDescription);
     DrawGenericList(&ListUi,
                     2, 18,
                     xScreen - 3,
@@ -3224,38 +3208,11 @@ BuildInstallPaths(PWSTR InstallDir,
                   PDISKENTRY DiskEntry,
                   PPARTENTRY PartEntry)
 {
-    WCHAR PathBuffer[MAX_PATH];
+    NTSTATUS Status;
 
-/** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/
-    /* Create 'InstallPath' string */
-    RtlFreeUnicodeString(&InstallPath);
-    RtlCreateUnicodeString(&InstallPath, InstallDir);
-
-    /* Create 'USetupData.DestinationRootPath' string */
-    RtlFreeUnicodeString(&USetupData.DestinationRootPath);
-    RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
-            L"\\Device\\Harddisk%lu\\Partition%lu\\",
-            DiskEntry->DiskNumber,
-            PartEntry->PartitionNumber);
-    RtlCreateUnicodeString(&USetupData.DestinationRootPath, PathBuffer);
-    DPRINT("DestinationRootPath: %wZ\n", &USetupData.DestinationRootPath);
-
-/** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/
-    /* Create 'USetupData.DestinationPath' string */
-    RtlFreeUnicodeString(&USetupData.DestinationPath);
-    CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
-                 USetupData.DestinationRootPath.Buffer, InstallDir);
-    RtlCreateUnicodeString(&USetupData.DestinationPath, PathBuffer);
-
-/** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/
-    /* Create 'USetupData.DestinationArcPath' */
-    RtlFreeUnicodeString(&USetupData.DestinationArcPath);
-    RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
-            L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
-            DiskEntry->BiosDiskNumber,
-            PartEntry->PartitionNumber);
-    ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallDir);
-    RtlCreateUnicodeString(&USetupData.DestinationArcPath, PathBuffer);
+    Status = InitDestinationPaths(&USetupData, InstallDir, DiskEntry, PartEntry);
+    // TODO: Check Status
+    UNREFERENCED_PARAMETER(Status);
 
     /* Initialize DestinationDriveLetter */
     DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter;
@@ -3539,6 +3496,7 @@ AddSectionToCopyQueueCab(HINF InfFile,
     PWCHAR FileKeyValue;
     PWCHAR DirKeyValue;
     PWCHAR TargetFileName;
+    WCHAR FileDstPath[MAX_PATH];
 
     /*
      * This code enumerates the list of files in reactos.dff / reactos.inf
@@ -3594,12 +3552,46 @@ AddSectionToCopyQueueCab(HINF InfFile,
             break;
         }
 
-        if (!SetupQueueCopy(SetupFileQueue,
+#if 1 // HACK moved! (r66604)
+        {
+        ULONG Length = wcslen(DirKeyValue);
+        if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
+            Length--;
+        DirKeyValue[Length] = UNICODE_NULL;
+        }
+
+        /* Build the full target path */
+        RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
+                          USetupData.DestinationRootPath.Buffer);
+        if (DirKeyValue[0] == UNICODE_NULL)
+        {
+            /* Installation path */
+
+            /* Add the installation path */
+            ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, USetupData.InstallPath.Buffer);
+        }
+        else if (DirKeyValue[0] == L'\\')
+        {
+            /* Absolute path */
+            // if (DirKeyValue[1] != UNICODE_NULL)
+                ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
+        }
+        else // if (DirKeyValue[0] != L'\\')
+        {
+            /* Path relative to the installation path */
+
+            /* Add the installation path */
+            ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
+                        USetupData.InstallPath.Buffer, DirKeyValue);
+        }
+#endif
+
+        if (!SetupQueueCopy(USetupData.SetupFileQueue,
                             SourceCabinet,
                             USetupData.SourceRootPath.Buffer,
                             USetupData.SourceRootDir.Buffer,
                             FileKeyName,
-                            DirKeyValue,
+                            FileDstPath,
                             TargetFileName))
         {
             /* FIXME: Handle error! */
@@ -3629,6 +3621,7 @@ AddSectionToCopyQueue(HINF InfFile,
     PWCHAR DirKeyValue;
     PWCHAR TargetFileName;
     WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough?
+    WCHAR FileDstPath[MAX_PATH];
 
     if (SourceCabinet)
         return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir);
@@ -3728,12 +3721,46 @@ AddSectionToCopyQueue(HINF InfFile,
             DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
         }
 
-        if (!SetupQueueCopy(SetupFileQueue,
+#if 1 // HACK moved! (r66604)
+        {
+        ULONG Length = wcslen(DirKeyValue);
+        if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
+            Length--;
+        DirKeyValue[Length] = UNICODE_NULL;
+        }
+
+        /* Build the full target path */
+        RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
+                          USetupData.DestinationRootPath.Buffer);
+        if (DirKeyValue[0] == UNICODE_NULL)
+        {
+            /* Installation path */
+
+            /* Add the installation path */
+            ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, USetupData.InstallPath.Buffer);
+        }
+        else if (DirKeyValue[0] == L'\\')
+        {
+            /* Absolute path */
+            // if (DirKeyValue[1] != UNICODE_NULL)
+                ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
+        }
+        else // if (DirKeyValue[0] != L'\\')
+        {
+            /* Path relative to the installation path */
+
+            /* Add the installation path */
+            ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
+                        USetupData.InstallPath.Buffer, DirKeyValue);
+        }
+#endif
+
+        if (!SetupQueueCopy(USetupData.SetupFileQueue,
                             SourceCabinet,
                             USetupData.SourceRootPath.Buffer,
                             CompleteOrigDirName,
                             FileKeyName,
-                            DirKeyValue,
+                            FileDstPath,
                             TargetFileName))
         {
             /* FIXME: Handle error! */
@@ -3767,7 +3794,7 @@ PrepareCopyPageInfFile(HINF InfFile,
     /* Add specific files depending of computer type */
     if (SourceCabinet == NULL)
     {
-        if (!ProcessComputerFiles(InfFile, ComputerList, &AdditionalSectionName))
+        if (!ProcessComputerFiles(InfFile, USetupData.ComputerList, &AdditionalSectionName))
             return FALSE;
 
         if (AdditionalSectionName)
@@ -3905,21 +3932,21 @@ PrepareCopyPage(PINPUT_RECORD Ir)
     MUIDisplayPage(PREPARE_COPY_PAGE);
 
     /* Create the file queue */
-    SetupFileQueue = SetupOpenFileQueue();
-    if (SetupFileQueue == NULL)
+    USetupData.SetupFileQueue = SetupOpenFileQueue();
+    if (USetupData.SetupFileQueue == NULL)
     {
         MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
         return QUIT_PAGE;
     }
 
-    if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir))
+    if (!PrepareCopyPageInfFile(USetupData.SetupInf, NULL, Ir))
     {
         /* FIXME: show an error dialog */
         return QUIT_PAGE;
     }
 
     /* Search for the 'Cabinets' section */
-    if (!SetupFindFirstLineW(SetupInf, L"Cabinets", NULL, &CabinetsContext))
+    if (!SetupFindFirstLineW(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext))
     {
         return FILE_COPY_PAGE;
     }
@@ -3983,9 +4010,15 @@ PrepareCopyPage(PINPUT_RECORD Ir)
     return FILE_COPY_PAGE;
 }
 
+typedef struct _COPYCONTEXT
+{
+    ULONG TotalOperations;
+    ULONG CompletedOperations;
+    PPROGRESSBAR ProgressBar;
+    PPROGRESSBAR MemoryBars[4];
+} COPYCONTEXT, *PCOPYCONTEXT;
 
-VOID
-NTAPI
+static VOID
 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
                       IN BOOLEAN First)
 {
@@ -4012,7 +4045,6 @@ SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
     ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
 }
 
-
 static UINT
 CALLBACK
 FileCopyCallback(PVOID Context,
@@ -4020,26 +4052,78 @@ FileCopyCallback(PVOID Context,
                  UINT_PTR Param1,
                  UINT_PTR Param2)
 {
-    PCOPYCONTEXT CopyContext;
-
-    CopyContext = (PCOPYCONTEXT)Context;
+    PCOPYCONTEXT CopyContext = (PCOPYCONTEXT)Context;
+    PFILEPATHS_W FilePathInfo;
+    PCWSTR SrcFileName, DstFileName;
 
     switch (Notification)
     {
         case SPFILENOTIFY_STARTSUBQUEUE:
+        {
             CopyContext->TotalOperations = (ULONG)Param2;
+            CopyContext->CompletedOperations = 0;
             ProgressSetStepCount(CopyContext->ProgressBar,
                                  CopyContext->TotalOperations);
             SetupUpdateMemoryInfo(CopyContext, TRUE);
             break;
+        }
 
+        case SPFILENOTIFY_STARTDELETE:
+        case SPFILENOTIFY_STARTRENAME:
         case SPFILENOTIFY_STARTCOPY:
-            /* Display copy message */
-            CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), (PWSTR)Param1);
+        {
+            FilePathInfo = (PFILEPATHS_W)Param1;
+
+            if (Notification == SPFILENOTIFY_STARTDELETE)
+            {
+                /* Display delete message */
+                ASSERT(Param2 == FILEOP_DELETE);
+
+                DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+                if (DstFileName) ++DstFileName;
+                else DstFileName = FilePathInfo->Target;
+
+                CONSOLE_SetStatusText(MUIGetString(STRING_DELETING),
+                                      DstFileName);
+            }
+            else if (Notification == SPFILENOTIFY_STARTRENAME)
+            {
+                /* Display move/rename message */
+                ASSERT(Param2 == FILEOP_RENAME);
+
+                SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
+                if (SrcFileName) ++SrcFileName;
+                else SrcFileName = FilePathInfo->Source;
+
+                DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+                if (DstFileName) ++DstFileName;
+                else DstFileName = FilePathInfo->Target;
+
+                // TODO: Determine whether using STRING_RENAMING or STRING_MOVING
+                CONSOLE_SetStatusText(MUIGetString(STRING_MOVING),
+                                      SrcFileName, DstFileName);
+            }
+            else if (Notification == SPFILENOTIFY_STARTCOPY)
+            {
+                /* Display copy message */
+                ASSERT(Param2 == FILEOP_COPY);
+
+                SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
+                if (SrcFileName) ++SrcFileName;
+                else SrcFileName = FilePathInfo->Source;
+
+                CONSOLE_SetStatusText(MUIGetString(STRING_COPYING),
+                                      SrcFileName);
+            }
+
             SetupUpdateMemoryInfo(CopyContext, FALSE);
             break;
+        }
 
+        case SPFILENOTIFY_ENDDELETE:
+        case SPFILENOTIFY_ENDRENAME:
         case SPFILENOTIFY_ENDCOPY:
+        {
             CopyContext->CompletedOperations++;
 
             /* SYSREG checkpoint */
@@ -4049,9 +4133,10 @@ FileCopyCallback(PVOID Context,
             ProgressNextStep(CopyContext->ProgressBar);
             SetupUpdateMemoryInfo(CopyContext, FALSE);
             break;
+        }
     }
 
-    return 0;
+    return FILEOP_DOIT;
 }
 
 
@@ -4072,13 +4157,11 @@ static PAGE_NUMBER
 FileCopyPage(PINPUT_RECORD Ir)
 {
     COPYCONTEXT CopyContext;
-    unsigned int mem_bar_width;
+    UINT MemBarWidth;
 
     MUIDisplayPage(FILE_COPY_PAGE);
 
     /* Create context for the copy process */
-    CopyContext.DestinationRootPath = USetupData.DestinationRootPath.Buffer;
-    CopyContext.InstallPath = InstallPath.Buffer;
     CopyContext.TotalOperations = 0;
     CopyContext.CompletedOperations = 0;
 
@@ -4093,13 +4176,13 @@ FileCopyPage(PINPUT_RECORD Ir)
                                                 MUIGetString(STRING_SETUPCOPYINGFILES));
 
     // fit memory bars to screen width, distribute them uniform
-    mem_bar_width = (xScreen - 26) / 5;
-    mem_bar_width -= mem_bar_width % 2;  // make even
+    MemBarWidth = (xScreen - 26) / 5;
+    MemBarWidth -= MemBarWidth % 2;  // make even
     /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
     /* Create the paged pool progress bar */
     CopyContext.MemoryBars[0] = CreateProgressBar(13,
                                                   40,
-                                                  13 + mem_bar_width,
+                                                  13 + MemBarWidth,
                                                   43,
                                                   13,
                                                   44,
@@ -4107,33 +4190,33 @@ FileCopyPage(PINPUT_RECORD Ir)
                                                   "Kernel Pool");
 
     /* Create the non paged pool progress bar */
-    CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (mem_bar_width / 2),
+    CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (MemBarWidth / 2),
                                                   40,
-                                                  (xScreen / 2) + (mem_bar_width / 2),
+                                                  (xScreen / 2) + (MemBarWidth / 2),
                                                   43,
-                                                  (xScreen / 2)- (mem_bar_width / 2),
+                                                  (xScreen / 2)- (MemBarWidth / 2),
                                                   44,
                                                   FALSE,
                                                   "Kernel Cache");
 
     /* Create the global memory progress bar */
-    CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - mem_bar_width,
+    CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - MemBarWidth,
                                                   40,
                                                   xScreen - 13,
                                                   43,
-                                                  xScreen - 13 - mem_bar_width,
+                                                  xScreen - 13 - MemBarWidth,
                                                   44,
                                                   FALSE,
                                                   "Free Memory");
 
     /* Do the file copying */
     SetupCommitFileQueueW(NULL,
-                          SetupFileQueue,
+                          USetupData.SetupFileQueue,
                           FileCopyCallback,
                           &CopyContext);
 
     /* If we get here, we're done, so cleanup the queue and progress bar */
-    SetupCloseFileQueue(SetupFileQueue);
+    SetupCloseFileQueue(USetupData.SetupFileQueue);
     DestroyProgressBar(CopyContext.ProgressBar);
     DestroyProgressBar(CopyContext.MemoryBars[0]);
     DestroyProgressBar(CopyContext.MemoryBars[1]);
@@ -4199,15 +4282,15 @@ RegistryPage(PINPUT_RECORD Ir)
 
     MUIDisplayPage(REGISTRY_PAGE);
 
-    Error = UpdateRegistry(SetupInf,
+    Error = UpdateRegistry(USetupData.SetupInf,
                            &USetupData,
                            RepairUpdateFlag,
                            PartitionList,
                            DestinationDriveLetter,
                            SelectedLanguageId,
-                           DisplayList,
-                           LayoutList,
-                           LanguageList,
+                           USetupData.DisplayList,
+                           USetupData.LayoutList,
+                           USetupData.LanguageList,
                            RegistryStatus);
     if (Error != ERROR_SUCCESS)
     {
@@ -4794,6 +4877,7 @@ QuitPage(PINPUT_RECORD Ir)
         DestroyPartitionList(PartitionList);
         PartitionList = NULL;
     }
+
     TempPartition = NULL;
     FormatState = Start;
 
@@ -4804,41 +4888,6 @@ QuitPage(PINPUT_RECORD Ir)
         FileSystemList = NULL;
     }
 
-    /* Destroy the computer settings list */
-    if (ComputerList != NULL)
-    {
-        DestroyGenericList(ComputerList, TRUE);
-        ComputerList = NULL;
-    }
-
-    /* Destroy the display settings list */
-    if (DisplayList != NULL)
-    {
-        DestroyGenericList(DisplayList, TRUE);
-        DisplayList = NULL;
-    }
-
-    /* Destroy the keyboard settings list */
-    if (KeyboardList != NULL)
-    {
-        DestroyGenericList(KeyboardList, TRUE);
-        KeyboardList = NULL;
-    }
-
-    /* Destroy the keyboard layout list */
-    if (LayoutList != NULL)
-    {
-        DestroyGenericList(LayoutList, TRUE);
-        LayoutList = NULL;
-    }
-
-    /* Destroy the languages list */
-    if (LanguageList != NULL)
-    {
-        DestroyGenericList(LanguageList, FALSE);
-        LanguageList = NULL;
-    }
-
     CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2));
 
     /* Wait for maximum 15 seconds or an ENTER key before quitting */
@@ -4920,7 +4969,7 @@ RunUSetup(VOID)
                                  0,
                                  0,
                                  PnpEventThread,
-                                 &SetupInf,
+                                 &USetupData.SetupInf,
                                  &hPnpThread,
                                  NULL);
     if (!NT_SUCCESS(Status))
@@ -4936,15 +4985,8 @@ RunUSetup(VOID)
         return STATUS_APP_INIT_FAILURE;
     }
 
-    /* Initialize global unicode strings */
-    RtlInitUnicodeString(&USetupData.SourcePath, NULL);
-    RtlInitUnicodeString(&USetupData.SourceRootPath, NULL);
-    RtlInitUnicodeString(&USetupData.SourceRootDir, NULL);
-    RtlInitUnicodeString(&InstallPath, NULL);
-    RtlInitUnicodeString(&USetupData.DestinationPath, NULL);
-    RtlInitUnicodeString(&USetupData.DestinationArcPath, NULL);
-    RtlInitUnicodeString(&USetupData.DestinationRootPath, NULL);
-    RtlInitUnicodeString(&USetupData.SystemRootPath, NULL);
+    /* Initialize Setup, phase 0 */
+    InitializeSetup(&USetupData, 0);
 
     /* Hide the cursor */
     CONSOLE_SetCursorType(TRUE, FALSE);
@@ -5109,7 +5151,8 @@ RunUSetup(VOID)
         }
     }
 
-    SetupCloseInfFile(SetupInf);
+    /* Setup has finished */
+    FinishSetup(&USetupData);
 
     if (Page == RECOVERY_PAGE)
         RecoveryConsole();