990dd20bd6dba3dedf53a39c985a5c1d755b87b3
[reactos.git] / reactos / lib / fslib / vfatxlib / vfatxlib.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS VFATx filesystem library
4 * FILE: vfatxlib.c
5 * PURPOSE: Main API
6 * PROGRAMMERS:
7 * REVISIONS:
8 * CSH 05/04-2003 Created
9 */
10
11 #include "vfatxlib.h"
12
13 #include <ndk/obfuncs.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 NTSTATUS NTAPI
19 VfatxFormat(IN PUNICODE_STRING DriveRoot,
20 IN FMIFS_MEDIA_FLAG MediaFlag,
21 IN PUNICODE_STRING Label,
22 IN BOOLEAN QuickFormat,
23 IN ULONG ClusterSize,
24 IN PFMIFSCALLBACK Callback)
25 {
26 OBJECT_ATTRIBUTES ObjectAttributes;
27 DISK_GEOMETRY DiskGeometry;
28 IO_STATUS_BLOCK Iosb;
29 HANDLE FileHandle;
30 PARTITION_INFORMATION PartitionInfo;
31 FORMAT_CONTEXT Context;
32 NTSTATUS Status;
33
34 DPRINT("VfatxFormat(DriveRoot '%wZ')\n", DriveRoot);
35
36 Context.TotalSectorCount = 0;
37 Context.CurrentSectorCount = 0;
38 Context.Callback = Callback;
39 Context.Success = FALSE;
40 Context.Percent = 0;
41
42 InitializeObjectAttributes(&ObjectAttributes,
43 DriveRoot,
44 0,
45 NULL,
46 NULL);
47
48 Status = NtOpenFile(&FileHandle,
49 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
50 &ObjectAttributes,
51 &Iosb,
52 FILE_SHARE_READ,
53 FILE_SYNCHRONOUS_IO_ALERT);
54 if (!NT_SUCCESS(Status))
55 {
56 DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status);
57 return Status;
58 }
59
60 Status = NtDeviceIoControlFile(FileHandle,
61 NULL,
62 NULL,
63 NULL,
64 &Iosb,
65 IOCTL_DISK_GET_DRIVE_GEOMETRY,
66 NULL,
67 0,
68 &DiskGeometry,
69 sizeof(DISK_GEOMETRY));
70 if (!NT_SUCCESS(Status))
71 {
72 DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
73 NtClose(FileHandle);
74 return Status;
75 }
76
77 if (DiskGeometry.MediaType == FixedMedia)
78 {
79 DPRINT("Cylinders %I64d\n", DiskGeometry.Cylinders.QuadPart);
80 DPRINT("TracksPerCylinder %ld\n", DiskGeometry.TracksPerCylinder);
81 DPRINT("SectorsPerTrack %ld\n", DiskGeometry.SectorsPerTrack);
82 DPRINT("BytesPerSector %ld\n", DiskGeometry.BytesPerSector);
83 DPRINT("DiskSize %I64d\n",
84 DiskGeometry.Cylinders.QuadPart *
85 (ULONGLONG)DiskGeometry.TracksPerCylinder *
86 (ULONGLONG)DiskGeometry.SectorsPerTrack *
87 (ULONGLONG)DiskGeometry.BytesPerSector);
88
89 Status = NtDeviceIoControlFile(FileHandle,
90 NULL,
91 NULL,
92 NULL,
93 &Iosb,
94 IOCTL_DISK_GET_PARTITION_INFO,
95 NULL,
96 0,
97 &PartitionInfo,
98 sizeof(PARTITION_INFORMATION));
99 if (!NT_SUCCESS(Status))
100 {
101 DPRINT("IOCTL_DISK_GET_PARTITION_INFO failed with status 0x%.08x\n", Status);
102 NtClose(FileHandle);
103 return Status;
104 }
105
106 /*
107 * FIXME: This is a hack!
108 * Partitioning software MUST set the correct number of hidden sectors!
109 */
110 PartitionInfo.HiddenSectors = DiskGeometry.SectorsPerTrack;
111 }
112 else
113 {
114 PartitionInfo.PartitionType = 0;
115 PartitionInfo.StartingOffset.QuadPart = 0ULL;
116 PartitionInfo.PartitionLength.QuadPart =
117 DiskGeometry.Cylinders.QuadPart *
118 (ULONGLONG)DiskGeometry.TracksPerCylinder *
119 (ULONGLONG)DiskGeometry.SectorsPerTrack *
120 (ULONGLONG)DiskGeometry.BytesPerSector;
121 PartitionInfo.HiddenSectors = 0;
122 PartitionInfo.PartitionNumber = 0;
123 PartitionInfo.BootIndicator = FALSE;
124 PartitionInfo.RewritePartition = FALSE;
125 PartitionInfo.RecognizedPartition = FALSE;
126 }
127
128 DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
129 DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset.QuadPart);
130 DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength.QuadPart);
131 DPRINT("HiddenSectors %lu\n", PartitionInfo.HiddenSectors);
132 DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
133 DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
134 DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
135 DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
136
137 if (Callback != NULL)
138 {
139 Context.Percent = 0;
140 Callback(PROGRESS, 0, (PVOID)&Context.Percent);
141 }
142
143 Status = FatxFormat(FileHandle,
144 &PartitionInfo,
145 &DiskGeometry,
146 QuickFormat,
147 &Context);
148 NtClose(FileHandle);
149
150 if (Callback != NULL)
151 {
152 Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
153 Callback(DONE, 0, (PVOID)&Context.Success);
154 }
155
156 DPRINT("VfatxFormat() done. Status 0x%.08x\n", Status);
157
158 return Status;
159 }
160
161
162 VOID
163 VfatxUpdateProgress(IN PFORMAT_CONTEXT Context,
164 IN ULONG Increment)
165 {
166 ULONG NewPercent;
167
168 Context->CurrentSectorCount += (ULONGLONG)Increment;
169
170 NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
171
172 if (NewPercent > Context->Percent)
173 {
174 Context->Percent = NewPercent;
175 if (Context->Callback != NULL)
176 {
177 Context->Callback(PROGRESS, 0, &Context->Percent);
178 }
179 }
180 }
181
182 /* EOF */