1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: File Management IFS Utility functions
4 * FILE: reactos/dll/win32/fmifs/format.c
5 * PURPOSE: Volume format
6 *
7 * PROGRAMMERS: Emanuele Aliberti
8 * Hervé Poussineau (hpoussin@reactos.org)
9 */
10
11 #include "precomp.h"
12 #include <ntstrsafe.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* FMIFS.6 */
18 VOID NTAPI
Format(IN PWCHAR DriveRoot,IN FMIFS_MEDIA_FLAG MediaFlag,IN PWCHAR Format,IN PWCHAR Label,IN BOOLEAN QuickFormat,IN PFMIFSCALLBACK Callback)19 Format(
20 IN PWCHAR DriveRoot,
21 IN FMIFS_MEDIA_FLAG MediaFlag,
22 IN PWCHAR Format,
23 IN PWCHAR Label,
24 IN BOOLEAN QuickFormat,
25 IN PFMIFSCALLBACK Callback)
26 {
27 FormatEx(DriveRoot,
28 MediaFlag,
29 Format,
30 Label,
31 QuickFormat,
32 0,
33 Callback);
34 }
35
36 /* FMIFS.7 */
37 VOID
38 NTAPI
FormatEx(IN PWCHAR DriveRoot,IN FMIFS_MEDIA_FLAG MediaFlag,IN PWCHAR Format,IN PWCHAR Label,IN BOOLEAN QuickFormat,IN ULONG ClusterSize,IN PFMIFSCALLBACK Callback)39 FormatEx(
40 IN PWCHAR DriveRoot,
41 IN FMIFS_MEDIA_FLAG MediaFlag,
42 IN PWCHAR Format,
43 IN PWCHAR Label,
44 IN BOOLEAN QuickFormat,
45 IN ULONG ClusterSize,
46 IN PFMIFSCALLBACK Callback)
47 {
48 PIFS_PROVIDER Provider;
49 UNICODE_STRING usDriveRoot;
50 UNICODE_STRING usLabel;
51 BOOLEAN Success = FALSE;
52 BOOLEAN BackwardCompatible = FALSE; // Default to latest FS versions.
53 MEDIA_TYPE MediaType;
54 WCHAR DriveName[MAX_PATH];
55 WCHAR VolumeName[MAX_PATH];
56
57 //
58 // TODO: Convert filesystem Format into ULIB format string.
59 //
60
61 Provider = GetProvider(Format);
62 if (!Provider)
63 {
64 /* Unknown file system */
65 goto Quit;
66 }
67
68 if (!NT_SUCCESS(RtlStringCchCopyW(DriveName, ARRAYSIZE(DriveName), DriveRoot)))
69 goto Quit;
70
71 if (DriveName[wcslen(DriveName) - 1] != L'\\')
72 {
73 /* Append the trailing backslash for GetVolumeNameForVolumeMountPointW */
74 if (!NT_SUCCESS(RtlStringCchCatW(DriveName, ARRAYSIZE(DriveName), L"\\")))
75 goto Quit;
76 }
77
78 if (!GetVolumeNameForVolumeMountPointW(DriveName, VolumeName, ARRAYSIZE(VolumeName)))
79 {
80 /* Couldn't get a volume GUID path, try formatting using a parameter provided path */
81 DPRINT1("Couldn't get a volume GUID path for drive %S\n", DriveName);
82 wcscpy(VolumeName, DriveName);
83 }
84
85 if (!RtlDosPathNameToNtPathName_U(VolumeName, &usDriveRoot, NULL, NULL))
86 goto Quit;
87
88 /* Trim the trailing backslash since we will work with a device object */
89 usDriveRoot.Length -= sizeof(WCHAR);
90
91 RtlInitUnicodeString(&usLabel, Label);
92
93 /* Set the BackwardCompatible flag in case we format with older FAT12/16 */
94 if (_wcsicmp(Format, L"FAT") == 0)
95 BackwardCompatible = TRUE;
96 // else if (wcsicmp(Format, L"FAT32") == 0)
97 // BackwardCompatible = FALSE;
98
99 /* Convert the FMIFS MediaFlag to a NT MediaType */
100 // FIXME: Actually covert all the possible flags.
101 switch (MediaFlag)
102 {
103 case FMIFS_FLOPPY:
104 MediaType = F5_320_1024; // FIXME: This is hardfixed!
105 break;
106 case FMIFS_REMOVABLE:
107 MediaType = RemovableMedia;
108 break;
109 case FMIFS_HARDDISK:
110 MediaType = FixedMedia;
111 break;
112 default:
113 DPRINT1("Unknown FMIFS MediaFlag %d, converting 1-to-1 to NT MediaType\n",
114 MediaFlag);
115 MediaType = (MEDIA_TYPE)MediaFlag;
116 break;
117 }
118
119 DPRINT("Format() - %S\n", Format);
120 Success = Provider->Format(&usDriveRoot,
121 Callback,
122 QuickFormat,
123 BackwardCompatible,
124 MediaType,
125 &usLabel,
126 ClusterSize);
127 if (!Success)
128 DPRINT1("Format() failed\n");
129
130 RtlFreeUnicodeString(&usDriveRoot);
131
132 Quit:
133 /* Report result */
134 Callback(DONE, 0, &Success);
135 }
136
137 /* EOF */
138