[SETUPLIB][USETUP] Factor out the usage of FS provider structures.

Similarly to FMIFS this structure should be private. Instead file-system
names are passed to the helper functions, allowing to use the names
returned by the FS drivers. The names are then internally mapped to the
corresponding FS providers.

In particular this allows to handle the "RAW" file-system and to assign
the 'Unformatted' flag to partitions having this FS.

Finally this helps us refining the checks performed to see whether the
current "active" system partition uses a supported file-system.
This commit is contained in:
Hermès Bélusca-Maïto 2019-02-24 17:52:33 +01:00
parent b18da6730e
commit c1fbc2d651
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
12 changed files with 765 additions and 414 deletions

View file

@ -2351,38 +2351,38 @@ InstallFatBootcodeToFloppy(
IN PUNICODE_STRING SourceRootPath,
IN PUNICODE_STRING DestinationArcPath)
{
static const PCWSTR FloppyDevice = L"\\Device\\Floppy0\\";
NTSTATUS Status;
PFILE_SYSTEM FatFS;
UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\");
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
/* Verify that the floppy disk is accessible */
if (DoesDirExist(NULL, FloppyDevice.Buffer) == FALSE)
if (DoesDirExist(NULL, FloppyDevice) == FALSE)
return STATUS_DEVICE_NOT_READY;
/* Format the floppy disk */
FatFS = GetFileSystemByName(L"FAT");
if (!FatFS)
{
DPRINT1("FAT FS non existent on this system?!\n");
return STATUS_NOT_SUPPORTED;
}
Status = FatFS->FormatFunc(&FloppyDevice,
FMIFS_FLOPPY,
NULL,
TRUE,
0,
NULL);
// FormatPartition(...)
Status = FormatFileSystem(FloppyDevice,
L"FAT",
FMIFS_FLOPPY,
NULL,
TRUE,
0,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
if (Status == STATUS_NOT_SUPPORTED)
DPRINT1("FAT FS non existent on this system?!\n");
else
DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
return Status;
}
/* Copy FreeLoader to the boot partition */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice.Buffer, L"freeldr.sys");
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice, L"freeldr.sys");
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
@ -2394,7 +2394,7 @@ InstallFatBootcodeToFloppy(
/* Create new 'freeldr.ini' */
DPRINT("Create new 'freeldr.ini'\n");
Status = CreateFreeLoaderIniForReactOS(FloppyDevice.Buffer, DestinationArcPath->Buffer);
Status = CreateFreeLoaderIniForReactOS(FloppyDevice, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
@ -2403,7 +2403,7 @@ InstallFatBootcodeToFloppy(
/* Install FAT12 boosector */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice.Buffer);
CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice);
DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath);

View file

@ -2,8 +2,8 @@
* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Filesystem support functions
* COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2017-2018 Hermes Belusca-Maito
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2017-2019 Hermes Belusca-Maito
*/
//
@ -28,10 +28,18 @@
#include <debug.h>
/* GLOBALS ******************************************************************/
/* LOCALS *******************************************************************/
/** IFS_PROVIDER **/
typedef struct _FILE_SYSTEM
{
PCWSTR FileSystemName;
FORMATEX FormatFunc;
CHKDSKEX ChkdskFunc;
} FILE_SYSTEM, *PFILE_SYSTEM;
/* The list of file systems on which we can install ReactOS */
FILE_SYSTEM RegisteredFileSystems[] =
static FILE_SYSTEM RegisteredFileSystems[] =
{
/* NOTE: The FAT formatter automatically determines
* whether it will use FAT-16 or FAT-32. */
@ -54,16 +62,24 @@ FILE_SYSTEM RegisteredFileSystems[] =
/* FUNCTIONS ****************************************************************/
PFILE_SYSTEM
GetRegisteredFileSystems(OUT PULONG Count)
/** QueryAvailableFileSystemFormat() **/
BOOLEAN
GetRegisteredFileSystems(
IN ULONG Index,
OUT PCWSTR* FileSystemName)
{
*Count = ARRAYSIZE(RegisteredFileSystems);
return RegisteredFileSystems;
if (Index >= ARRAYSIZE(RegisteredFileSystems))
return FALSE;
*FileSystemName = RegisteredFileSystems[Index].FileSystemName;
return TRUE;
}
PFILE_SYSTEM
/** GetProvider() **/
static PFILE_SYSTEM
GetFileSystemByName(
// IN PFILE_SYSTEM_LIST List,
IN PCWSTR FileSystemName)
{
#if 0 // Reenable when the list of registered FSes will again be dynamic
@ -75,25 +91,33 @@ GetFileSystemByName(
while (ListEntry != &List->ListHead)
{
Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
if (Item->FileSystemName && wcsicmp(FileSystemName, Item->FileSystemName) == 0)
if (Item->FileSystemName &&
(wcsicmp(FileSystemName, Item->FileSystemName) == 0 ||
/* Map FAT32 back to FAT */
(wcsicmp(FileSystemName, L"FAT32") == 0 && wcsicmp(Item->FileSystemName, L"FAT") == 0)))
{
return Item;
}
ListEntry = ListEntry->Flink;
}
#else
ULONG Count;
PFILE_SYSTEM FileSystems;
ULONG Count = ARRAYSIZE(RegisteredFileSystems);
PFILE_SYSTEM FileSystems = RegisteredFileSystems;
FileSystems = GetRegisteredFileSystems(&Count);
if (!FileSystems || Count == 0)
return NULL;
ASSERT(FileSystems && Count != 0);
while (Count--)
{
if (FileSystems->FileSystemName && wcsicmp(FileSystemName, FileSystems->FileSystemName) == 0)
if (FileSystems->FileSystemName &&
(wcsicmp(FileSystemName, FileSystems->FileSystemName) == 0 ||
/* Map FAT32 back to FAT */
(wcsicmp(FileSystemName, L"FAT32") == 0 && wcsicmp(FileSystems->FileSystemName, L"FAT") == 0)))
{
return FileSystems;
}
++FileSystems;
}
@ -105,63 +129,30 @@ GetFileSystemByName(
//
// FileSystem recognition (using NT OS functionality)
// FileSystem recognition, using NT OS functionality
//
/* NOTE: Ripped & adapted from base/system/autochk/autochk.c */
static NTSTATUS
_MyGetFileSystem(
IN struct _PARTENTRY* PartEntry,
NTSTATUS
GetFileSystemNameByHandle(
IN HANDLE PartitionHandle,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize)
{
NTSTATUS Status;
UNICODE_STRING PartitionRootPath;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE FileHandle;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR PathBuffer[MAX_PATH];
UCHAR Buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
/* Set PartitionRootPath */
RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
PartEntry->DiskEntry->DiskNumber,
PartEntry->PartitionNumber);
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath);
/* Open the partition */
InitializeObjectAttributes(&ObjectAttributes,
&PartitionRootPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle, // PartitionHandle,
FILE_GENERIC_READ /* | SYNCHRONIZE */,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionRootPath, Status);
return Status;
}
/* Retrieve the FS attributes */
Status = NtQueryVolumeInformationFile(FileHandle,
Status = NtQueryVolumeInformationFile(PartitionHandle,
&IoStatusBlock,
FileFsAttribute,
sizeof(Buffer),
FileFsAttributeInformation);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtQueryVolumeInformationFile failed for partition '%wZ', Status 0x%08lx\n",
&PartitionRootPath, Status);
DPRINT1("NtQueryVolumeInformationFile failed, Status 0x%08lx\n", Status);
return Status;
}
@ -173,45 +164,87 @@ _MyGetFileSystem(
FileFsAttribute->FileSystemNameLength);
}
PFILE_SYSTEM
GetFileSystem(
// IN PFILE_SYSTEM_LIST FileSystemList,
IN struct _PARTENTRY* PartEntry)
NTSTATUS
GetFileSystemName_UStr(
IN PUNICODE_STRING PartitionPath,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize)
{
PFILE_SYSTEM CurrentFileSystem;
NTSTATUS Status;
PWSTR FileSystemName = NULL;
WCHAR FsRecFileSystemName[MAX_PATH];
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE PartitionHandle;
IO_STATUS_BLOCK IoStatusBlock;
CurrentFileSystem = PartEntry->FileSystem;
/* We have a file system, return it */
if (CurrentFileSystem != NULL && CurrentFileSystem->FileSystemName != NULL)
return CurrentFileSystem;
DPRINT1("File system not found, try to guess one...\n");
CurrentFileSystem = NULL;
/*
* We don't have one...
*
* Try to infer a file system using NT file system recognition.
*/
Status = _MyGetFileSystem(PartEntry, FsRecFileSystemName, sizeof(FsRecFileSystemName));
if (NT_SUCCESS(Status) && *FsRecFileSystemName)
/* Open the partition */
InitializeObjectAttributes(&ObjectAttributes,
PartitionPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&PartitionHandle,
FILE_GENERIC_READ /* | SYNCHRONIZE */,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
if (!NT_SUCCESS(Status))
{
/* Temporary HACK: map FAT32 back to FAT */
if (wcscmp(FsRecFileSystemName, L"FAT32") == 0)
RtlStringCbCopyW(FsRecFileSystemName, sizeof(FsRecFileSystemName), L"FAT");
DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", PartitionPath, Status);
return Status;
}
FileSystemName = FsRecFileSystemName;
/* Retrieve the FS attributes */
Status = GetFileSystemNameByHandle(PartitionHandle, FileSystemName, FileSystemNameSize);
if (!NT_SUCCESS(Status))
{
DPRINT1("GetFileSystemNameByHandle() failed for partition '%wZ', Status 0x%08lx\n",
PartitionPath, Status);
}
/* Close the partition */
NtClose(PartitionHandle);
return Status;
}
NTSTATUS
GetFileSystemName(
IN PCWSTR Partition,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize)
{
UNICODE_STRING PartitionPath;
RtlInitUnicodeString(&PartitionPath, Partition);
return GetFileSystemName_UStr(&PartitionPath,
FileSystemName,
FileSystemNameSize);
}
NTSTATUS
InferFileSystemByHandle(
IN HANDLE PartitionHandle,
IN UCHAR PartitionType,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize)
{
NTSTATUS Status;
if (FileSystemNameSize < sizeof(WCHAR))
return STATUS_BUFFER_TOO_SMALL;
*FileSystemName = L'\0';
/* Try to infer a file system using NT file system recognition */
Status = GetFileSystemNameByHandle(PartitionHandle,
FileSystemName,
FileSystemNameSize);
if (NT_SUCCESS(Status) && *FileSystemName)
{
goto Quit;
}
/*
* We don't have one...
*
* Try to infer a preferred file system for this partition, given its ID.
*
* WARNING: This is partly a hack, since partitions with the same ID can
@ -224,43 +257,274 @@ GetFileSystem(
* On the contrary, for unformatted partitions with a given ID, the
* following code is OK.
*/
if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
(PartEntry->PartitionType == PARTITION_FAT_16) ||
(PartEntry->PartitionType == PARTITION_HUGE ) ||
(PartEntry->PartitionType == PARTITION_XINT13) ||
(PartEntry->PartitionType == PARTITION_FAT32 ) ||
(PartEntry->PartitionType == PARTITION_FAT32_XINT13))
if ((PartitionType == PARTITION_FAT_12) ||
(PartitionType == PARTITION_FAT_16) ||
(PartitionType == PARTITION_HUGE ) ||
(PartitionType == PARTITION_XINT13))
{
FileSystemName = L"FAT";
/* FAT12 or FAT16 */
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT");
}
else if (PartEntry->PartitionType == PARTITION_LINUX)
else if ((PartitionType == PARTITION_FAT32) ||
(PartitionType == PARTITION_FAT32_XINT13))
{
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT32");
}
else if (PartitionType == PARTITION_LINUX)
{
// WARNING: See the warning above.
/* Could also be EXT2/3/4, ReiserFS, ... */
FileSystemName = L"BTRFS";
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"BTRFS");
}
else if (PartEntry->PartitionType == PARTITION_IFS)
else if (PartitionType == PARTITION_IFS)
{
// WARNING: See the warning above.
/* Could also be HPFS */
FileSystemName = L"NTFS";
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"NTFS");
}
Quit:
// HACK: WARNING: We cannot write on this FS yet!
if (FileSystemName)
if (*FileSystemName)
{
if (PartEntry->PartitionType == PARTITION_IFS)
DPRINT1("Recognized file system %S that doesn't support write support yet!\n", FileSystemName);
// WARNING: We cannot write on this FS yet!
if (PartitionType == PARTITION_IFS)
{
DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
FileSystemName);
}
}
DPRINT1("GetFileSystem -- PartitionType: 0x%02X ; FileSystemName (guessed): %S\n",
PartEntry->PartitionType, FileSystemName ? FileSystemName : L"None");
DPRINT1("InferFileSystem -- PartitionType: 0x%02X ; FileSystem (guessed): %S\n",
PartitionType, *FileSystemName ? FileSystemName : L"None");
if (FileSystemName)
CurrentFileSystem = GetFileSystemByName(FileSystemName);
return Status;
}
return CurrentFileSystem;
NTSTATUS
InferFileSystem(
IN PCWSTR Partition,
IN UCHAR PartitionType,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize)
{
NTSTATUS Status;
UNICODE_STRING PartitionPath;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE PartitionHandle;
IO_STATUS_BLOCK IoStatusBlock;
/* Open the partition */
RtlInitUnicodeString(&PartitionPath, Partition);
InitializeObjectAttributes(&ObjectAttributes,
&PartitionPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&PartitionHandle,
FILE_GENERIC_READ /* | SYNCHRONIZE */,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionPath, Status);
return Status;
}
/* Retrieve the FS */
Status = InferFileSystemByHandle(PartitionHandle,
PartitionType,
FileSystemName,
FileSystemNameSize);
/* Close the partition */
NtClose(PartitionHandle);
return Status;
}
/** 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)
{
PFILE_SYSTEM FileSystem;
FileSystem = GetFileSystemByName(FileSystemName);
if (!FileSystem || !FileSystem->ChkdskFunc)
{
// BOOLEAN Argument = FALSE;
// Callback(DONE, 0, &Argument);
return STATUS_NOT_SUPPORTED;
}
return FileSystem->ChkdskFunc(DriveRoot,
FixErrors,
Verbose,
CheckOnlyIfDirty,
ScanDrive,
Callback);
}
NTSTATUS
ChkdskFileSystem(
IN PCWSTR DriveRoot,
IN PCWSTR FileSystemName,
IN BOOLEAN FixErrors,
IN BOOLEAN Verbose,
IN BOOLEAN CheckOnlyIfDirty,
IN BOOLEAN ScanDrive,
IN PFMIFSCALLBACK Callback)
{
UNICODE_STRING DriveRootU;
RtlInitUnicodeString(&DriveRootU, DriveRoot);
return ChkdskFileSystem_UStr(&DriveRootU,
FileSystemName,
FixErrors,
Verbose,
CheckOnlyIfDirty,
ScanDrive,
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)
{
PFILE_SYSTEM FileSystem;
FileSystem = GetFileSystemByName(FileSystemName);
if (!FileSystem || !FileSystem->FormatFunc)
{
// BOOLEAN Argument = FALSE;
// Callback(DONE, 0, &Argument);
return STATUS_NOT_SUPPORTED;
}
return FileSystem->FormatFunc(DriveRoot,
MediaFlag,
Label,
QuickFormat,
ClusterSize,
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)
{
UNICODE_STRING DriveRootU;
UNICODE_STRING LabelU;
RtlInitUnicodeString(&DriveRootU, DriveRoot);
RtlInitUnicodeString(&LabelU, Label);
return FormatFileSystem_UStr(&DriveRootU,
FileSystemName,
MediaFlag,
&LabelU,
QuickFormat,
ClusterSize,
Callback);
}
UCHAR
FileSystemToPartitionType(
IN PCWSTR FileSystem,
IN PULARGE_INTEGER StartSector,
IN PULARGE_INTEGER SectorCount)
{
ASSERT(FileSystem && StartSector && SectorCount);
if (wcsicmp(FileSystem, L"FAT") == 0 ||
wcsicmp(FileSystem, L"FAT32") == 0 ||
wcsicmp(FileSystem, L"RAW") == 0)
{
if (SectorCount->QuadPart < 8192)
{
/* FAT12 CHS partition (disk is smaller than 4.1MB) */
return PARTITION_FAT_12;
}
else if (StartSector->QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
if (SectorCount->QuadPart < 65536)
{
/* FAT16 CHS partition (partition size < 32MB) */
return PARTITION_FAT_16;
}
else if (SectorCount->QuadPart < 1048576)
{
/* FAT16 CHS partition (partition size < 512MB) */
return PARTITION_HUGE;
}
else
{
/* FAT32 CHS partition (partition size >= 512MB) */
return PARTITION_FAT32;
}
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
if (SectorCount->QuadPart < 1048576)
{
/* FAT16 LBA partition (partition size < 512MB) */
return PARTITION_XINT13;
}
else
{
/* FAT32 LBA partition (partition size >= 512MB) */
return PARTITION_FAT32_XINT13;
}
}
}
else if (wcsicmp(FileSystem, L"NTFS") == 0)
{
return PARTITION_IFS;
}
else if (wcsicmp(FileSystem, L"BTRFS") == 0 ||
wcsicmp(FileSystem, L"EXT2") == 0 ||
wcsicmp(FileSystem, L"EXT3") == 0 ||
wcsicmp(FileSystem, L"EXT4") == 0 ||
wcsicmp(FileSystem, L"FFS") == 0 ||
wcsicmp(FileSystem, L"REISERFS") == 0)
{
return PARTITION_LINUX;
}
else
{
/* Unknown file system */
DPRINT1("Unknown file system '%S'\n", FileSystem);
return PARTITION_ENTRY_UNUSED;
}
}
@ -271,84 +535,35 @@ Quit:
BOOLEAN
PreparePartitionForFormatting(
IN struct _PARTENTRY* PartEntry,
IN PFILE_SYSTEM FileSystem)
IN PCWSTR FileSystemName)
{
if (!FileSystem)
UCHAR PartitionType;
if (!FileSystemName || !*FileSystemName)
{
DPRINT1("No file system specified?\n");
return FALSE;
}
if (wcscmp(FileSystem->FileSystemName, L"FAT") == 0)
PartitionType = FileSystemToPartitionType(FileSystemName,
&PartEntry->StartSector,
&PartEntry->SectorCount);
if (PartitionType == PARTITION_ENTRY_UNUSED)
{
if (PartEntry->SectorCount.QuadPart < 8192)
{
/* FAT12 CHS partition (disk is smaller than 4.1MB) */
SetPartitionType(PartEntry, PARTITION_FAT_12);
}
else if (PartEntry->StartSector.QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
if (PartEntry->SectorCount.QuadPart < 65536)
{
/* FAT16 CHS partition (partition size < 32MB) */
SetPartitionType(PartEntry, PARTITION_FAT_16);
}
else if (PartEntry->SectorCount.QuadPart < 1048576)
{
/* FAT16 CHS partition (partition size < 512MB) */
SetPartitionType(PartEntry, PARTITION_HUGE);
}
else
{
/* FAT32 CHS partition (partition size >= 512MB) */
SetPartitionType(PartEntry, PARTITION_FAT32);
}
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
if (PartEntry->SectorCount.QuadPart < 1048576)
{
/* FAT16 LBA partition (partition size < 512MB) */
SetPartitionType(PartEntry, PARTITION_XINT13);
}
else
{
/* FAT32 LBA partition (partition size >= 512MB) */
SetPartitionType(PartEntry, PARTITION_FAT32_XINT13);
}
}
}
else if (wcscmp(FileSystem->FileSystemName, L"BTRFS") == 0)
{
SetPartitionType(PartEntry, PARTITION_LINUX);
}
#if 0
else if (wcscmp(FileSystem->FileSystemName, L"EXT2") == 0)
{
SetPartitionType(PartEntry, PARTITION_LINUX);
}
else if (wcscmp(FileSystem->FileSystemName, L"NTFS") == 0)
{
SetPartitionType(PartEntry, PARTITION_IFS);
}
#endif
else
{
/* Unknown file system? */
DPRINT1("Unknown file system \"%S\"?\n", FileSystem->FileSystemName);
/* Unknown file system */
DPRINT1("Unknown file system '%S'\n", FileSystemName);
return FALSE;
}
SetPartitionType(PartEntry, PartitionType);
//
// FIXME: Do this now, or after the partition was actually formatted??
//
/* Set the new partition's file system proper */
PartEntry->FormatState = Formatted; // Well... This may be set after the real formatting takes place (in which case we should change the FormatState to another value)
PartEntry->FileSystem = FileSystem;
RtlStringCbCopyW(PartEntry->FileSystem,
sizeof(PartEntry->FileSystem),
FileSystemName);
return TRUE;
}

View file

@ -2,40 +2,113 @@
* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Filesystem support functions
* COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2017-2018 Hermes Belusca-Maito
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2017-2019 Hermes Belusca-Maito
*/
#pragma once
#include <fmifs/fmifs.h>
typedef struct _FILE_SYSTEM
{
PCWSTR FileSystemName;
FORMATEX FormatFunc;
CHKDSKEX ChkdskFunc;
} FILE_SYSTEM, *PFILE_SYSTEM;
/** QueryAvailableFileSystemFormat() **/
BOOLEAN
GetRegisteredFileSystems(
IN ULONG Index,
OUT PCWSTR* FileSystemName);
PFILE_SYSTEM
GetRegisteredFileSystems(OUT PULONG Count);
NTSTATUS
GetFileSystemNameByHandle(
IN HANDLE PartitionHandle,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize);
PFILE_SYSTEM
GetFileSystemByName(
// IN PFILE_SYSTEM_LIST List,
IN PCWSTR FileSystemName);
NTSTATUS
GetFileSystemName_UStr(
IN PUNICODE_STRING PartitionPath,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize);
NTSTATUS
GetFileSystemName(
IN PCWSTR Partition,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize);
NTSTATUS
InferFileSystemByHandle(
IN HANDLE PartitionHandle,
IN UCHAR PartitionType,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize);
NTSTATUS
InferFileSystem(
IN PCWSTR Partition,
IN UCHAR PartitionType,
IN OUT PWSTR FileSystemName,
IN SIZE_T FileSystemNameSize);
/** 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);
NTSTATUS
ChkdskFileSystem(
IN PCWSTR DriveRoot,
IN PCWSTR FileSystemName,
IN BOOLEAN FixErrors,
IN BOOLEAN Verbose,
IN BOOLEAN CheckOnlyIfDirty,
IN BOOLEAN ScanDrive,
IN 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);
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);
UCHAR
FileSystemToPartitionType(
IN PCWSTR FileSystem,
IN PULARGE_INTEGER StartSector,
IN PULARGE_INTEGER SectorCount);
//
// Formatting routines
//
struct _PARTENTRY; // Defined in partlist.h
PFILE_SYSTEM
GetFileSystem(
// IN PFILE_SYSTEM_LIST FileSystemList,
IN struct _PARTENTRY* PartEntry);
BOOLEAN
PreparePartitionForFormatting(
IN struct _PARTENTRY* PartEntry,
IN PFILE_SYSTEM FileSystem);
IN PCWSTR FileSystemName);
/* EOF */

View file

@ -2,7 +2,8 @@
* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Partition list functions
* COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2018-2019 Hermes Belusca-Maito
*/
#include "precomp.h"
@ -752,18 +753,19 @@ CreateInsertBlankRegion(
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
NewPartEntry->StartSector.QuadPart = StartSector;
NewPartEntry->SectorCount.QuadPart = SectorCount;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem[0] = L'\0';
DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
/* Insert the table into the list */
/* Insert the new entry into the list */
InsertTailList(ListHead, &NewPartEntry->ListEntry);
return NewPartEntry;
@ -788,17 +790,8 @@ InitializePartitionEntry(
{
DPRINT1("Convert existing partition entry\n");
/* Convert current entry to 'new (unformatted)' */
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
PartEntry->AutoCreate = AutoCreate;
PartEntry->BootIndicator = FALSE;
PartEntry->LogicalPartition = FALSE;
NewPartEntry = PartEntry;
NewPartEntry->AutoCreate = AutoCreate;
}
else
{
@ -811,28 +804,32 @@ InitializePartitionEntry(
if (NewPartEntry == NULL)
return NULL;
/* Insert the new entry into the list */
InsertTailList(&PartEntry->ListEntry,
&NewPartEntry->ListEntry);
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
NewPartEntry->BootIndicator = FALSE;
NewPartEntry->LogicalPartition = FALSE;
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
NewPartEntry->StartSector.QuadPart;
PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
/* Insert the new entry into the list */
InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry);
}
/* Create entry as 'New (Unformatted)' */
NewPartEntry->New = TRUE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->PartitionType = FileSystemToPartitionType(L"RAW", &NewPartEntry->StartSector, &NewPartEntry->SectorCount);
ASSERT(NewPartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem[0] = L'\0';
// NewPartEntry->AutoCreate = AutoCreate;
NewPartEntry->BootIndicator = FALSE;
NewPartEntry->LogicalPartition = FALSE;
DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
@ -852,10 +849,10 @@ AddPartitionToDisk(
NTSTATUS Status;
PPARTITION_INFORMATION PartitionInfo;
PPARTENTRY PartEntry;
HANDLE FileHandle;
HANDLE PartitionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR Buffer[MAX_PATH];
WCHAR PathBuffer[MAX_PATH];
UNICODE_STRING Name;
UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
@ -889,10 +886,16 @@ AddPartitionToDisk(
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex;
/* Specify the partition as initially unformatted */
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem[0] = L'\0';
/* Initialize the partition volume label */
RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
if (IsContainerPartition(PartEntry->PartitionType))
{
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry;
@ -901,12 +904,76 @@ AddPartitionToDisk(
{
ASSERT(PartitionInfo->RecognizedPartition);
PartEntry->FileSystem = GetFileSystem(PartEntry);
if (PartEntry->FileSystem)
PartEntry->FormatState = Preformatted;
/* Open the volume, ignore any errors */
RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
DiskEntry->DiskNumber,
PartEntry->PartitionNumber);
RtlInitUnicodeString(&Name, PathBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
PartitionHandle = NULL;
Status = NtOpenFile(&PartitionHandle,
FILE_READ_DATA | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
}
if (/* NT_SUCCESS(Status) && */ PartitionHandle)
{
/* We don't have a FS, try to guess one */
Status = InferFileSystemByHandle(PartitionHandle,
PartEntry->PartitionType,
PartEntry->FileSystem,
sizeof(PartEntry->FileSystem));
if (!NT_SUCCESS(Status))
DPRINT1("InferFileSystemByHandle() failed, Status 0x%08lx\n", Status);
}
if (*PartEntry->FileSystem)
{
if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
PartEntry->FormatState = Unformatted;
else
PartEntry->FormatState = Preformatted;
}
else
PartEntry->FormatState = Unformatted;
// PartEntry->FormatState = UnknownFormat;
{
PartEntry->FormatState = UnknownFormat;
}
/* Retrieve the partition volume label */
if (PartitionHandle)
{
Status = NtQueryVolumeInformationFile(PartitionHandle,
&IoStatusBlock,
&LabelBuffer,
sizeof(LabelBuffer),
FileFsVolumeInformation);
if (NT_SUCCESS(Status))
{
/* Copy the (possibly truncated) volume label and NULL-terminate it */
RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
}
else
{
DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
}
}
/* Close the partition */
if (PartitionHandle)
NtClose(PartitionHandle);
}
else
{
@ -914,56 +981,6 @@ AddPartitionToDisk(
PartEntry->FormatState = UnknownFormat;
}
/* Initialize the partition volume label */
RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
/* Open the volume, ignore any errors */
RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
DiskEntry->DiskNumber,
PartEntry->PartitionNumber);
RtlInitUnicodeString(&Name, Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_READ_DATA | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(Status))
{
/* Retrieve the partition volume label */
Status = NtQueryVolumeInformationFile(FileHandle,
&IoStatusBlock,
&LabelBuffer,
sizeof(LabelBuffer),
FileFsVolumeInformation);
/* Close the handle */
NtClose(FileHandle);
/* Check for success */
if (NT_SUCCESS(Status))
{
/* Copy the (possibly truncated) volume label and NULL-terminate it */
RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
}
else
{
DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
}
}
else
{
DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
}
InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
}
@ -2784,7 +2801,7 @@ DismountVolume(
IsContainerPartition(PartEntry->PartitionType) ||
!IsRecognizedPartition(PartEntry->PartitionType) ||
PartEntry->FormatState == Unformatted /* || PartEntry->FormatState == UnknownFormat */ ||
PartEntry->FileSystem == NULL ||
!*PartEntry->FileSystem ||
PartEntry->PartitionNumber == 0)
{
/* The partition is not mounted, so just return success */
@ -2981,7 +2998,7 @@ DeleteCurrentPartition(
PartEntry->IsPartitioned = FALSE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
PartEntry->FileSystem[0] = L'\0';
PartEntry->DriveLetter = 0;
PartEntry->OnDiskPartitionNumber = 0;
PartEntry->PartitionNumber = 0;
@ -2993,6 +3010,84 @@ DeleteCurrentPartition(
AssignDriveLetters(List);
}
static
BOOLEAN
IsSupportedActivePartition(
IN PPARTENTRY PartEntry)
{
/* Check the type and the filesystem of this partition */
/*
* We do not support extended partition containers (on MBR disks) marked
* as active, and containing code inside their extended boot records.
*/
if (IsContainerPartition(PartEntry->PartitionType))
{
DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
return FALSE;
}
/*
* ADDITIONAL CHECKS / BIG HACK:
*
* Retrieve its file system and check whether we have
* write support for it. If that is the case we are fine
* and we can use it directly. However if we don't have
* write support we will need to change the active system
* partition.
*
* NOTE that this is completely useless on architectures
* where a real system partition is required, as on these
* architectures the partition uses the FAT FS, for which
* we do have write support.
* NOTE also that for those architectures looking for a
* partition boot indicator is insufficient.
*/
if ((PartEntry->FormatState == Unformatted ) ||
(PartEntry->FormatState == Preformatted) ||
(PartEntry->FormatState == Formatted ))
{
ASSERT(*PartEntry->FileSystem);
/* NOTE: Please keep in sync with the RegisteredFileSystems list! */
if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
// wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0 ||
wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
{
return TRUE;
}
else
{
// WARNING: We cannot write on this FS yet!
DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
PartEntry->FileSystem);
return FALSE;
}
}
else // if (PartEntry->FormatState == UnknownFormat)
{
ASSERT(!*PartEntry->FileSystem);
DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
return FALSE;
}
// HACK: WARNING: We cannot write on this FS yet!
// See fsutil.c:InferFileSystem()
if (PartEntry->PartitionType == PARTITION_IFS)
{
DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
PartEntry->FileSystem);
return FALSE;
}
return TRUE;
}
VOID
CheckActiveSystemPartition(
IN PPARTLIST List)
@ -3001,8 +3096,6 @@ CheckActiveSystemPartition(
PPARTENTRY PartEntry;
PLIST_ENTRY ListEntry;
PFILE_SYSTEM FileSystem;
/* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead))
{
@ -3154,36 +3247,9 @@ CheckActiveSystemPartition(
/* Save it */
List->OriginalSystemPartition = List->SystemPartition;
/*
* ADDITIONAL CHECKS / BIG HACK:
*
* Retrieve its file system and check whether we have
* write support for it. If that is the case we are fine
* and we can use it directly. However if we don't have
* write support we will need to change the active system
* partition.
*
* NOTE that this is completely useless on architectures
* where a real system partition is required, as on these
* architectures the partition uses the FAT FS, for which
* we do have write support.
* NOTE also that for those architectures looking for a
* partition boot indicator is insufficient.
*/
FileSystem = GetFileSystem(List->OriginalSystemPartition);
if (FileSystem == NULL)
/* If we get a candidate active partition, validate it */
if (!IsSupportedActivePartition(List->OriginalSystemPartition))
{
DPRINT1("System partition %lu in disk %lu with no FS?!\n",
List->OriginalSystemPartition->PartitionNumber,
List->OriginalSystemPartition->DiskEntry->DiskNumber);
goto FindAndUseAlternativeSystemPartition;
}
// HACK: WARNING: We cannot write on this FS yet!
// See fsutil.c:GetFileSystem()
if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
{
DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
FileSystem->FileSystemName);
goto FindAndUseAlternativeSystemPartition;
}

View file

@ -2,7 +2,8 @@
* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Partition list functions
* COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
* Copyright 2018-2019 Hermes Belusca-Maito
*/
#pragma once
@ -30,8 +31,6 @@ typedef enum _FORMATSTATE
Formatted
} FORMATSTATE, *PFORMATSTATE;
struct _FILE_SYSTEM;
typedef struct _PARTENTRY
{
LIST_ENTRY ListEntry;
@ -52,13 +51,16 @@ typedef struct _PARTENTRY
WCHAR DriveLetter;
WCHAR VolumeLabel[20];
// CHAR FileSystemName[9]; // NOTE: Superseded by the FileSystem member
WCHAR FileSystem[MAX_PATH+1];
FORMATSTATE FormatState;
BOOLEAN LogicalPartition;
/* Partition is partitioned disk space */
BOOLEAN IsPartitioned;
/** The following three properties may be replaced by flags **/
/* Partition is new, table does not exist on disk yet */
BOOLEAN New;
@ -68,9 +70,6 @@ typedef struct _PARTENTRY
/* Partition must be checked */
BOOLEAN NeedsCheck;
FORMATSTATE FormatState;
struct _FILE_SYSTEM* FileSystem;
} PARTENTRY, *PPARTENTRY;

View file

@ -56,14 +56,9 @@ ChkdskCallback(
NTSTATUS
ChkdskPartition(
IN PUNICODE_STRING DriveRoot,
/*IN PFILE_SYSTEM_ITEM FileSystemItem*/
IN PFILE_SYSTEM FileSystem)
IN PCWSTR FileSystemName)
{
NTSTATUS Status;
// PFILE_SYSTEM FileSystem = FileSystemItem->FileSystem;
if (!FileSystem || !FileSystem->ChkdskFunc)
return STATUS_NOT_SUPPORTED;
ChkdskProgressBar = CreateProgressBar(6,
yScreen - 14,
@ -76,12 +71,13 @@ ChkdskPartition(
ProgressSetStepCount(ChkdskProgressBar, 100);
Status = FileSystem->ChkdskFunc(DriveRoot,
TRUE, /* FixErrors */
FALSE, /* Verbose */
TRUE, /* CheckOnlyIfDirty */
FALSE, /* ScanDrive */
ChkdskCallback); /* Callback */
Status = ChkdskFileSystem_UStr(DriveRoot,
FileSystemName,
TRUE, /* FixErrors */
FALSE, /* Verbose */
TRUE, /* CheckOnlyIfDirty */
FALSE, /* ScanDrive */
ChkdskCallback); /* Callback */
DestroyProgressBar(ChkdskProgressBar);
ChkdskProgressBar = NULL;

View file

@ -28,7 +28,6 @@
NTSTATUS
ChkdskPartition(
IN PUNICODE_STRING DriveRoot,
/*IN PFILE_SYSTEM_ITEM FileSystemItem*/
IN PFILE_SYSTEM FileSystem);
IN PCWSTR FileSystemName);
/* EOF */

View file

@ -88,13 +88,10 @@ FormatCallback(
NTSTATUS
FormatPartition(
IN PUNICODE_STRING DriveRoot,
IN PFILE_SYSTEM_ITEM FileSystemItem)
IN PCWSTR FileSystemName,
IN BOOLEAN QuickFormat)
{
NTSTATUS Status;
PFILE_SYSTEM FileSystem = FileSystemItem->FileSystem;
if (!FileSystem || !FileSystem->FormatFunc)
return STATUS_NOT_SUPPORTED;
FormatProgressBar = CreateProgressBar(6,
yScreen - 14,
@ -107,12 +104,13 @@ FormatPartition(
ProgressSetStepCount(FormatProgressBar, 100);
Status = FileSystem->FormatFunc(DriveRoot,
FMIFS_HARDDISK, /* MediaFlag */
NULL, /* Label */
FileSystemItem->QuickFormat, /* QuickFormat */
0, /* ClusterSize */
FormatCallback); /* Callback */
Status = FormatFileSystem_UStr(DriveRoot,
FileSystemName,
FMIFS_HARDDISK, /* MediaFlag */
NULL, /* Label */
QuickFormat, /* QuickFormat */
0, /* ClusterSize */
FormatCallback); /* Callback */
DestroyProgressBar(FormatProgressBar);
FormatProgressBar = NULL;

View file

@ -29,6 +29,7 @@
NTSTATUS
FormatPartition(
IN PUNICODE_STRING DriveRoot,
IN PFILE_SYSTEM_ITEM FileSystemItem);
IN PCWSTR FileSystemName,
IN BOOLEAN QuickFormat);
/* EOF */

View file

@ -34,8 +34,7 @@
static VOID
AddProvider(
IN OUT PFILE_SYSTEM_LIST List,
IN PCWSTR FileSystemName, // Redundant, I need to check whether this is reaaaaally needed....
IN PFILE_SYSTEM FileSystem)
IN PCWSTR FileSystem)
{
PFILE_SYSTEM_ITEM Item;
@ -43,7 +42,6 @@ AddProvider(
if (!Item)
return;
Item->FileSystemName = FileSystemName;
Item->FileSystem = FileSystem;
Item->QuickFormat = TRUE;
InsertTailList(&List->ListHead, &Item->ListEntry);
@ -55,7 +53,6 @@ AddProvider(
if (!Item)
return;
Item->FileSystemName = FileSystemName;
Item->FileSystem = FileSystem;
Item->QuickFormat = FALSE;
InsertTailList(&List->ListHead, &Item->ListEntry);
@ -63,19 +60,21 @@ AddProvider(
static VOID
InitializeFileSystemList(
IN PFILE_SYSTEM_LIST List)
IN PFILE_SYSTEM_LIST List,
IN BOOLEAN ForceFormat)
{
ULONG Count;
PFILE_SYSTEM FileSystems;
ULONG Index = 0;
PCWSTR FileSystemName;
FileSystems = GetRegisteredFileSystems(&Count);
if (!FileSystems || Count == 0)
return;
while (Count--)
while (GetRegisteredFileSystems(Index++, &FileSystemName))
{
AddProvider(List, FileSystems->FileSystemName, FileSystems);
++FileSystems;
AddProvider(List, FileSystemName);
}
if (!ForceFormat)
{
/* Add the 'Keep existing filesystem' dummy provider */
AddProvider(List, NULL);
}
}
@ -99,19 +98,14 @@ CreateFileSystemList(
List->Selected = NULL;
InitializeListHead(&List->ListHead);
InitializeFileSystemList(List);
if (!ForceFormat)
{
/* Add the 'Keep existing filesystem' dummy provider */
AddProvider(List, NULL, NULL);
}
InitializeFileSystemList(List, ForceFormat);
/* Search for SelectFileSystem in list */
ListEntry = List->ListHead.Flink;
while (ListEntry != &List->ListHead)
{
Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
if (Item->FileSystemName && wcscmp(SelectFileSystem, Item->FileSystemName) == 0)
if (Item->FileSystem && wcsicmp(SelectFileSystem, Item->FileSystem) == 0)
{
List->Selected = Item;
break;
@ -171,12 +165,12 @@ DrawFileSystemList(
coPos,
&Written);
if (Item->FileSystemName)
if (Item->FileSystem)
{
if (Item->QuickFormat)
snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK1), Item->FileSystemName);
else
snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK2), Item->FileSystemName);
snprintf(Buffer, sizeof(Buffer),
MUIGetString(Item->QuickFormat ? STRING_FORMATDISK1
: STRING_FORMATDISK2),
Item->FileSystem);
}
else
{
@ -184,13 +178,17 @@ DrawFileSystemList(
}
if (ListEntry == &List->Selected->ListEntry)
{
CONSOLE_SetInvertedTextXY(List->Left,
List->Top + (SHORT)Index,
Buffer);
}
else
{
CONSOLE_SetTextXY(List->Left,
List->Top + (SHORT)Index,
Buffer);
}
Index++;
ListEntry = ListEntry->Flink;
}

View file

@ -16,7 +16,8 @@
* 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
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/fslist.h
* PURPOSE: Filesystem list functions
@ -30,8 +31,7 @@
typedef struct _FILE_SYSTEM_ITEM
{
LIST_ENTRY ListEntry;
PCWSTR FileSystemName; /* Not owned by the item */ // Redundant, I need to check whether this is reaaaaally needed....
PFILE_SYSTEM FileSystem;
PCWSTR FileSystem;
BOOLEAN QuickFormat;
} FILE_SYSTEM_ITEM, *PFILE_SYSTEM_ITEM;

View file

@ -22,7 +22,7 @@
* FILE: base/setup/usetup/usetup.c
* PURPOSE: Text-mode setup
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org)
* Hervé Poussineau (hpoussin@reactos.org)
*/
#include <usetup.h>
@ -3071,7 +3071,8 @@ FormatPartitionPage(PINPUT_RECORD Ir)
if (SelectedFileSystem->FileSystem)
{
Status = FormatPartition(&PartitionRootPath,
SelectedFileSystem);
SelectedFileSystem->FileSystem,
SelectedFileSystem->QuickFormat);
if (Status == STATUS_NOT_SUPPORTED)
{
sprintf(Buffer,
@ -3079,7 +3080,7 @@ FormatPartitionPage(PINPUT_RECORD Ir)
"\n"
" \x07 Press ENTER to continue Setup.\n"
" \x07 Press F3 to quit Setup.",
SelectedFileSystem->FileSystem->FileSystemName);
SelectedFileSystem->FileSystem);
PopupError(Buffer,
MUIGetString(STRING_QUITCONTINUE),
@ -3147,7 +3148,6 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
NTSTATUS Status;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PFILE_SYSTEM CurrentFileSystem;
UNICODE_STRING PartitionRootPath;
WCHAR PathBuffer[MAX_PATH];
CHAR Buffer[MAX_PATH];
@ -3163,6 +3163,20 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
return INSTALL_DIRECTORY_PAGE;
}
CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART));
CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
DPRINT1("CheckFileSystemPage -- PartitionType: 0x%02X ; FileSystem: %S\n",
PartEntry->PartitionType, (*PartEntry->FileSystem ? PartEntry->FileSystem : L"n/a"));
/* HACK: Do not try to check a partition with an unknown filesystem */
if (!*PartEntry->FileSystem)
{
PartEntry->NeedsCheck = FALSE;
return CHECK_FILE_SYSTEM_PAGE;
}
/* Set PartitionRootPath */
RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
L"\\Device\\Harddisk%lu\\Partition%lu",
@ -3171,30 +3185,22 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath);
CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART));
CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
CurrentFileSystem = PartEntry->FileSystem;
DPRINT1("CheckFileSystemPage -- PartitionType: 0x%02X ; FileSystemName: %S\n",
PartEntry->PartitionType, (CurrentFileSystem ? CurrentFileSystem->FileSystemName : L"n/a"));
/* HACK: Do not try to check a partition with an unknown filesystem */
if (CurrentFileSystem == NULL)
{
PartEntry->NeedsCheck = FALSE;
return CHECK_FILE_SYSTEM_PAGE;
}
Status = ChkdskPartition(&PartitionRootPath, CurrentFileSystem);
/* Check the partition */
Status = ChkdskPartition(&PartitionRootPath, PartEntry->FileSystem);
if (Status == STATUS_NOT_SUPPORTED)
{
/*
* Partition checking is not supported with the current filesystem,
* so disable FS checks on it.
*/
PartEntry->NeedsCheck = FALSE;
sprintf(Buffer,
"Setup is currently unable to check a partition formatted in %S.\n"
"\n"
" \x07 Press ENTER to continue Setup.\n"
" \x07 Press F3 to quit Setup.",
CurrentFileSystem->FileSystemName);
PartEntry->FileSystem);
PopupError(Buffer,
MUIGetString(STRING_QUITCONTINUE),
@ -4204,7 +4210,7 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir)
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
PartitionList->SystemPartition->FileSystem->FileSystemName);
PartitionList->SystemPartition->FileSystem);
return QUIT_PAGE;
}
@ -4241,7 +4247,7 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir)
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
PartitionList->SystemPartition->FileSystem->FileSystemName);
PartitionList->SystemPartition->FileSystem);
return QUIT_PAGE;
}