ReactOS  0.4.14-dev-115-g4576127
fat32.c File Reference
#include "vfatlib.h"
#include <debug.h>
Include dependency graph for fat32.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS Fat32WriteBootSector (IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
 
static NTSTATUS Fat32WriteFsInfo (IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
 
static NTSTATUS Fat32WriteFAT (IN HANDLE FileHandle, IN ULONG SectorOffset, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
 
static NTSTATUS Fat32WriteRootDirectory (IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
 
NTSTATUS Fat32Format (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)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file fat32.c.

Function Documentation

◆ Fat32Format()

NTSTATUS Fat32Format ( 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 
)

Definition at line 386 of file fat32.c.

393 {
395  OEM_STRING VolumeLabel;
396  ULONG TmpVal1;
397  ULONG TmpVal2;
399  ULONG UsableFatEntries;
400  ULONG FirstDataSector;
401  ULONG DataClusters;
402 
403  /* Calculate cluster size */
404  if (ClusterSize == 0)
405  {
406  if (PartitionInfo->PartitionLength.QuadPart < 8LL * 1024LL * 1024LL * 1024LL)
407  {
408  /* Partition < 8GB ==> 4KB Cluster */
409  ClusterSize = 4096;
410  }
411  else if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL * 1024LL)
412  {
413  /* Partition 8GB - 16GB ==> 8KB Cluster */
414  ClusterSize = 8192;
415  }
416  else if (PartitionInfo->PartitionLength.QuadPart < 32LL * 1024LL * 1024LL * 1024LL)
417  {
418  /* Partition 16GB - 32GB ==> 16KB Cluster */
419  ClusterSize = 16384;
420  }
421  else
422  {
423  /* Partition >= 32GB ==> 32KB Cluster */
424  ClusterSize = 32768;
425  }
426  }
427 
429  memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
430  /* FIXME: Add dummy bootloader for real */
431  BootSector.Jump[0] = 0xeb;
432  BootSector.Jump[1] = 0x58;
433  BootSector.Jump[2] = 0x90;
434  BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
437  BootSector.FATCount = 2;
439  BootSector.Sectors = 0;
440  BootSector.Media = 0xf8;
441  BootSector.FATSectors = 0;
442  BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
443  BootSector.Heads = DiskGeometry->TracksPerCylinder;
444  BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
445  BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
446  GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
447  BootSector.FATSectors32 = 0; /* Set later */
448  BootSector.ExtFlag = 0; /* Mirror all FATs */
449  BootSector.FSVersion = 0x0000; /* 0:0 */
450  BootSector.RootCluster = 2;
451  BootSector.FSInfoSector = 1;
452  BootSector.BootBackup = 6;
453  BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
454  BootSector.ExtBootSignature = 0x29;
455  BootSector.VolumeID = CalcVolumeSerialNumber();
456  if ((Label == NULL) || (Label->Buffer == NULL))
457  {
458  memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
459  }
460  else
461  {
462  RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
463  RtlFillMemory(&BootSector.VolumeLabel[0], 11, ' ');
464  memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
465  VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
466  RtlFreeOemString(&VolumeLabel);
467  }
468 
469  memcpy(&BootSector.SysType[0], "FAT32 ", 8);
470 
471  /* Calculate number of FAT sectors */
472  /* (BytesPerSector / 4) FAT entries (32bit) fit into one sector */
473  TmpVal1 = BootSector.SectorsHuge - BootSector.ReservedSectors;
474  TmpVal2 = ((BootSector.BytesPerSector / 4) * BootSector.SectorsPerCluster) + BootSector.FATCount;
475  BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
476  DPRINT("FATSectors32 = %lu\n", BootSector.FATSectors32);
477 
478  /* edge case: first 2 fat entries are not usable, so the calculation might need a correction */
479  UsableFatEntries = BootSector.FATSectors32 * (BootSector.BytesPerSector / 4) - 2;
480  FirstDataSector = BootSector.ReservedSectors + BootSector.FATCount * BootSector.FATSectors32;
481  DataClusters = (BootSector.SectorsHuge - FirstDataSector) / BootSector.SectorsPerCluster;
482  if (DataClusters > UsableFatEntries)
483  {
484  /* Need more fat entries */
485  BootSector.FATSectors32 += (DataClusters - UsableFatEntries);
486 
487  DPRINT("UsableFatEntries = %lu\n", UsableFatEntries);
488  DPRINT("DataClusters = %lu\n", DataClusters);
489  DPRINT("BootSector.FATSectors32 incremented to %lu\n", BootSector.FATSectors32);
490  }
491 
492  /* Init context data */
493  Context->TotalSectorCount =
494  2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster;
495 
496  if (!QuickFormat)
497  {
498  Context->TotalSectorCount += BootSector.SectorsHuge;
499 
501  BootSector.SectorsHuge,
504  Context);
505  if (!NT_SUCCESS(Status))
506  {
507  DPRINT("FatWipeSectors() failed with status 0x%.08x\n", Status);
508  return Status;
509  }
510  }
511 
513  &BootSector,
514  Context);
515  if (!NT_SUCCESS(Status))
516  {
517  DPRINT("Fat32WriteBootSector() failed with status 0x%.08x\n", Status);
518  return Status;
519  }
520 
522  &BootSector,
523  Context);
524  if (!NT_SUCCESS(Status))
525  {
526  DPRINT("Fat32WriteFsInfo() failed with status 0x%.08x\n", Status);
527  return Status;
528  }
529 
530  /* Write first FAT copy */
532  0,
533  &BootSector,
534  Context);
535  if (!NT_SUCCESS(Status))
536  {
537  DPRINT("Fat32WriteFAT() failed with status 0x%.08x\n", Status);
538  return Status;
539  }
540 
541  /* Write second FAT copy */
543  BootSector.FATSectors32,
544  &BootSector,
545  Context);
546  if (!NT_SUCCESS(Status))
547  {
548  DPRINT("Fat32WriteFAT() failed with status 0x%.08x.\n", Status);
549  return Status;
550  }
551 
553  &BootSector,
554  Context);
555  if (!NT_SUCCESS(Status))
556  {
557  DPRINT("Fat32WriteRootDirectory() failed with status 0x%.08x\n", Status);
558  }
559 
560  return Status;
561 }
WORD SectorsPerTrack
Definition: fatfs.h:83
WORD BytesPerSector
Definition: fatfs.h:75
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:85
BYTE SectorsPerCluster
Definition: fatfs.h:76
WORD ReservedSectors
Definition: fatfs.h:77
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RtlFreeOemString(POEM_STRING OemString)
static NTSTATUS Fat32WriteFsInfo(IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
Definition: fat32.c:97
STRING OEM_STRING
Definition: umtypes.h:203
struct _BootSector BootSector
Definition: vfat.h:108
HANDLE FileHandle
Definition: stats.c:38
WORD RootEntries
Definition: fatfs.h:79
WORD Heads
Definition: fatfs.h:84
smooth NULL
Definition: ftsmooth.c:416
DWORD HiddenSectors
Definition: fatfs.h:85
void DPRINT(...)
Definition: polytest.cpp:61
BOOL QuickFormat
Definition: format.c:66
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD ClusterSize
Definition: format.c:67
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
NTSTATUS FatWipeSectors(IN HANDLE FileHandle, IN ULONG TotalSectors, IN ULONG SectorsPerCluster, IN ULONG BytesPerSector, IN OUT PFORMAT_CONTEXT Context)
Definition: common.c:56
ULONG GetShiftCount(IN ULONG Value)
Definition: common.c:21
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static NTSTATUS Fat32WriteBootSector(IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
Definition: fat32.c:21
Status
Definition: gdiplustypes.h:24
ULONG CalcVolumeSerialNumber(VOID)
Definition: common.c:35
static NTSTATUS Fat32WriteRootDirectory(IN HANDLE FileHandle, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
Definition: fat32.c:323
unsigned int ULONG
Definition: retypes.h:1
static NTSTATUS Fat32WriteFAT(IN HANDLE FileHandle, IN ULONG SectorOffset, IN PFAT32_BOOT_SECTOR BootSector, IN OUT PFORMAT_CONTEXT Context)
Definition: fat32.c:223
PWCHAR Label
Definition: format.c:70
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593

Referenced by VfatFormat().

◆ Fat32WriteBootSector()

static NTSTATUS Fat32WriteBootSector ( IN HANDLE  FileHandle,
IN PFAT32_BOOT_SECTOR  BootSector,
IN OUT PFORMAT_CONTEXT  Context 
)
static

Definition at line 21 of file fat32.c.

24 {
27  PFAT32_BOOT_SECTOR NewBootSector;
29 
30  /* Allocate buffer for new bootsector */
31  NewBootSector = (PFAT32_BOOT_SECTOR)RtlAllocateHeap(RtlGetProcessHeap(),
32  0,
34  if (NewBootSector == NULL)
36 
37  /* Zero the new bootsector */
38  RtlZeroMemory(NewBootSector, BootSector->BytesPerSector);
39 
40  /* Copy FAT32 BPB to new bootsector */
41  memcpy(NewBootSector, BootSector,
43  /* FAT32 BPB length (up to (not including) Res2) */
44 
45  /* Write the boot sector signature */
46  NewBootSector->Signature1 = 0xAA550000;
47 
48  /* Write sector 0 */
49  FileOffset.QuadPart = 0ULL;
51  NULL,
52  NULL,
53  NULL,
55  NewBootSector,
57  &FileOffset,
58  NULL);
59  if (!NT_SUCCESS(Status))
60  {
61  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
62  goto done;
63  }
64 
66 
67  /* Write backup boot sector */
68  if (BootSector->BootBackup != 0x0000)
69  {
70  FileOffset.QuadPart = (ULONGLONG)((ULONG)BootSector->BootBackup * BootSector->BytesPerSector);
72  NULL,
73  NULL,
74  NULL,
76  NewBootSector,
78  &FileOffset,
79  NULL);
80  if (!NT_SUCCESS(Status))
81  {
82  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
83  goto done;
84  }
85 
87  }
88 
89 done:
90  /* Free the buffer */
91  RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
92  return Status;
93 }
WORD BytesPerSector
Definition: fatfs.h:75
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
struct _FAT32_BOOT_SECTOR * PFAT32_BOOT_SECTOR
unsigned long Signature1
Definition: vfatlib.h:84
HANDLE FileHandle
Definition: stats.c:38
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define ULL(a, b)
Definition: format_msg.c:27
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
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)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID UpdateProgress(PFORMAT_CONTEXT Context, ULONG Increment)
Definition: vfatlib.c:322

Referenced by Fat32Format().

◆ Fat32WriteFAT()

static NTSTATUS Fat32WriteFAT ( IN HANDLE  FileHandle,
IN ULONG  SectorOffset,
IN PFAT32_BOOT_SECTOR  BootSector,
IN OUT PFORMAT_CONTEXT  Context 
)
static

Definition at line 223 of file fat32.c.

227 {
230  PUCHAR Buffer;
232  ULONG i;
233  ULONG Sectors;
234 
235  /* Allocate buffer */
236  Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
237  0,
238  64 * 1024);
239  if (Buffer == NULL)
241 
242  /* Zero the buffer */
243  RtlZeroMemory(Buffer, 64 * 1024);
244 
245  /* FAT cluster 0 */
246  Buffer[0] = 0xf8; /* Media type */
247  Buffer[1] = 0xff;
248  Buffer[2] = 0xff;
249  Buffer[3] = 0x0f;
250 
251  /* FAT cluster 1 */
252  Buffer[4] = 0xff; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
253  Buffer[5] = 0xff;
254  Buffer[6] = 0xff;
255  Buffer[7] = 0x0f;
256 
257  /* FAT cluster 2 */
258  Buffer[8] = 0xff; /* End of root directory */
259  Buffer[9] = 0xff;
260  Buffer[10] = 0xff;
261  Buffer[11] = 0x0f;
262 
263  /* Write first sector of the FAT */
266  NULL,
267  NULL,
268  NULL,
269  &IoStatusBlock,
270  Buffer,
272  &FileOffset,
273  NULL);
274  if (!NT_SUCCESS(Status))
275  {
276  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
277  goto done;
278  }
279 
281 
282  /* Zero the begin of the buffer */
283  RtlZeroMemory(Buffer, 12);
284 
285  /* Zero the rest of the FAT */
286  Sectors = 64 * 1024 / BootSector->BytesPerSector;
287  for (i = 1; i < BootSector->FATSectors32; i += Sectors)
288  {
289  /* Zero some sectors of the FAT */
291 
292  if ((BootSector->FATSectors32 - i) <= Sectors)
293  {
294  Sectors = BootSector->FATSectors32 - i;
295  }
296 
298  NULL,
299  NULL,
300  NULL,
301  &IoStatusBlock,
302  Buffer,
303  Sectors * BootSector->BytesPerSector,
304  &FileOffset,
305  NULL);
306  if (!NT_SUCCESS(Status))
307  {
308  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
309  goto done;
310  }
311 
312  UpdateProgress(Context, Sectors);
313  }
314 
315 done:
316  /* Free the buffer */
317  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
318  return Status;
319 }
WORD BytesPerSector
Definition: fatfs.h:75
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
unsigned char * PUCHAR
Definition: retypes.h:3
WORD ReservedSectors
Definition: fatfs.h:77
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE FileHandle
Definition: stats.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SectorOffset(L)
Definition: cdprocs.h:1632
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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)
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
VOID UpdateProgress(PFORMAT_CONTEXT Context, ULONG Increment)
Definition: vfatlib.c:322

Referenced by Fat32Format().

◆ Fat32WriteFsInfo()

static NTSTATUS Fat32WriteFsInfo ( IN HANDLE  FileHandle,
IN PFAT32_BOOT_SECTOR  BootSector,
IN OUT PFORMAT_CONTEXT  Context 
)
static

Definition at line 97 of file fat32.c.

100 {
103  PFAT32_FSINFO FsInfo;
105  ULONGLONG FirstDataSector;
106 
107  /* Allocate buffer for new sector */
108  FsInfo = (PFAT32_FSINFO)RtlAllocateHeap(RtlGetProcessHeap(),
109  0,
111  if (FsInfo == NULL)
113 
114  /* Zero the first FsInfo sector */
116 
117  FirstDataSector = BootSector->ReservedSectors +
118  (BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
119 
121  FsInfo->StrucSig = FSINFO_SIGNATURE;
122  FsInfo->FreeCount = (BootSector->SectorsHuge - FirstDataSector) / BootSector->SectorsPerCluster - 1;
123  FsInfo->NextFree = 0xffffffff;
125 
126  /* Write the first FsInfo sector */
127  FileOffset.QuadPart = BootSector->FSInfoSector * BootSector->BytesPerSector;
129  NULL,
130  NULL,
131  NULL,
132  &IoStatusBlock,
133  FsInfo,
135  &FileOffset,
136  NULL);
137  if (!NT_SUCCESS(Status))
138  {
139  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
140  goto done;
141  }
142 
144 
145  /* Write backup of the first FsInfo sector */
146  if (BootSector->BootBackup != 0x0000)
147  {
148  /* Reset the free cluster count for the backup */
149  FsInfo->FreeCount = 0xffffffff;
150 
151  FileOffset.QuadPart = (ULONGLONG)(((ULONG)BootSector->BootBackup + (ULONG)BootSector->FSInfoSector) * BootSector->BytesPerSector);
153  NULL,
154  NULL,
155  NULL,
156  &IoStatusBlock,
157  FsInfo,
159  &FileOffset,
160  NULL);
161  if (!NT_SUCCESS(Status))
162  {
163  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
164  goto done;
165  }
166 
168  }
169 
170  /* Zero the second FsInfo sector */
173 
174  /* Write the second FsInfo sector */
175  FileOffset.QuadPart = (BootSector->FSInfoSector + 1) * BootSector->BytesPerSector;
177  NULL,
178  NULL,
179  NULL,
180  &IoStatusBlock,
181  FsInfo,
183  &FileOffset,
184  NULL);
185  if (!NT_SUCCESS(Status))
186  {
187  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
188  goto done;
189  }
190 
192 
193  /* Write backup of the second FsInfo sector */
194  if (BootSector->BootBackup != 0x0000)
195  {
196  FileOffset.QuadPart = (ULONGLONG)(((ULONG)BootSector->BootBackup + (ULONG)BootSector->FSInfoSector + 1) * BootSector->BytesPerSector);
198  NULL,
199  NULL,
200  NULL,
201  &IoStatusBlock,
202  FsInfo,
204  &FileOffset,
205  NULL);
206  if (!NT_SUCCESS(Status))
207  {
208  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
209  goto done;
210  }
211 
213  }
214 
215 done:
216  /* Free the buffer */
217  RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
218  return Status;
219 }
WORD BytesPerSector
Definition: fatfs.h:75
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BYTE SectorsPerCluster
Definition: fatfs.h:76
unsigned long TrailSig
Definition: vfatlib.h:95
WORD ReservedSectors
Definition: fatfs.h:77
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE FileHandle
Definition: stats.c:38
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
unsigned long LeadSig
Definition: vfatlib.h:89
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
unsigned long NextFree
Definition: vfatlib.h:93
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)
struct _FAT32_FSINFO * PFAT32_FSINFO
#define FSINFO_SECTOR_BEGIN_SIGNATURE
Definition: fat.h:204
Status
Definition: gdiplustypes.h:24
unsigned long FreeCount
Definition: vfatlib.h:92
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FSINFO_SECTOR_END_SIGNATURE
Definition: fat.h:205
unsigned long StrucSig
Definition: vfatlib.h:91
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define FSINFO_SIGNATURE
Definition: fat.h:207
VOID UpdateProgress(PFORMAT_CONTEXT Context, ULONG Increment)
Definition: vfatlib.c:322

Referenced by Fat32Format().

◆ Fat32WriteRootDirectory()

static NTSTATUS Fat32WriteRootDirectory ( IN HANDLE  FileHandle,
IN PFAT32_BOOT_SECTOR  BootSector,
IN OUT PFORMAT_CONTEXT  Context 
)
static

Definition at line 323 of file fat32.c.

326 {
329  PUCHAR Buffer;
331  ULONGLONG FirstDataSector;
332  ULONGLONG FirstRootDirSector;
333 
334  /* Allocate buffer for the cluster */
335  Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
336  0,
338  if (Buffer == NULL)
340 
341  /* Zero the buffer */
343 
344  DPRINT("BootSector->ReservedSectors = %lu\n", BootSector->ReservedSectors);
345  DPRINT("BootSector->FATSectors32 = %lu\n", BootSector->FATSectors32);
346  DPRINT("BootSector->RootCluster = %lu\n", BootSector->RootCluster);
347  DPRINT("BootSector->SectorsPerCluster = %lu\n", BootSector->SectorsPerCluster);
348 
349  /* Write cluster */
350  FirstDataSector = BootSector->ReservedSectors +
351  (BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
352 
353  DPRINT("FirstDataSector = %lu\n", FirstDataSector);
354 
355  FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
356  FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
357 
358  DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
359  DPRINT("FileOffset = %lu\n", FileOffset.QuadPart);
360 
362  NULL,
363  NULL,
364  NULL,
365  &IoStatusBlock,
366  Buffer,
368  &FileOffset,
369  NULL);
370  if (!NT_SUCCESS(Status))
371  {
372  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
373  goto done;
374  }
375 
377 
378 done:
379  /* Free the buffer */
380  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
381  return Status;
382 }
WORD BytesPerSector
Definition: fatfs.h:75
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BYTE SectorsPerCluster
Definition: fatfs.h:76
unsigned char * PUCHAR
Definition: retypes.h:3
WORD ReservedSectors
Definition: fatfs.h:77
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE FileHandle
Definition: stats.c:38
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
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)
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
VOID UpdateProgress(PFORMAT_CONTEXT Context, ULONG Increment)
Definition: vfatlib.c:322

Referenced by Fat32Format().