ReactOS  0.4.15-dev-3308-g9455def
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 258 of file fsutil.c.

266 {
267  UNICODE_STRING DriveRootU;
268 
269  RtlInitUnicodeString(&DriveRootU, DriveRoot);
270  return ChkdskFileSystem_UStr(&DriveRootU,
271  FileSystemName,
272  FixErrors,
273  Verbose,
274  CheckOnlyIfDirty,
275  ScanDrive,
276  Callback);
277 }
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:215
_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 215 of file fsutil.c.

223 {
227 
228  FileSystem = GetFileSystemByName(FileSystemName);
229 
230  if (!FileSystem || !FileSystem->ChkdskFunc)
231  {
232  // Success = FALSE;
233  // Callback(DONE, 0, &Success);
234  return STATUS_NOT_SUPPORTED;
235  }
236 
238  Success = FileSystem->ChkdskFunc(DriveRoot,
239  Callback,
240  FixErrors,
241  Verbose,
242  CheckOnlyIfDirty,
243  ScanDrive,
244  NULL,
245  NULL,
246  NULL,
247  NULL,
248  (PULONG)&Status);
249  if (!Success)
250  DPRINT1("ChkdskFunc() failed with Status 0x%lx\n", Status);
251 
252  // Callback(DONE, 0, &Success);
253 
254  return Status;
255 }
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:168
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 668 of file fsutil.c.

675 {
677  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
678  // UNICODE_STRING PartitionRootPath;
679  WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
680 
681  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
682 
683  /* HACK: Do not try to check a partition with an unknown filesystem */
684  if (!*PartEntry->FileSystem)
685  {
686  PartEntry->NeedsCheck = FALSE;
687  return STATUS_SUCCESS;
688  }
689 
690  /* Set PartitionRootPath */
691  RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
692  L"\\Device\\Harddisk%lu\\Partition%lu",
693  DiskEntry->DiskNumber,
694  PartEntry->PartitionNumber);
695  DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
696 
697  /* Check the partition */
698  Status = ChkdskFileSystem(PartitionRootPath,
699  PartEntry->FileSystem,
700  FixErrors,
701  Verbose,
702  CheckOnlyIfDirty,
703  ScanDrive,
704  Callback);
705  if (!NT_SUCCESS(Status))
706  return Status;
707 
708  PartEntry->NeedsCheck = FALSE;
709  return STATUS_SUCCESS;
710 }
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:258
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
__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 347 of file fsutil.c.

355 {
356  UNICODE_STRING DriveRootU;
357  UNICODE_STRING LabelU;
358 
359  RtlInitUnicodeString(&DriveRootU, DriveRoot);
360  RtlInitUnicodeString(&LabelU, Label);
361 
362  return FormatFileSystem_UStr(&DriveRootU,
363  FileSystemName,
364  MediaFlag,
365  &LabelU,
366  QuickFormat,
367  ClusterSize,
368  Callback);
369 }
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:282
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 282 of file fsutil.c.

290 {
293  BOOLEAN BackwardCompatible = FALSE; // Default to latest FS versions.
294  MEDIA_TYPE MediaType;
295 
296  FileSystem = GetFileSystemByName(FileSystemName);
297 
298  if (!FileSystem || !FileSystem->FormatFunc)
299  {
300  // Success = FALSE;
301  // Callback(DONE, 0, &Success);
302  return STATUS_NOT_SUPPORTED;
303  }
304 
305  /* Set the BackwardCompatible flag in case we format with older FAT12/16 */
306  if (wcsicmp(FileSystemName, L"FAT") == 0)
307  BackwardCompatible = TRUE;
308  // else if (wcsicmp(FileSystemName, L"FAT32") == 0)
309  // BackwardCompatible = FALSE;
310 
311  /* Convert the FMIFS MediaFlag to a NT MediaType */
312  // FIXME: Actually covert all the possible flags.
313  switch (MediaFlag)
314  {
315  case FMIFS_FLOPPY:
316  MediaType = F5_320_1024; // FIXME: This is hardfixed!
317  break;
318  case FMIFS_REMOVABLE:
319  MediaType = RemovableMedia;
320  break;
321  case FMIFS_HARDDISK:
322  MediaType = FixedMedia;
323  break;
324  default:
325  DPRINT1("Unknown FMIFS MediaFlag %d, converting 1-to-1 to NT MediaType\n",
326  MediaFlag);
327  MediaType = (MEDIA_TYPE)MediaFlag;
328  break;
329  }
330 
331  Success = FileSystem->FormatFunc(DriveRoot,
332  Callback,
333  QuickFormat,
334  BackwardCompatible,
335  MediaType,
336  Label,
337  ClusterSize);
338  if (!Success)
339  DPRINT1("FormatFunc() failed\n");
340 
341  // Callback(DONE, 0, &Success);
342 
344 }
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:168
#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 713 of file fsutil.c.

721 {
723  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
725  // UNICODE_STRING PartitionRootPath;
726  WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
727 
728  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
729 
730  if (!FileSystemName || !*FileSystemName)
731  {
732  DPRINT1("No file system specified?\n");
734  }
735 
736  /*
737  * Prepare the partition for formatting (for MBR disks, reset the
738  * partition type), and adjust the filesystem name in case of FAT
739  * vs. FAT32, depending on the geometry of the partition.
740  */
741 
742 // FIXME: Do this only if QuickFormat == FALSE? What about FAT handling?
743 
744  /*
745  * Retrieve a partition type as a hint only. It will be used to determine
746  * whether to actually use FAT12/16 or FAT32 filesystem, depending on the
747  * geometry of the partition. If the partition resides on an MBR disk,
748  * the partition style will be reset to this value as well, unless the
749  * partition is OEM.
750  */
752  PartEntry->StartSector.QuadPart,
753  PartEntry->SectorCount.QuadPart);
755  {
756  /* Unknown file system */
757  DPRINT1("Unknown file system '%S'\n", FileSystemName);
759  }
760 
761  /* Reset the MBR partition type, unless this is an OEM partition */
762  if (DiskEntry->DiskStyle == PARTITION_STYLE_MBR)
763  {
764  if (!IsOEMPartition(PartEntry->PartitionType))
766  }
767 
768  /*
769  * Adjust the filesystem name in case of FAT vs. FAT32, according to
770  * the type of partition returned by FileSystemToMBRPartitionType().
771  */
772  if (wcsicmp(FileSystemName, L"FAT") == 0)
773  {
774  if ((PartitionType == PARTITION_FAT32) ||
776  {
777  FileSystemName = L"FAT32";
778  }
779  }
780 
781  /* Commit the partition changes to the disk */
782  Status = WritePartitions(DiskEntry);
783  if (!NT_SUCCESS(Status))
784  {
785  DPRINT1("WritePartitions(disk %lu) failed, Status 0x%08lx\n",
786  DiskEntry->DiskNumber, Status);
788  }
789 
790  /* Set PartitionRootPath */
791  RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
792  L"\\Device\\Harddisk%lu\\Partition%lu",
793  DiskEntry->DiskNumber,
794  PartEntry->PartitionNumber);
795  DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
796 
797  /* Format the partition */
798  Status = FormatFileSystem(PartitionRootPath,
799  FileSystemName,
800  MediaFlag,
801  Label,
802  QuickFormat,
803  ClusterSize,
804  Callback);
805  if (!NT_SUCCESS(Status))
806  return Status;
807 
808 //
809 // TODO: Here, call a partlist.c function that update the actual
810 // FS name and the label fields of the volume.
811 //
812  PartEntry->FormatState = Formatted;
813 
814  /* Set the new partition's file system proper */
815  RtlStringCbCopyW(PartEntry->FileSystem,
816  sizeof(PartEntry->FileSystem),
817  FileSystemName);
818 
819  PartEntry->New = FALSE;
820 
821  return STATUS_SUCCESS;
822 }
#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:44
__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:347
_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 153 of file fsutil.c.

156 {
158  return FALSE;
159 
160  *FileSystemName = RegisteredFileSystems[Index].FileSystemName;
161 
162  return TRUE;
163 }
#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 556 of file fsutil.c.

560 {
562  NTSTATUS LockStatus;
566  PARTITION_INFORMATION_EX PartInfo;
567  BOOTCODE NewBootSector = {0};
568 
569  /* Allocate and read the new bootsector from SrcPath */
570  RtlInitUnicodeString(&Name, SrcPath);
571  Status = ReadBootCodeFromFile(&NewBootSector,
572  &Name,
574  if (!NT_SUCCESS(Status))
575  return Status;
576 
577  /*
578  * The BTRFS driver requires the volume to be locked in order to modify
579  * the first sectors of the partition, even though they are outside the
580  * file-system space / in the reserved area (they are situated before
581  * the super-block at 0x1000) and is in principle allowed by the NT
582  * storage stack.
583  * So we lock here in order to write the bootsector at sector 0.
584  * If locking fails, we ignore and continue nonetheless.
585  */
586  LockStatus = NtFsControlFile(DstPath,
587  NULL,
588  NULL,
589  NULL,
590  &IoStatusBlock,
592  NULL,
593  0,
594  NULL,
595  0);
596  if (!NT_SUCCESS(LockStatus))
597  {
598  DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus);
599  }
600 
601  /* Obtain partition info and write it to the bootsector */
603  NULL,
604  NULL,
605  NULL,
606  &IoStatusBlock,
608  NULL,
609  0,
610  &PartInfo,
611  sizeof(PartInfo));
612  if (!NT_SUCCESS(Status))
613  {
614  DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
615  goto Quit;
616  }
617 
618  /* Write new bootsector to RootPath */
619  ((PBTRFS_BOOTSECTOR)NewBootSector.BootCode)->PartitionStartLBA =
621 
622  /* Write sector 0 */
623  FileOffset.QuadPart = 0ULL;
625  NULL,
626  NULL,
627  NULL,
628  &IoStatusBlock,
629  NewBootSector.BootCode,
630  NewBootSector.Length,
631  &FileOffset,
632  NULL);
633  if (!NT_SUCCESS(Status))
634  {
635  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
636  goto Quit;
637  }
638 
639 Quit:
640  /* Unlock the volume */
641  LockStatus = NtFsControlFile(DstPath,
642  NULL,
643  NULL,
644  NULL,
645  &IoStatusBlock,
647  NULL,
648  0,
649  NULL,
650  0);
651  if (!NT_SUCCESS(LockStatus))
652  {
653  DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus);
654  }
655 
656  /* Free the new bootsector */
657  FreeBootCode(&NewBootSector);
658 
659  return Status;
660 }
#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 435 of file fsutil.c.

439 {
445  BOOTCODE OrigBootSector = {0};
446  BOOTCODE NewBootSector = {0};
447 
448  /* Allocate and read the current original partition bootsector */
449  Status = ReadBootCodeByHandle(&OrigBootSector,
452  if (!NT_SUCCESS(Status))
453  return Status;
454 
455  /* Allocate and read the new bootsector (2 sectors) from SrcPath */
456  RtlInitUnicodeString(&Name, SrcPath);
457  Status = ReadBootCodeFromFile(&NewBootSector,
458  &Name,
460  if (!NT_SUCCESS(Status))
461  {
462  FreeBootCode(&OrigBootSector);
463  return Status;
464  }
465 
466  /* Adjust the bootsector (copy a part of the FAT32 BPB) */
467  RtlCopyMemory(&((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->OemName,
468  &((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
469  FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
471 
472  /*
473  * We know we copy the boot code to a file only when DstPath != RootPartition,
474  * otherwise the boot code is copied to the specified root partition.
475  */
476  if (DstPath != RootPartition)
477  {
478  /* Copy to a file: Disable the backup bootsector */
479  ((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->BackupBootSector = 0;
480  }
481  else
482  {
483  /* Copy to a disk: Get the location of the backup bootsector */
484  BackupBootSector = ((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->BackupBootSector;
485  }
486 
487  /* Free the original bootsector */
488  FreeBootCode(&OrigBootSector);
489 
490  /* Write the first sector of the new bootcode to DstPath sector 0 */
491  FileOffset.QuadPart = 0ULL;
493  NULL,
494  NULL,
495  NULL,
496  &IoStatusBlock,
497  NewBootSector.BootCode,
499  &FileOffset,
500  NULL);
501  if (!NT_SUCCESS(Status))
502  {
503  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
504  FreeBootCode(&NewBootSector);
505  return Status;
506  }
507 
508  if (DstPath == RootPartition)
509  {
510  /* Copy to a disk: Write the backup bootsector */
511  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
512  {
515  NULL,
516  NULL,
517  NULL,
518  &IoStatusBlock,
519  NewBootSector.BootCode,
521  &FileOffset,
522  NULL);
523  if (!NT_SUCCESS(Status))
524  {
525  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
526  FreeBootCode(&NewBootSector);
527  return Status;
528  }
529  }
530  }
531 
532  /* Write the second sector of the new bootcode to boot disk sector 14 */
533  // FileOffset.QuadPart = (ULONGLONG)(14 * FAT32_BOOTSECTOR_SIZE);
534  FileOffset.QuadPart = 14 * FAT32_BOOTSECTOR_SIZE;
535  Status = NtWriteFile(DstPath, // or really RootPartition ???
536  NULL,
537  NULL,
538  NULL,
539  &IoStatusBlock,
540  ((PUCHAR)NewBootSector.BootCode + FAT32_BOOTSECTOR_SIZE),
542  &FileOffset,
543  NULL);
544  if (!NT_SUCCESS(Status))
545  {
546  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
547  }
548 
549  /* Free the new bootsector */
550  FreeBootCode(&NewBootSector);
551 
552  return Status;
553 }
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 377 of file fsutil.c.

381 {
386  BOOTCODE OrigBootSector = {0};
387  BOOTCODE NewBootSector = {0};
388 
389  /* Allocate and read the current original partition bootsector */
390  Status = ReadBootCodeByHandle(&OrigBootSector,
393  if (!NT_SUCCESS(Status))
394  return Status;
395 
396  /* Allocate and read the new bootsector from SrcPath */
397  RtlInitUnicodeString(&Name, SrcPath);
398  Status = ReadBootCodeFromFile(&NewBootSector,
399  &Name,
401  if (!NT_SUCCESS(Status))
402  {
403  FreeBootCode(&OrigBootSector);
404  return Status;
405  }
406 
407  /* Adjust the bootsector (copy a part of the FAT12/16 BPB) */
408  RtlCopyMemory(&((PFAT_BOOTSECTOR)NewBootSector.BootCode)->OemName,
409  &((PFAT_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
410  FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
412 
413  /* Free the original bootsector */
414  FreeBootCode(&OrigBootSector);
415 
416  /* Write the new bootsector to DstPath */
417  FileOffset.QuadPart = 0ULL;
419  NULL,
420  NULL,
421  NULL,
422  &IoStatusBlock,
423  NewBootSector.BootCode,
424  NewBootSector.Length,
425  &FileOffset,
426  NULL);
427 
428  /* Free the new bootsector */
429  FreeBootCode(&NewBootSector);
430 
431  return Status;
432 }
#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)