xref: /reactos/sdk/lib/fslib/vfatlib/fat12.c (revision 38791299)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:   See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:     ReactOS VFAT filesystem library
4c2c66affSColin Finck  * FILE:        fat12.c
5c2c66affSColin Finck  * PURPOSE:     Fat12 support
6c2c66affSColin Finck  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7c2c66affSColin Finck  *              Eric Kohl
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck /* INCLUDES *******************************************************************/
11c2c66affSColin Finck 
12c2c66affSColin Finck #include "vfatlib.h"
13c2c66affSColin Finck 
14c2c66affSColin Finck #define NDEBUG
15c2c66affSColin Finck #include <debug.h>
16c2c66affSColin Finck 
17c2c66affSColin Finck 
18c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
19c2c66affSColin Finck 
20c2c66affSColin Finck static NTSTATUS
Fat12WriteBootSector(IN HANDLE FileHandle,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)21c2c66affSColin Finck Fat12WriteBootSector(IN HANDLE FileHandle,
22c2c66affSColin Finck                      IN PFAT16_BOOT_SECTOR BootSector,
23c2c66affSColin Finck                      IN OUT PFORMAT_CONTEXT Context)
24c2c66affSColin Finck {
25c2c66affSColin Finck     IO_STATUS_BLOCK IoStatusBlock;
26c2c66affSColin Finck     NTSTATUS Status;
27c2c66affSColin Finck     PFAT16_BOOT_SECTOR NewBootSector;
28c2c66affSColin Finck     LARGE_INTEGER FileOffset;
29c2c66affSColin Finck 
30c2c66affSColin Finck     /* Allocate buffer for new bootsector */
31c2c66affSColin Finck     NewBootSector = (PFAT16_BOOT_SECTOR)RtlAllocateHeap(RtlGetProcessHeap (),
32c2c66affSColin Finck                                             0,
33c2c66affSColin Finck                                             BootSector->BytesPerSector);
34c2c66affSColin Finck     if (NewBootSector == NULL)
35c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
36c2c66affSColin Finck 
37c2c66affSColin Finck     /* Zero the new bootsector */
38c2c66affSColin Finck     RtlZeroMemory(NewBootSector, BootSector->BytesPerSector);
39c2c66affSColin Finck 
40c2c66affSColin Finck     /* Copy FAT16 BPB to new bootsector */
41*38791299SPierre Schweitzer     memcpy(NewBootSector, BootSector,
426ff94017SPierre Schweitzer            FIELD_OFFSET(FAT16_BOOT_SECTOR, Res2) - FIELD_OFFSET(FAT16_BOOT_SECTOR, Jump));
43c2c66affSColin Finck            /* FAT16 BPB length (up to (not including) Res2) */
44c2c66affSColin Finck 
45c2c66affSColin Finck     /* Write the boot sector signature */
46c2c66affSColin Finck     NewBootSector->Signature1 = 0xAA550000;
47c2c66affSColin Finck 
48c2c66affSColin Finck     /* Write sector 0 */
49c2c66affSColin Finck     FileOffset.QuadPart = 0ULL;
50c2c66affSColin Finck     Status = NtWriteFile(FileHandle,
51c2c66affSColin Finck                          NULL,
52c2c66affSColin Finck                          NULL,
53c2c66affSColin Finck                          NULL,
54c2c66affSColin Finck                          &IoStatusBlock,
55c2c66affSColin Finck                          NewBootSector,
56c2c66affSColin Finck                          BootSector->BytesPerSector,
57c2c66affSColin Finck                          &FileOffset,
58c2c66affSColin Finck                          NULL);
59c2c66affSColin Finck     if (!NT_SUCCESS(Status))
60c2c66affSColin Finck     {
61c2c66affSColin Finck         DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
62c2c66affSColin Finck         goto done;
63c2c66affSColin Finck     }
64c2c66affSColin Finck 
65c2c66affSColin Finck     UpdateProgress(Context, 1);
66c2c66affSColin Finck 
67c2c66affSColin Finck done:
68c2c66affSColin Finck     /* Free the buffer */
69c2c66affSColin Finck     RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
70c2c66affSColin Finck     return Status;
71c2c66affSColin Finck }
72c2c66affSColin Finck 
73c2c66affSColin Finck 
74c2c66affSColin Finck static NTSTATUS
Fat12WriteFAT(IN HANDLE FileHandle,IN ULONG SectorOffset,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)75c2c66affSColin Finck Fat12WriteFAT(IN HANDLE FileHandle,
76c2c66affSColin Finck               IN ULONG SectorOffset,
77c2c66affSColin Finck               IN PFAT16_BOOT_SECTOR BootSector,
78c2c66affSColin Finck               IN OUT PFORMAT_CONTEXT Context)
79c2c66affSColin Finck {
80c2c66affSColin Finck     IO_STATUS_BLOCK IoStatusBlock;
81c2c66affSColin Finck     NTSTATUS Status;
82c2c66affSColin Finck     PUCHAR Buffer;
83c2c66affSColin Finck     LARGE_INTEGER FileOffset;
84c2c66affSColin Finck     ULONG i;
85c2c66affSColin Finck     ULONG Size;
86c2c66affSColin Finck     ULONG Sectors;
87c2c66affSColin Finck 
88c2c66affSColin Finck     /* Allocate buffer */
89c2c66affSColin Finck     Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
90c2c66affSColin Finck                                      0,
91c2c66affSColin Finck                                      32 * 1024);
92c2c66affSColin Finck     if (Buffer == NULL)
93c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
94c2c66affSColin Finck 
95c2c66affSColin Finck     /* Zero the buffer */
96c2c66affSColin Finck     RtlZeroMemory(Buffer, 32 * 1024);
97c2c66affSColin Finck 
98c2c66affSColin Finck     /* FAT cluster 0 & 1*/
99c2c66affSColin Finck     Buffer[0] = 0xf8; /* Media type */
100c2c66affSColin Finck     Buffer[1] = 0xff;
101c2c66affSColin Finck     Buffer[2] = 0xff;
102c2c66affSColin Finck 
103c2c66affSColin Finck     /* Write first sector of the FAT */
104c2c66affSColin Finck     FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
105c2c66affSColin Finck     Status = NtWriteFile(FileHandle,
106c2c66affSColin Finck                          NULL,
107c2c66affSColin Finck                          NULL,
108c2c66affSColin Finck                          NULL,
109c2c66affSColin Finck                          &IoStatusBlock,
110c2c66affSColin Finck                          Buffer,
111c2c66affSColin Finck                          BootSector->BytesPerSector,
112c2c66affSColin Finck                          &FileOffset,
113c2c66affSColin Finck                          NULL);
114c2c66affSColin Finck     if (!NT_SUCCESS(Status))
115c2c66affSColin Finck     {
116c2c66affSColin Finck         DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
117c2c66affSColin Finck         goto done;
118c2c66affSColin Finck     }
119c2c66affSColin Finck 
120c2c66affSColin Finck     UpdateProgress(Context, 1);
121c2c66affSColin Finck 
122c2c66affSColin Finck     /* Zero the begin of the buffer */
123c2c66affSColin Finck     RtlZeroMemory(Buffer, 3);
124c2c66affSColin Finck 
125c2c66affSColin Finck     /* Zero the rest of the FAT */
126c2c66affSColin Finck     Sectors = 32 * 1024 / BootSector->BytesPerSector;
127c2c66affSColin Finck     for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
128c2c66affSColin Finck     {
129c2c66affSColin Finck         /* Zero some sectors of the FAT */
130c2c66affSColin Finck         FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
131c2c66affSColin Finck         if (((ULONG)BootSector->FATSectors - i) <= Sectors)
132c2c66affSColin Finck         {
133c2c66affSColin Finck             Sectors = (ULONG)BootSector->FATSectors - i;
134c2c66affSColin Finck         }
135c2c66affSColin Finck 
136c2c66affSColin Finck         Size = Sectors * BootSector->BytesPerSector;
137c2c66affSColin Finck         Status = NtWriteFile(FileHandle,
138c2c66affSColin Finck                              NULL,
139c2c66affSColin Finck                              NULL,
140c2c66affSColin Finck                              NULL,
141c2c66affSColin Finck                              &IoStatusBlock,
142c2c66affSColin Finck                              Buffer,
143c2c66affSColin Finck                              Size,
144c2c66affSColin Finck                              &FileOffset,
145c2c66affSColin Finck                              NULL);
146c2c66affSColin Finck         if (!NT_SUCCESS(Status))
147c2c66affSColin Finck         {
148c2c66affSColin Finck             DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
149c2c66affSColin Finck             goto done;
150c2c66affSColin Finck         }
151c2c66affSColin Finck 
152c2c66affSColin Finck         UpdateProgress(Context, Sectors);
153c2c66affSColin Finck     }
154c2c66affSColin Finck 
155c2c66affSColin Finck done:
156c2c66affSColin Finck     /* Free the buffer */
157c2c66affSColin Finck     RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
158c2c66affSColin Finck     return Status;
159c2c66affSColin Finck }
160c2c66affSColin Finck 
161c2c66affSColin Finck 
162c2c66affSColin Finck static NTSTATUS
Fat12WriteRootDirectory(IN HANDLE FileHandle,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)163c2c66affSColin Finck Fat12WriteRootDirectory(IN HANDLE FileHandle,
164c2c66affSColin Finck                         IN PFAT16_BOOT_SECTOR BootSector,
165c2c66affSColin Finck                         IN OUT PFORMAT_CONTEXT Context)
166c2c66affSColin Finck {
167c2c66affSColin Finck     IO_STATUS_BLOCK IoStatusBlock;
168c2c66affSColin Finck     NTSTATUS Status = STATUS_SUCCESS;
169c2c66affSColin Finck     PUCHAR Buffer;
170c2c66affSColin Finck     LARGE_INTEGER FileOffset;
171c2c66affSColin Finck     ULONG FirstRootDirSector;
172c2c66affSColin Finck     ULONG RootDirSectors;
173c2c66affSColin Finck     ULONG Sectors;
174c2c66affSColin Finck     ULONG Size;
175c2c66affSColin Finck     ULONG i;
176c2c66affSColin Finck 
177c2c66affSColin Finck     DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
178c2c66affSColin Finck     DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
179c2c66affSColin Finck     DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
180c2c66affSColin Finck 
181c2c66affSColin Finck     /* Write cluster */
182c2c66affSColin Finck     RootDirSectors = ((BootSector->RootEntries * 32) +
183c2c66affSColin Finck         (BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
184c2c66affSColin Finck     FirstRootDirSector =
185c2c66affSColin Finck         BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
186c2c66affSColin Finck 
187c2c66affSColin Finck     DPRINT("RootDirSectors = %lu\n", RootDirSectors);
188c2c66affSColin Finck     DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
189c2c66affSColin Finck 
190c2c66affSColin Finck     /* Allocate buffer for the cluster */
191c2c66affSColin Finck     Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
192c2c66affSColin Finck                                      0,
193c2c66affSColin Finck                                      32 * 1024);
194c2c66affSColin Finck     if (Buffer == NULL)
195c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
196c2c66affSColin Finck 
197c2c66affSColin Finck     /* Zero the buffer */
198c2c66affSColin Finck     RtlZeroMemory(Buffer, 32 * 1024);
199c2c66affSColin Finck 
200c2c66affSColin Finck     Sectors = 32 * 1024 / BootSector->BytesPerSector;
201c2c66affSColin Finck     for (i = 0; i < RootDirSectors; i += Sectors)
202c2c66affSColin Finck     {
203c2c66affSColin Finck         /* Zero some sectors of the root directory */
204c2c66affSColin Finck         FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
205c2c66affSColin Finck 
206c2c66affSColin Finck         if ((RootDirSectors - i) <= Sectors)
207c2c66affSColin Finck         {
208c2c66affSColin Finck             Sectors = RootDirSectors - i;
209c2c66affSColin Finck         }
210c2c66affSColin Finck 
211c2c66affSColin Finck         Size = Sectors * BootSector->BytesPerSector;
212c2c66affSColin Finck 
213c2c66affSColin Finck         Status = NtWriteFile(FileHandle,
214c2c66affSColin Finck                              NULL,
215c2c66affSColin Finck                              NULL,
216c2c66affSColin Finck                              NULL,
217c2c66affSColin Finck                              &IoStatusBlock,
218c2c66affSColin Finck                              Buffer,
219c2c66affSColin Finck                              Size,
220c2c66affSColin Finck                              &FileOffset,
221c2c66affSColin Finck                              NULL);
222c2c66affSColin Finck         if (!NT_SUCCESS(Status))
223c2c66affSColin Finck         {
224c2c66affSColin Finck             DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
225c2c66affSColin Finck             goto done;
226c2c66affSColin Finck         }
227c2c66affSColin Finck 
228c2c66affSColin Finck         UpdateProgress(Context, Sectors);
229c2c66affSColin Finck     }
230c2c66affSColin Finck 
231c2c66affSColin Finck done:
232c2c66affSColin Finck     /* Free the buffer */
233c2c66affSColin Finck     RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
234c2c66affSColin Finck     return Status;
235c2c66affSColin Finck }
236c2c66affSColin Finck 
237c2c66affSColin Finck 
238c2c66affSColin Finck NTSTATUS
Fat12Format(IN HANDLE FileHandle,IN PPARTITION_INFORMATION PartitionInfo,IN PDISK_GEOMETRY DiskGeometry,IN PUNICODE_STRING Label,IN BOOLEAN QuickFormat,IN ULONG ClusterSize,IN OUT PFORMAT_CONTEXT Context)239c2c66affSColin Finck Fat12Format(IN HANDLE FileHandle,
240c2c66affSColin Finck             IN PPARTITION_INFORMATION PartitionInfo,
241c2c66affSColin Finck             IN PDISK_GEOMETRY DiskGeometry,
242c2c66affSColin Finck             IN PUNICODE_STRING Label,
243c2c66affSColin Finck             IN BOOLEAN QuickFormat,
244c2c66affSColin Finck             IN ULONG ClusterSize,
245c2c66affSColin Finck             IN OUT PFORMAT_CONTEXT Context)
246c2c66affSColin Finck {
247c2c66affSColin Finck     FAT16_BOOT_SECTOR BootSector;
248c2c66affSColin Finck     OEM_STRING VolumeLabel;
249c2c66affSColin Finck     ULONG SectorCount;
250c2c66affSColin Finck     ULONG RootDirSectors;
251c2c66affSColin Finck     ULONG TmpVal1;
252c2c66affSColin Finck     ULONG TmpVal2;
253c2c66affSColin Finck     ULONG TmpVal3;
254c2c66affSColin Finck     NTSTATUS Status;
255c2c66affSColin Finck 
256c2c66affSColin Finck     /* Calculate cluster size */
257c2c66affSColin Finck     if (ClusterSize == 0)
258c2c66affSColin Finck     {
259c2c66affSColin Finck         if (DiskGeometry->MediaType == FixedMedia)
260c2c66affSColin Finck         {
261c2c66affSColin Finck             /* 4KB Cluster (Harddisk only) */
262c2c66affSColin Finck             ClusterSize = 4096;
263c2c66affSColin Finck         }
264c2c66affSColin Finck         else
265c2c66affSColin Finck         {
266c2c66affSColin Finck             /* 512 byte cluster (floppy) */
267c2c66affSColin Finck             ClusterSize = 512;
268c2c66affSColin Finck         }
269c2c66affSColin Finck     }
270c2c66affSColin Finck 
271c2c66affSColin Finck     SectorCount = PartitionInfo->PartitionLength.QuadPart >>
272c2c66affSColin Finck         GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
273c2c66affSColin Finck 
274c2c66affSColin Finck     DPRINT("SectorCount = %lu\n", SectorCount);
275c2c66affSColin Finck 
276c2c66affSColin Finck     RtlZeroMemory(&BootSector, sizeof(FAT16_BOOT_SECTOR));
277c2c66affSColin Finck     memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
2786ff94017SPierre Schweitzer     /* FIXME: Add dummy bootloader for real */
2796ff94017SPierre Schweitzer     BootSector.Jump[0] = 0xeb;
2806ff94017SPierre Schweitzer     BootSector.Jump[1] = 0x3c;
2816ff94017SPierre Schweitzer     BootSector.Jump[2] = 0x90;
282c2c66affSColin Finck     BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
283c2c66affSColin Finck     BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
284c2c66affSColin Finck     BootSector.ReservedSectors = 1;
285c2c66affSColin Finck     BootSector.FATCount = 2;
286c2c66affSColin Finck     BootSector.RootEntries = 512;
287c2c66affSColin Finck     BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
288c2c66affSColin Finck     BootSector.Media = 0xf8;
289c2c66affSColin Finck     BootSector.FATSectors = 0;  /* Set later. See below. */
290c2c66affSColin Finck     BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
291c2c66affSColin Finck     BootSector.Heads = DiskGeometry->TracksPerCylinder;
292c2c66affSColin Finck     BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
293c2c66affSColin Finck     BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
294c2c66affSColin Finck     BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
295c2c66affSColin Finck     BootSector.ExtBootSignature = 0x29;
296c2c66affSColin Finck     BootSector.VolumeID = CalcVolumeSerialNumber();
297c2c66affSColin Finck     if ((Label == NULL) || (Label->Buffer == NULL))
298c2c66affSColin Finck     {
299c2c66affSColin Finck         memcpy(&BootSector.VolumeLabel[0], "NO NAME    ", 11);
300c2c66affSColin Finck     }
301c2c66affSColin Finck     else
302c2c66affSColin Finck     {
303c2c66affSColin Finck         RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
304c2c66affSColin Finck         RtlFillMemory(&BootSector.VolumeLabel[0], 11, ' ');
305c2c66affSColin Finck         memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
306c2c66affSColin Finck                VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
307c2c66affSColin Finck         RtlFreeOemString(&VolumeLabel);
308c2c66affSColin Finck     }
309c2c66affSColin Finck 
310c2c66affSColin Finck     memcpy(&BootSector.SysType[0], "FAT12   ", 8);
311c2c66affSColin Finck 
312c2c66affSColin Finck     RootDirSectors = ((BootSector.RootEntries * 32) +
313c2c66affSColin Finck         (BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
314c2c66affSColin Finck 
315c2c66affSColin Finck     /* Calculate number of FAT sectors */
316c2c66affSColin Finck     /* ((BootSector.BytesPerSector * 2) / 3) FAT entries (12bit) fit into one sector */
317c2c66affSColin Finck     TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
318c2c66affSColin Finck     TmpVal2 = (((BootSector.BytesPerSector * 2) / 3) * BootSector.SectorsPerCluster) + BootSector.FATCount;
319c2c66affSColin Finck     TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
320c2c66affSColin Finck     BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
321c2c66affSColin Finck 
322c2c66affSColin Finck     DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors);
323c2c66affSColin Finck 
324c2c66affSColin Finck     /* Init context data */
325c2c66affSColin Finck     Context->TotalSectorCount =
326c2c66affSColin Finck         1 + (BootSector.FATSectors * 2) + RootDirSectors;
327c2c66affSColin Finck 
328c2c66affSColin Finck     if (!QuickFormat)
329c2c66affSColin Finck     {
330c2c66affSColin Finck         Context->TotalSectorCount += SectorCount;
331c2c66affSColin Finck 
332c2c66affSColin Finck         Status = FatWipeSectors(FileHandle,
333c2c66affSColin Finck                                 SectorCount,
334c2c66affSColin Finck                                 (ULONG)BootSector.SectorsPerCluster,
335c2c66affSColin Finck                                 (ULONG)BootSector.BytesPerSector,
336c2c66affSColin Finck                                 Context);
337c2c66affSColin Finck         if (!NT_SUCCESS(Status))
338c2c66affSColin Finck         {
339c2c66affSColin Finck             DPRINT("FatWipeSectors() failed with status 0x%.08x\n", Status);
340c2c66affSColin Finck             return Status;
341c2c66affSColin Finck         }
342c2c66affSColin Finck     }
343c2c66affSColin Finck 
344c2c66affSColin Finck     Status = Fat12WriteBootSector(FileHandle,
345c2c66affSColin Finck                                   &BootSector,
346c2c66affSColin Finck                                   Context);
347c2c66affSColin Finck     if (!NT_SUCCESS(Status))
348c2c66affSColin Finck     {
349c2c66affSColin Finck         DPRINT("Fat12WriteBootSector() failed with status 0x%.08x\n", Status);
350c2c66affSColin Finck         return Status;
351c2c66affSColin Finck     }
352c2c66affSColin Finck 
353c2c66affSColin Finck     /* Write first FAT copy */
354c2c66affSColin Finck     Status = Fat12WriteFAT(FileHandle,
355c2c66affSColin Finck                            0,
356c2c66affSColin Finck                            &BootSector,
357c2c66affSColin Finck                            Context);
358c2c66affSColin Finck     if (!NT_SUCCESS(Status))
359c2c66affSColin Finck     {
360c2c66affSColin Finck         DPRINT("Fat12WriteFAT() failed with status 0x%.08x\n", Status);
361c2c66affSColin Finck         return Status;
362c2c66affSColin Finck     }
363c2c66affSColin Finck 
364c2c66affSColin Finck     /* Write second FAT copy */
365c2c66affSColin Finck     Status = Fat12WriteFAT(FileHandle,
366c2c66affSColin Finck                            (ULONG)BootSector.FATSectors,
367c2c66affSColin Finck                            &BootSector,
368c2c66affSColin Finck                            Context);
369c2c66affSColin Finck     if (!NT_SUCCESS(Status))
370c2c66affSColin Finck     {
371c2c66affSColin Finck         DPRINT("Fat12WriteFAT() failed with status 0x%.08x.\n", Status);
372c2c66affSColin Finck         return Status;
373c2c66affSColin Finck     }
374c2c66affSColin Finck 
375c2c66affSColin Finck     Status = Fat12WriteRootDirectory(FileHandle,
376c2c66affSColin Finck                                      &BootSector,
377c2c66affSColin Finck                                      Context);
378c2c66affSColin Finck     if (!NT_SUCCESS(Status))
379c2c66affSColin Finck     {
380c2c66affSColin Finck         DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
381c2c66affSColin Finck     }
382c2c66affSColin Finck 
383c2c66affSColin Finck     return Status;
384c2c66affSColin Finck }
385