40d2105e841b64c01a1edaba35d131e25dd8cd98
[reactos.git] / reactos / sdk / 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 else
107 {
108 PartitionInfo.PartitionType = 0;
109 PartitionInfo.StartingOffset.QuadPart = 0ULL;
110 PartitionInfo.PartitionLength.QuadPart =
111 DiskGeometry.Cylinders.QuadPart *
112 (ULONGLONG)DiskGeometry.TracksPerCylinder *
113 (ULONGLONG)DiskGeometry.SectorsPerTrack *
114 (ULONGLONG)DiskGeometry.BytesPerSector;
115 PartitionInfo.HiddenSectors = 0;
116 PartitionInfo.PartitionNumber = 0;
117 PartitionInfo.BootIndicator = FALSE;
118 PartitionInfo.RewritePartition = FALSE;
119 PartitionInfo.RecognizedPartition = FALSE;
120 }
121
122 DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
123 DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset.QuadPart);
124 DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength.QuadPart);
125 DPRINT("HiddenSectors %lu\n", PartitionInfo.HiddenSectors);
126 DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
127 DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
128 DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
129 DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
130
131 if (Callback != NULL)
132 {
133 Context.Percent = 0;
134 Callback(PROGRESS, 0, (PVOID)&Context.Percent);
135 }
136
137 Status = FatxFormat(FileHandle,
138 &PartitionInfo,
139 &DiskGeometry,
140 QuickFormat,
141 &Context);
142 NtClose(FileHandle);
143
144 if (Callback != NULL)
145 {
146 Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
147 Callback(DONE, 0, (PVOID)&Context.Success);
148 }
149
150 DPRINT("VfatxFormat() done. Status 0x%.08x\n", Status);
151
152 return Status;
153 }
154
155
156 VOID
157 VfatxUpdateProgress(IN PFORMAT_CONTEXT Context,
158 IN ULONG Increment)
159 {
160 ULONG NewPercent;
161
162 Context->CurrentSectorCount += (ULONGLONG)Increment;
163
164 NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
165
166 if (NewPercent > Context->Percent)
167 {
168 Context->Percent = NewPercent;
169 if (Context->Callback != NULL)
170 {
171 Context->Callback(PROGRESS, 0, &Context->Percent);
172 }
173 }
174 }
175
176 /* EOF */