diff --git a/base/setup/lib/bootsup.c b/base/setup/lib/bootsup.c index 3d494c949ad..ec9a1a4cf56 100644 --- a/base/setup/lib/bootsup.c +++ b/base/setup/lib/bootsup.c @@ -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); diff --git a/base/setup/lib/fsutil.c b/base/setup/lib/fsutil.c index b9d0ed838fe..89555184650 100644 --- a/base/setup/lib/fsutil.c +++ b/base/setup/lib/fsutil.c @@ -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 -/* 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; } diff --git a/base/setup/lib/fsutil.h b/base/setup/lib/fsutil.h index bb10c4a0f6c..f6c83e953f7 100644 --- a/base/setup/lib/fsutil.h +++ b/base/setup/lib/fsutil.h @@ -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 -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 */ diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c index aee3c3c161a..5c20c4bf36c 100644 --- a/base/setup/lib/utils/partlist.c +++ b/base/setup/lib/utils/partlist.c @@ -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; } diff --git a/base/setup/lib/utils/partlist.h b/base/setup/lib/utils/partlist.h index a27454b4aa0..57873a444ed 100644 --- a/base/setup/lib/utils/partlist.h +++ b/base/setup/lib/utils/partlist.h @@ -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; diff --git a/base/setup/usetup/chkdsk.c b/base/setup/usetup/chkdsk.c index 26f9b79c58a..615e7022c0e 100644 --- a/base/setup/usetup/chkdsk.c +++ b/base/setup/usetup/chkdsk.c @@ -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; diff --git a/base/setup/usetup/chkdsk.h b/base/setup/usetup/chkdsk.h index 0eb2bed372c..3207d2f7f69 100644 --- a/base/setup/usetup/chkdsk.h +++ b/base/setup/usetup/chkdsk.h @@ -28,7 +28,6 @@ NTSTATUS ChkdskPartition( IN PUNICODE_STRING DriveRoot, - /*IN PFILE_SYSTEM_ITEM FileSystemItem*/ - IN PFILE_SYSTEM FileSystem); + IN PCWSTR FileSystemName); /* EOF */ diff --git a/base/setup/usetup/format.c b/base/setup/usetup/format.c index db8c14dcca8..08e029ce543 100644 --- a/base/setup/usetup/format.c +++ b/base/setup/usetup/format.c @@ -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; diff --git a/base/setup/usetup/format.h b/base/setup/usetup/format.h index 3032f496515..b84ae57559d 100644 --- a/base/setup/usetup/format.h +++ b/base/setup/usetup/format.h @@ -29,6 +29,7 @@ NTSTATUS FormatPartition( IN PUNICODE_STRING DriveRoot, - IN PFILE_SYSTEM_ITEM FileSystemItem); + IN PCWSTR FileSystemName, + IN BOOLEAN QuickFormat); /* EOF */ diff --git a/base/setup/usetup/fslist.c b/base/setup/usetup/fslist.c index 6aa8c4e1932..75c9fbfaf0d 100644 --- a/base/setup/usetup/fslist.c +++ b/base/setup/usetup/fslist.c @@ -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; } diff --git a/base/setup/usetup/fslist.h b/base/setup/usetup/fslist.h index d5f8b4c5ce2..fc4a8b2f2da 100644 --- a/base/setup/usetup/fslist.h +++ b/base/setup/usetup/fslist.h @@ -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; diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index f10effde103..b8df7c9261b 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -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 @@ -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; }