ReactOS 0.4.15-dev-8434-g155a7c7
fsutil.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Setup Library
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Filesystem Format and ChkDsk support functions
5 * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup <chorns@users.sourceforge.net>
6 * Copyright 2017-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
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>
36typedef 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
66typedef 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
103typedef struct _BTRFS_BOOTSECTOR
104{
109 UCHAR Fill[1521]; // 1536 - 15
113
114typedef struct _NTFS_BOOTSECTOR
115{
139 UCHAR BootCodeAndData[7680]; // The remainder of the boot sector (8192 - 512)
142
143// TODO: Add more bootsector structures!
144
145#include <poppack.h>
146
147
148/* LOCALS *******************************************************************/
149
151typedef struct _FILE_SYSTEM
152{
157
158/* The list of file systems on which we can install ReactOS */
160{
161 /* NOTE: The FAT formatter will automatically
162 * determine whether to use FAT12/16 or FAT32. */
163 { L"FAT" , VfatFormat, VfatChkdsk },
164 { L"FAT32", VfatFormat, VfatChkdsk },
165#if 0
166 { L"FATX" , VfatxFormat, VfatxChkdsk },
167 { L"NTFS" , NtfsFormat, NtfsChkdsk },
168#endif
169 { L"BTRFS", BtrfsFormat, BtrfsChkdsk },
170#if 0
171 { L"EXT2" , Ext2Format, Ext2Chkdsk },
172 { L"EXT3" , Ext2Format, Ext2Chkdsk },
173 { L"EXT4" , Ext2Format, Ext2Chkdsk },
174#endif
175};
176
177
178/* FUNCTIONS ****************************************************************/
179
183 IN ULONG Index,
184 OUT PCWSTR* FileSystemName)
185{
187 return FALSE;
188
189 *FileSystemName = RegisteredFileSystems[Index].FileSystemName;
190
191 return TRUE;
192}
193
194
196static PFILE_SYSTEM
198 IN PCWSTR FileSystemName)
199{
200#if 0 // Reenable when the list of registered FSes will again be dynamic
201
202 PLIST_ENTRY ListEntry;
204
205 ListEntry = List->ListHead.Flink;
206 while (ListEntry != &List->ListHead)
207 {
208 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
209 if (Item->FileSystemName &&
210 (_wcsicmp(FileSystemName, Item->FileSystemName) == 0))
211 {
212 return Item;
213 }
214
215 ListEntry = ListEntry->Flink;
216 }
217
218#else
219
222
223 ASSERT(FileSystems && Count != 0);
224
225 while (Count--)
226 {
227 if (FileSystems->FileSystemName &&
228 (_wcsicmp(FileSystemName, FileSystems->FileSystemName) == 0))
229 {
230 return FileSystems;
231 }
232
233 ++FileSystems;
234 }
235
236#endif
237
238 return NULL;
239}
240
241
245 _In_ PUNICODE_STRING DriveRoot,
246 _In_ PCWSTR FileSystemName,
249 _In_ BOOLEAN CheckOnlyIfDirty,
250 _In_ BOOLEAN ScanDrive,
252{
256
257 FileSystem = GetFileSystemByName(FileSystemName);
258
259 if (!FileSystem || !FileSystem->ChkdskFunc)
260 {
261 // Success = FALSE;
262 // Callback(DONE, 0, &Success);
264 }
265
267 Success = FileSystem->ChkdskFunc(DriveRoot,
268 Callback,
269 FixErrors,
270 Verbose,
271 CheckOnlyIfDirty,
272 ScanDrive,
273 NULL,
274 NULL,
275 NULL,
276 NULL,
277 (PULONG)&Status);
278 if (!Success)
279 DPRINT1("ChkdskFunc() failed with Status 0x%lx\n", Status);
280
281 // Callback(DONE, 0, &Success);
282
283 return Status;
284}
285
288 _In_ PCWSTR DriveRoot,
289 _In_ PCWSTR FileSystemName,
292 _In_ BOOLEAN CheckOnlyIfDirty,
293 _In_ BOOLEAN ScanDrive,
295{
296 UNICODE_STRING DriveRootU;
297
298 RtlInitUnicodeString(&DriveRootU, DriveRoot);
299 return ChkdskFileSystem_UStr(&DriveRootU,
300 FileSystemName,
301 FixErrors,
302 Verbose,
303 CheckOnlyIfDirty,
304 ScanDrive,
305 Callback);
306}
307
308
312 _In_ PUNICODE_STRING DriveRoot,
313 _In_ PCWSTR FileSystemName,
314 _In_ FMIFS_MEDIA_FLAG MediaFlag,
319{
322 BOOLEAN BackwardCompatible = FALSE; // Default to latest FS versions.
323 MEDIA_TYPE MediaType;
324
325 FileSystem = GetFileSystemByName(FileSystemName);
326
327 if (!FileSystem || !FileSystem->FormatFunc)
328 {
329 // Success = FALSE;
330 // Callback(DONE, 0, &Success);
332 }
333
334 /* Set the BackwardCompatible flag in case we format with older FAT12/16 */
335 if (_wcsicmp(FileSystemName, L"FAT") == 0)
336 BackwardCompatible = TRUE;
337 // else if (_wcsicmp(FileSystemName, L"FAT32") == 0)
338 // BackwardCompatible = FALSE;
339
340 /* Convert the FMIFS MediaFlag to a NT MediaType */
341 // FIXME: Actually covert all the possible flags.
342 switch (MediaFlag)
343 {
344 case FMIFS_FLOPPY:
345 MediaType = F5_320_1024; // FIXME: This is hardfixed!
346 break;
347 case FMIFS_REMOVABLE:
348 MediaType = RemovableMedia;
349 break;
350 case FMIFS_HARDDISK:
351 MediaType = FixedMedia;
352 break;
353 default:
354 DPRINT1("Unknown FMIFS MediaFlag %d, converting 1-to-1 to NT MediaType\n",
355 MediaFlag);
356 MediaType = (MEDIA_TYPE)MediaFlag;
357 break;
358 }
359
360 Success = FileSystem->FormatFunc(DriveRoot,
361 Callback,
363 BackwardCompatible,
364 MediaType,
365 Label,
367 if (!Success)
368 DPRINT1("FormatFunc() failed\n");
369
370 // Callback(DONE, 0, &Success);
371
373}
374
377 _In_ PCWSTR DriveRoot,
378 _In_ PCWSTR FileSystemName,
379 _In_ FMIFS_MEDIA_FLAG MediaFlag,
384{
385 UNICODE_STRING DriveRootU;
386 UNICODE_STRING LabelU;
387
388 RtlInitUnicodeString(&DriveRootU, DriveRoot);
389 RtlInitUnicodeString(&LabelU, Label);
390
391 return FormatFileSystem_UStr(&DriveRootU,
392 FileSystemName,
393 MediaFlag,
394 &LabelU,
397 Callback);
398}
399
400
401//
402// Bootsector routines
403//
404
407 IN PCWSTR SrcPath, // FAT12/16 bootsector source file (on the installation medium)
408 IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
409 IN HANDLE RootPartition) // Partition holding the (old) FAT12/16 information
410{
415 BOOTCODE OrigBootSector = {0};
416 BOOTCODE NewBootSector = {0};
417
418 /* Allocate and read the current original partition bootsector */
419 Status = ReadBootCodeByHandle(&OrigBootSector,
422 if (!NT_SUCCESS(Status))
423 return Status;
424
425 /* Allocate and read the new bootsector from SrcPath */
426 RtlInitUnicodeString(&Name, SrcPath);
427 Status = ReadBootCodeFromFile(&NewBootSector,
428 &Name,
430 if (!NT_SUCCESS(Status))
431 {
432 FreeBootCode(&OrigBootSector);
433 return Status;
434 }
435
436 /* Adjust the bootsector (copy a part of the FAT12/16 BPB) */
437 RtlCopyMemory(&((PFAT_BOOTSECTOR)NewBootSector.BootCode)->OemName,
438 &((PFAT_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
439 FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
441
442 /* Free the original bootsector */
443 FreeBootCode(&OrigBootSector);
444
445 /* Write the new bootsector to DstPath */
446 FileOffset.QuadPart = 0ULL;
448 NULL,
449 NULL,
450 NULL,
452 NewBootSector.BootCode,
453 NewBootSector.Length,
454 &FileOffset,
455 NULL);
456
457 /* Free the new bootsector */
458 FreeBootCode(&NewBootSector);
459
460 return Status;
461}
462
465 IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium)
466 IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
467 IN HANDLE RootPartition) // Partition holding the (old) FAT32 information
468{
474 BOOTCODE OrigBootSector = {0};
475 BOOTCODE NewBootSector = {0};
476
477 /* Allocate and read the current original partition bootsector */
478 Status = ReadBootCodeByHandle(&OrigBootSector,
481 if (!NT_SUCCESS(Status))
482 return Status;
483
484 /* Allocate and read the new bootsector (2 sectors) from SrcPath */
485 RtlInitUnicodeString(&Name, SrcPath);
486 Status = ReadBootCodeFromFile(&NewBootSector,
487 &Name,
489 if (!NT_SUCCESS(Status))
490 {
491 FreeBootCode(&OrigBootSector);
492 return Status;
493 }
494
495 /* Adjust the bootsector (copy a part of the FAT32 BPB) */
496 RtlCopyMemory(&((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->OemName,
497 &((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
498 FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
500
501 /*
502 * We know we copy the boot code to a file only when DstPath != RootPartition,
503 * otherwise the boot code is copied to the specified root partition.
504 */
505 if (DstPath != RootPartition)
506 {
507 /* Copy to a file: Disable the backup bootsector */
508 ((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->BackupBootSector = 0;
509 }
510 else
511 {
512 /* Copy to a disk: Get the location of the backup bootsector */
513 BackupBootSector = ((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->BackupBootSector;
514 }
515
516 /* Free the original bootsector */
517 FreeBootCode(&OrigBootSector);
518
519 /* Write the first sector of the new bootcode to DstPath sector 0 */
520 FileOffset.QuadPart = 0ULL;
522 NULL,
523 NULL,
524 NULL,
526 NewBootSector.BootCode,
528 &FileOffset,
529 NULL);
530 if (!NT_SUCCESS(Status))
531 {
532 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
533 FreeBootCode(&NewBootSector);
534 return Status;
535 }
536
537 if (DstPath == RootPartition)
538 {
539 /* Copy to a disk: Write the backup bootsector */
540 if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
541 {
544 NULL,
545 NULL,
546 NULL,
548 NewBootSector.BootCode,
550 &FileOffset,
551 NULL);
552 if (!NT_SUCCESS(Status))
553 {
554 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
555 FreeBootCode(&NewBootSector);
556 return Status;
557 }
558 }
559 }
560
561 /* Write the second sector of the new bootcode to boot disk sector 14 */
562 // FileOffset.QuadPart = (ULONGLONG)(14 * FAT32_BOOTSECTOR_SIZE);
563 FileOffset.QuadPart = 14 * FAT32_BOOTSECTOR_SIZE;
564 Status = NtWriteFile(DstPath, // or really RootPartition ???
565 NULL,
566 NULL,
567 NULL,
569 ((PUCHAR)NewBootSector.BootCode + FAT32_BOOTSECTOR_SIZE),
571 &FileOffset,
572 NULL);
573 if (!NT_SUCCESS(Status))
574 {
575 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
576 }
577
578 /* Free the new bootsector */
579 FreeBootCode(&NewBootSector);
580
581 return Status;
582}
583
586 IN PCWSTR SrcPath, // BTRFS bootsector source file (on the installation medium)
587 IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
588 IN HANDLE RootPartition) // Partition holding the (old) BTRFS information
589{
591 NTSTATUS LockStatus;
596 BOOTCODE NewBootSector = {0};
597
598 /* Allocate and read the new bootsector from SrcPath */
599 RtlInitUnicodeString(&Name, SrcPath);
600 Status = ReadBootCodeFromFile(&NewBootSector,
601 &Name,
603 if (!NT_SUCCESS(Status))
604 return Status;
605
606 /*
607 * The BTRFS driver requires the volume to be locked in order to modify
608 * the first sectors of the partition, even though they are outside the
609 * file-system space / in the reserved area (they are situated before
610 * the super-block at 0x1000) and is in principle allowed by the NT
611 * storage stack.
612 * So we lock here in order to write the bootsector at sector 0.
613 * If locking fails, we ignore and continue nonetheless.
614 */
615 LockStatus = NtFsControlFile(DstPath,
616 NULL,
617 NULL,
618 NULL,
621 NULL,
622 0,
623 NULL,
624 0);
625 if (!NT_SUCCESS(LockStatus))
626 {
627 DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus);
628 }
629
630 /* Obtain partition info and write it to the bootsector */
632 NULL,
633 NULL,
634 NULL,
637 NULL,
638 0,
639 &PartInfo,
640 sizeof(PartInfo));
641 if (!NT_SUCCESS(Status))
642 {
643 DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
644 goto Quit;
645 }
646
647 /* Write new bootsector to RootPath */
648 ((PBTRFS_BOOTSECTOR)NewBootSector.BootCode)->PartitionStartLBA =
650
651 /* Write sector 0 */
652 FileOffset.QuadPart = 0ULL;
654 NULL,
655 NULL,
656 NULL,
658 NewBootSector.BootCode,
659 NewBootSector.Length,
660 &FileOffset,
661 NULL);
662 if (!NT_SUCCESS(Status))
663 {
664 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
665 goto Quit;
666 }
667
668Quit:
669 /* Unlock the volume */
670 LockStatus = NtFsControlFile(DstPath,
671 NULL,
672 NULL,
673 NULL,
676 NULL,
677 0,
678 NULL,
679 0);
680 if (!NT_SUCCESS(LockStatus))
681 {
682 DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus);
683 }
684
685 /* Free the new bootsector */
686 FreeBootCode(&NewBootSector);
687
688 return Status;
689}
690
693 IN PCWSTR SrcPath, // NTFS bootsector source file (on the installation medium)
694 IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
695 IN HANDLE RootPartition) // Partition holding the (old) NTFS information
696{
701 BOOTCODE OrigBootSector = {0};
702 BOOTCODE NewBootSector = {0};
703
704 /* Allocate and read the current original partition bootsector */
706 if (!NT_SUCCESS(Status))
707 {
708 DPRINT1("InstallNtfsBootCode: Status %lx\n", Status);
709 return Status;
710 }
711
712 /* Allocate and read the new bootsector (16 sectors) from SrcPath */
713 RtlInitUnicodeString(&Name, SrcPath);
715 if (!NT_SUCCESS(Status))
716 {
717 DPRINT1("InstallNtfsBootCode: Status %lx\n", Status);
718 FreeBootCode(&OrigBootSector);
719 return Status;
720 }
721
722 /* Adjust the bootsector (copy a part of the NTFS BPB) */
723 RtlCopyMemory(&((PNTFS_BOOTSECTOR)NewBootSector.BootCode)->OEMID,
724 &((PNTFS_BOOTSECTOR)OrigBootSector.BootCode)->OEMID,
726
727 /* Write sector 0 */
728 FileOffset.QuadPart = 0ULL;
730 NULL,
731 NULL,
732 NULL,
734 NewBootSector.BootCode,
735 NewBootSector.Length,
736 &FileOffset,
737 NULL);
738 if (!NT_SUCCESS(Status))
739 {
740 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
741 goto Quit;
742 }
743
744Quit:
745 /* Free the new bootsector */
746 FreeBootCode(&NewBootSector);
747
748 return Status;
749}
750
751
752//
753// Formatting routines
754//
755
758 _In_ PPARTENTRY PartEntry,
761 _In_ BOOLEAN CheckOnlyIfDirty,
762 _In_ BOOLEAN ScanDrive,
764{
765 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
766 // UNICODE_STRING PartitionRootPath;
767 WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
768
769 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
770
771 /* Do not check a partition with an unknown file system */
772 if (!*PartEntry->FileSystem)
773 return STATUS_UNRECOGNIZED_VOLUME; // STATUS_NOT_SUPPORTED;
774
775 /* Set PartitionRootPath */
776 RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
777 L"\\Device\\Harddisk%lu\\Partition%lu",
778 DiskEntry->DiskNumber,
779 PartEntry->PartitionNumber);
780 DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
781
782 /* Check the partition */
783 return ChkdskFileSystem(PartitionRootPath,
784 PartEntry->FileSystem,
785 FixErrors,
786 Verbose,
787 CheckOnlyIfDirty,
788 ScanDrive,
789 Callback);
790}
791
794 _In_ PPARTENTRY PartEntry,
795 _In_ PCWSTR FileSystemName,
796 _In_ FMIFS_MEDIA_FLAG MediaFlag,
801{
803 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
805 // UNICODE_STRING PartitionRootPath;
806 WCHAR PartitionRootPath[MAX_PATH]; // PathBuffer
807
808 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
809
810 if (!FileSystemName || !*FileSystemName)
811 {
812 DPRINT1("No file system specified?\n");
814 }
815
816 /*
817 * Prepare the partition for formatting (for MBR disks, reset the
818 * partition type), and adjust the file system name in case of FAT
819 * vs. FAT32, depending on the geometry of the partition.
820 */
821
822// FIXME: Do this only if QuickFormat == FALSE? What about FAT handling?
823
824 /*
825 * Retrieve a partition type as a hint only. It will be used to determine
826 * whether to actually use FAT12/16 or FAT32 file system, depending on the
827 * geometry of the partition. If the partition resides on an MBR disk,
828 * the partition style will be reset to this value as well, unless the
829 * partition is OEM.
830 */
832 PartEntry->StartSector.QuadPart,
833 PartEntry->SectorCount.QuadPart);
835 {
836 /* Unknown file system */
837 DPRINT1("Unknown file system '%S'\n", FileSystemName);
839 }
840
841 /* Reset the MBR partition type, unless this is an OEM partition */
842 if (DiskEntry->DiskStyle == PARTITION_STYLE_MBR)
843 {
844 if (!IsOEMPartition(PartEntry->PartitionType))
846 }
847
848 /*
849 * Adjust the file system name in case of FAT vs. FAT32, according to
850 * the type of partition returned by FileSystemToMBRPartitionType().
851 */
852 if (_wcsicmp(FileSystemName, L"FAT") == 0)
853 {
856 {
857 FileSystemName = L"FAT32";
858 }
859 }
860
861 /* Commit the partition changes to the disk */
862 Status = WritePartitions(DiskEntry);
863 if (!NT_SUCCESS(Status))
864 {
865 DPRINT1("WritePartitions(disk %lu) failed, Status 0x%08lx\n",
866 DiskEntry->DiskNumber, Status);
868 }
869
870 /* Set PartitionRootPath */
871 RtlStringCchPrintfW(PartitionRootPath, ARRAYSIZE(PartitionRootPath),
872 L"\\Device\\Harddisk%lu\\Partition%lu",
873 DiskEntry->DiskNumber,
874 PartEntry->PartitionNumber);
875 DPRINT("PartitionRootPath: %S\n", PartitionRootPath);
876
877 /* Format the partition */
878 Status = FormatFileSystem(PartitionRootPath,
879 FileSystemName,
880 MediaFlag,
881 Label,
884 Callback);
885 if (!NT_SUCCESS(Status))
886 return Status;
887
888//
889// TODO: Here, call a partlist.c function that update the actual
890// FS name and the label fields of the volume.
891//
892 PartEntry->FormatState = Formatted;
893
894 /* Set the new partition's file system proper */
895 RtlStringCbCopyW(PartEntry->FileSystem,
896 sizeof(PartEntry->FileSystem),
897 FileSystemName);
898
899 PartEntry->New = FALSE;
900
901 return STATUS_SUCCESS;
902}
903
904
905//
906// FileSystem Volume Operations Queue
907//
908
909static FSVOL_OP
911 _In_ PPARTENTRY PartEntry,
914{
917 FORMAT_VOLUME_INFO FmtInfo = {0};
918
919 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
920
921 FmtInfo.PartEntry = PartEntry;
922
923RetryFormat:
926 (ULONG_PTR)&FmtInfo,
928 if (Result != FSVOL_DOIT)
929 goto EndFormat;
930
931 ASSERT(FmtInfo.FileSystemName && *FmtInfo.FileSystemName);
932
933 /* Format the partition */
934 Status = FormatPartition(PartEntry,
935 FmtInfo.FileSystemName,
936 FmtInfo.MediaFlag,
937 FmtInfo.Label,
938 FmtInfo.QuickFormat,
939 FmtInfo.ClusterSize,
940 FmtInfo.Callback);
941 if (!NT_SUCCESS(Status))
942 {
943 // FmtInfo.NtPathPartition = PathBuffer;
944 FmtInfo.ErrorStatus = Status;
945
948 (ULONG_PTR)&FmtInfo,
949 0);
950 if (Result == FSVOL_RETRY)
951 goto RetryFormat;
952 // else if (Result == FSVOL_ABORT || Result == FSVOL_SKIP), stop.
953 }
954
956 /* This notification is always sent, even in case of error or abort */
957 FmtInfo.ErrorStatus = Status;
960 (ULONG_PTR)&FmtInfo,
961 0);
962 return Result;
963}
964
965static FSVOL_OP
967 _In_ PPARTENTRY PartEntry,
970{
973 CHECK_VOLUME_INFO ChkInfo = {0};
974
975 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
976
977 ASSERT(*PartEntry->FileSystem);
978
979 ChkInfo.PartEntry = PartEntry;
980
981RetryCheck:
984 (ULONG_PTR)&ChkInfo,
986 if (Result != FSVOL_DOIT)
987 goto EndCheck;
988
989 /* Check the partition */
990 Status = ChkdskPartition(PartEntry,
991 ChkInfo.FixErrors,
992 ChkInfo.Verbose,
993 ChkInfo.CheckOnlyIfDirty,
994 ChkInfo.ScanDrive,
995 ChkInfo.Callback);
996
997 /* If volume checking succeeded, or if it is not supported
998 * with the current file system, disable checks on the volume */
1000 PartEntry->NeedsCheck = FALSE;
1001
1002 if (!NT_SUCCESS(Status))
1003 {
1004 // ChkInfo.NtPathPartition = PathBuffer;
1005 ChkInfo.ErrorStatus = Status;
1006
1009 (ULONG_PTR)&ChkInfo,
1010 0);
1011 if (Result == FSVOL_RETRY)
1012 goto RetryCheck;
1013 // else if (Result == FSVOL_ABORT || Result == FSVOL_SKIP), stop.
1014
1015 // PartEntry->NeedsCheck = FALSE;
1016 }
1017
1018EndCheck:
1019 /* This notification is always sent, even in case of error or abort */
1020 ChkInfo.ErrorStatus = Status;
1023 (ULONG_PTR)&ChkInfo,
1024 0);
1025 return Result;
1026}
1027
1028static BOOLEAN
1031 OUT PPARTENTRY *pPartEntry)
1032{
1033 PLIST_ENTRY Entry1, Entry2;
1034 PDISKENTRY DiskEntry;
1035 PPARTENTRY PartEntry;
1036
1037 for (Entry1 = List->DiskListHead.Flink;
1038 Entry1 != &List->DiskListHead;
1039 Entry1 = Entry1->Flink)
1040 {
1041 DiskEntry = CONTAINING_RECORD(Entry1,
1042 DISKENTRY,
1043 ListEntry);
1044
1045 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1046 {
1047 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1048 continue;
1049 }
1050
1051 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
1052 Entry2 != &DiskEntry->PrimaryPartListHead;
1053 Entry2 = Entry2->Flink)
1054 {
1055 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1056 if (PartEntry->IsPartitioned && PartEntry->New)
1057 {
1058 ASSERT(DiskEntry == PartEntry->DiskEntry);
1059 *pPartEntry = PartEntry;
1060 return TRUE;
1061 }
1062 }
1063
1064 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
1065 Entry2 != &DiskEntry->LogicalPartListHead;
1066 Entry2 = Entry2->Flink)
1067 {
1068 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1069 if (PartEntry->IsPartitioned && PartEntry->New)
1070 {
1071 ASSERT(DiskEntry == PartEntry->DiskEntry);
1072 *pPartEntry = PartEntry;
1073 return TRUE;
1074 }
1075 }
1076 }
1077
1078 *pPartEntry = NULL;
1079 return FALSE;
1080}
1081
1082static BOOLEAN
1085 OUT PPARTENTRY *pPartEntry)
1086{
1087 PLIST_ENTRY Entry1, Entry2;
1088 PDISKENTRY DiskEntry;
1089 PPARTENTRY PartEntry;
1090
1091 for (Entry1 = List->DiskListHead.Flink;
1092 Entry1 != &List->DiskListHead;
1093 Entry1 = Entry1->Flink)
1094 {
1095 DiskEntry = CONTAINING_RECORD(Entry1,
1096 DISKENTRY,
1097 ListEntry);
1098
1099 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1100 {
1101 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1102 continue;
1103 }
1104
1105 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
1106 Entry2 != &DiskEntry->PrimaryPartListHead;
1107 Entry2 = Entry2->Flink)
1108 {
1109 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1110 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
1111 {
1112 ASSERT(DiskEntry == PartEntry->DiskEntry);
1113 *pPartEntry = PartEntry;
1114 return TRUE;
1115 }
1116 }
1117
1118 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
1119 Entry2 != &DiskEntry->LogicalPartListHead;
1120 Entry2 = Entry2->Flink)
1121 {
1122 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
1123 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
1124 {
1125 ASSERT(DiskEntry == PartEntry->DiskEntry);
1126 *pPartEntry = PartEntry;
1127 return TRUE;
1128 }
1129 }
1130 }
1131
1132 *pPartEntry = NULL;
1133 return FALSE;
1134}
1135
1136BOOLEAN
1143{
1144 BOOLEAN Success = TRUE; // Suppose success originally.
1146 PPARTENTRY PartEntry;
1147
1148 /* Machine state for the format step */
1149 typedef enum _FORMATMACHINESTATE
1150 {
1151 Start,
1152 FormatSystemVolume,
1153 FormatInstallVolume,
1154 FormatOtherVolume,
1155 FormatDone
1156 } FORMATMACHINESTATE;
1157 FORMATMACHINESTATE FormatState, OldFormatState;
1158 static const PCSTR FormatStateNames[] = {
1159 "Start",
1160 "FormatSystemVolume",
1161 "FormatInstallVolume",
1162 "FormatOtherVolume",
1163 "FormatDone"
1164 };
1165
1167
1168 /* Commit all partition changes to all the disks */
1170 {
1171 DPRINT("WritePartitionsToDisk() failed\n");
1172 /* Result = */ FsVolCallback(Context,
1174 STATUS_PARTITION_FAILURE, // FIXME
1175 0);
1176 return FALSE;
1177 }
1178
1179//
1180// FIXME: Should we do the following here, or in the caller?
1181//
1182 /*
1183 * In all cases, whether or not we are going to perform a formatting,
1184 * we must perform a file system check of both the system and the
1185 * installation volumes.
1186 */
1189
1192 0, 0);
1193 if (Result == FSVOL_ABORT)
1194 return FALSE;
1195
1196 /*
1197 * Commit the Format queue
1198 */
1199
1203 0);
1204 if (Result == FSVOL_ABORT)
1205 return FALSE;
1207 if (Result == FSVOL_SKIP)
1208 goto StartCheckQueue;
1211 /* Reset the formatter machine state */
1212 FormatState = Start;
1213NextFormat:
1214 PartEntry = NULL;
1215 OldFormatState = FormatState;
1216 switch (FormatState)
1217 {
1218 case Start:
1219 {
1220 /*
1221 * We start by formatting the system volume in case it is new
1222 * (it didn't exist before) and is not the same as the installation
1223 * volume. Otherwise we just require a file system check on it,
1224 * and start by formatting the installation volume instead.
1225 */
1228 {
1229 PartEntry = SystemPartition;
1230
1231 if (PartEntry->FormatState == Unformatted)
1232 {
1233 // TODO: Should we let the user use a custom file system,
1234 // or should we always use FAT(32) for it?
1235 // For "compatibility", FAT(32) would be best indeed.
1236
1237 FormatState = FormatSystemVolume;
1238 DPRINT1("FormatState: %s --> %s\n",
1239 FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
1240 break;
1241 }
1242
1243 /* The system volume is separate, so it had better be formatted! */
1244 ASSERT((PartEntry->FormatState == Preformatted) ||
1245 (PartEntry->FormatState == Formatted));
1246
1247 /* Require a file system check on the system volume too */
1248 PartEntry->NeedsCheck = TRUE;
1249 }
1251 }
1252
1253 case FormatSystemVolume:
1254 {
1255 PartEntry = InstallPartition;
1256
1257 FormatState = FormatInstallVolume;
1258 DPRINT1("FormatState: %s --> %s\n",
1259 FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
1260 break;
1261 }
1262
1263 case FormatInstallVolume:
1264 case FormatOtherVolume:
1265 {
1267 if (Found) ASSERT(PartEntry);
1268
1269 FormatState = (PartEntry ? FormatOtherVolume : FormatDone);
1270 DPRINT1("FormatState: %s --> %s\n",
1271 FormatStateNames[OldFormatState], FormatStateNames[FormatState]);
1272 if (Found)
1273 break;
1275 }
1276
1277 case FormatDone:
1278 {
1279 DPRINT1("FormatState: FormatDone\n");
1280 Success = TRUE;
1281 goto EndFormat;
1282 }
1284 }
1285
1286 ASSERT(PartEntry);
1288 if (Result == FSVOL_ABORT)
1289 {
1290 Success = FALSE;
1291 goto Quit;
1292 }
1293 /* Schedule a check for this volume */
1294 PartEntry->NeedsCheck = TRUE;
1295 /* Go to the next volume to be formatted */
1296 goto NextFormat;
1297
1298EndFormat:
1302 0);
1303
1304
1305 /*
1306 * Commit the CheckFS queue
1307 */
1308
1309StartCheckQueue:
1313 0);
1314 if (Result == FSVOL_ABORT)
1315 return FALSE;
1316
1317NextCheck:
1318 if (!GetNextUncheckedPartition(PartitionList, &PartEntry))
1319 {
1320 Success = TRUE;
1321 goto EndCheck;
1322 }
1323
1324 ASSERT(PartEntry);
1325 Result = DoChecking(PartEntry, Context, FsVolCallback);
1326 if (Result == FSVOL_ABORT)
1327 {
1328 Success = FALSE;
1329 goto Quit;
1330 }
1331 /* Go to the next volume to be checked */
1332 goto NextCheck;
1333
1334EndCheck:
1338 0);
1339
1340
1341Quit:
1342 /* All the queues have been committed */
1345 Success,
1346 0);
1347 return Success;
1348}
1349
1350/* EOF */
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
FILESYSTEM_CHKDSK FileSystems[]
Definition: autochk.c:47
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL FixErrors
Definition: chkdsk.c:69
BOOL Verbose
Definition: chkdsk.c:72
BOOL QuickFormat
Definition: format.c:66
PWCHAR Label
Definition: format.c:70
DWORD ClusterSize
Definition: format.c:67
PWCHAR FileSystem
Definition: format.c:72
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define PARTITION_FAT32
Definition: disk.h:95
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
#define SECTORSIZE
Definition: bootcode.h:13
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)
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)
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
@ Success
Definition: eventcreate.c:712
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
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
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1304
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
FMIFS_MEDIA_FLAG
Definition: fmifs.h:38
@ FMIFS_FLOPPY
Definition: fmifs.h:47
@ FMIFS_REMOVABLE
Definition: fmifs.h:50
@ FMIFS_HARDDISK
Definition: fmifs.h:51
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
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
BOOLEAN(NTAPI * PFMIFSCALLBACK)(IN CALLBACKCOMMAND Command, IN ULONG SubAction, IN PVOID ActionInfo)
Definition: fmifs.h:89
VOID EndCheck(_In_ NTSTATUS Status)
Definition: fmtchk.c:150
VOID EndFormat(_In_ NTSTATUS Status)
Definition: fmtchk.c:97
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
return pTarget Start()
Status
Definition: gdiplustypes.h:25
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
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
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
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
#define C_ASSERT(e)
Definition: intsafe.h:73
#define IsOEMPartition(PartitionType)
Definition: partlist.h:22
@ Preformatted
Definition: partlist.h:37
@ Formatted
Definition: partlist.h:38
@ Unformatted
Definition: partlist.h:34
#define ASSERT(a)
Definition: mode.c:44
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define ULL(a, b)
Definition: format_msg.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define _In_
Definition: ms_sal.h:308
#define __fallthrough
Definition: ms_sal.h:2886
#define _In_opt_
Definition: ms_sal.h:309
int Count
Definition: noreturn.cpp:7
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
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)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
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)
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(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)
#define DEFAULT_UNREACHABLE
enum _MEDIA_TYPE MEDIA_TYPE
@ RemovableMedia
Definition: ntdddisk.h:382
@ FixedMedia
Definition: ntdddisk.h:383
@ F5_320_1024
Definition: ntdddisk.h:379
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
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 STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_PARTITION_FAILURE
Definition: ntstatus.h:604
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
#define L(x)
Definition: ntvdm.h:50
CHAR PartitionType
Definition: part_xbox.c:32
unsigned short USHORT
Definition: pedump.c:61
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static BOOLEAN GetNextUnformattedPartition(IN PPARTLIST List, OUT PPARTENTRY *pPartEntry)
Definition: fsutil.c:1029
NTSTATUS InstallFat32BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:464
struct _BTRFS_BOOTSECTOR * PBTRFS_BOOTSECTOR
static BOOLEAN GetNextUncheckedPartition(IN PPARTLIST List, OUT PPARTENTRY *pPartEntry)
Definition: fsutil.c:1083
NTSTATUS FormatPartition(_In_ PPARTENTRY PartEntry, _In_ PCWSTR FileSystemName, _In_ FMIFS_MEDIA_FLAG MediaFlag, _In_opt_ PCWSTR Label, _In_ BOOLEAN QuickFormat, _In_ ULONG ClusterSize, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:793
struct _FILE_SYSTEM FILE_SYSTEM
static FILE_SYSTEM RegisteredFileSystems[]
Definition: fsutil.c:159
NTSTATUS FormatFileSystem(_In_ PCWSTR DriveRoot, _In_ PCWSTR FileSystemName, _In_ FMIFS_MEDIA_FLAG MediaFlag, _In_opt_ PCWSTR Label, _In_ BOOLEAN QuickFormat, _In_ ULONG ClusterSize, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:376
BOOLEAN FsVolCommitOpsQueue(_In_ PPARTLIST PartitionList, _In_ PPARTENTRY SystemPartition, _In_ PPARTENTRY InstallPartition, _In_opt_ PFSVOL_CALLBACK FsVolCallback, _In_opt_ PVOID Context)
Definition: fsutil.c:1137
struct _BTRFS_BOOTSECTOR BTRFS_BOOTSECTOR
struct _NTFS_BOOTSECTOR * PNTFS_BOOTSECTOR
NTSTATUS InstallBtrfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:585
BOOLEAN GetRegisteredFileSystems(IN ULONG Index, OUT PCWSTR *FileSystemName)
Definition: fsutil.c:182
NTSTATUS InstallNtfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:692
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
struct _FILE_SYSTEM * PFILE_SYSTEM
NTSTATUS ChkdskPartition(_In_ PPARTENTRY PartEntry, _In_ BOOLEAN FixErrors, _In_ BOOLEAN Verbose, _In_ BOOLEAN CheckOnlyIfDirty, _In_ BOOLEAN ScanDrive, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:757
struct _FAT32_BOOTSECTOR FAT32_BOOTSECTOR
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
NTSTATUS InstallFatBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:406
NTSTATUS ChkdskFileSystem_UStr(_In_ PUNICODE_STRING DriveRoot, _In_ PCWSTR FileSystemName, _In_ BOOLEAN FixErrors, _In_ BOOLEAN Verbose, _In_ BOOLEAN CheckOnlyIfDirty, _In_ BOOLEAN ScanDrive, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:244
NTSTATUS ChkdskFileSystem(_In_ PCWSTR DriveRoot, _In_ PCWSTR FileSystemName, _In_ BOOLEAN FixErrors, _In_ BOOLEAN Verbose, _In_ BOOLEAN CheckOnlyIfDirty, _In_ BOOLEAN ScanDrive, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:287
struct _NTFS_BOOTSECTOR NTFS_BOOTSECTOR
static FSVOL_OP DoFormatting(_In_ PPARTENTRY PartEntry, _In_opt_ PVOID Context, _In_opt_ PFSVOL_CALLBACK FsVolCallback)
Definition: fsutil.c:910
static PFILE_SYSTEM GetFileSystemByName(IN PCWSTR FileSystemName)
Definition: fsutil.c:197
static FSVOL_OP DoChecking(_In_ PPARTENTRY PartEntry, _In_opt_ PVOID Context, _In_opt_ PFSVOL_CALLBACK FsVolCallback)
Definition: fsutil.c:966
NTSTATUS FormatFileSystem_UStr(_In_ PUNICODE_STRING DriveRoot, _In_ PCWSTR FileSystemName, _In_ FMIFS_MEDIA_FLAG MediaFlag, _In_opt_ PUNICODE_STRING Label, _In_ BOOLEAN QuickFormat, _In_ ULONG ClusterSize, _In_opt_ PFMIFSCALLBACK Callback)
Definition: fsutil.c:311
struct _FAT_BOOTSECTOR FAT_BOOTSECTOR
@ FSVOLNOTIFY_STARTCHECK
Definition: fsutil.h:146
@ FSVOLNOTIFY_ENDQUEUE
Definition: fsutil.h:138
@ FSVOLNOTIFY_STARTSUBQUEUE
Definition: fsutil.h:139
@ FSVOLNOTIFY_ENDFORMAT
Definition: fsutil.h:144
@ FSVOLNOTIFY_STARTFORMAT
Definition: fsutil.h:143
@ FSVOLNOTIFY_STARTQUEUE
Definition: fsutil.h:137
@ FSVOLNOTIFY_ENDSUBQUEUE
Definition: fsutil.h:140
@ FSVOLNOTIFY_PARTITIONERROR
Definition: fsutil.h:142
@ FSVOLNOTIFY_CHECKERROR
Definition: fsutil.h:148
@ FSVOLNOTIFY_FORMATERROR
Definition: fsutil.h:145
@ FSVOLNOTIFY_ENDCHECK
Definition: fsutil.h:147
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:77
#define NTFS_BOOTSECTOR_SIZE
Definition: fsutil.h:71
enum _FSVOL_OP FSVOL_OP
#define FAT_BOOTSECTOR_SIZE
Definition: fsutil.h:68
@ FSVOL_FORMAT
Definition: fsutil.h:155
@ FSVOL_CHECK
Definition: fsutil.h:156
@ FSVOL_DOIT
Definition: fsutil.h:159
@ FSVOL_ABORT
Definition: fsutil.h:158
@ FSVOL_RETRY
Definition: fsutil.h:160
@ FSVOL_SKIP
Definition: fsutil.h:161
#define FAT32_BOOTSECTOR_SIZE
Definition: fsutil.h:69
#define BTRFS_BOOTSECTOR_SIZE
Definition: fsutil.h:70
IN HANDLE DstPath
Definition: fsutil.h:76
FSVOL_OP(CALLBACK * PFSVOL_CALLBACK)(_In_opt_ PVOID Context, _In_ FSVOLNOTIFY FormatStatus, _In_ ULONG_PTR Param1, _In_ ULONG_PTR Param2)
Definition: fsutil.h:196
BOOLEAN WritePartitionsToDisk(IN PPARTLIST List)
Definition: partlist.c:3723
VOID SetMBRPartitionType(IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
Definition: partlist.c:3897
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3579
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
ULONG Length
Definition: bootcode.h:18
PVOID BootCode
Definition: bootcode.h:17
USHORT BootSectorMagic
Definition: fsutil.c:110
UCHAR BootDrive
Definition: fsutil.c:107
UCHAR ChunkMapSize
Definition: fsutil.c:106
UCHAR JumpBoot[3]
Definition: fsutil.c:105
ULONGLONG PartitionStartLBA
Definition: fsutil.c:108
UCHAR Fill[1521]
Definition: fsutil.c:109
BOOLEAN Verbose
Definition: fsutil.h:188
NTSTATUS ErrorStatus
Definition: fsutil.h:184
PFMIFSCALLBACK Callback
Definition: fsutil.h:191
BOOLEAN CheckOnlyIfDirty
Definition: fsutil.h:189
PPARTENTRY PartEntry
Definition: fsutil.h:182
BOOLEAN FixErrors
Definition: fsutil.h:187
BOOLEAN ScanDrive
Definition: fsutil.h:190
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:129
ULONG DiskNumber
Definition: partlist.h:108
PARTITION_STYLE DiskStyle
Definition: partlist.h:118
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:128
USHORT BootSectorMagic
Definition: fsutil.c:98
UCHAR BootCodeAndData[420]
Definition: fsutil.c:96
CHAR FileSystemType[8]
Definition: fsutil.c:94
UCHAR MediaDescriptor
Definition: fsutil.c:76
ULONG HiddenSectors
Definition: fsutil.c:80
UCHAR NumberOfFats
Definition: fsutil.c:73
ULONG VolumeSerialNumber
Definition: fsutil.c:92
CHAR VolumeLabel[11]
Definition: fsutil.c:93
USHORT ExtendedFlags
Definition: fsutil.c:83
ULONG SectorsPerFatBig
Definition: fsutil.c:82
UCHAR JumpBoot[3]
Definition: fsutil.c:68
CHAR OemName[8]
Definition: fsutil.c:69
USHORT NumberOfHeads
Definition: fsutil.c:79
USHORT ReservedSectors
Definition: fsutil.c:72
USHORT RootDirEntries
Definition: fsutil.c:74
USHORT FsInfo
Definition: fsutil.c:86
USHORT BytesPerSector
Definition: fsutil.c:70
USHORT FileSystemVersion
Definition: fsutil.c:84
ULONG TotalSectorsBig
Definition: fsutil.c:81
UCHAR BootSignature
Definition: fsutil.c:91
ULONG RootDirStartCluster
Definition: fsutil.c:85
UCHAR DriveNumber
Definition: fsutil.c:89
UCHAR SectorsPerCluster
Definition: fsutil.c:71
USHORT SectorsPerFat
Definition: fsutil.c:77
USHORT SectorsPerTrack
Definition: fsutil.c:78
UCHAR Reserved1
Definition: fsutil.c:90
USHORT BackupBootSector
Definition: fsutil.c:87
USHORT TotalSectors
Definition: fsutil.c:75
ULONG TotalSectorsBig
Definition: fsutil.c:51
UCHAR JumpBoot[3]
Definition: fsutil.c:38
USHORT SectorsPerTrack
Definition: fsutil.c:48
USHORT TotalSectors
Definition: fsutil.c:45
UCHAR NumberOfFats
Definition: fsutil.c:43
CHAR VolumeLabel[11]
Definition: fsutil.c:56
USHORT NumberOfHeads
Definition: fsutil.c:49
USHORT SectorsPerFat
Definition: fsutil.c:47
CHAR OemName[8]
Definition: fsutil.c:39
USHORT ReservedSectors
Definition: fsutil.c:42
ULONG HiddenSectors
Definition: fsutil.c:50
CHAR FileSystemType[8]
Definition: fsutil.c:57
USHORT BytesPerSector
Definition: fsutil.c:40
USHORT RootDirEntries
Definition: fsutil.c:44
ULONG VolumeSerialNumber
Definition: fsutil.c:55
UCHAR MediaDescriptor
Definition: fsutil.c:46
USHORT BootSectorMagic
Definition: fsutil.c:61
UCHAR Reserved1
Definition: fsutil.c:53
UCHAR BootCodeAndData[448]
Definition: fsutil.c:59
UCHAR DriveNumber
Definition: fsutil.c:52
UCHAR BootSignature
Definition: fsutil.c:54
UCHAR SectorsPerCluster
Definition: fsutil.c:41
PULIB_CHKDSK ChkdskFunc
Definition: fsutil.c:155
PCWSTR FileSystemName
Definition: fsutil.c:153
PULIB_FORMAT FormatFunc
Definition: fsutil.c:154
PFMIFSCALLBACK Callback
Definition: fsutil.h:176
BOOLEAN QuickFormat
Definition: fsutil.h:174
PPARTENTRY PartEntry
Definition: fsutil.h:166
NTSTATUS ErrorStatus
Definition: fsutil.h:168
FMIFS_MEDIA_FLAG MediaFlag
Definition: fsutil.h:172
PCWSTR FileSystemName
Definition: fsutil.h:171
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT Heads
Definition: fsutil.c:124
ULONGLONG SectorCount
Definition: fsutil.c:128
UCHAR Unused4[3]
Definition: fsutil.c:132
UCHAR Unused3[4]
Definition: fsutil.c:126
UCHAR MediaId
Definition: fsutil.c:121
UCHAR Checksum[4]
Definition: fsutil.c:136
USHORT Unknown[2]
Definition: fsutil.c:127
ULONGLONG SerialNumber
Definition: fsutil.c:135
UCHAR SectorsPerCluster
Definition: fsutil.c:119
CHAR ClustersPerMftRecord
Definition: fsutil.c:131
UCHAR Unused1[2]
Definition: fsutil.c:122
UCHAR Jump[3]
Definition: fsutil.c:116
UCHAR BootCodeAndData[7680]
Definition: fsutil.c:139
USHORT BytesPerSector
Definition: fsutil.c:118
UCHAR Unused0[7]
Definition: fsutil.c:120
UCHAR OEMID[8]
Definition: fsutil.c:117
UCHAR BootStrap[426]
Definition: fsutil.c:137
ULONGLONG MftMirrLocation
Definition: fsutil.c:130
USHORT EndSector
Definition: fsutil.c:138
CHAR ClustersPerIndexRecord
Definition: fsutil.c:133
ULONGLONG MftLocation
Definition: fsutil.c:129
USHORT SectorsPerTrack
Definition: fsutil.c:123
UCHAR Unused2[4]
Definition: fsutil.c:125
UCHAR Unused5[3]
Definition: fsutil.c:134
BOOLEAN IsPartitioned
Definition: partlist.h:66
BOOLEAN New
Definition: partlist.h:71
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
FORMATSTATE FormatState
Definition: partlist.h:61
BOOLEAN NeedsCheck
Definition: partlist.h:74
LARGE_INTEGER StartingOffset
Definition: imports.h:221
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
static FSVOL_OP CALLBACK FsVolCallback(_In_opt_ PVOID Context, _In_ FSVOLNOTIFY FormatStatus, _In_ ULONG_PTR Param1, _In_ ULONG_PTR Param2)
Definition: usetup.c:2594
static PPARTLIST PartitionList
Definition: usetup.c:71
static PPARTENTRY InstallPartition
Definition: usetup.c:48
static PPARTENTRY SystemPartition
Definition: usetup.c:59
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175