ReactOS  0.4.15-dev-3440-g915569a
fsutil.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Setup Library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Filesystem Format and ChkDsk support functions.
5  * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
6  * Copyright 2017-2020 Hermes Belusca-Maito
7  */
8 
9 //
10 // See also: https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/dll/win32/fmifs/init.c;h=e895f5ef9cae4806123f6bbdd3dfed37ec1c8d33;hb=b9db9a4e377a2055f635b2fb69fef4e1750d219c
11 // for how to get FS providers in a dynamic way. In the (near) future we may
12 // consider merging some of this code with us into a fmifs / fsutil / fslib library...
13 //
14 
15 /* INCLUDES *****************************************************************/
16 
17 #include "precomp.h"
18 
19 #include "partlist.h"
20 #include "fsrec.h"
21 #include "bootcode.h"
22 #include "fsutil.h"
23 
24 #include <fslib/vfatlib.h>
25 #include <fslib/btrfslib.h>
26 // #include <fslib/ext2lib.h>
27 // #include <fslib/ntfslib.h>
28 
29 #define NDEBUG
30 #include <debug.h>
31 
32 
33 /* TYPEDEFS *****************************************************************/
34 
35 #include <pshpack1.h>
36 typedef struct _FAT_BOOTSECTOR
37 {
38  UCHAR JumpBoot[3]; // Jump instruction to boot code
39  CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
40  USHORT BytesPerSector; // Bytes per sector
41  UCHAR SectorsPerCluster; // Number of sectors in a cluster
42  USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
43  UCHAR NumberOfFats; // Number of FAT tables
44  USHORT RootDirEntries; // Number of root directory entries (fat12/16)
45  USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
46  UCHAR MediaDescriptor; // Media descriptor byte
47  USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
48  USHORT SectorsPerTrack; // Number of sectors in a track
49  USHORT NumberOfHeads; // Number of heads on the disk
50  ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
51  ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
52  UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
53  UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
54  UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
55  ULONG VolumeSerialNumber; // Volume serial number
56  CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
57  CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
58 
59  UCHAR BootCodeAndData[448]; // The remainder of the boot sector
60 
62 
65 
66 typedef struct _FAT32_BOOTSECTOR
67 {
68  UCHAR JumpBoot[3]; // Jump instruction to boot code
69  CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
70  USHORT BytesPerSector; // Bytes per sector
71  UCHAR SectorsPerCluster; // Number of sectors in a cluster
72  USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
73  UCHAR NumberOfFats; // Number of FAT tables
74  USHORT RootDirEntries; // Number of root directory entries (fat12/16)
75  USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
76  UCHAR MediaDescriptor; // Media descriptor byte
77  USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
78  USHORT SectorsPerTrack; // Number of sectors in a track
79  USHORT NumberOfHeads; // Number of heads on the disk
80  ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
81  ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
82  ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
83  USHORT ExtendedFlags; // Extended flags (fat32)
84  USHORT FileSystemVersion; // File system version (fat32)
85  ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32)
86  USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
87  USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
88  UCHAR Reserved[12]; // Reserved for future expansion
89  UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
90  UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
91  UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
92  ULONG VolumeSerialNumber; // Volume serial number
93  CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
94  CHAR FileSystemType[8]; // Always set to the string "FAT32 "
95 
96  UCHAR BootCodeAndData[420]; // The remainder of the boot sector
97 
99 
102 
103 typedef struct _BTRFS_BOOTSECTOR
104 {
109  UCHAR Fill[1521]; // 1536 - 15
113 
114 // TODO: Add more bootsector structures!
115 
116 #include <poppack.h>
117 
118 
119 /* LOCALS *******************************************************************/
120 
122 typedef struct _FILE_SYSTEM
123 {
128 
129 /* The list of file systems on which we can install ReactOS */
131 {
132  /* NOTE: The FAT formatter will automatically
133  * determine whether to use FAT12/16 or FAT32. */
134  { L"FAT" , VfatFormat, VfatChkdsk },
135  { L"FAT32", VfatFormat, VfatChkdsk },
136 #if 0
137  { L"FATX" , VfatxFormat, VfatxChkdsk },
138  { L"NTFS" , NtfsFormat, NtfsChkdsk },
139 #endif
140  { L"BTRFS", BtrfsFormat, BtrfsChkdsk },
141 #if 0
142  { L"EXT2" , Ext2Format, Ext2Chkdsk },
143  { L"EXT3" , Ext2Format, Ext2Chkdsk },
144  { L"EXT4" , Ext2Format, Ext2Chkdsk },
145 #endif
146 };
147 
148 
149 /* FUNCTIONS ****************************************************************/
150 
152 BOOLEAN
154  IN ULONG Index,
155  OUT PCWSTR* FileSystemName)
156 {
158  return FALSE;
159 
160  *FileSystemName = RegisteredFileSystems[Index].FileSystemName;
161 
162  return TRUE;
163 }
164 
165 
167 static PFILE_SYSTEM
169  IN PCWSTR FileSystemName)
170 {
171 #if 0 // Reenable when the list of registered FSes will again be dynamic
172 
173  PLIST_ENTRY ListEntry;
175 
176  ListEntry = List->ListHead.Flink;
177  while (ListEntry != &List->ListHead)
178  {
179  Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
180  if (Item->FileSystemName &&
181  (wcsicmp(FileSystemName, Item->FileSystemName) == 0))
182  {
183  return Item;
184  }
185 
186  ListEntry = ListEntry->Flink;
187  }
188 
189 #else
190 
193 
194  ASSERT(FileSystems && Count != 0);
195 
196  while (Count--)
197  {
198  if (FileSystems->FileSystemName &&
199  (wcsicmp(FileSystemName, FileSystems->FileSystemName) == 0))
200  {
201  return FileSystems;
202  }
203 
204  ++FileSystems;
205  }
206 
207 #endif
208 
209  return NULL;
210 }
211 
212 
214 NTSTATUS
216  IN PUNICODE_STRING DriveRoot,
217  IN PCWSTR FileSystemName,
220  IN BOOLEAN CheckOnlyIfDirty,
221  IN BOOLEAN ScanDrive,
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 }
256 
257 NTSTATUS
259  IN PCWSTR DriveRoot,
260  IN PCWSTR FileSystemName,
263  IN BOOLEAN CheckOnlyIfDirty,
264  IN BOOLEAN ScanDrive,
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 }
278 
279 
281 NTSTATUS
283  IN PUNICODE_STRING DriveRoot,
284  IN PCWSTR FileSystemName,
285  IN FMIFS_MEDIA_FLAG MediaFlag,
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 }
345 
346 NTSTATUS
348  IN PCWSTR DriveRoot,
349  IN PCWSTR FileSystemName,
350  IN FMIFS_MEDIA_FLAG MediaFlag,
351  IN PCWSTR Label,
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 }
370 
371 
372 //
373 // Bootsector routines
374 //
375 
376 NTSTATUS
378  IN PCWSTR SrcPath, // FAT12/16 bootsector source file (on the installation medium)
379  IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
380  IN HANDLE RootPartition) // Partition holding the (old) FAT12/16 information
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 }
433 
434 NTSTATUS
436  IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium)
437  IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
438  IN HANDLE RootPartition) // Partition holding the (old) FAT32 information
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 }
554 
555 NTSTATUS
557  IN PCWSTR SrcPath, // BTRFS bootsector source file (on the installation medium)
558  IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
559  IN HANDLE RootPartition) // Partition holding the (old) BTRFS information
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 }
661 
662 
663 //
664 // Formatting routines
665 //
666 
667 NTSTATUS
669  IN PPARTENTRY PartEntry,
672  IN BOOLEAN CheckOnlyIfDirty,
673  IN BOOLEAN ScanDrive,
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 }
711 
712 NTSTATUS
714  IN PPARTENTRY PartEntry,
715  IN PCWSTR FileSystemName,
716  IN FMIFS_MEDIA_FLAG MediaFlag,
717  IN PCWSTR Label,
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 }
823 
824 /* EOF */
USHORT BytesPerSector
Definition: fsutil.c:70
BOOLEAN NTAPI Ext2Chkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: Mke2fs.c:1007
UCHAR SectorsPerCluster
Definition: fsutil.c:41
#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
#define FAT_BOOTSECTOR_SIZE
Definition: fsutil.h:68
struct _FILE_SYSTEM FILE_SYSTEM
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
return STATUS_NOT_SUPPORTED
BOOLEAN NTAPI BtrfsFormat(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
PWCHAR FileSystem
Definition: format.c:72
UCHAR SectorsPerCluster
Definition: fsutil.c:71
USHORT TotalSectors
Definition: fsutil.c:45
UCHAR Reserved1
Definition: fsutil.c:90
ULONGLONG PartitionStartLBA
Definition: fsutil.c:108
BOOL Verbose
Definition: chkdsk.c:72
USHORT BootSectorMagic
Definition: fsutil.c:98
#define TRUE
Definition: types.h:120
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
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
#define BTRFS_BOOTSECTOR_SIZE
Definition: fsutil.h:70
UCHAR JumpBoot[3]
Definition: fsutil.c:105
BOOLEAN NTAPI NtfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: ntfslib.c:33
LONG NTSTATUS
Definition: precomp.h:26
USHORT BootSectorMagic
Definition: fsutil.c:110
UCHAR JumpBoot[3]
Definition: fsutil.c:68
PULIB_FORMAT FormatFunc
Definition: fsutil.c:125
ULONG Length
Definition: bootcode.h:18
ULONG DiskNumber
Definition: partlist.h:111
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
ULONG TotalSectorsBig
Definition: fsutil.c:81
enum _MEDIA_TYPE MEDIA_TYPE
BOOLEAN NTAPI VfatxChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: vfatxlib.c:162
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)
NTSTATUS InstallBtrfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:556
BOOLEAN NTAPI VfatFormat(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: vfatlib.c:50
struct _BTRFS_BOOTSECTOR * PBTRFS_BOOTSECTOR
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61
ULONG VolumeSerialNumber
Definition: fsutil.c:92
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
USHORT BytesPerSector
Definition: fsutil.c:40
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
CHAR VolumeLabel[11]
Definition: fsutil.c:56
#define L(x)
Definition: ntvdm.h:50
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
struct _FAT_BOOTSECTOR FAT_BOOTSECTOR
UCHAR ChunkMapSize
Definition: fsutil.c:106
#define FALSE
Definition: types.h:117
IN HANDLE DstPath
Definition: fsutil.h:75
ULONG SectorsPerFatBig
Definition: fsutil.c:82
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
USHORT RootDirEntries
Definition: fsutil.c:44
C_ASSERT(sizeof(FAT_BOOTSECTOR)==FAT_BOOTSECTOR_SIZE)
CHAR OemName[8]
Definition: fsutil.c:39
struct NameRec_ * Name
Definition: cdprocs.h:459
UCHAR JumpBoot[3]
Definition: fsutil.c:38
BOOLEAN NTAPI Ext2Format(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: Mke2fs.c:803
unsigned char BOOLEAN
BOOLEAN(NTAPI * PULIB_FORMAT)(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: fmifs.h:217
USHORT NumberOfHeads
Definition: fsutil.c:49
UCHAR BootCodeAndData[448]
Definition: fsutil.c:59
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
BOOL QuickFormat
Definition: format.c:66
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ULL(a, b)
Definition: format_msg.c:27
CHAR FileSystemType[8]
Definition: fsutil.c:94
PULIB_CHKDSK ChkdskFunc
Definition: fsutil.c:126
UCHAR BootSignature
Definition: fsutil.c:54
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI BtrfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
USHORT RootDirEntries
Definition: fsutil.c:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
#define ASSERT(a)
Definition: mode.c:44
USHORT ReservedSectors
Definition: fsutil.c:42
USHORT ReservedSectors
Definition: fsutil.c:72
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CHAR OemName[8]
Definition: fsutil.c:69
BOOLEAN NTAPI VfatxFormat(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: vfatxlib.c:20
_In_ WDFCOLLECTION _In_ ULONG Index
uint64_t ULONGLONG
Definition: typedefs.h:67
static FILE_SYSTEM RegisteredFileSystems[]
Definition: fsutil.c:130
#define MAX_PATH
Definition: compat.h:34
DWORD ClusterSize
Definition: format.c:67
UCHAR Reserved1
Definition: fsutil.c:53
USHORT SectorsPerFat
Definition: fsutil.c:47
UCHAR BootSignature
Definition: fsutil.c:91
USHORT BackupBootSector
Definition: fsutil.c:87
PVOID BootCode
Definition: bootcode.h:17
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
USHORT BootSectorMagic
Definition: fsutil.c:61
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:75
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
UCHAR NumberOfFats
Definition: fsutil.c:43
CHAR VolumeLabel[11]
Definition: fsutil.c:93
#define wcsicmp
Definition: compat.h:15
UCHAR DriveNumber
Definition: fsutil.c:89
LARGE_INTEGER StartingOffset
Definition: imports.h:221
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN GetRegisteredFileSystems(IN ULONG Index, OUT PCWSTR *FileSystemName)
Definition: fsutil.c:153
UCHAR Fill[1521]
Definition: fsutil.c:109
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
USHORT TotalSectors
Definition: fsutil.c:75
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
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 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: fsutil.c:713
USHORT SectorsPerTrack
Definition: fsutil.c:78
ULONG VolumeSerialNumber
Definition: fsutil.c:55
Definition: typedefs.h:119
UCHAR MediaDescriptor
Definition: fsutil.c:76
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
USHORT SectorsPerTrack
Definition: fsutil.c:48
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
NTSTATUS ChkdskPartition(IN PPARTENTRY PartEntry, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PFMIFSCALLBACK Callback)
Definition: fsutil.c:668
struct _FAT32_BOOTSECTOR FAT32_BOOTSECTOR
static PFILE_SYSTEM GetFileSystemByName(IN PCWSTR FileSystemName)
Definition: fsutil.c:168
USHORT FileSystemVersion
Definition: fsutil.c:84
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
USHORT FsInfo
Definition: fsutil.c:86
BOOLEAN(NTAPI * PFMIFSCALLBACK)(IN CALLBACKCOMMAND Command, IN ULONG SubAction, IN PVOID ActionInfo)
Definition: fmifs.h:89
FILESYSTEM_CHKDSK FileSystems[]
Definition: autochk.c:47
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI VfatChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: vfatlib.c:374
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
UCHAR MediaDescriptor
Definition: fsutil.c:46
CHAR FileSystemType[8]
Definition: fsutil.c:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
USHORT SectorsPerFat
Definition: fsutil.c:77
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
UCHAR NumberOfFats
Definition: fsutil.c:73
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
BOOLEAN(NTAPI * PULIB_CHKDSK)(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: fmifs.h:201
NTSTATUS InstallFat32BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:435
struct _FILE_SYSTEM * PFILE_SYSTEM
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
BOOL FixErrors
Definition: chkdsk.c:69
USHORT NumberOfHeads
Definition: fsutil.c:79
#define DPRINT1
Definition: precomp.h:8
ULONG TotalSectorsBig
Definition: fsutil.c:51
ULONG HiddenSectors
Definition: fsutil.c:50
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3619
#define OUT
Definition: typedefs.h:40
ULONG HiddenSectors
Definition: fsutil.c:80
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
CHAR PartitionType
Definition: part_xbox.c:32
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
unsigned int ULONG
Definition: retypes.h:1
UCHAR BootCodeAndData[420]
Definition: fsutil.c:96
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PWCHAR Label
Definition: format.c:70
UCHAR BootDrive
Definition: fsutil.c:107
struct _BTRFS_BOOTSECTOR BTRFS_BOOTSECTOR
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
#define STATUS_SUCCESS
Definition: shellext.h:65
#define FAT32_BOOTSECTOR_SIZE
Definition: fsutil.h:69
PCWSTR FileSystemName
Definition: fsutil.c:124
#define DPRINT
Definition: sndvol32.h:71
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1303
#define SECTORSIZE
Definition: bootcode.h:13
#define IsOEMPartition(PartitionType)
Definition: partlist.h:22
BOOLEAN NTAPI NtfsFormat(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN QuickFormat, IN BOOLEAN BackwardCompatible, IN MEDIA_TYPE MediaType, IN PUNICODE_STRING Label, IN ULONG ClusterSize)
Definition: ntfslib.c:18
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
VOID SetMBRPartitionType(IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
Definition: partlist.c:3937
UCHAR DriveNumber
Definition: fsutil.c:52
LONGLONG QuadPart
Definition: typedefs.h:114
#define STATUS_PARTITION_FAILURE
Definition: ntstatus.h:604
ULONG RootDirStartCluster
Definition: fsutil.c:85
FMIFS_MEDIA_FLAG
Definition: fmifs.h:37
NTSTATUS InstallFatBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:377
USHORT ExtendedFlags
Definition: fsutil.c:83