mirror of
https://github.com/reactos/reactos.git
synced 2025-05-11 13:27:47 +00:00
[SETUPLIB] Move the filesystem recognition helpers to their own file.
This commit is contained in:
parent
8a4273b6ee
commit
b51b8ee2d5
7 changed files with 361 additions and 332 deletions
|
@ -9,6 +9,7 @@ list(APPEND SOURCE
|
||||||
utils/arcname.c
|
utils/arcname.c
|
||||||
utils/bldrsup.c
|
utils/bldrsup.c
|
||||||
utils/filesup.c
|
utils/filesup.c
|
||||||
|
utils/fsrec.c
|
||||||
utils/genlist.c
|
utils/genlist.c
|
||||||
utils/inicache.c
|
utils/inicache.c
|
||||||
utils/ntverrsrc.c
|
utils/ntverrsrc.c
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
#include "fsutil.h"
|
|
||||||
#include "partlist.h"
|
#include "partlist.h"
|
||||||
|
#include "fsrec.h"
|
||||||
|
#include "fsutil.h"
|
||||||
|
|
||||||
#include <fslib/vfatlib.h>
|
#include <fslib/vfatlib.h>
|
||||||
#include <fslib/btrfslib.h>
|
#include <fslib/btrfslib.h>
|
||||||
|
@ -128,222 +129,6 @@ GetFileSystemByName(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// FileSystem recognition, using NT OS functionality
|
|
||||||
//
|
|
||||||
|
|
||||||
/* NOTE: Ripped & adapted from base/system/autochk/autochk.c */
|
|
||||||
NTSTATUS
|
|
||||||
GetFileSystemNameByHandle(
|
|
||||||
IN HANDLE PartitionHandle,
|
|
||||||
IN OUT PWSTR FileSystemName,
|
|
||||||
IN SIZE_T FileSystemNameSize)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
UCHAR Buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
|
|
||||||
PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
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 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* be formatted with different file systems: for example, usual Linux
|
|
||||||
* partitions that are formatted in EXT2/3/4, ReiserFS, etc... have the
|
|
||||||
* same partition ID 0x83.
|
|
||||||
*
|
|
||||||
* The proper fix is to make a function that detects the existing FS
|
|
||||||
* from a given partition (not based on the partition ID).
|
|
||||||
* On the contrary, for unformatted partitions with a given ID, the
|
|
||||||
* following code is OK.
|
|
||||||
*/
|
|
||||||
if ((PartitionType == PARTITION_FAT_12) ||
|
|
||||||
(PartitionType == PARTITION_FAT_16) ||
|
|
||||||
(PartitionType == PARTITION_HUGE ) ||
|
|
||||||
(PartitionType == PARTITION_XINT13))
|
|
||||||
{
|
|
||||||
/* FAT12 or FAT16 */
|
|
||||||
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT");
|
|
||||||
}
|
|
||||||
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, ... */
|
|
||||||
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"BTRFS");
|
|
||||||
}
|
|
||||||
else if (PartitionType == PARTITION_IFS)
|
|
||||||
{
|
|
||||||
// WARNING: See the warning above.
|
|
||||||
/* Could also be HPFS */
|
|
||||||
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"NTFS");
|
|
||||||
}
|
|
||||||
|
|
||||||
Quit:
|
|
||||||
if (*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("InferFileSystem -- PartitionType: 0x%02X ; FileSystem (guessed): %S\n",
|
|
||||||
PartitionType, *FileSystemName ? FileSystemName : L"None");
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
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() **/
|
/** ChkdskEx() **/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ChkdskFileSystem_UStr(
|
ChkdskFileSystem_UStr(
|
||||||
|
@ -453,81 +238,6 @@ FormatFileSystem(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -16,38 +16,6 @@ GetRegisteredFileSystems(
|
||||||
IN ULONG Index,
|
IN ULONG Index,
|
||||||
OUT PCWSTR* FileSystemName);
|
OUT PCWSTR* FileSystemName);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
GetFileSystemNameByHandle(
|
|
||||||
IN HANDLE PartitionHandle,
|
|
||||||
IN OUT PWSTR FileSystemName,
|
|
||||||
IN SIZE_T FileSystemNameSize);
|
|
||||||
|
|
||||||
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() **/
|
/** ChkdskEx() **/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -93,13 +61,6 @@ FormatFileSystem(
|
||||||
IN PFMIFSCALLBACK Callback);
|
IN PFMIFSCALLBACK Callback);
|
||||||
|
|
||||||
|
|
||||||
UCHAR
|
|
||||||
FileSystemToPartitionType(
|
|
||||||
IN PCWSTR FileSystem,
|
|
||||||
IN PULARGE_INTEGER StartSector,
|
|
||||||
IN PULARGE_INTEGER SectorCount);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -33,6 +33,7 @@ extern HANDLE ProcessHeap;
|
||||||
#include "utils/bldrsup.h"
|
#include "utils/bldrsup.h"
|
||||||
#include "bootsup.h"
|
#include "bootsup.h"
|
||||||
#include "utils/filesup.h"
|
#include "utils/filesup.h"
|
||||||
|
#include "utils/fsrec.h"
|
||||||
#include "fsutil.h"
|
#include "fsutil.h"
|
||||||
#include "utils/genlist.h"
|
#include "utils/genlist.h"
|
||||||
#include "utils/inicache.h"
|
#include "utils/inicache.h"
|
||||||
|
|
307
base/setup/lib/utils/fsrec.c
Normal file
307
base/setup/lib/utils/fsrec.c
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Setup Library
|
||||||
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: Filesystem Recognition support functions,
|
||||||
|
* using NT OS functionality.
|
||||||
|
* COPYRIGHT: Copyright 2017-2020 Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
#include "fsrec.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Ripped & adapted from base/system/autochk/autochk.c */
|
||||||
|
NTSTATUS
|
||||||
|
GetFileSystemNameByHandle(
|
||||||
|
IN HANDLE PartitionHandle,
|
||||||
|
IN OUT PWSTR FileSystemName,
|
||||||
|
IN SIZE_T FileSystemNameSize)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
UCHAR Buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
|
||||||
|
PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* be formatted with different file systems: for example, usual Linux
|
||||||
|
* partitions that are formatted in EXT2/3/4, ReiserFS, etc... have the
|
||||||
|
* same partition ID 0x83.
|
||||||
|
*
|
||||||
|
* The proper fix is to make a function that detects the existing FS
|
||||||
|
* from a given partition (not based on the partition ID).
|
||||||
|
* On the contrary, for unformatted partitions with a given ID, the
|
||||||
|
* following code is OK.
|
||||||
|
*/
|
||||||
|
if ((PartitionType == PARTITION_FAT_12) ||
|
||||||
|
(PartitionType == PARTITION_FAT_16) ||
|
||||||
|
(PartitionType == PARTITION_HUGE ) ||
|
||||||
|
(PartitionType == PARTITION_XINT13))
|
||||||
|
{
|
||||||
|
/* FAT12 or FAT16 */
|
||||||
|
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT");
|
||||||
|
}
|
||||||
|
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, ... */
|
||||||
|
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"BTRFS");
|
||||||
|
}
|
||||||
|
else if (PartitionType == PARTITION_IFS)
|
||||||
|
{
|
||||||
|
// WARNING: See the warning above.
|
||||||
|
/* Could also be HPFS */
|
||||||
|
Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"NTFS");
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (*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("InferFileSystem -- PartitionType: 0x%02X ; FileSystem (guessed): %S\n",
|
||||||
|
PartitionType, *FileSystemName ? FileSystemName : L"None");
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
49
base/setup/lib/utils/fsrec.h
Normal file
49
base/setup/lib/utils/fsrec.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Setup Library
|
||||||
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: Filesystem Recognition support functions,
|
||||||
|
* using NT OS functionality.
|
||||||
|
* COPYRIGHT: Copyright 2017-2020 Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetFileSystemNameByHandle(
|
||||||
|
IN HANDLE PartitionHandle,
|
||||||
|
IN OUT PWSTR FileSystemName,
|
||||||
|
IN SIZE_T FileSystemNameSize);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
UCHAR
|
||||||
|
FileSystemToPartitionType(
|
||||||
|
IN PCWSTR FileSystem,
|
||||||
|
IN PULARGE_INTEGER StartSector,
|
||||||
|
IN PULARGE_INTEGER SectorCount);
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -10,7 +10,7 @@
|
||||||
#include <ntddscsi.h>
|
#include <ntddscsi.h>
|
||||||
|
|
||||||
#include "partlist.h"
|
#include "partlist.h"
|
||||||
#include "fsutil.h"
|
#include "fsrec.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
Loading…
Reference in a new issue