Skip to content

Commit

Permalink
WIP - [SETUPLIB][USETUP] Isolate and decouple the filesystem volume o…
Browse files Browse the repository at this point in the history
…perations code from the UI.

The idea is similar to the SetupCommitFileQueue() function:
filesystem volume operations are "queued" (and are retrieved via the
GetNextUnformatted/UncheckedPartition() helpers) and processed via a
"commit queue", that employs a user-specified callback. That latter
one can deal with displaying the appropriate UI screens, etc.
  • Loading branch information
HBelusca committed Oct 26, 2023
1 parent 0aa99aa commit c15a2bb
Show file tree
Hide file tree
Showing 12 changed files with 1,115 additions and 636 deletions.
428 changes: 400 additions & 28 deletions base/setup/lib/fsutil.c

Large diffs are not rendered by default.

139 changes: 111 additions & 28 deletions base/setup/lib/fsutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);


//
Expand Down Expand Up @@ -127,4 +127,87 @@ FormatPartition(
IN ULONG ClusterSize,
IN PFMIFSCALLBACK Callback);


//
// FileSystem Volume Operations Queue
//

// Like the SPFILENOTIFY_xxxx values
typedef enum _FSVOLNOTIFY
{
FSVOLNOTIFY_STARTQUEUE = 0,
FSVOLNOTIFY_ENDQUEUE,
FSVOLNOTIFY_STARTSUBQUEUE,
FSVOLNOTIFY_ENDSUBQUEUE,
ChangeSystemPartition, // FIXME: Deprecate!
SystemPartitionError, // FIXME: Deprecate!
// FSVOLNOTIFY_STARTPARTITION, FSVOLNOTIFY_ENDPARTITION, FSVOLNOTIFY_PARTITIONERROR,
FSVOLNOTIFY_STARTFORMAT,
FSVOLNOTIFY_ENDFORMAT,
FSVOLNOTIFY_FORMATERROR,
FSVOLNOTIFY_STARTCHECK,
FSVOLNOTIFY_ENDCHECK,
FSVOLNOTIFY_CHECKERROR
} FSVOLNOTIFY;

// Like the FILEOP_xxxx values
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_PARTITION_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_PARTITION_INFO, *PFORMAT_PARTITION_INFO;

typedef struct _CHECK_PARTITION_INFO
{
PPARTENTRY PartEntry;
// PCWSTR NtPathPartition;
NTSTATUS ErrorStatus;

/* Input information given by the 'FSVOLNOTIFY_STARTCHECK' step ****/
// PCWSTR FileSystemName; // Obtained from PartEntry!
BOOLEAN FixErrors;
BOOLEAN Verbose;
BOOLEAN CheckOnlyIfDirty;
BOOLEAN ScanDrive;
PFMIFSCALLBACK Callback;

} CHECK_PARTITION_INFO, *PCHECK_PARTITION_INFO;

typedef FSVOL_OP
(CALLBACK *PFSVOL_CALLBACK)(
IN PVOID Context OPTIONAL,
IN FSVOLNOTIFY FormatStatus,
IN ULONG_PTR Param1,
IN ULONG_PTR Param2);

BOOLEAN
FsVolCommitOpsQueue(
IN PPARTLIST PartitionList,
IN PPARTENTRY InstallPartition,
IN PPARTENTRY SystemPartition,
IN PFSVOL_CALLBACK FsVolCallback OPTIONAL,
IN PVOID Context OPTIONAL);

/* EOF */
89 changes: 89 additions & 0 deletions base/setup/lib/setuplib.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,95 @@ 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,
SystemPartitionError,
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)
{
CreatePartition(PartitionList,
SystemPartition,
0LL, // SystemPartition->SectorCount.QuadPart,
TRUE);
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,
Expand Down
10 changes: 10 additions & 0 deletions base/setup/lib/setuplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,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,
Expand Down
13 changes: 12 additions & 1 deletion base/setup/lib/utils/partlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -2641,7 +2641,18 @@ UpdateDiskLayout(
HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
LinkInfo->PartitionNumber = 0;
LinkInfo->PartitionType = PARTITION_EXTENDED;

if (PartEntry->StartSector.QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
LinkInfo->PartitionType = PARTITION_EXTENDED;
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
LinkInfo->PartitionType = PARTITION_XINT13_EXTENDED;
}

LinkInfo->BootIndicator = FALSE;
LinkInfo->RecognizedPartition = FALSE;
LinkInfo->RewritePartition = TRUE;
Expand Down
35 changes: 18 additions & 17 deletions base/setup/usetup/chkdsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ static
BOOLEAN
NTAPI
ChkdskCallback(
IN CALLBACKCOMMAND Command,
IN ULONG Modifier,
IN PVOID Argument)
_In_ CALLBACKCOMMAND Command,
_In_ ULONG Modifier,
_In_ PVOID Argument)
{
switch (Command)
{
Expand All @@ -53,11 +53,17 @@ ChkdskCallback(
return TRUE;
}

NTSTATUS
DoChkdsk(
IN PPARTENTRY PartEntry)
VOID
StartCheck(
_Inout_ PCHECK_PARTITION_INFO PartInfo)
{
NTSTATUS Status;
// TODO: Think about which values could be defaulted...
// PartInfo->FileSystemName = PartInfo->PartEntry->FileSystem;
PartInfo->FixErrors = TRUE;
PartInfo->Verbose = FALSE;
PartInfo->CheckOnlyIfDirty = TRUE;
PartInfo->ScanDrive = FALSE;
PartInfo->Callback = ChkdskCallback;

ChkdskProgressBar = CreateProgressBar(6,
yScreen - 14,
Expand All @@ -69,21 +75,16 @@ DoChkdsk(
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 */

VOID
EndCheck(
_In_ NTSTATUS Status)
{
DestroyProgressBar(ChkdskProgressBar);
ChkdskProgressBar = NULL;

DPRINT("ChkdskPartition() finished with status 0x%08lx\n", Status);

return Status;
}

/* EOF */
10 changes: 7 additions & 3 deletions base/setup/usetup/chkdsk.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@

#pragma once

NTSTATUS
DoChkdsk(
IN PPARTENTRY PartEntry);
VOID
StartCheck(
_Inout_ PCHECK_PARTITION_INFO PartInfo);

VOID
EndCheck(
_In_ NTSTATUS Status);

/* EOF */
Loading

0 comments on commit c15a2bb

Please sign in to comment.