mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 21:55:08 +00:00
282 lines
7.4 KiB
C
282 lines
7.4 KiB
C
/*
|
|
* PROJECT: ReactOS Setup Library
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Filesystem support functions
|
|
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
* Copyright 2017-2019 Hermes Belusca-Maito
|
|
*/
|
|
|
|
//
|
|
// See also: https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/dll/win32/fmifs/init.c;h=e895f5ef9cae4806123f6bbdd3dfed37ec1c8d33;hb=b9db9a4e377a2055f635b2fb69fef4e1750d219c
|
|
// for how to get FS providers in a dynamic way. In the (near) future we may
|
|
// consider merging some of this code with us into a fmifs / fsutil / fslib library...
|
|
//
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include "partlist.h"
|
|
#include "fsrec.h"
|
|
#include "fsutil.h"
|
|
|
|
#include <fslib/vfatlib.h>
|
|
#include <fslib/btrfslib.h>
|
|
// #include <fslib/ext2lib.h>
|
|
// #include <fslib/ntfslib.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
|
|
/* 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 */
|
|
static FILE_SYSTEM RegisteredFileSystems[] =
|
|
{
|
|
/* NOTE: The FAT formatter automatically determines
|
|
* whether it will use FAT-16 or FAT-32. */
|
|
{ L"FAT" , VfatFormat, VfatChkdsk },
|
|
#if 0
|
|
{ L"FAT32", VfatFormat, VfatChkdsk }, // Do we support specific FAT sub-formats specifications?
|
|
{ L"FATX" , VfatxFormat, VfatxChkdsk },
|
|
{ L"NTFS" , NtfsFormat, NtfsChkdsk },
|
|
#endif
|
|
{ L"BTRFS", BtrfsFormatEx, BtrfsChkdskEx },
|
|
#if 0
|
|
{ L"EXT2" , Ext2Format, Ext2Chkdsk },
|
|
{ L"EXT3" , Ext2Format, Ext2Chkdsk },
|
|
{ L"EXT4" , Ext2Format, Ext2Chkdsk },
|
|
{ L"FFS" , FfsFormat , FfsChkdsk },
|
|
{ L"REISERFS", ReiserfsFormat, ReiserfsChkdsk },
|
|
#endif
|
|
};
|
|
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
/** QueryAvailableFileSystemFormat() **/
|
|
BOOLEAN
|
|
GetRegisteredFileSystems(
|
|
IN ULONG Index,
|
|
OUT PCWSTR* FileSystemName)
|
|
{
|
|
if (Index >= ARRAYSIZE(RegisteredFileSystems))
|
|
return FALSE;
|
|
|
|
*FileSystemName = RegisteredFileSystems[Index].FileSystemName;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/** GetProvider() **/
|
|
static PFILE_SYSTEM
|
|
GetFileSystemByName(
|
|
IN PCWSTR FileSystemName)
|
|
{
|
|
#if 0 // Reenable when the list of registered FSes will again be dynamic
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
PFILE_SYSTEM_ITEM Item;
|
|
|
|
ListEntry = List->ListHead.Flink;
|
|
while (ListEntry != &List->ListHead)
|
|
{
|
|
Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
|
|
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 = ARRAYSIZE(RegisteredFileSystems);
|
|
PFILE_SYSTEM FileSystems = RegisteredFileSystems;
|
|
|
|
ASSERT(FileSystems && Count != 0);
|
|
|
|
while (Count--)
|
|
{
|
|
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;
|
|
}
|
|
|
|
#endif
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/** 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);
|
|
}
|
|
|
|
|
|
//
|
|
// 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", 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 */
|
|
RtlStringCbCopyW(PartEntry->FileSystem,
|
|
sizeof(PartEntry->FileSystem),
|
|
FileSystemName);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|