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);
/* 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);
/* 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);
* 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
*/
//
#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. */
/* 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
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;
}
//
-// 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);
+ /* Retrieve the FS attributes */
+ Status = NtQueryVolumeInformationFile(PartitionHandle,
+ &IoStatusBlock,
+ FileFsAttribute,
+ sizeof(Buffer),
+ FileFsAttributeInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtQueryVolumeInformationFile failed, Status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ if (FileSystemNameSize < FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ return RtlStringCbCopyNW(FileSystemName, FileSystemNameSize,
+ FileFsAttribute->FileSystemName,
+ FileFsAttribute->FileSystemNameLength);
+}
+
+NTSTATUS
+GetFileSystemName_UStr(
+ IN PUNICODE_STRING PartitionPath,
+ IN OUT PWSTR FileSystemName,
+ IN SIZE_T FileSystemNameSize)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE PartitionHandle;
+ IO_STATUS_BLOCK IoStatusBlock;
/* Open the partition */
InitializeObjectAttributes(&ObjectAttributes,
- &PartitionRootPath,
+ PartitionPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
- Status = NtOpenFile(&FileHandle, // PartitionHandle,
+ Status = NtOpenFile(&PartitionHandle,
FILE_GENERIC_READ /* | SYNCHRONIZE */,
&ObjectAttributes,
&IoStatusBlock,
0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionRootPath, Status);
+ DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", PartitionPath, Status);
return Status;
}
/* Retrieve the FS attributes */
- Status = NtQueryVolumeInformationFile(FileHandle,
- &IoStatusBlock,
- FileFsAttribute,
- sizeof(Buffer),
- FileFsAttributeInformation);
- NtClose(FileHandle);
-
+ Status = GetFileSystemNameByHandle(PartitionHandle, FileSystemName, FileSystemNameSize);
if (!NT_SUCCESS(Status))
{
- DPRINT1("NtQueryVolumeInformationFile failed for partition '%wZ', Status 0x%08lx\n",
- &PartitionRootPath, Status);
- return Status;
+ DPRINT1("GetFileSystemNameByHandle() failed for partition '%wZ', Status 0x%08lx\n",
+ PartitionPath, Status);
}
- if (FileSystemNameSize < FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
- return STATUS_BUFFER_TOO_SMALL;
+ /* Close the partition */
+ NtClose(PartitionHandle);
- return RtlStringCbCopyNW(FileSystemName, FileSystemNameSize,
- FileFsAttribute->FileSystemName,
- FileFsAttribute->FileSystemNameLength);
+ return Status;
}
-PFILE_SYSTEM
-GetFileSystem(
- // IN PFILE_SYSTEM_LIST FileSystemList,
- IN struct _PARTENTRY* PartEntry)
+NTSTATUS
+GetFileSystemName(
+ IN PCWSTR Partition,
+ IN OUT PWSTR FileSystemName,
+ IN SIZE_T FileSystemNameSize)
{
- PFILE_SYSTEM CurrentFileSystem;
- NTSTATUS Status;
- PWSTR FileSystemName = NULL;
- WCHAR FsRecFileSystemName[MAX_PATH];
+ UNICODE_STRING PartitionPath;
- CurrentFileSystem = PartEntry->FileSystem;
+ RtlInitUnicodeString(&PartitionPath, Partition);
+ return GetFileSystemName_UStr(&PartitionPath,
+ FileSystemName,
+ FileSystemNameSize);
+}
- /* We have a file system, return it */
- if (CurrentFileSystem != NULL && CurrentFileSystem->FileSystemName != NULL)
- return CurrentFileSystem;
+NTSTATUS
+InferFileSystemByHandle(
+ IN HANDLE PartitionHandle,
+ IN UCHAR PartitionType,
+ IN OUT PWSTR FileSystemName,
+ IN SIZE_T FileSystemNameSize)
+{
+ NTSTATUS Status;
- DPRINT1("File system not found, try to guess one...\n");
+ if (FileSystemNameSize < sizeof(WCHAR))
+ return STATUS_BUFFER_TOO_SMALL;
- CurrentFileSystem = NULL;
+ *FileSystemName = L'\0';
- /*
- * 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)
+ /* Try to infer a file system using NT file system recognition */
+ Status = GetFileSystemNameByHandle(PartitionHandle,
+ FileSystemName,
+ FileSystemNameSize);
+ if (NT_SUCCESS(Status) && *FileSystemName)
{
- /* Temporary HACK: map FAT32 back to FAT */
- if (wcscmp(FsRecFileSystemName, L"FAT32") == 0)
- RtlStringCbCopyW(FsRecFileSystemName, sizeof(FsRecFileSystemName), L"FAT");
-
- FileSystemName = FsRecFileSystemName;
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
* 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;
-//
-// Formatting routines
-//
+ FileSystem = GetFileSystemByName(FileSystemName);
-BOOLEAN
-PreparePartitionForFormatting(
- IN struct _PARTENTRY* PartEntry,
- IN PFILE_SYSTEM FileSystem)
+ 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)
{
- if (!FileSystem)
+ PFILE_SYSTEM FileSystem;
+
+ FileSystem = GetFileSystemByName(FileSystemName);
+
+ if (!FileSystem || !FileSystem->FormatFunc)
{
- DPRINT1("No file system specified?\n");
- return FALSE;
+ // BOOLEAN Argument = FALSE;
+ // Callback(DONE, 0, &Argument);
+ return STATUS_NOT_SUPPORTED;
}
- if (wcscmp(FileSystem->FileSystemName, L"FAT") == 0)
+ 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 (PartEntry->SectorCount.QuadPart < 8192)
+ if (SectorCount->QuadPart < 8192)
{
/* FAT12 CHS partition (disk is smaller than 4.1MB) */
- SetPartitionType(PartEntry, PARTITION_FAT_12);
+ return PARTITION_FAT_12;
}
- else if (PartEntry->StartSector.QuadPart < 1450560)
+ else if (StartSector->QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
- if (PartEntry->SectorCount.QuadPart < 65536)
+ if (SectorCount->QuadPart < 65536)
{
/* FAT16 CHS partition (partition size < 32MB) */
- SetPartitionType(PartEntry, PARTITION_FAT_16);
+ return PARTITION_FAT_16;
}
- else if (PartEntry->SectorCount.QuadPart < 1048576)
+ else if (SectorCount->QuadPart < 1048576)
{
/* FAT16 CHS partition (partition size < 512MB) */
- SetPartitionType(PartEntry, PARTITION_HUGE);
+ return PARTITION_HUGE;
}
else
{
/* FAT32 CHS partition (partition size >= 512MB) */
- SetPartitionType(PartEntry, PARTITION_FAT32);
+ return PARTITION_FAT32;
}
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
- if (PartEntry->SectorCount.QuadPart < 1048576)
+ if (SectorCount->QuadPart < 1048576)
{
/* FAT16 LBA partition (partition size < 512MB) */
- SetPartitionType(PartEntry, PARTITION_XINT13);
+ return PARTITION_XINT13;
}
else
{
/* FAT32 LBA partition (partition size >= 512MB) */
- SetPartitionType(PartEntry, PARTITION_FAT32_XINT13);
+ return PARTITION_FAT32_XINT13;
}
}
}
- else if (wcscmp(FileSystem->FileSystemName, L"BTRFS") == 0)
+ else if (wcsicmp(FileSystem, L"NTFS") == 0)
{
- SetPartitionType(PartEntry, PARTITION_LINUX);
+ return PARTITION_IFS;
}
-#if 0
- else if (wcscmp(FileSystem->FileSystemName, L"EXT2") == 0)
+ 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)
{
- SetPartitionType(PartEntry, PARTITION_LINUX);
+ return PARTITION_LINUX;
}
- else if (wcscmp(FileSystem->FileSystemName, L"NTFS") == 0)
+ else
{
- SetPartitionType(PartEntry, PARTITION_IFS);
+ /* Unknown file system */
+ DPRINT1("Unknown file system '%S'\n", FileSystem);
+ return PARTITION_ENTRY_UNUSED;
}
-#endif
- else
+}
+
+
+//
+// Formatting routines
+//
+
+BOOLEAN
+PreparePartitionForFormatting(
+ IN struct _PARTENTRY* PartEntry,
+ IN PCWSTR FileSystemName)
+{
+ UCHAR PartitionType;
+
+ if (!FileSystemName || !*FileSystemName)
+ {
+ DPRINT1("No file system specified?\n");
+ return FALSE;
+ }
+
+ PartitionType = FileSystemToPartitionType(FileSystemName,
+ &PartEntry->StartSector,
+ &PartEntry->SectorCount);
+ if (PartitionType == PARTITION_ENTRY_UNUSED)
{
- /* 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;
}
* 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);
-struct _PARTENTRY; // Defined in partlist.h
+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);
-PFILE_SYSTEM
-GetFileSystem(
- // IN PFILE_SYSTEM_LIST FileSystemList,
- IN struct _PARTENTRY* PartEntry);
+/** 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
BOOLEAN
PreparePartitionForFormatting(
IN struct _PARTENTRY* PartEntry,
- IN PFILE_SYSTEM FileSystem);
+ IN PCWSTR FileSystemName);
/* EOF */
* 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"
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;
{
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
{
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);
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;
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;
{
ASSERT(PartitionInfo->RecognizedPartition);
- PartEntry->FileSystem = GetFileSystem(PartEntry);
- if (PartEntry->FileSystem)
- PartEntry->FormatState = Preformatted;
- else
- PartEntry->FormatState = Unformatted;
- // PartEntry->FormatState = UnknownFormat;
- }
- else
- {
- /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
- PartEntry->FormatState = UnknownFormat;
- }
+ /* Open the volume, ignore any errors */
+ RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskEntry->DiskNumber,
+ PartEntry->PartitionNumber);
+ RtlInitUnicodeString(&Name, PathBuffer);
- /* 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);
- 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);
+ }
- 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))
+ 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)
{
- /* Copy the (possibly truncated) volume label and NULL-terminate it */
- RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
- LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
+ if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
+ PartEntry->FormatState = Unformatted;
+ else
+ PartEntry->FormatState = Preformatted;
}
else
{
- DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
+ 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
{
- DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
+ /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
+ PartEntry->FormatState = UnknownFormat;
}
InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
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 */
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;
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)
PPARTENTRY PartEntry;
PLIST_ENTRY ListEntry;
- PFILE_SYSTEM FileSystem;
-
/* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead))
{
/* 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)
- {
- 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)
+ /* If we get a candidate active partition, validate it */
+ if (!IsSupportedActivePartition(List->OriginalSystemPartition))
{
- DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
- FileSystem->FileSystemName);
goto FindAndUseAlternativeSystemPartition;
}
* 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
Formatted
} FORMATSTATE, *PFORMATSTATE;
-struct _FILE_SYSTEM;
-
typedef struct _PARTENTRY
{
LIST_ENTRY ListEntry;
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;
/* Partition must be checked */
BOOLEAN NeedsCheck;
- FORMATSTATE FormatState;
- struct _FILE_SYSTEM* FileSystem;
-
} PARTENTRY, *PPARTENTRY;
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,
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;
NTSTATUS
ChkdskPartition(
IN PUNICODE_STRING DriveRoot,
- /*IN PFILE_SYSTEM_ITEM FileSystemItem*/
- IN PFILE_SYSTEM FileSystem);
+ IN PCWSTR FileSystemName);
/* EOF */
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,
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;
NTSTATUS
FormatPartition(
IN PUNICODE_STRING DriveRoot,
- IN PFILE_SYSTEM_ITEM FileSystemItem);
+ IN PCWSTR FileSystemName,
+ IN BOOLEAN QuickFormat);
/* EOF */
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;
if (!Item)
return;
- Item->FileSystemName = FileSystemName;
Item->FileSystem = FileSystem;
Item->QuickFormat = TRUE;
InsertTailList(&List->ListHead, &Item->ListEntry);
if (!Item)
return;
- Item->FileSystemName = FileSystemName;
Item->FileSystem = FileSystem;
Item->QuickFormat = FALSE;
InsertTailList(&List->ListHead, &Item->ListEntry);
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 (GetRegisteredFileSystems(Index++, &FileSystemName))
+ {
+ AddProvider(List, FileSystemName);
+ }
- while (Count--)
+ if (!ForceFormat)
{
- AddProvider(List, FileSystems->FileSystemName, FileSystems);
- ++FileSystems;
+ /* Add the 'Keep existing filesystem' dummy provider */
+ AddProvider(List, NULL);
}
}
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;
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
{
}
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;
}
* 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
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;
* 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>
if (SelectedFileSystem->FileSystem)
{
Status = FormatPartition(&PartitionRootPath,
- SelectedFileSystem);
+ SelectedFileSystem->FileSystem,
+ SelectedFileSystem->QuickFormat);
if (Status == STATUS_NOT_SUPPORTED)
{
sprintf(Buffer,
"\n"
" \x07 Press ENTER to continue Setup.\n"
" \x07 Press F3 to quit Setup.",
- SelectedFileSystem->FileSystem->FileSystemName);
+ SelectedFileSystem->FileSystem);
PopupError(Buffer,
MUIGetString(STRING_QUITCONTINUE),
NTSTATUS Status;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
- PFILE_SYSTEM CurrentFileSystem;
UNICODE_STRING PartitionRootPath;
WCHAR PathBuffer[MAX_PATH];
CHAR Buffer[MAX_PATH];
return INSTALL_DIRECTORY_PAGE;
}
- /* Set PartitionRootPath */
- RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
- L"\\Device\\Harddisk%lu\\Partition%lu",
- DiskEntry->DiskNumber,
- PartEntry->PartitionNumber);
- 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"));
+ 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 (CurrentFileSystem == NULL)
+ if (!*PartEntry->FileSystem)
{
PartEntry->NeedsCheck = FALSE;
return CHECK_FILE_SYSTEM_PAGE;
}
- Status = ChkdskPartition(&PartitionRootPath, CurrentFileSystem);
+ /* Set PartitionRootPath */
+ RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskEntry->DiskNumber,
+ PartEntry->PartitionNumber);
+ RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
+ DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath);
+
+ /* 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),
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
- PartitionList->SystemPartition->FileSystem->FileSystemName);
+ PartitionList->SystemPartition->FileSystem);
return QUIT_PAGE;
}
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER,
- PartitionList->SystemPartition->FileSystem->FileSystemName);
+ PartitionList->SystemPartition->FileSystem);
return QUIT_PAGE;
}