ReactOS  0.4.15-dev-2095-g7caf9e9
fsutil.h File Reference
#include <fmifs/fmifs.h>
Include dependency graph for fsutil.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FAT_BOOTSECTOR_SIZE   (1 * SECTORSIZE)
 
#define FAT32_BOOTSECTOR_SIZE   (1 * SECTORSIZE)
 
#define BTRFS_BOOTSECTOR_SIZE   (3 * SECTORSIZE)
 
#define InstallFat12BootCode   InstallFatBootCode
 
#define InstallFat16BootCode   InstallFatBootCode
 

Typedefs

typedef IN HANDLE DstPath
 
typedef IN HANDLE IN HANDLE RootPartition
 

Functions

BOOLEAN GetRegisteredFileSystems (IN ULONG Index, OUT PCWSTR *FileSystemName)
 
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)
 
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)
 
typedef NTSTATUS (*PFS_INSTALL_BOOTCODE)(IN PCWSTR SrcPath
 
NTSTATUS InstallFatBootCode (IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
 
NTSTATUS InstallFat32BootCode (IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
 
NTSTATUS InstallBtrfsBootCode (IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
 
NTSTATUS ChkdskPartition (IN PPARTENTRY PartEntry, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PFMIFSCALLBACK Callback)
 
NTSTATUS FormatPartition (IN PPARTENTRY PartEntry, IN PCWSTR FileSystemName, IN FMIFS_MEDIA_FLAG MediaFlag, IN PCWSTR Label, IN BOOLEAN QuickFormat, IN ULONG ClusterSize, IN PFMIFSCALLBACK Callback)
 

Macro Definition Documentation

◆ BTRFS_BOOTSECTOR_SIZE

#define BTRFS_BOOTSECTOR_SIZE   (3 * SECTORSIZE)

Definition at line 70 of file fsutil.h.

◆ FAT32_BOOTSECTOR_SIZE

#define FAT32_BOOTSECTOR_SIZE   (1 * SECTORSIZE)

Definition at line 69 of file fsutil.h.

◆ FAT_BOOTSECTOR_SIZE

#define FAT_BOOTSECTOR_SIZE   (1 * SECTORSIZE)

Definition at line 68 of file fsutil.h.

◆ InstallFat12BootCode

#define InstallFat12BootCode   InstallFatBootCode

Definition at line 84 of file fsutil.h.

◆ InstallFat16BootCode

#define InstallFat16BootCode   InstallFatBootCode

Definition at line 85 of file fsutil.h.

Typedef Documentation

◆ DstPath

typedef IN HANDLE DstPath

Definition at line 75 of file fsutil.h.

◆ RootPartition

Definition at line 75 of file fsutil.h.

Function Documentation

◆ ChkdskFileSystem()

NTSTATUS ChkdskFileSystem ( IN PCWSTR  DriveRoot,
IN PCWSTR  FileSystemName,
IN BOOLEAN  FixErrors,
IN BOOLEAN  Verbose,
IN BOOLEAN  CheckOnlyIfDirty,
IN BOOLEAN  ScanDrive,
IN PFMIFSCALLBACK  Callback 
)

Definition at line 260 of file fsutil.c.

268 {
269  UNICODE_STRING DriveRootU;
270 
271  RtlInitUnicodeString(&DriveRootU, DriveRoot);
272  return ChkdskFileSystem_UStr(&DriveRootU,
273  FileSystemName,
274  FixErrors,
275  Verbose,
276  CheckOnlyIfDirty,
277  ScanDrive,
278  Callback);
279 }
BOOL Verbose
Definition: chkdsk.c:72
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)
Definition: fsutil.c:217
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
BOOL FixErrors
Definition: chkdsk.c:69
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

Referenced by ChkdskPartition().

◆ ChkdskFileSystem_UStr()

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 
)

ChkdskEx()

Definition at line 217 of file fsutil.c.

225 {
229 
230  FileSystem = GetFileSystemByName(FileSystemName);
231 
232  if (!FileSystem || !FileSystem->ChkdskFunc)
233  {
234  // Success = FALSE;
235  // Callback(DONE, 0, &Success);
236  return STATUS_NOT_SUPPORTED;
237  }
238 
240  Success = FileSystem->ChkdskFunc(DriveRoot,
241  Callback,
242  FixErrors,
243  Verbose,
244  CheckOnlyIfDirty,
245  ScanDrive,
246  NULL,
247  NULL,
248  NULL,
249  NULL,
250  (PULONG)&Status);
251  if (!Success)
252  DPRINT1("ChkdskFunc() failed with Status 0x%lx\n", Status);
253 
254  // Callback(DONE, 0, &Success);
255 
256  return Status;
257 }
return STATUS_NOT_SUPPORTED
PWCHAR FileSystem
Definition: format.c:72
BOOL Verbose
Definition: chkdsk.c:72
LONG NTSTATUS
Definition: precomp.h:26
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
static PFILE_SYSTEM GetFileSystemByName(IN PCWSTR FileSystemName)
Definition: fsutil.c:170
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
BOOL FixErrors
Definition: chkdsk.c:69
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by ChkdskFileSystem().

◆ ChkdskPartition()

NTSTATUS ChkdskPartition ( IN PPARTENTRY  PartEntry,
IN BOOLEAN  FixErrors,
IN BOOLEAN  Verbose,
IN BOOLEAN  CheckOnlyIfDirty,
IN BOOLEAN  ScanDrive,
IN PFMIFSCALLBACK  Callback 
)

Definition at line 670 of file fsutil.c.

677 {
679  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
680  // UNICODE_STRING PartitionRootPath;
681  WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
682 
683  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
684 
685  /* HACK: Do not try to check a partition with an unknown filesystem */
686  if (!*PartEntry->FileSystem)
687  {
688  PartEntry->NeedsCheck = FALSE;
689  return STATUS_SUCCESS;
690  }
691 
692  /* Set PartitionRootPath */
693  RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
694  L"\\Device\\Harddisk%lu\\Partition%lu",
695  DiskEntry->DiskNumber,
696  PartEntry->PartitionNumber);
697  DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
698 
699  /* Check the partition */
700  Status = ChkdskFileSystem(PartitionRootPath,
701  PartEntry->FileSystem,
702  FixErrors,
703  Verbose,
704  CheckOnlyIfDirty,
705  ScanDrive,
706  Callback);
707  if (!NT_SUCCESS(Status))
708  return Status;
709 
710  PartEntry->NeedsCheck = FALSE;
711  return STATUS_SUCCESS;
712 }
BOOL Verbose
Definition: chkdsk.c:72
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
ULONG DiskNumber
Definition: partlist.h:111
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
NTSTATUS ChkdskFileSystem(IN PCWSTR DriveRoot, IN PCWSTR FileSystemName, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PFMIFSCALLBACK Callback)
Definition: fsutil.c:260
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
static const WCHAR L[]
Definition: oid.c:1250
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
BOOL FixErrors
Definition: chkdsk.c:69
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by DoChkdsk().

◆ FormatFileSystem()

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 
)

Definition at line 349 of file fsutil.c.

357 {
358  UNICODE_STRING DriveRootU;
359  UNICODE_STRING LabelU;
360 
361  RtlInitUnicodeString(&DriveRootU, DriveRoot);
362  RtlInitUnicodeString(&LabelU, Label);
363 
364  return FormatFileSystem_UStr(&DriveRootU,
365  FileSystemName,
366  MediaFlag,
367  &LabelU,
368  QuickFormat,
369  ClusterSize,
370  Callback);
371 }
BOOL QuickFormat
Definition: format.c:66
DWORD ClusterSize
Definition: format.c:67
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
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)
Definition: fsutil.c:284
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PWCHAR Label
Definition: format.c:70

Referenced by FormatPartition(), and InstallFatBootcodeToFloppy().

◆ FormatFileSystem_UStr()

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 
)

FormatEx()

Definition at line 284 of file fsutil.c.

292 {
295  BOOLEAN BackwardCompatible = FALSE; // Default to latest FS versions.
296  MEDIA_TYPE MediaType;
297 
298  FileSystem = GetFileSystemByName(FileSystemName);
299 
300  if (!FileSystem || !FileSystem->FormatFunc)
301  {
302  // Success = FALSE;
303  // Callback(DONE, 0, &Success);
304  return STATUS_NOT_SUPPORTED;
305  }
306 
307  /* Set the BackwardCompatible flag in case we format with older FAT12/16 */
308  if (wcsicmp(FileSystemName, L"FAT") == 0)
309  BackwardCompatible = TRUE;
310  // else if (wcsicmp(FileSystemName, L"FAT32") == 0)
311  // BackwardCompatible = FALSE;
312 
313  /* Convert the FMIFS MediaFlag to a NT MediaType */
314  // FIXME: Actually covert all the possible flags.
315  switch (MediaFlag)
316  {
317  case FMIFS_FLOPPY:
318  MediaType = F5_320_1024; // FIXME: This is hardfixed!
319  break;
320  case FMIFS_REMOVABLE:
321  MediaType = RemovableMedia;
322  break;
323  case FMIFS_HARDDISK:
324  MediaType = FixedMedia;
325  break;
326  default:
327  DPRINT1("Unknown FMIFS MediaFlag %d, converting 1-to-1 to NT MediaType\n",
328  MediaFlag);
329  MediaType = (MEDIA_TYPE)MediaFlag;
330  break;
331  }
332 
333  Success = FileSystem->FormatFunc(DriveRoot,
334  Callback,
335  QuickFormat,
336  BackwardCompatible,
337  MediaType,
338  Label,
339  ClusterSize);
340  if (!Success)
341  DPRINT1("FormatFunc() failed\n");
342 
343  // Callback(DONE, 0, &Success);
344 
346 }
return STATUS_NOT_SUPPORTED
PWCHAR FileSystem
Definition: format.c:72
#define TRUE
Definition: types.h:120
enum _MEDIA_TYPE MEDIA_TYPE
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
BOOL QuickFormat
Definition: format.c:66
DWORD ClusterSize
Definition: format.c:67
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define wcsicmp
Definition: compat.h:15
static const WCHAR L[]
Definition: oid.c:1250
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
static PFILE_SYSTEM GetFileSystemByName(IN PCWSTR FileSystemName)
Definition: fsutil.c:170
#define DPRINT1
Definition: precomp.h:8
PWCHAR Label
Definition: format.c:70
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by FormatFileSystem().

◆ FormatPartition()

NTSTATUS FormatPartition ( IN PPARTENTRY  PartEntry,
IN PCWSTR  FileSystemName,
IN FMIFS_MEDIA_FLAG  MediaFlag,
IN PCWSTR  Label,
IN BOOLEAN  QuickFormat,
IN ULONG  ClusterSize,
IN PFMIFSCALLBACK  Callback 
)

Definition at line 715 of file fsutil.c.

723 {
725  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
727  // UNICODE_STRING PartitionRootPath;
728  WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
729 
730  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
731 
732  if (!FileSystemName || !*FileSystemName)
733  {
734  DPRINT1("No file system specified?\n");
736  }
737 
738  /*
739  * Prepare the partition for formatting (for MBR disks, reset the
740  * partition type), and adjust the filesystem name in case of FAT
741  * vs. FAT32, depending on the geometry of the partition.
742  */
743 
744 // FIXME: Do this only if QuickFormat == FALSE? What about FAT handling?
745 
746  /*
747  * Retrieve a partition type as a hint only. It will be used to determine
748  * whether to actually use FAT12/16 or FAT32 filesystem, depending on the
749  * geometry of the partition. If the partition resides on an MBR disk,
750  * the partition style will be reset to this value as well, unless the
751  * partition is OEM.
752  */
754  PartEntry->StartSector.QuadPart,
755  PartEntry->SectorCount.QuadPart);
757  {
758  /* Unknown file system */
759  DPRINT1("Unknown file system '%S'\n", FileSystemName);
761  }
762 
763  /* Reset the MBR partition type, unless this is an OEM partition */
764  if (DiskEntry->DiskStyle == PARTITION_STYLE_MBR)
765  {
766  if (!IsOEMPartition(PartEntry->PartitionType))
768  }
769 
770  /*
771  * Adjust the filesystem name in case of FAT vs. FAT32, according to
772  * the type of partition returned by FileSystemToMBRPartitionType().
773  */
774  if (wcsicmp(FileSystemName, L"FAT") == 0)
775  {
776  if ((PartitionType == PARTITION_FAT32) ||
778  {
779  FileSystemName = L"FAT32";
780  }
781  }
782 
783  /* Commit the partition changes to the disk */
784  Status = WritePartitions(DiskEntry);
785  if (!NT_SUCCESS(Status))
786  {
787  DPRINT1("WritePartitions(disk %lu) failed, Status 0x%08lx\n",
788  DiskEntry->DiskNumber, Status);
790  }
791 
792  /* Set PartitionRootPath */
793  RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
794  L"\\Device\\Harddisk%lu\\Partition%lu",
795  DiskEntry->DiskNumber,
796  PartEntry->PartitionNumber);
797  DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
798 
799  /* Format the partition */
800  Status = FormatFileSystem(PartitionRootPath,
801  FileSystemName,
802  MediaFlag,
803  Label,
804  QuickFormat,
805  ClusterSize,
806  Callback);
807  if (!NT_SUCCESS(Status))
808  return Status;
809 
810 //
811 // TODO: Here, call a partlist.c function that update the actual
812 // FS name and the label fields of the volume.
813 //
814  PartEntry->FormatState = Formatted;
815 
816  /* Set the new partition's file system proper */
817  RtlStringCbCopyW(PartEntry->FileSystem,
818  sizeof(PartEntry->FileSystem),
819  FileSystemName);
820 
821  PartEntry->New = FALSE;
822 
823  return STATUS_SUCCESS;
824 }
#define PARTITION_FAT32
Definition: disk.h:95
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
ULONG DiskNumber
Definition: partlist.h:111
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
#define FALSE
Definition: types.h:117
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
BOOL QuickFormat
Definition: format.c:66
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
DWORD ClusterSize
Definition: format.c:67
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
#define wcsicmp
Definition: compat.h:15
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
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)
Definition: fsutil.c:349
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
#define DPRINT1
Definition: precomp.h:8
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3619
CHAR PartitionType
Definition: part_xbox.c:32
PWCHAR Label
Definition: format.c:70
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define IsOEMPartition(PartitionType)
Definition: partlist.h:22
VOID SetMBRPartitionType(IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
Definition: partlist.c:3937
#define STATUS_PARTITION_FAILURE
Definition: ntstatus.h:604

Referenced by DoFormat().

◆ GetRegisteredFileSystems()

BOOLEAN GetRegisteredFileSystems ( IN ULONG  Index,
OUT PCWSTR FileSystemName 
)

QueryAvailableFileSystemFormat()

Definition at line 155 of file fsutil.c.

158 {
160  return FALSE;
161 
162  *FileSystemName = RegisteredFileSystems[Index].FileSystemName;
163 
164  return TRUE;
165 }
#define TRUE
Definition: types.h:120
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define FALSE
Definition: types.h:117
_In_ WDFCOLLECTION _In_ ULONG Index
static FILE_SYSTEM RegisteredFileSystems[]
Definition: fsutil.c:130
PCWSTR FileSystemName
Definition: fsutil.c:124

Referenced by InitializeFileSystemList().

◆ InstallBtrfsBootCode()

NTSTATUS InstallBtrfsBootCode ( IN PCWSTR  SrcPath,
IN HANDLE  DstPath,
IN HANDLE  RootPartition 
)

Definition at line 558 of file fsutil.c.

562 {
564  NTSTATUS LockStatus;
568  PARTITION_INFORMATION_EX PartInfo;
569  BOOTCODE NewBootSector = {0};
570 
571  /* Allocate and read the new bootsector from SrcPath */
572  RtlInitUnicodeString(&Name, SrcPath);
573  Status = ReadBootCodeFromFile(&NewBootSector,
574  &Name,
576  if (!NT_SUCCESS(Status))
577  return Status;
578 
579  /*
580  * The BTRFS driver requires the volume to be locked in order to modify
581  * the first sectors of the partition, even though they are outside the
582  * file-system space / in the reserved area (they are situated before
583  * the super-block at 0x1000) and is in principle allowed by the NT
584  * storage stack.
585  * So we lock here in order to write the bootsector at sector 0.
586  * If locking fails, we ignore and continue nonetheless.
587  */
588  LockStatus = NtFsControlFile(DstPath,
589  NULL,
590  NULL,
591  NULL,
592  &IoStatusBlock,
594  NULL,
595  0,
596  NULL,
597  0);
598  if (!NT_SUCCESS(LockStatus))
599  {
600  DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus);
601  }
602 
603  /* Obtain partition info and write it to the bootsector */
605  NULL,
606  NULL,
607  NULL,
608  &IoStatusBlock,
610  NULL,
611  0,
612  &PartInfo,
613  sizeof(PartInfo));
614  if (!NT_SUCCESS(Status))
615  {
616  DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
617  goto Quit;
618  }
619 
620  /* Write new bootsector to RootPath */
621  ((PBTRFS_BOOTSECTOR)NewBootSector.BootCode)->PartitionStartLBA =
623 
624  /* Write sector 0 */
625  FileOffset.QuadPart = 0ULL;
627  NULL,
628  NULL,
629  NULL,
630  &IoStatusBlock,
631  NewBootSector.BootCode,
632  NewBootSector.Length,
633  &FileOffset,
634  NULL);
635  if (!NT_SUCCESS(Status))
636  {
637  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
638  goto Quit;
639  }
640 
641 Quit:
642  /* Unlock the volume */
643  LockStatus = NtFsControlFile(DstPath,
644  NULL,
645  NULL,
646  NULL,
647  &IoStatusBlock,
649  NULL,
650  0,
651  NULL,
652  0);
653  if (!NT_SUCCESS(LockStatus))
654  {
655  DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus);
656  }
657 
658  /* Free the new bootsector */
659  FreeBootCode(&NewBootSector);
660 
661  return Status;
662 }
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define BTRFS_BOOTSECTOR_SIZE
Definition: fsutil.h:70
LONG NTSTATUS
Definition: precomp.h:26
ULONG Length
Definition: bootcode.h:18
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
struct _BTRFS_BOOTSECTOR * PBTRFS_BOOTSECTOR
IN HANDLE DstPath
Definition: fsutil.h:75
struct NameRec_ * Name
Definition: cdprocs.h:459
#define ULL(a, b)
Definition: format_msg.c:27
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID BootCode
Definition: bootcode.h:17
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:75
LARGE_INTEGER StartingOffset
Definition: imports.h:221
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define SECTORSIZE
Definition: bootcode.h:13
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by InstallBtrfsBootcodeToPartition().

◆ InstallFat32BootCode()

NTSTATUS InstallFat32BootCode ( IN PCWSTR  SrcPath,
IN HANDLE  DstPath,
IN HANDLE  RootPartition 
)

Definition at line 437 of file fsutil.c.

441 {
447  BOOTCODE OrigBootSector = {0};
448  BOOTCODE NewBootSector = {0};
449 
450  /* Allocate and read the current original partition bootsector */
451  Status = ReadBootCodeByHandle(&OrigBootSector,
454  if (!NT_SUCCESS(Status))
455  return Status;
456 
457  /* Allocate and read the new bootsector (2 sectors) from SrcPath */
458  RtlInitUnicodeString(&Name, SrcPath);
459  Status = ReadBootCodeFromFile(&NewBootSector,
460  &Name,
462  if (!NT_SUCCESS(Status))
463  {
464  FreeBootCode(&OrigBootSector);
465  return Status;
466  }
467 
468  /* Adjust the bootsector (copy a part of the FAT32 BPB) */
469  RtlCopyMemory(&((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->OemName,
470  &((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
471  FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
473 
474  /*
475  * We know we copy the boot code to a file only when DstPath != RootPartition,
476  * otherwise the boot code is copied to the specified root partition.
477  */
478  if (DstPath != RootPartition)
479  {
480  /* Copy to a file: Disable the backup bootsector */
481  ((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->BackupBootSector = 0;
482  }
483  else
484  {
485  /* Copy to a disk: Get the location of the backup bootsector */
486  BackupBootSector = ((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->BackupBootSector;
487  }
488 
489  /* Free the original bootsector */
490  FreeBootCode(&OrigBootSector);
491 
492  /* Write the first sector of the new bootcode to DstPath sector 0 */
493  FileOffset.QuadPart = 0ULL;
495  NULL,
496  NULL,
497  NULL,
498  &IoStatusBlock,
499  NewBootSector.BootCode,
501  &FileOffset,
502  NULL);
503  if (!NT_SUCCESS(Status))
504  {
505  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
506  FreeBootCode(&NewBootSector);
507  return Status;
508  }
509 
510  if (DstPath == RootPartition)
511  {
512  /* Copy to a disk: Write the backup bootsector */
513  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
514  {
517  NULL,
518  NULL,
519  NULL,
520  &IoStatusBlock,
521  NewBootSector.BootCode,
523  &FileOffset,
524  NULL);
525  if (!NT_SUCCESS(Status))
526  {
527  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
528  FreeBootCode(&NewBootSector);
529  return Status;
530  }
531  }
532  }
533 
534  /* Write the second sector of the new bootcode to boot disk sector 14 */
535  // FileOffset.QuadPart = (ULONGLONG)(14 * FAT32_BOOTSECTOR_SIZE);
536  FileOffset.QuadPart = 14 * FAT32_BOOTSECTOR_SIZE;
537  Status = NtWriteFile(DstPath, // or really RootPartition ???
538  NULL,
539  NULL,
540  NULL,
541  &IoStatusBlock,
542  ((PUCHAR)NewBootSector.BootCode + FAT32_BOOTSECTOR_SIZE),
544  &FileOffset,
545  NULL);
546  if (!NT_SUCCESS(Status))
547  {
548  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
549  }
550 
551  /* Free the new bootsector */
552  FreeBootCode(&NewBootSector);
553 
554  return Status;
555 }
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61
IN HANDLE DstPath
Definition: fsutil.h:75
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
#define ULL(a, b)
Definition: format_msg.c:27
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
PVOID BootCode
Definition: bootcode.h:17
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:75
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
unsigned short USHORT
Definition: pedump.c:61
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define FAT32_BOOTSECTOR_SIZE
Definition: fsutil.h:69
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1303

Referenced by InstallFatBootcodeToPartition().

◆ InstallFatBootCode()

NTSTATUS InstallFatBootCode ( IN PCWSTR  SrcPath,
IN HANDLE  DstPath,
IN HANDLE  RootPartition 
)

Definition at line 379 of file fsutil.c.

383 {
388  BOOTCODE OrigBootSector = {0};
389  BOOTCODE NewBootSector = {0};
390 
391  /* Allocate and read the current original partition bootsector */
392  Status = ReadBootCodeByHandle(&OrigBootSector,
395  if (!NT_SUCCESS(Status))
396  return Status;
397 
398  /* Allocate and read the new bootsector from SrcPath */
399  RtlInitUnicodeString(&Name, SrcPath);
400  Status = ReadBootCodeFromFile(&NewBootSector,
401  &Name,
403  if (!NT_SUCCESS(Status))
404  {
405  FreeBootCode(&OrigBootSector);
406  return Status;
407  }
408 
409  /* Adjust the bootsector (copy a part of the FAT12/16 BPB) */
410  RtlCopyMemory(&((PFAT_BOOTSECTOR)NewBootSector.BootCode)->OemName,
411  &((PFAT_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
412  FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
414 
415  /* Free the original bootsector */
416  FreeBootCode(&OrigBootSector);
417 
418  /* Write the new bootsector to DstPath */
419  FileOffset.QuadPart = 0ULL;
421  NULL,
422  NULL,
423  NULL,
424  &IoStatusBlock,
425  NewBootSector.BootCode,
426  NewBootSector.Length,
427  &FileOffset,
428  NULL);
429 
430  /* Free the new bootsector */
431  FreeBootCode(&NewBootSector);
432 
433  return Status;
434 }
#define FAT_BOOTSECTOR_SIZE
Definition: fsutil.h:68
LONG NTSTATUS
Definition: precomp.h:26
ULONG Length
Definition: bootcode.h:18
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
IN HANDLE DstPath
Definition: fsutil.h:75
struct NameRec_ * Name
Definition: cdprocs.h:459
#define ULL(a, b)
Definition: format_msg.c:27
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID BootCode
Definition: bootcode.h:17
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:75
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1303

◆ NTSTATUS()

typedef NTSTATUS ( PFS_INSTALL_BOOTCODE)