mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[SETUPLIB][USETUP] Isolate and decouple the filesystem operations code from the UI (#7049)
The idea is reminiscent of the SetupCommitFileQueue() function: filesystem volume operations are "queued" and processed via a "commit queue". The commit queue uses a user-specified callback, that is used to interact with the user whenever an operation (filesystem formatting, checking) is started, ended, or fails, for example by displaying appropriate UI screens and choices, etc.
This commit is contained in:
parent
a207a3c931
commit
a7a7e6a09c
16 changed files with 1377 additions and 1112 deletions
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions.
|
||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Copyright 2017-2020 Hermes Belusca-Maito
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions
|
||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
* Copyright 2017-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
//
|
||||
|
@ -242,13 +242,13 @@ GetFileSystemByName(
|
|||
/** ChkdskEx() **/
|
||||
NTSTATUS
|
||||
ChkdskFileSystem_UStr(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PUNICODE_STRING DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
PFILE_SYSTEM FileSystem;
|
||||
NTSTATUS Status;
|
||||
|
@ -285,13 +285,13 @@ ChkdskFileSystem_UStr(
|
|||
|
||||
NTSTATUS
|
||||
ChkdskFileSystem(
|
||||
IN PCWSTR DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PCWSTR DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
UNICODE_STRING DriveRootU;
|
||||
|
||||
|
@ -309,13 +309,13 @@ ChkdskFileSystem(
|
|||
/** FormatEx() **/
|
||||
NTSTATUS
|
||||
FormatFileSystem_UStr(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PUNICODE_STRING DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PUNICODE_STRING Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
PFILE_SYSTEM FileSystem;
|
||||
BOOLEAN Success;
|
||||
|
@ -374,13 +374,13 @@ FormatFileSystem_UStr(
|
|||
|
||||
NTSTATUS
|
||||
FormatFileSystem(
|
||||
IN PCWSTR DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PCWSTR Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PCWSTR DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PCWSTR Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
UNICODE_STRING DriveRootU;
|
||||
UNICODE_STRING LabelU;
|
||||
|
@ -755,26 +755,22 @@ Quit:
|
|||
|
||||
NTSTATUS
|
||||
ChkdskPartition(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
|
||||
// UNICODE_STRING PartitionRootPath;
|
||||
WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
|
||||
|
||||
ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
|
||||
|
||||
/* HACK: Do not try to check a partition with an unknown filesystem */
|
||||
/* Do not check a partition with an unknown file system */
|
||||
if (!*PartEntry->FileSystem)
|
||||
{
|
||||
PartEntry->NeedsCheck = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNRECOGNIZED_VOLUME; // STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* Set PartitionRootPath */
|
||||
RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
|
||||
|
@ -784,29 +780,24 @@ ChkdskPartition(
|
|||
DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
|
||||
|
||||
/* Check the partition */
|
||||
Status = ChkdskFileSystem(PartitionRootPath,
|
||||
PartEntry->FileSystem,
|
||||
FixErrors,
|
||||
Verbose,
|
||||
CheckOnlyIfDirty,
|
||||
ScanDrive,
|
||||
Callback);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
PartEntry->NeedsCheck = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
return ChkdskFileSystem(PartitionRootPath,
|
||||
PartEntry->FileSystem,
|
||||
FixErrors,
|
||||
Verbose,
|
||||
CheckOnlyIfDirty,
|
||||
ScanDrive,
|
||||
Callback);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FormatPartition(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PCWSTR Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PCWSTR Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
|
||||
|
@ -824,7 +815,7 @@ FormatPartition(
|
|||
|
||||
/*
|
||||
* Prepare the partition for formatting (for MBR disks, reset the
|
||||
* partition type), and adjust the filesystem name in case of FAT
|
||||
* partition type), and adjust the file system name in case of FAT
|
||||
* vs. FAT32, depending on the geometry of the partition.
|
||||
*/
|
||||
|
||||
|
@ -832,7 +823,7 @@ FormatPartition(
|
|||
|
||||
/*
|
||||
* Retrieve a partition type as a hint only. It will be used to determine
|
||||
* whether to actually use FAT12/16 or FAT32 filesystem, depending on the
|
||||
* whether to actually use FAT12/16 or FAT32 file system, depending on the
|
||||
* geometry of the partition. If the partition resides on an MBR disk,
|
||||
* the partition style will be reset to this value as well, unless the
|
||||
* partition is OEM.
|
||||
|
@ -855,7 +846,7 @@ FormatPartition(
|
|||
}
|
||||
|
||||
/*
|
||||
* Adjust the filesystem name in case of FAT vs. FAT32, according to
|
||||
* Adjust the file system name in case of FAT vs. FAT32, according to
|
||||
* the type of partition returned by FileSystemToMBRPartitionType().
|
||||
*/
|
||||
if (wcsicmp(FileSystemName, L"FAT") == 0)
|
||||
|
@ -910,4 +901,450 @@ FormatPartition(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FileSystem Volume Operations Queue
|
||||
//
|
||||
|
||||
static FSVOL_OP
|
||||
DoFormatting(
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_opt_ PVOID Context,
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback)
|
||||
{
|
||||
FSVOL_OP Result;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
FORMAT_VOLUME_INFO FmtInfo = {0};
|
||||
|
||||
ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
|
||||
|
||||
FmtInfo.PartEntry = PartEntry;
|
||||
|
||||
RetryFormat:
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_STARTFORMAT,
|
||||
(ULONG_PTR)&FmtInfo,
|
||||
FSVOL_FORMAT);
|
||||
if (Result != FSVOL_DOIT)
|
||||
goto EndFormat;
|
||||
|
||||
ASSERT(FmtInfo.FileSystemName && *FmtInfo.FileSystemName);
|
||||
|
||||
/* Format the partition */
|
||||
Status = FormatPartition(PartEntry,
|
||||
FmtInfo.FileSystemName,
|
||||
FmtInfo.MediaFlag,
|
||||
FmtInfo.Label,
|
||||
FmtInfo.QuickFormat,
|
||||
FmtInfo.ClusterSize,
|
||||
FmtInfo.Callback);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
// FmtInfo.NtPathPartition = PathBuffer;
|
||||
FmtInfo.ErrorStatus = Status;
|
||||
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_FORMATERROR,
|
||||
(ULONG_PTR)&FmtInfo,
|
||||
0);
|
||||
if (Result == FSVOL_RETRY)
|
||||
goto RetryFormat;
|
||||
// else if (Result == FSVOL_ABORT || Result == FSVOL_SKIP), stop.
|
||||
}
|
||||
|
||||
EndFormat:
|
||||
/* This notification is always sent, even in case of error or abort */
|
||||
FmtInfo.ErrorStatus = Status;
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_ENDFORMAT,
|
||||
(ULONG_PTR)&FmtInfo,
|
||||
0);
|
||||
return Result;
|
||||
}
|
||||
|
||||
static FSVOL_OP
|
||||
DoChecking(
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_opt_ PVOID Context,
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback)
|
||||
{
|
||||
FSVOL_OP Result;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
CHECK_VOLUME_INFO ChkInfo = {0};
|
||||
|
||||
ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
|
||||
|
||||
ASSERT(*PartEntry->FileSystem);
|
||||
|
||||
ChkInfo.PartEntry = PartEntry;
|
||||
|
||||
RetryCheck:
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_STARTCHECK,
|
||||
(ULONG_PTR)&ChkInfo,
|
||||
FSVOL_CHECK);
|
||||
if (Result != FSVOL_DOIT)
|
||||
goto EndCheck;
|
||||
|
||||
/* Check the partition */
|
||||
Status = ChkdskPartition(PartEntry,
|
||||
ChkInfo.FixErrors,
|
||||
ChkInfo.Verbose,
|
||||
ChkInfo.CheckOnlyIfDirty,
|
||||
ChkInfo.ScanDrive,
|
||||
ChkInfo.Callback);
|
||||
|
||||
/* If volume checking succeeded, or if it is not supported
|
||||
* with the current file system, disable checks on the volume */
|
||||
if (NT_SUCCESS(Status) || (Status == STATUS_NOT_SUPPORTED))
|
||||
PartEntry->NeedsCheck = FALSE;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
// ChkInfo.NtPathPartition = PathBuffer;
|
||||
ChkInfo.ErrorStatus = Status;
|
||||
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_CHECKERROR,
|
||||
(ULONG_PTR)&ChkInfo,
|
||||
0);
|
||||
if (Result == FSVOL_RETRY)
|
||||
goto RetryCheck;
|
||||
// else if (Result == FSVOL_ABORT || Result == FSVOL_SKIP), stop.
|
||||
|
||||
// PartEntry->NeedsCheck = FALSE;
|
||||
}
|
||||
|
||||
EndCheck:
|
||||
/* This notification is always sent, even in case of error or abort */
|
||||
ChkInfo.ErrorStatus = Status;
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_ENDCHECK,
|
||||
(ULONG_PTR)&ChkInfo,
|
||||
0);
|
||||
return Result;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
GetNextUnformattedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PPARTENTRY *pPartEntry)
|
||||
{
|
||||
PLIST_ENTRY Entry1, Entry2;
|
||||
PDISKENTRY DiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
for (Entry1 = List->DiskListHead.Flink;
|
||||
Entry1 != &List->DiskListHead;
|
||||
Entry1 = Entry1->Flink)
|
||||
{
|
||||
DiskEntry = CONTAINING_RECORD(Entry1,
|
||||
DISKENTRY,
|
||||
ListEntry);
|
||||
|
||||
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
|
||||
{
|
||||
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->PrimaryPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->New)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->LogicalPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->New)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pPartEntry = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
GetNextUncheckedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PPARTENTRY *pPartEntry)
|
||||
{
|
||||
PLIST_ENTRY Entry1, Entry2;
|
||||
PDISKENTRY DiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
for (Entry1 = List->DiskListHead.Flink;
|
||||
Entry1 != &List->DiskListHead;
|
||||
Entry1 = Entry1->Flink)
|
||||
{
|
||||
DiskEntry = CONTAINING_RECORD(Entry1,
|
||||
DISKENTRY,
|
||||
ListEntry);
|
||||
|
||||
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
|
||||
{
|
||||
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->PrimaryPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->LogicalPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pPartEntry = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FsVolCommitOpsQueue(
|
||||
_In_ PPARTLIST PartitionList,
|
||||
_In_ PPARTENTRY SystemPartition,
|
||||
_In_ PPARTENTRY InstallPartition,
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback,
|
||||
_In_opt_ PVOID Context)
|
||||
{
|
||||
BOOLEAN Success = TRUE; // Suppose success originally.
|
||||
FSVOL_OP Result;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
/* Machine state for the format step */
|
||||
typedef enum _FORMATMACHINESTATE
|
||||
{
|
||||
Start,
|
||||
FormatSystemVolume,
|
||||
FormatInstallVolume,
|
||||
FormatOtherVolume,
|
||||
FormatDone
|
||||
} FORMATMACHINESTATE;
|
||||
FORMATMACHINESTATE FormatState, OldFormatState;
|
||||
static const PCSTR FormatStateNames[] = {
|
||||
"Start",
|
||||
"FormatSystemVolume",
|
||||
"FormatInstallVolume",
|
||||
"FormatOtherVolume",
|
||||
"FormatDone"
|
||||
};
|
||||
|
||||
ASSERT(PartitionList && InstallPartition && SystemPartition);
|
||||
|
||||
/* Commit all partition changes to all the disks */
|
||||
if (!WritePartitionsToDisk(PartitionList))
|
||||
{
|
||||
DPRINT("WritePartitionsToDisk() failed\n");
|
||||
/* Result = */ FsVolCallback(Context,
|
||||
FSVOLNOTIFY_PARTITIONERROR,
|
||||
STATUS_PARTITION_FAILURE, // FIXME
|
||||
0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME: Should we do the following here, or in the caller?
|
||||
//
|
||||
/*
|
||||
* In all cases, whether or not we are going to perform a formatting,
|
||||
* we must perform a file system check of both the system and the
|
||||
* installation volumes.
|
||||
*/
|
||||
SystemPartition->NeedsCheck = TRUE;
|
||||
InstallPartition->NeedsCheck = TRUE;
|
||||
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_STARTQUEUE,
|
||||
0, 0);
|
||||
if (Result == FSVOL_ABORT)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Commit the Format queue
|
||||
*/
|
||||
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_STARTSUBQUEUE,
|
||||
FSVOL_FORMAT,
|
||||
0);
|
||||
if (Result == FSVOL_ABORT)
|
||||
return FALSE;
|
||||
/** HACK!! **/
|
||||
if (Result == FSVOL_SKIP)
|
||||
goto StartCheckQueue;
|
||||
/** END HACK!! **/
|
||||
|
||||
/* Reset the formatter machine state */
|
||||
FormatState = Start;
|
||||
NextFormat:
|
||||
PartEntry = NULL;
|
||||
OldFormatState = FormatState;
|
||||
switch (FormatState)
|
||||
{
|
||||
case Start:
|
||||
{
|
||||
/*
|
||||
* We start by formatting the system volume in case it is new
|
||||
* (it didn't exist before) and is not the same as the installation
|
||||
* volume. Otherwise we just require a file system check on it,
|
||||
* and start by formatting the installation volume instead.
|
||||
*/
|
||||
ASSERT(SystemPartition->IsPartitioned);
|
||||
if (SystemPartition != InstallPartition)
|
||||
{
|
||||
PartEntry = SystemPartition;
|
||||
|
||||
if (PartEntry->FormatState == Unformatted)
|
||||
{
|
||||
// TODO: Should we let the user use a custom file system,
|
||||
// or should we always use FAT(32) for it?
|
||||
// For "compatibility", FAT(32) would be best indeed.
|
||||
|
||||
FormatState = FormatSystemVolume;
|
||||
DPRINT1("FormatState: %s --> %s\n",
|
||||
FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The system volume is separate, so it had better be formatted! */
|
||||
ASSERT((PartEntry->FormatState == Preformatted) ||
|
||||
(PartEntry->FormatState == Formatted));
|
||||
|
||||
/* Require a file system check on the system volume too */
|
||||
PartEntry->NeedsCheck = TRUE;
|
||||
}
|
||||
__fallthrough;
|
||||
}
|
||||
|
||||
case FormatSystemVolume:
|
||||
{
|
||||
PartEntry = InstallPartition;
|
||||
|
||||
FormatState = FormatInstallVolume;
|
||||
DPRINT1("FormatState: %s --> %s\n",
|
||||
FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
|
||||
break;
|
||||
}
|
||||
|
||||
case FormatInstallVolume:
|
||||
case FormatOtherVolume:
|
||||
{
|
||||
BOOLEAN Found = GetNextUnformattedPartition(PartitionList, &PartEntry);
|
||||
if (Found) ASSERT(PartEntry);
|
||||
|
||||
FormatState = (PartEntry ? FormatOtherVolume : FormatDone);
|
||||
DPRINT1("FormatState: %s --> %s\n",
|
||||
FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
|
||||
if (Found)
|
||||
break;
|
||||
__fallthrough;
|
||||
}
|
||||
|
||||
case FormatDone:
|
||||
{
|
||||
DPRINT1("FormatState: FormatDone\n");
|
||||
Success = TRUE;
|
||||
goto EndFormat;
|
||||
}
|
||||
DEFAULT_UNREACHABLE;
|
||||
}
|
||||
|
||||
ASSERT(PartEntry);
|
||||
Result = DoFormatting(PartEntry, Context, FsVolCallback);
|
||||
if (Result == FSVOL_ABORT)
|
||||
{
|
||||
Success = FALSE;
|
||||
goto Quit;
|
||||
}
|
||||
/* Schedule a check for this volume */
|
||||
PartEntry->NeedsCheck = TRUE;
|
||||
/* Go to the next volume to be formatted */
|
||||
goto NextFormat;
|
||||
|
||||
EndFormat:
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_ENDSUBQUEUE,
|
||||
FSVOL_FORMAT,
|
||||
0);
|
||||
|
||||
|
||||
/*
|
||||
* Commit the CheckFS queue
|
||||
*/
|
||||
|
||||
StartCheckQueue:
|
||||
Result = FsVolCallback(Context,
|
||||
FSVOLNOTIFY_STARTSUBQUEUE,
|
||||
FSVOL_CHECK,
|
||||
0);
|
||||
if (Result == FSVOL_ABORT)
|
||||
return FALSE;
|
||||
|
||||
NextCheck:
|
||||
if (!GetNextUncheckedPartition(PartitionList, &PartEntry))
|
||||
{
|
||||
Success = TRUE;
|
||||
goto EndCheck;
|
||||
}
|
||||
|
||||
ASSERT(PartEntry);
|
||||
Result = DoChecking(PartEntry, Context, FsVolCallback);
|
||||
if (Result == FSVOL_ABORT)
|
||||
{
|
||||
Success = FALSE;
|
||||
goto Quit;
|
||||
}
|
||||
/* Go to the next volume to be checked */
|
||||
goto NextCheck;
|
||||
|
||||
EndCheck:
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_ENDSUBQUEUE,
|
||||
FSVOL_CHECK,
|
||||
0);
|
||||
|
||||
|
||||
Quit:
|
||||
/* All the queues have been committed */
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_ENDQUEUE,
|
||||
Success,
|
||||
0);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions.
|
||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Copyright 2017-2020 Hermes Belusca-Maito
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions
|
||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
* Copyright 2017-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -20,45 +20,45 @@ GetRegisteredFileSystems(
|
|||
/** ChkdskEx() **/
|
||||
NTSTATUS
|
||||
ChkdskFileSystem_UStr(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PUNICODE_STRING DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
NTSTATUS
|
||||
ChkdskFileSystem(
|
||||
IN PCWSTR DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PCWSTR DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
|
||||
/** FormatEx() **/
|
||||
NTSTATUS
|
||||
FormatFileSystem_UStr(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PUNICODE_STRING DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PUNICODE_STRING Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
NTSTATUS
|
||||
FormatFileSystem(
|
||||
IN PCWSTR DriveRoot,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PCWSTR Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PCWSTR DriveRoot,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PCWSTR Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
|
||||
//
|
||||
|
@ -110,21 +110,101 @@ InstallNtfsBootCode(
|
|||
|
||||
NTSTATUS
|
||||
ChkdskPartition(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_ BOOLEAN FixErrors,
|
||||
_In_ BOOLEAN Verbose,
|
||||
_In_ BOOLEAN CheckOnlyIfDirty,
|
||||
_In_ BOOLEAN ScanDrive,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
NTSTATUS
|
||||
FormatPartition(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PCWSTR Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback);
|
||||
_In_ PPARTENTRY PartEntry,
|
||||
_In_ PCWSTR FileSystemName,
|
||||
_In_ FMIFS_MEDIA_FLAG MediaFlag,
|
||||
_In_opt_ PCWSTR Label,
|
||||
_In_ BOOLEAN QuickFormat,
|
||||
_In_ ULONG ClusterSize,
|
||||
_In_opt_ PFMIFSCALLBACK Callback);
|
||||
|
||||
|
||||
//
|
||||
// FileSystem Volume Operations Queue
|
||||
//
|
||||
|
||||
typedef enum _FSVOLNOTIFY
|
||||
{
|
||||
FSVOLNOTIFY_STARTQUEUE = 0,
|
||||
FSVOLNOTIFY_ENDQUEUE,
|
||||
FSVOLNOTIFY_STARTSUBQUEUE,
|
||||
FSVOLNOTIFY_ENDSUBQUEUE,
|
||||
// FSVOLNOTIFY_STARTPARTITION, FSVOLNOTIFY_ENDPARTITION,
|
||||
FSVOLNOTIFY_PARTITIONERROR,
|
||||
FSVOLNOTIFY_STARTFORMAT,
|
||||
FSVOLNOTIFY_ENDFORMAT,
|
||||
FSVOLNOTIFY_FORMATERROR,
|
||||
FSVOLNOTIFY_STARTCHECK,
|
||||
FSVOLNOTIFY_ENDCHECK,
|
||||
FSVOLNOTIFY_CHECKERROR,
|
||||
/**/ChangeSystemPartition/**/ // FIXME: Deprecate!
|
||||
} FSVOLNOTIFY;
|
||||
|
||||
typedef enum _FSVOL_OP
|
||||
{
|
||||
/* Operations ****/
|
||||
FSVOL_FORMAT = 0,
|
||||
FSVOL_CHECK,
|
||||
/* Response actions ****/
|
||||
FSVOL_ABORT = 0,
|
||||
FSVOL_DOIT,
|
||||
FSVOL_RETRY = FSVOL_DOIT,
|
||||
FSVOL_SKIP,
|
||||
} FSVOL_OP;
|
||||
|
||||
typedef struct _FORMAT_VOLUME_INFO
|
||||
{
|
||||
PPARTENTRY PartEntry;
|
||||
// PCWSTR NtPathPartition;
|
||||
NTSTATUS ErrorStatus;
|
||||
|
||||
/* Input information given by the 'FSVOLNOTIFY_STARTFORMAT' step ****/
|
||||
PCWSTR FileSystemName;
|
||||
FMIFS_MEDIA_FLAG MediaFlag;
|
||||
PCWSTR Label;
|
||||
BOOLEAN QuickFormat;
|
||||
ULONG ClusterSize;
|
||||
PFMIFSCALLBACK Callback;
|
||||
|
||||
} FORMAT_VOLUME_INFO, *PFORMAT_VOLUME_INFO;
|
||||
|
||||
typedef struct _CHECK_VOLUME_INFO
|
||||
{
|
||||
PPARTENTRY PartEntry;
|
||||
// PCWSTR NtPathPartition;
|
||||
NTSTATUS ErrorStatus;
|
||||
|
||||
/* Input information given by the 'FSVOLNOTIFY_STARTCHECK' step ****/
|
||||
BOOLEAN FixErrors;
|
||||
BOOLEAN Verbose;
|
||||
BOOLEAN CheckOnlyIfDirty;
|
||||
BOOLEAN ScanDrive;
|
||||
PFMIFSCALLBACK Callback;
|
||||
|
||||
} CHECK_VOLUME_INFO, *PCHECK_VOLUME_INFO;
|
||||
|
||||
typedef FSVOL_OP
|
||||
(CALLBACK *PFSVOL_CALLBACK)(
|
||||
_In_opt_ PVOID Context,
|
||||
_In_ FSVOLNOTIFY FormatStatus,
|
||||
_In_ ULONG_PTR Param1,
|
||||
_In_ ULONG_PTR Param2);
|
||||
|
||||
BOOLEAN
|
||||
FsVolCommitOpsQueue(
|
||||
_In_ PPARTLIST PartitionList,
|
||||
_In_ PPARTENTRY SystemPartition,
|
||||
_In_ PPARTENTRY InstallPartition,
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback,
|
||||
_In_opt_ PVOID Context);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -619,6 +619,99 @@ LoadSetupInf(
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find or set the active system partition.
|
||||
**/
|
||||
BOOLEAN
|
||||
InitSystemPartition(
|
||||
/**/_In_ PPARTLIST PartitionList, /* HACK HACK! */
|
||||
/**/_In_ PPARTENTRY InstallPartition, /* HACK HACK! */
|
||||
/**/_Out_ PPARTENTRY* pSystemPartition, /* HACK HACK! */
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback,
|
||||
_In_opt_ PVOID Context)
|
||||
{
|
||||
FSVOL_OP Result;
|
||||
PPARTENTRY SystemPartition;
|
||||
PPARTENTRY OldActivePart;
|
||||
|
||||
/*
|
||||
* If we install on a fixed disk, try to find a supported system
|
||||
* partition on the system. Otherwise if we install on a removable disk
|
||||
* use the install partition as the system partition.
|
||||
*/
|
||||
if (InstallPartition->DiskEntry->MediaType == FixedMedia)
|
||||
{
|
||||
SystemPartition = FindSupportedSystemPartition(PartitionList,
|
||||
FALSE,
|
||||
InstallPartition->DiskEntry,
|
||||
InstallPartition);
|
||||
/* Use the original system partition as the old active partition hint */
|
||||
OldActivePart = PartitionList->SystemPartition;
|
||||
|
||||
if ( SystemPartition && PartitionList->SystemPartition &&
|
||||
(SystemPartition != PartitionList->SystemPartition) )
|
||||
{
|
||||
DPRINT1("We are using a different system partition!!\n");
|
||||
|
||||
Result = FsVolCallback(Context,
|
||||
ChangeSystemPartition,
|
||||
(ULONG_PTR)SystemPartition,
|
||||
0);
|
||||
if (Result != FSVOL_DOIT)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else // if (InstallPartition->DiskEntry->MediaType == RemovableMedia)
|
||||
{
|
||||
SystemPartition = InstallPartition;
|
||||
/* Don't specify any old active partition hint */
|
||||
OldActivePart = NULL;
|
||||
}
|
||||
|
||||
if (!SystemPartition)
|
||||
{
|
||||
FsVolCallback(Context,
|
||||
FSVOLNOTIFY_PARTITIONERROR,
|
||||
ERROR_SYSTEM_PARTITION_NOT_FOUND,
|
||||
0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pSystemPartition = SystemPartition;
|
||||
|
||||
/*
|
||||
* If the system partition can be created in some
|
||||
* non-partitioned space, create it now.
|
||||
*/
|
||||
if (!SystemPartition->IsPartitioned)
|
||||
{
|
||||
/* Automatically create the partition; it will be
|
||||
* formatted later with default parameters */
|
||||
// FIXME: Don't use the whole empty space, but a minimal size
|
||||
// specified from the TXTSETUP.SIF or unattended setup.
|
||||
CreatePartition(PartitionList,
|
||||
SystemPartition,
|
||||
0ULL,
|
||||
0);
|
||||
ASSERT(SystemPartition->IsPartitioned);
|
||||
}
|
||||
|
||||
/* Set it as such */
|
||||
if (!SetActivePartition(PartitionList, SystemPartition, OldActivePart))
|
||||
{
|
||||
DPRINT1("SetActivePartition(0x%p) failed?!\n", SystemPartition);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* In all cases, whether or not we are going to perform a formatting,
|
||||
* we must perform a filesystem check of the system partition.
|
||||
*/
|
||||
SystemPartition->NeedsCheck = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
InitDestinationPaths(
|
||||
IN OUT PUSETUP_DATA pSetupData,
|
||||
|
|
|
@ -167,6 +167,16 @@ ERROR_NUMBER
|
|||
LoadSetupInf(
|
||||
IN OUT PUSETUP_DATA pSetupData);
|
||||
|
||||
#define ERROR_SYSTEM_PARTITION_NOT_FOUND (ERROR_LAST_ERROR_CODE + 1)
|
||||
|
||||
BOOLEAN
|
||||
InitSystemPartition(
|
||||
/**/_In_ PPARTLIST PartitionList, /* HACK HACK! */
|
||||
/**/_In_ PPARTENTRY InstallPartition, /* HACK HACK! */
|
||||
/**/_Out_ PPARTENTRY* pSystemPartition, /* HACK HACK! */
|
||||
_In_opt_ PFSVOL_CALLBACK FsVolCallback,
|
||||
_In_opt_ PVOID Context);
|
||||
|
||||
NTSTATUS
|
||||
InitDestinationPaths(
|
||||
IN OUT PUSETUP_DATA pSetupData,
|
||||
|
|
|
@ -3946,122 +3946,4 @@ SetMBRPartitionType(
|
|||
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetNextUnformattedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PDISKENTRY *pDiskEntry OPTIONAL,
|
||||
OUT PPARTENTRY *pPartEntry)
|
||||
{
|
||||
PLIST_ENTRY Entry1, Entry2;
|
||||
PDISKENTRY DiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
for (Entry1 = List->DiskListHead.Flink;
|
||||
Entry1 != &List->DiskListHead;
|
||||
Entry1 = Entry1->Flink)
|
||||
{
|
||||
DiskEntry = CONTAINING_RECORD(Entry1,
|
||||
DISKENTRY,
|
||||
ListEntry);
|
||||
|
||||
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
|
||||
{
|
||||
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->PrimaryPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->New)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
if (pDiskEntry) *pDiskEntry = DiskEntry;
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->LogicalPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->New)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
if (pDiskEntry) *pDiskEntry = DiskEntry;
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pDiskEntry) *pDiskEntry = NULL;
|
||||
*pPartEntry = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
GetNextUncheckedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PDISKENTRY *pDiskEntry OPTIONAL,
|
||||
OUT PPARTENTRY *pPartEntry)
|
||||
{
|
||||
PLIST_ENTRY Entry1, Entry2;
|
||||
PDISKENTRY DiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
for (Entry1 = List->DiskListHead.Flink;
|
||||
Entry1 != &List->DiskListHead;
|
||||
Entry1 = Entry1->Flink)
|
||||
{
|
||||
DiskEntry = CONTAINING_RECORD(Entry1,
|
||||
DISKENTRY,
|
||||
ListEntry);
|
||||
|
||||
if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
|
||||
{
|
||||
DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->PrimaryPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
if (pDiskEntry) *pDiskEntry = DiskEntry;
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
|
||||
Entry2 != &DiskEntry->LogicalPartListHead;
|
||||
Entry2 = Entry2->Flink)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
|
||||
{
|
||||
ASSERT(DiskEntry == PartEntry->DiskEntry);
|
||||
if (pDiskEntry) *pDiskEntry = DiskEntry;
|
||||
*pPartEntry = PartEntry;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pDiskEntry) *pDiskEntry = NULL;
|
||||
*pPartEntry = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -353,16 +353,4 @@ SetMBRPartitionType(
|
|||
IN PPARTENTRY PartEntry,
|
||||
IN UCHAR PartitionType);
|
||||
|
||||
BOOLEAN
|
||||
GetNextUnformattedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PDISKENTRY *pDiskEntry OPTIONAL,
|
||||
OUT PPARTENTRY *pPartEntry);
|
||||
|
||||
BOOLEAN
|
||||
GetNextUncheckedPartition(
|
||||
IN PPARTLIST List,
|
||||
OUT PDISKENTRY *pDiskEntry OPTIONAL,
|
||||
OUT PPARTENTRY *pPartEntry);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -13,12 +13,11 @@ list(APPEND SOURCE
|
|||
spapisup/cabinet.c
|
||||
spapisup/fileqsup.c
|
||||
spapisup/infsupp.c
|
||||
chkdsk.c
|
||||
cmdcons.c
|
||||
console.c
|
||||
consup.c
|
||||
devinst.c
|
||||
format.c
|
||||
fmtchk.c
|
||||
fslist.c
|
||||
genlist.c
|
||||
keytrans.c
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2006 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/chkdsk.c
|
||||
* PURPOSE: Filesystem chkdsk support functions
|
||||
* PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "usetup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static PPROGRESSBAR ChkdskProgressBar = NULL;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ChkdskCallback(
|
||||
IN CALLBACKCOMMAND Command,
|
||||
IN ULONG Modifier,
|
||||
IN PVOID Argument)
|
||||
{
|
||||
switch (Command)
|
||||
{
|
||||
default:
|
||||
DPRINT("Unknown callback %lu\n", (ULONG)Command);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DoChkdsk(
|
||||
IN PPARTENTRY PartEntry)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChkdskProgressBar = CreateProgressBar(6,
|
||||
yScreen - 14,
|
||||
xScreen - 7,
|
||||
yScreen - 10,
|
||||
10,
|
||||
24,
|
||||
TRUE,
|
||||
MUIGetString(STRING_CHECKINGDISK));
|
||||
|
||||
ProgressSetStepCount(ChkdskProgressBar, 100);
|
||||
|
||||
// TODO: Think about which values could be defaulted...
|
||||
Status = ChkdskPartition(PartEntry,
|
||||
TRUE, /* FixErrors */
|
||||
FALSE, /* Verbose */
|
||||
TRUE, /* CheckOnlyIfDirty */
|
||||
FALSE, /* ScanDrive */
|
||||
ChkdskCallback); /* Callback */
|
||||
|
||||
DestroyProgressBar(ChkdskProgressBar);
|
||||
ChkdskProgressBar = NULL;
|
||||
|
||||
DPRINT("ChkdskPartition() finished with status 0x%08lx\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2006 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/chkdsk.h
|
||||
* PURPOSE: Filesystem chkdsk support functions
|
||||
* PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
NTSTATUS
|
||||
DoChkdsk(
|
||||
IN PPARTENTRY PartEntry);
|
||||
|
||||
/* EOF */
|
159
base/setup/usetup/fmtchk.c
Normal file
159
base/setup/usetup/fmtchk.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions
|
||||
* COPYRIGHT: Copyright 2003 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
* Copyright 2006 Hervé Poussineau <hpoussin@reactos.org>
|
||||
* Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "usetup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static PPROGRESSBAR ProgressBar = NULL;
|
||||
|
||||
/* FORMAT FUNCTIONS **********************************************************/
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FormatCallback(
|
||||
_In_ CALLBACKCOMMAND Command,
|
||||
_In_ ULONG Modifier,
|
||||
_In_ PVOID Argument)
|
||||
{
|
||||
switch (Command)
|
||||
{
|
||||
case PROGRESS:
|
||||
{
|
||||
PULONG Percent = (PULONG)Argument;
|
||||
DPRINT("%lu percent completed\n", *Percent);
|
||||
ProgressSetStep(ProgressBar, *Percent);
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case OUTPUT:
|
||||
{
|
||||
PTEXTOUTPUT output = (PTEXTOUTPUT)Argument;
|
||||
DPRINT("%s\n", output->Output);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case DONE:
|
||||
{
|
||||
#if 0
|
||||
PBOOLEAN Success = (PBOOLEAN)Argument;
|
||||
if (*Success == FALSE)
|
||||
{
|
||||
DPRINT("FormatEx was unable to complete successfully.\n\n");
|
||||
}
|
||||
#endif
|
||||
DPRINT("Done\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DPRINT("Unknown callback %lu\n", (ULONG)Command);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
StartFormat(
|
||||
_Inout_ PFORMAT_VOLUME_INFO FmtInfo,
|
||||
_In_ PFILE_SYSTEM_ITEM SelectedFileSystem)
|
||||
{
|
||||
ASSERT(SelectedFileSystem && SelectedFileSystem->FileSystem);
|
||||
|
||||
// TODO: Think about which values could be defaulted...
|
||||
FmtInfo->FileSystemName = SelectedFileSystem->FileSystem;
|
||||
FmtInfo->MediaFlag = FMIFS_HARDDISK;
|
||||
FmtInfo->Label = NULL;
|
||||
FmtInfo->QuickFormat = SelectedFileSystem->QuickFormat;
|
||||
FmtInfo->ClusterSize = 0;
|
||||
FmtInfo->Callback = FormatCallback;
|
||||
|
||||
ProgressBar = CreateProgressBar(6,
|
||||
yScreen - 14,
|
||||
xScreen - 7,
|
||||
yScreen - 10,
|
||||
10,
|
||||
24,
|
||||
TRUE,
|
||||
MUIGetString(STRING_FORMATTINGPART));
|
||||
|
||||
ProgressSetStepCount(ProgressBar, 100);
|
||||
}
|
||||
|
||||
VOID
|
||||
EndFormat(
|
||||
_In_ NTSTATUS Status)
|
||||
{
|
||||
DestroyProgressBar(ProgressBar);
|
||||
ProgressBar = NULL;
|
||||
|
||||
DPRINT("FormatPartition() finished with status 0x%08lx\n", Status);
|
||||
}
|
||||
|
||||
/* CHKDSK FUNCTIONS **********************************************************/
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ChkdskCallback(
|
||||
_In_ CALLBACKCOMMAND Command,
|
||||
_In_ ULONG Modifier,
|
||||
_In_ PVOID Argument)
|
||||
{
|
||||
switch (Command)
|
||||
{
|
||||
default:
|
||||
DPRINT("Unknown callback %lu\n", (ULONG)Command);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
StartCheck(
|
||||
_Inout_ PCHECK_VOLUME_INFO ChkInfo)
|
||||
{
|
||||
// TODO: Think about which values could be defaulted...
|
||||
ChkInfo->FixErrors = TRUE;
|
||||
ChkInfo->Verbose = FALSE;
|
||||
ChkInfo->CheckOnlyIfDirty = TRUE;
|
||||
ChkInfo->ScanDrive = FALSE;
|
||||
ChkInfo->Callback = ChkdskCallback;
|
||||
|
||||
ProgressBar = CreateProgressBar(6,
|
||||
yScreen - 14,
|
||||
xScreen - 7,
|
||||
yScreen - 10,
|
||||
10,
|
||||
24,
|
||||
TRUE,
|
||||
MUIGetString(STRING_CHECKINGDISK));
|
||||
|
||||
ProgressSetStepCount(ProgressBar, 100);
|
||||
}
|
||||
|
||||
VOID
|
||||
EndCheck(
|
||||
_In_ NTSTATUS Status)
|
||||
{
|
||||
DestroyProgressBar(ProgressBar);
|
||||
ProgressBar = NULL;
|
||||
|
||||
DPRINT("ChkdskPartition() finished with status 0x%08lx\n", Status);
|
||||
}
|
||||
|
||||
/* EOF */
|
29
base/setup/usetup/fmtchk.h
Normal file
29
base/setup/usetup/fmtchk.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Filesystem Format and ChkDsk support functions
|
||||
* COPYRIGHT: Copyright 2003 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||
* Copyright 2006 Hervé Poussineau <hpoussin@reactos.org>
|
||||
* Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
VOID
|
||||
StartFormat(
|
||||
_Inout_ PFORMAT_VOLUME_INFO FmtInfo,
|
||||
_In_ PFILE_SYSTEM_ITEM SelectedFileSystem);
|
||||
|
||||
VOID
|
||||
EndFormat(
|
||||
_In_ NTSTATUS Status);
|
||||
|
||||
VOID
|
||||
StartCheck(
|
||||
_Inout_ PCHECK_VOLUME_INFO ChkInfo);
|
||||
|
||||
VOID
|
||||
EndCheck(
|
||||
_In_ NTSTATUS Status);
|
||||
|
||||
/* EOF */
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2003 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/format.c
|
||||
* PURPOSE: Filesystem format support functions
|
||||
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "usetup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static PPROGRESSBAR FormatProgressBar = NULL;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FormatCallback(
|
||||
IN CALLBACKCOMMAND Command,
|
||||
IN ULONG Modifier,
|
||||
IN PVOID Argument)
|
||||
{
|
||||
switch (Command)
|
||||
{
|
||||
case PROGRESS:
|
||||
{
|
||||
PULONG Percent;
|
||||
|
||||
Percent = (PULONG)Argument;
|
||||
DPRINT("%lu percent completed\n", *Percent);
|
||||
|
||||
ProgressSetStep(FormatProgressBar, *Percent);
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case OUTPUT:
|
||||
{
|
||||
PTEXTOUTPUT Output;
|
||||
output = (PTEXTOUTPUT) Argument;
|
||||
DPRINT("%s\n", output->Output);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case DONE:
|
||||
{
|
||||
// PBOOLEAN Success;
|
||||
DPRINT("Done\n");
|
||||
#if 0
|
||||
Success = (PBOOLEAN)Argument;
|
||||
if (*Success == FALSE)
|
||||
{
|
||||
DPRINT("FormatEx was unable to complete successfully.\n\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DPRINT("Unknown callback %lu\n", (ULONG)Command);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DoFormat(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN QuickFormat)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
FormatProgressBar = CreateProgressBar(6,
|
||||
yScreen - 14,
|
||||
xScreen - 7,
|
||||
yScreen - 10,
|
||||
10,
|
||||
24,
|
||||
TRUE,
|
||||
MUIGetString(STRING_FORMATTINGPART));
|
||||
|
||||
ProgressSetStepCount(FormatProgressBar, 100);
|
||||
|
||||
// TODO: Think about which values could be defaulted...
|
||||
Status = FormatPartition(PartEntry,
|
||||
FileSystemName,
|
||||
FMIFS_HARDDISK, /* MediaFlag */
|
||||
NULL, /* Label */
|
||||
QuickFormat, /* QuickFormat */
|
||||
0, /* ClusterSize */
|
||||
FormatCallback); /* Callback */
|
||||
|
||||
DestroyProgressBar(FormatProgressBar);
|
||||
FormatProgressBar = NULL;
|
||||
|
||||
DPRINT("FormatPartition() finished with status 0x%08lx\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2003 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/format.h
|
||||
* PURPOSE: Filesystem format support functions
|
||||
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
NTSTATUS
|
||||
DoFormat(
|
||||
IN PPARTENTRY PartEntry,
|
||||
IN PCWSTR FileSystemName,
|
||||
IN BOOLEAN QuickFormat);
|
||||
|
||||
/* EOF */
|
|
@ -28,19 +28,6 @@
|
|||
|
||||
// #include "../lib/utils/partlist.h"
|
||||
|
||||
typedef enum _FORMATMACHINESTATE
|
||||
{
|
||||
Start,
|
||||
FormatSystemPartition,
|
||||
FormatInstallPartition,
|
||||
FormatOtherPartition,
|
||||
FormatDone,
|
||||
// CheckSystemPartition,
|
||||
// CheckInstallPartition,
|
||||
// CheckOtherPartition,
|
||||
// CheckDone
|
||||
} FORMATMACHINESTATE, *PFORMATMACHINESTATE;
|
||||
|
||||
typedef struct _PARTLIST_UI
|
||||
{
|
||||
PPARTLIST List;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,8 +99,9 @@ typedef enum _PAGE_NUMBER
|
|||
CONFIRM_DELETE_SYSTEM_PARTITION_PAGE,
|
||||
DELETE_PARTITION_PAGE,
|
||||
|
||||
SELECT_FILE_SYSTEM_PAGE,
|
||||
FORMAT_PARTITION_PAGE,
|
||||
START_PARTITION_OPERATIONS_PAGE, /* Virtual page */
|
||||
SELECT_FILE_SYSTEM_PAGE, /* Virtual page */
|
||||
FORMAT_PARTITION_PAGE, /* Virtual page */
|
||||
CHECK_FILE_SYSTEM_PAGE,
|
||||
BOOTLOADER_SELECT_PAGE,
|
||||
|
||||
|
|
Loading…
Reference in a new issue