* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/usetup.c
* PURPOSE: Text-mode setup
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org)
*/
#include "bootsup.h"
#include "chkdsk.h"
#include "cmdcons.h"
+#include "devinst.h"
#include "format.h"
#define NDEBUG
static BOOLEAN RepairUpdateFlag = FALSE;
-static HANDLE hPnpThread = NULL;
-
static PPARTLIST PartitionList = NULL;
static PPARTENTRY TempPartition = NULL;
static PFILE_SYSTEM_LIST FileSystemList = NULL;
{
/* We have retrieved a partition that is mounted */
return RtlStringCchPrintfA(Buffer, cchBufferSize,
- "%c:%S \"%S\"",
+ "%C:%S \"%S\"",
PartEntry->DriveLetter,
NtOsInstall->PathComponent,
NtOsInstall->InstallationName);
PGENERIC_LIST_ENTRY ListEntry;
PCWSTR LocaleId;
- CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
+ MUIDisplayPage(SETUP_INIT_PAGE);
/* Initialize Setup, phase 1 */
Error = InitializeSetup(&USetupData, 1);
return QUIT_PAGE;
}
- /* Start the PnP thread */
- if (hPnpThread != NULL)
- {
- NtResumeThread(hPnpThread, NULL);
- hPnpThread = NULL;
- }
+ /* Initialize the user-mode PnP manager */
+ if (!EnableUserModePnpManager())
+ DPRINT1("The user-mode PnP manager could not initialize, expect unavailable devices!\n");
+
+ /* Wait for any immediate pending installations to finish */
+ if (WaitNoPendingInstallEvents(NULL) != STATUS_WAIT_0)
+ DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
CheckUnattendedSetup(&USetupData);
{
if (PartitionList->CurrentPartition->LogicalPartition)
{
+ Error = LogicalPartitionCreationChecks(PartitionList);
+ if (Error != NOT_AN_ERROR)
+ {
+ MUIDisplayError(Error, Ir, POPUP_WAIT_ANY_KEY);
+ return SELECT_PARTITION_PAGE;
+ }
+
CreateLogicalPartition(PartitionList,
0ULL,
TRUE);
}
else
{
+ Error = PrimaryPartitionCreationChecks(PartitionList);
+ if (Error != NOT_AN_ERROR)
+ {
+ MUIDisplayError(Error, Ir, POPUP_WAIT_ANY_KEY);
+ return SELECT_PARTITION_PAGE;
+ }
+
CreatePrimaryPartition(PartitionList,
0ULL,
TRUE);
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
else
{
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
else
{
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
else
{
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
{
CONSOLE_PrintTextXY(6, 10,
MUIGetString(STRING_HDDINFOUNK2),
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':',
PartEntry->PartitionType,
PartSize,
{
CONSOLE_PrintTextXY(6, 10,
" %c%c %s %I64u %s",
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':',
PartTypeString,
PartSize,
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
else
{
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
while (TRUE)
* QuitPage
*
* SIDEEFFECTS
- * Sets PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType (via UpdatePartitionType)
+ * Calls UpdatePartitionType()
* Calls CheckActiveSystemPartition()
*
* RETURNS
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT));
{
CONSOLE_PrintTextXY(8, 10,
MUIGetString(STRING_HDDINFOUNK4),
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':',
PartEntry->PartitionType,
PartSize,
{
CONSOLE_PrintTextXY(8, 10,
"%c%c %s %I64u %s",
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':',
PartTypeString,
PartSize,
DiskEntry->Bus,
DiskEntry->Id,
&DiskEntry->DriverName,
- DiskEntry->NoMbr ? "GPT" : "MBR");
+ DiskEntry->DiskStyle == PARTITION_STYLE_MBR ? L"MBR" :
+ DiskEntry->DiskStyle == PARTITION_STYLE_GPT ? L"GPT" :
+ L"RAW");
}
if (FileSystemList == NULL)
{
- /* Create the file system list, and by default select the "FAT" file system */
- FileSystemList = CreateFileSystemList(6, 26, PartEntry->New, L"FAT");
+ PWSTR DefaultFs;
+
+ if (IsUnattendedSetup)
+ {
+ switch (USetupData.FsType)
+ {
+ /* 1 is for BtrFS */
+ case 1:
+ DefaultFs = L"BTRFS";
+ break;
+
+ /* If we don't understand input, default to FAT */
+ default:
+ DefaultFs = L"FAT";
+ break;
+ }
+ }
+ else
+ {
+ /* By default select the "FAT" file system */
+ DefaultFs = L"FAT";
+ }
+
+ /* Create the file system list */
+ FileSystemList = CreateFileSystemList(6, 26, PartEntry->New, DefaultFs);
if (FileSystemList == NULL)
{
/* FIXME: show an error dialog */
{
if (USetupData.FormatPartition)
{
- /*
- * We use whatever currently selected file system we have
- * (by default, this is "FAT", as per the initialization
- * performed above). Note that it may be interesting to specify
- * which file system to use in unattended installations, in the
- * txtsetup.sif file.
- */
return FORMAT_PARTITION_PAGE;
}
UNREFERENCED_PARAMETER(Status);
/* Initialize DestinationDriveLetter */
- DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter;
+ DestinationDriveLetter = PartEntry->DriveLetter;
}
}
-static BOOLEAN
-AddSectionToCopyQueueCab(HINF InfFile,
- PWCHAR SectionName,
- PWCHAR SourceCabinet,
- PCUNICODE_STRING DestinationPath,
- PINPUT_RECORD Ir)
-{
- INFCONTEXT FilesContext;
- INFCONTEXT DirContext;
- PWCHAR FileKeyName;
- PWCHAR FileKeyValue;
- PWCHAR DirKeyValue;
- PWCHAR TargetFileName;
-
- /*
- * This code enumerates the list of files in reactos.dff / reactos.inf
- * that need to be extracted from reactos.cab and be installed in their
- * respective directories.
- */
-
- /* Search for the SectionName section */
- if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext))
- {
- MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
- return FALSE;
- }
-
- /*
- * Enumerate the files in the section and add them to the file queue.
- */
- do
- {
- /* Get source file name and target directory id */
- if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT1("INF_GetData() failed\n");
- break;
- }
-
- /* Get optional target file name */
- if (!INF_GetDataField(&FilesContext, 2, &TargetFileName))
- TargetFileName = NULL;
-
- DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
-
- /* Lookup target directory */
- if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext))
- {
- /* FIXME: Handle error! */
- DPRINT1("SetupFindFirstLine() failed\n");
- INF_FreeData(FileKeyName);
- INF_FreeData(FileKeyValue);
- INF_FreeData(TargetFileName);
- break;
- }
-
- INF_FreeData(FileKeyValue);
-
- if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT1("INF_GetData() failed\n");
- INF_FreeData(FileKeyName);
- INF_FreeData(TargetFileName);
- break;
- }
-
- if (!SetupQueueCopy(USetupData.SetupFileQueue,
- SourceCabinet,
- USetupData.SourceRootPath.Buffer,
- USetupData.SourceRootDir.Buffer,
- FileKeyName,
- DirKeyValue,
- TargetFileName))
- {
- /* FIXME: Handle error! */
- DPRINT1("SetupQueueCopy() failed\n");
- }
-
- INF_FreeData(FileKeyName);
- INF_FreeData(TargetFileName);
- INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&FilesContext, &FilesContext));
-
- return TRUE;
-}
-
-
-static BOOLEAN
-AddSectionToCopyQueue(HINF InfFile,
- PWCHAR SectionName,
- PWCHAR SourceCabinet,
- PCUNICODE_STRING DestinationPath,
- PINPUT_RECORD Ir)
-{
- INFCONTEXT FilesContext;
- INFCONTEXT DirContext;
- PWCHAR FileKeyName;
- PWCHAR FileKeyValue;
- PWCHAR DirKeyValue;
- PWCHAR TargetFileName;
- WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough?
-
- if (SourceCabinet)
- return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir);
-
- /*
- * This code enumerates the list of files in txtsetup.sif
- * that need to be installed in their respective directories.
- */
-
- /* Search for the SectionName section */
- if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext))
- {
- MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
- return FALSE;
- }
-
- /*
- * Enumerate the files in the section and add them to the file queue.
- */
- do
- {
- /* Get source file name */
- if (!INF_GetDataField(&FilesContext, 0, &FileKeyName))
- {
- /* FIXME: Handle error! */
- DPRINT1("INF_GetData() failed\n");
- break;
- }
-
- /* Get target directory id */
- if (!INF_GetDataField(&FilesContext, 13, &FileKeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT1("INF_GetData() failed\n");
- INF_FreeData(FileKeyName);
- break;
- }
-
- /* Get optional target file name */
- if (!INF_GetDataField(&FilesContext, 11, &TargetFileName))
- TargetFileName = NULL;
- else if (!*TargetFileName)
- TargetFileName = NULL;
-
- DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
-
- /* Lookup target directory */
- if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext))
- {
- /* FIXME: Handle error! */
- DPRINT1("SetupFindFirstLine() failed\n");
- INF_FreeData(FileKeyName);
- INF_FreeData(FileKeyValue);
- INF_FreeData(TargetFileName);
- break;
- }
-
- INF_FreeData(FileKeyValue);
-
- if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT1("INF_GetData() failed\n");
- INF_FreeData(FileKeyName);
- INF_FreeData(TargetFileName);
- break;
- }
-
- if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
- {
- /* Installation path */
- DPRINT("InstallationPath: '%S'\n", DirKeyValue);
-
- RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
- USetupData.SourceRootDir.Buffer);
-
- DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName);
- }
- else if (DirKeyValue[0] == L'\\')
- {
- /* Absolute path */
- DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
-
- RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
- DirKeyValue);
-
- DPRINT("AbsolutePath(2): '%S'\n", CompleteOrigDirName);
- }
- else // if (DirKeyValue[0] != L'\\')
- {
- /* Path relative to the installation path */
- DPRINT("RelativePath: '%S'\n", DirKeyValue);
-
- CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2,
- USetupData.SourceRootDir.Buffer, DirKeyValue);
-
- DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
- }
-
- if (!SetupQueueCopy(USetupData.SetupFileQueue,
- SourceCabinet,
- USetupData.SourceRootPath.Buffer,
- CompleteOrigDirName,
- FileKeyName,
- DirKeyValue,
- TargetFileName))
- {
- /* FIXME: Handle error! */
- DPRINT1("SetupQueueCopy() failed\n");
- }
-
- INF_FreeData(FileKeyName);
- INF_FreeData(TargetFileName);
- INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&FilesContext, &FilesContext));
-
- return TRUE;
-}
-
-
-static BOOLEAN
-PrepareCopyPageInfFile(HINF InfFile,
- PWCHAR SourceCabinet,
- PINPUT_RECORD Ir)
+// PSETUP_ERROR_ROUTINE
+static VOID
+__cdecl
+USetupErrorRoutine(
+ IN PUSETUP_DATA pSetupData,
+ ...)
{
- NTSTATUS Status;
- INFCONTEXT DirContext;
- PWCHAR AdditionalSectionName = NULL;
- PWCHAR DirKeyValue;
- WCHAR PathBuffer[MAX_PATH];
-
- /* Add common files */
- if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &USetupData.DestinationPath, Ir))
- return FALSE;
-
- /* Add specific files depending of computer type */
- if (SourceCabinet == NULL)
- {
- if (!ProcessComputerFiles(InfFile, USetupData.ComputerList, &AdditionalSectionName))
- return FALSE;
-
- if (AdditionalSectionName)
- {
- if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &USetupData.DestinationPath, Ir))
- return FALSE;
- }
- }
-
- /* Create directories */
-
- /*
- * FIXME:
- * Copying files to USetupData.DestinationRootPath should be done from within
- * the SystemPartitionFiles section.
- * At the moment we check whether we specify paths like '\foo' or '\\' for that.
- * For installing to USetupData.DestinationPath specify just '\' .
- */
-
- /* Get destination path */
- RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), USetupData.DestinationPath.Buffer);
+ INPUT_RECORD Ir;
+ va_list arg_ptr;
- DPRINT("FullPath(1): '%S'\n", PathBuffer);
+ va_start(arg_ptr, pSetupData);
- /* Create the install directory */
- Status = SetupCreateDirectory(PathBuffer);
- if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
+ if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
+ pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE)
{
- DPRINT1("Creating directory '%S' failed: Status = 0x%08lx\n", PathBuffer, Status);
- MUIDisplayError(ERROR_CREATE_INSTALL_DIR, Ir, POPUP_WAIT_ENTER);
- return FALSE;
+ // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber...
+ MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr);
}
- /* Search for the 'Directories' section */
- if (!SetupFindFirstLineW(InfFile, L"Directories", NULL, &DirContext))
- {
- if (SourceCabinet)
- MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER, L"Directories");
- else
- MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, L"Directories");
-
- return FALSE;
- }
-
- /* Enumerate the directory values and create the subdirectories */
- do
- {
- if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
- {
- DPRINT1("break\n");
- break;
- }
-
- if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
- {
- /* Installation path */
- DPRINT("InstallationPath: '%S'\n", DirKeyValue);
-
- RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer),
- USetupData.DestinationPath.Buffer);
-
- DPRINT("InstallationPath(2): '%S'\n", PathBuffer);
- }
- else if (DirKeyValue[0] == L'\\')
- {
- /* Absolute path */
- DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
- USetupData.DestinationRootPath.Buffer, DirKeyValue);
-
- DPRINT("AbsolutePath(2): '%S'\n", PathBuffer);
-
- Status = SetupCreateDirectory(PathBuffer);
- if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
- {
- INF_FreeData(DirKeyValue);
- DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
- MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
- return FALSE;
- }
- }
- else // if (DirKeyValue[0] != L'\\')
- {
- /* Path relative to the installation path */
- DPRINT("RelativePath: '%S'\n", DirKeyValue);
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
- USetupData.DestinationPath.Buffer, DirKeyValue);
-
- DPRINT("RelativePath(2): '%S'\n", PathBuffer);
-
- Status = SetupCreateDirectory(PathBuffer);
- if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
- {
- INF_FreeData(DirKeyValue);
- DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
- MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
- return FALSE;
- }
- }
-
- INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&DirContext, &DirContext));
-
- return TRUE;
+ va_end(arg_ptr);
}
-
/*
* Displays the PrepareCopyPage.
*
* QuitPage
*
* SIDEEFFECTS
- * Inits SetupFileQueue
- * Calls PrepareCopyPageInfFile
+ * Calls PrepareFileCopy
*
* RETURNS
* Number of the next page.
static PAGE_NUMBER
PrepareCopyPage(PINPUT_RECORD Ir)
{
- HINF InfHandle;
- WCHAR PathBuffer[MAX_PATH];
- INFCONTEXT CabinetsContext;
- ULONG InfFileSize;
- PWCHAR KeyValue;
- UINT ErrorLine;
- PVOID InfFileData;
+ // ERROR_NUMBER ErrorNumber;
+ BOOLEAN Success;
MUIDisplayPage(PREPARE_COPY_PAGE);
- /* Create the file queue */
- USetupData.SetupFileQueue = SetupOpenFileQueue();
- if (USetupData.SetupFileQueue == NULL)
- {
- MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
-
- if (!PrepareCopyPageInfFile(USetupData.SetupInf, NULL, Ir))
+ /* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL);
+ if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
{
- /* FIXME: show an error dialog */
+ // MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
- /* Search for the 'Cabinets' section */
- if (!SetupFindFirstLineW(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext))
- {
- return FILE_COPY_PAGE;
- }
-
- /*
- * Enumerate the directory values in the 'Cabinets'
- * section and parse their inf files.
- */
- do
- {
- if (!INF_GetData(&CabinetsContext, NULL, &KeyValue))
- break;
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
- USetupData.SourcePath.Buffer, KeyValue);
-
- CabinetInitialize();
- CabinetSetEventHandlers(NULL, NULL, NULL);
- CabinetSetCabinetName(PathBuffer);
-
- if (CabinetOpen() == CAB_STATUS_SUCCESS)
- {
- DPRINT("Cabinet %S\n", CabinetGetCabinetName());
-
- InfFileData = CabinetGetCabinetReservedArea(&InfFileSize);
- if (InfFileData == NULL)
- {
- MUIDisplayError(ERROR_CABINET_SCRIPT, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
- }
- else
- {
- DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
- MUIDisplayError(ERROR_CABINET_MISSING, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
-
- InfHandle = INF_OpenBufferedFileA((PSTR)InfFileData,
- InfFileSize,
- NULL,
- INF_STYLE_WIN4,
- USetupData.LanguageId,
- &ErrorLine);
-
- if (InfHandle == INVALID_HANDLE_VALUE)
- {
- MUIDisplayError(ERROR_INVALID_CABINET_INF, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
-
- CabinetCleanup();
-
- if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
- {
- /* FIXME: show an error dialog */
- return QUIT_PAGE;
- }
- } while (SetupFindNextLine(&CabinetsContext, &CabinetsContext));
-
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)
{
ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
}
-
static UINT
CALLBACK
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;
+
+ if (!wcsicmp(SrcFileName, DstFileName))
+ Param2 = STRING_MOVING;
+ else
+ Param2 = STRING_RENAMING;
+
+ CONSOLE_SetStatusText(MUIGetString(Param2),
+ SrcFileName, DstFileName);
+ }
+ else if (Notification == SPFILENOTIFY_STARTCOPY)
+ {
+ /* Display copy message */
+ ASSERT(Param2 == FILEOP_COPY);
+
+ /* NOTE: When extracting from CABs the Source is the CAB name */
+ DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+ if (DstFileName) ++DstFileName;
+ else DstFileName = FilePathInfo->Target;
+
+ CONSOLE_SetStatusText(MUIGetString(STRING_COPYING),
+ DstFileName);
+ }
+
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
+
+ case SPFILENOTIFY_COPYERROR:
+ {
+ FilePathInfo = (PFILEPATHS_W)Param1;
+
+ DPRINT1("An error happened while trying to copy file '%S' (error 0x%08lx), skipping it...\n",
+ FilePathInfo->Target, FilePathInfo->Win32Error);
+ return FILEOP_SKIP;
+ }
+ case SPFILENOTIFY_ENDDELETE:
+ case SPFILENOTIFY_ENDRENAME:
case SPFILENOTIFY_ENDCOPY:
+ {
CopyContext->CompletedOperations++;
/* SYSREG checkpoint */
ProgressNextStep(CopyContext->ProgressBar);
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
}
- return 0;
+ return FILEOP_DOIT;
}
* RegistryPage(At once)
*
* SIDEEFFECTS
- * Calls SetupCommitFileQueueW
- * Calls SetupCloseFileQueue
+ * Calls DoFileCopy
*
* RETURNS
* Number of the next page.
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 = USetupData.InstallPath.Buffer;
CopyContext.TotalOperations = 0;
CopyContext.CompletedOperations = 0;
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,
"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,
- USetupData.SetupFileQueue,
- FileCopyCallback,
- &CopyContext);
+ DoFileCopy(&USetupData, FileCopyCallback, &CopyContext);
- /* If we get here, we're done, so cleanup the queue and progress bar */
- SetupCloseFileQueue(USetupData.SetupFileQueue);
+ /* If we get here, we're done, so cleanup the progress bar */
DestroyProgressBar(CopyContext.ProgressBar);
DestroyProgressBar(CopyContext.MemoryBars[0]);
DestroyProgressBar(CopyContext.MemoryBars[1]);
MUIDisplayPage(REGISTRY_PAGE);
- Error = UpdateRegistry(USetupData.SetupInf,
- &USetupData,
+ Error = UpdateRegistry(&USetupData,
RepairUpdateFlag,
PartitionList,
DestinationDriveLetter,
SelectedLanguageId,
- USetupData.DisplayList,
- USetupData.LayoutList,
- USetupData.LanguageList,
RegistryStatus);
if (Error != ERROR_SUCCESS)
{
DPRINT("Found OS/2 boot manager partition\n");
InstallOnFloppy = TRUE;
}
- else if (PartitionType == PARTITION_EXT2)
+ else if (PartitionType == PARTITION_LINUX)
{
- /* Linux EXT2 partition */
- DPRINT("Found Linux EXT2 partition\n");
+ /* Linux partition */
+ DPRINT("Found Linux native partition (ext2/ext3/ReiserFS/BTRFS/etc)\n");
InstallOnFloppy = FALSE;
}
else if (PartitionType == PARTITION_IFS)
{
NTSTATUS Status;
+ // FIXME! We must not use the partition type, but instead use the partition FileSystem!!
Status = InstallVBRToPartition(&USetupData.SystemRootPath,
&USetupData.SourceRootPath,
&USetupData.DestinationArcPath,
PartitionList->SystemPartition->PartitionType);
if (!NT_SUCCESS(Status))
{
- MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
+ MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
+ PartitionList->SystemPartition->FileSystem->FileSystemName);
return QUIT_PAGE;
}
WCHAR DestinationDevicePathBuffer[MAX_PATH];
/* Step 1: Write the VBR */
+ // FIXME! We must not use the partition type, but instead use the partition FileSystem!!
Status = InstallVBRToPartition(&USetupData.SystemRootPath,
&USetupData.SourceRootPath,
&USetupData.DestinationArcPath,
PartitionList->SystemPartition->PartitionType);
if (!NT_SUCCESS(Status))
{
- MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
+ MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
+ PartitionList->SystemPartition->FileSystem->FileSystemName);
return QUIT_PAGE;
}
if (!NT_SUCCESS(Status))
{
DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n", Status);
- MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER);
+ MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER, L"MBR");
return QUIT_PAGE;
}
}
-DWORD WINAPI
-PnpEventThread(IN LPVOID lpParameter);
-
-
/*
* The start routine and page management
*/
if (!NT_SUCCESS(Status))
DPRINT1("NtInitializeRegistry() failed (Status 0x%08lx)\n", Status);
- /* Create the PnP thread in suspended state */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- PnpEventThread,
- &USetupData.SetupInf,
- &hPnpThread,
- NULL);
+ /* Initialize the user-mode PnP manager */
+ Status = InitializeUserModePnpManager(&USetupData.SetupInf);
if (!NT_SUCCESS(Status))
- hPnpThread = NULL;
+ {
+ // PrintString(??);
+ DPRINT1("The user-mode PnP manager could not initialize (Status 0x%08lx), expect unavailable devices!\n", Status);
+ }
if (!CONSOLE_Init())
{
/* Initialize Setup, phase 0 */
InitializeSetup(&USetupData, 0);
+ USetupData.ErrorRoutine = USetupErrorRoutine;
- /* Hide the cursor */
+ /* Hide the cursor and clear the screen and keyboard buffer */
CONSOLE_SetCursorType(TRUE, FALSE);
-
- /* Global Initialization page */
CONSOLE_ClearScreen();
CONSOLE_Flush();
+
+ /* Global Initialization page */
Page = SetupStartPage(&Ir);
while (Page != REBOOT_PAGE && Page != RECOVERY_PAGE)
Page = QuitPage(&Ir);
break;
- case RECOVERY_PAGE:
+ /* Virtual pages */
+ case SETUP_INIT_PAGE:
case REBOOT_PAGE:
+ case RECOVERY_PAGE:
break;
}
}
+ /* Terminate the user-mode PnP manager */
+ TerminateUserModePnpManager();
+
/* Setup has finished */
FinishSetup(&USetupData);