- Added vfatxlib.
Added: trunk/reactos/include/fslib/vfatxlib.h
Added: trunk/reactos/lib/fslib/vfatxlib/
Added: trunk/reactos/lib/fslib/vfatxlib/Makefile
Added: trunk/reactos/lib/fslib/vfatxlib/fatx.c
Added: trunk/reactos/lib/fslib/vfatxlib/vfatxlib.c
Added: trunk/reactos/lib/fslib/vfatxlib/vfatxlib.h

Added: trunk/reactos/include/fslib/vfatxlib.h
--- trunk/reactos/include/fslib/vfatxlib.h	2005-01-25 21:16:19 UTC (rev 13285)
+++ trunk/reactos/include/fslib/vfatxlib.h	2005-01-25 22:10:39 UTC (rev 13286)
@@ -0,0 +1,24 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS VFAT filesystem library
+ * FILE:        include/fslib/vfatlib.h
+ * PURPOSE:     Public definitions for vfat filesystem library
+ */
+#ifndef __VFATXLIB_H
+#define __VFATXLIB_H
+
+#include <fmifs.h>
+
+NTSTATUS
+VfatxInitialize (VOID);
+
+NTSTATUS
+VfatxCleanup (VOID);
+
+NTSTATUS
+VfatxFormat (PUNICODE_STRING DriveRoot,
+	    ULONG MediaFlag,
+	    BOOLEAN QuickFormat,
+	    PFMIFSCALLBACK Callback);
+
+#endif /*__VFATLIB_H */

Added: trunk/reactos/lib/fslib/vfatxlib/Makefile
--- trunk/reactos/lib/fslib/vfatxlib/Makefile	2005-01-25 21:16:19 UTC (rev 13285)
+++ trunk/reactos/lib/fslib/vfatxlib/Makefile	2005-01-25 22:10:39 UTC (rev 13286)
@@ -0,0 +1,18 @@
+# $Id$
+
+PATH_TO_TOP = ../../..
+
+TARGET_TYPE = library
+
+TARGET_NAME = vfatxlib
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall -Werror
+
+TARGET_OBJECTS = \
+ fatx.o \
+ vfatxlib.o
+ 
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk

Added: trunk/reactos/lib/fslib/vfatxlib/fatx.c
--- trunk/reactos/lib/fslib/vfatxlib/fatx.c	2005-01-25 21:16:19 UTC (rev 13285)
+++ trunk/reactos/lib/fslib/vfatxlib/fatx.c	2005-01-25 22:10:39 UTC (rev 13286)
@@ -0,0 +1,431 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS VFATX filesystem library
+ * FILE:        fatx.c
+ * PURPOSE:     Fatx support
+ * PROGRAMMERS: Hartmut Birr
+ * REVISIONS:
+ */
+#define NDEBUG
+#include <debug.h>
+#define NTOS_MODE_USER
+#include <ntos.h>
+#include <ddk/ntddscsi.h>
+#include <mem.h>
+#include "vfatxlib.h"
+
+
+static ULONG
+GetShiftCount(ULONG Value)
+{
+  ULONG i = 1;
+  while (Value > 0)
+    {
+      i++;
+      Value /= 2;
+    }
+  return i - 2;
+}
+
+
+static ULONG
+CalcVolumeSerialNumber(VOID)
+{
+  LARGE_INTEGER SystemTime;
+  TIME_FIELDS TimeFields;
+  ULONG Serial;
+  PUCHAR Buffer;
+
+  NtQuerySystemTime (&SystemTime);
+  RtlTimeToTimeFields (&SystemTime, &TimeFields);
+
+  Buffer = (PUCHAR)&Serial;
+  Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
+  Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
+  Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
+  Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
+
+  return Serial;
+}
+
+
+static NTSTATUS
+FatxWriteBootSector (IN HANDLE FileHandle,
+		     IN PFATX_BOOT_SECTOR BootSector,
+		     IN OUT PFORMAT_CONTEXT Context)
+{
+  IO_STATUS_BLOCK IoStatusBlock;
+  NTSTATUS Status;
+  PUCHAR NewBootSector;
+  LARGE_INTEGER FileOffset;
+
+  /* Allocate buffer for new bootsector */
+  NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
+    0,
+    sizeof(FATX_BOOT_SECTOR));
+  if (NewBootSector == NULL)
+    return(STATUS_INSUFFICIENT_RESOURCES);
+
+  /* Zero the new bootsector */
+  memset(NewBootSector, 0, sizeof(FATX_BOOT_SECTOR));
+
+  /* Copy FAT16 BPB to new bootsector */
+  memcpy(NewBootSector, BootSector, 18); /* FAT16 BPB length (up to (not including) Res2) */
+
+  /* Write sector 0 */
+  FileOffset.QuadPart = 0ULL;
+  Status = NtWriteFile(FileHandle,
+    NULL,
+    NULL,
+    NULL,
+    &IoStatusBlock,
+    NewBootSector,
+    sizeof(FATX_BOOT_SECTOR),
+    &FileOffset,
+    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+      RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
+      return Status;
+    }
+
+  UpdateProgress (Context, 1);
+
+  /* Free the new boot sector */
+  RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
+
+  return Status;
+}
+
+
+static NTSTATUS
+Fatx16WriteFAT (IN HANDLE FileHandle,
+	        IN ULONG SectorOffset,
+		IN ULONG FATSectors,
+	        IN OUT PFORMAT_CONTEXT Context)
+{
+  IO_STATUS_BLOCK IoStatusBlock;
+  NTSTATUS Status;
+  PUCHAR Buffer;
+  LARGE_INTEGER FileOffset;
+  ULONG i;
+  ULONG Sectors;
+
+  /* Allocate buffer */
+  Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
+    0,
+    32 * 1024);
+  if (Buffer == NULL)
+    return(STATUS_INSUFFICIENT_RESOURCES);
+
+  /* Zero the buffer */
+  memset(Buffer, 0, 32 * 1024);
+
+  /* FAT cluster 0 */
+  Buffer[0] = 0xf8; /* Media type */
+  Buffer[1] = 0xff;
+
+  /* FAT cluster 1 */
+  Buffer[2] = 0xff; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
+  Buffer[3] = 0xff;
+
+  /* Write first sector of the FAT */
+  FileOffset.QuadPart = (SectorOffset * 512) + sizeof(FATX_BOOT_SECTOR);
+  Status = NtWriteFile(FileHandle,
+    NULL,
+    NULL,
+    NULL,
+    &IoStatusBlock,
+    Buffer,
+    512,
+    &FileOffset,
+    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+      return(Status);
+    }
+
+  UpdateProgress (Context, 1);
+
+  /* Zero the begin of the buffer */
+  memset(Buffer, 0, 4);
+
+  /* Zero the rest of the FAT */
+  Sectors = 32 * 1024 / 512;
+  for (i = 1; i < FATSectors; i += Sectors)
+    {
+      /* Zero some sectors of the FAT */
+      FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR) ;
+      if ((FATSectors - i) <= Sectors)
+	{
+	  Sectors = FATSectors - i;
+	}
+
+      Status = NtWriteFile(FileHandle,
+        NULL,
+        NULL,
+        NULL,
+        &IoStatusBlock,
+        Buffer,
+        Sectors * 512,
+        &FileOffset,
+        NULL);
+      if (!NT_SUCCESS(Status))
+        {
+          DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+          RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+          return(Status);
+        }
+
+      UpdateProgress (Context, Sectors);
+    }
+
+  /* Free the buffer */
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+  return(Status);
+}
+
+static NTSTATUS
+Fatx32WriteFAT (IN HANDLE FileHandle,
+	        IN ULONG SectorOffset,
+	        IN ULONG FATSectors,
+	        IN OUT PFORMAT_CONTEXT Context)
+{
+  IO_STATUS_BLOCK IoStatusBlock;
+  NTSTATUS Status;
+  PUCHAR Buffer;
+  LARGE_INTEGER FileOffset;
+  ULONG i;
+  ULONG Sectors;
+
+  /* Allocate buffer */
+  Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
+    0,
+    64 * 1024);
+  if (Buffer == NULL)
+    return(STATUS_INSUFFICIENT_RESOURCES);
+
+  /* Zero the buffer */
+  memset(Buffer, 0, 64 * 1024);
+
+  /* FAT cluster 0 */
+  Buffer[0] = 0xf8; /* Media type */
+  Buffer[1] = 0xff;
+  Buffer[2] = 0xff;
+  Buffer[3] = 0x0f;
+  /* FAT cluster 1 */
+  Buffer[4] = 0xff; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
+  Buffer[5] = 0xff;
+  Buffer[6] = 0xff;
+  Buffer[7] = 0x0f;
+
+  /* Write first sector of the FAT */
+  FileOffset.QuadPart = (SectorOffset * 512) + sizeof(FATX_BOOT_SECTOR);
+  Status = NtWriteFile(FileHandle,
+    NULL,
+    NULL,
+    NULL,
+    &IoStatusBlock,
+    Buffer,
+    512,
+    &FileOffset,
+    NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+      RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+      return(Status);
+    }
+
+  UpdateProgress (Context, 1);
+
+  /* Zero the begin of the buffer */
+  memset(Buffer, 0, 8);
+
+  /* Zero the rest of the FAT */
+  Sectors = 64 * 1024 / 512;
+  for (i = 1; i < FATSectors; i += Sectors)
+    {
+      /* Zero some sectors of the FAT */
+      FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR);
+
+      if ((FATSectors - i) <= Sectors)
+        {
+          Sectors = FATSectors - i;
+        }
+
+      Status = NtWriteFile(FileHandle,
+        NULL,
+        NULL,
+        NULL,
+        &IoStatusBlock,
+        Buffer,
+        Sectors * 512,
+        &FileOffset,
+        NULL);
+      if (!NT_SUCCESS(Status))
+        {
+          DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+          RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+          return(Status);
+        }
+
+      UpdateProgress (Context, Sectors);
+    }
+
+  /* Free the buffer */
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+  return(Status);
+}
+
+static NTSTATUS
+FatxWriteRootDirectory (IN HANDLE FileHandle,
+			IN ULONG FATSectors,
+			IN OUT PFORMAT_CONTEXT Context)
+{
+  IO_STATUS_BLOCK IoStatusBlock;
+  NTSTATUS Status = STATUS_SUCCESS;
+  PUCHAR Buffer;
+  LARGE_INTEGER FileOffset;
+  ULONG FirstRootDirSector;
+  ULONG RootDirSectors;
+
+  /* Write cluster */
+  RootDirSectors = 256 * 64 / 512;
+  FirstRootDirSector = sizeof(FATX_BOOT_SECTOR) / 512 + FATSectors;
+
+  DPRINT("RootDirSectors = %lu\n", RootDirSectors);
+  DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
+
+  /* Allocate buffer for the cluster */
+  Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
+    0,
+    RootDirSectors * 512);
+  if (Buffer == NULL)
+    return(STATUS_INSUFFICIENT_RESOURCES);
+
+  /* Zero the buffer */
+  memset(Buffer, 0xff, RootDirSectors * 512);
+
+  /* Zero some sectors of the root directory */
+  FileOffset.QuadPart = FirstRootDirSector * 512;
+
+  Status = NtWriteFile(FileHandle,
+	     NULL,
+	     NULL,
+	     NULL,
+	     &IoStatusBlock,
+	     Buffer,
+	     RootDirSectors * 512,
+	     &FileOffset,
+	     NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
+    }
+
+  /* Free the buffer */
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+  return(Status);
+}
+
+
+NTSTATUS
+FatxFormat (HANDLE FileHandle,
+	    PPARTITION_INFORMATION PartitionInfo,
+	    PDISK_GEOMETRY DiskGeometry,
+	    BOOLEAN QuickFormat,
+	    PFORMAT_CONTEXT Context)
+{
+  FATX_BOOT_SECTOR BootSector;
+  ULONGLONG SectorCount;
+  ULONG ClusterCount;
+  ULONG RootDirSectors;
+  ULONG FATSectors;
+
+  NTSTATUS Status;
+
+  SectorCount = PartitionInfo->PartitionLength.QuadPart >> GetShiftCount(512); /* Use shifting to avoid 64-bit division */
+  
+  memset(&BootSector, 0, sizeof(FATX_BOOT_SECTOR));
+  memcpy(&BootSector.SysType[0], "FATX", 4);
+  BootSector.SectorsPerCluster = 32;
+  BootSector.FATCount = 1;
+  BootSector.VolumeID = CalcVolumeSerialNumber();
+  RootDirSectors = 256 * 64 / 512;
+
+  /* Calculate number of FAT sectors */
+  ClusterCount = SectorCount >> GetShiftCount(32);
+
+  if (ClusterCount > 65525)
+  {
+     FATSectors = (((ClusterCount * 4) + 4095) & ~4095) >> GetShiftCount(512);
+  }
+  else
+  {
+     FATSectors = (((ClusterCount * 2) + 4095) & ~4095) >> GetShiftCount(512);
+  }
+  DPRINT("FATSectors = %hu\n", FATSectors);
+
+  /* Init context data */
+  if (QuickFormat)
+    {
+      Context->TotalSectorCount =
+	1 + FATSectors + RootDirSectors;
+    }
+  else
+    {
+      Context->TotalSectorCount = SectorCount;
+    }
+
+  Status = FatxWriteBootSector (FileHandle,
+				&BootSector,
+				Context);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("FatxWriteBootSector() failed with status 0x%.08x\n", Status);
+      return Status;
+    }
+
+  /* Write first FAT copy */
+  if (ClusterCount > 65525)
+  {
+     Status = Fatx32WriteFAT (FileHandle,
+			      0,
+			      FATSectors,
+			      Context);
+  }
+  else
+  {
+     Status = Fatx16WriteFAT (FileHandle,
+			      0,
+			      FATSectors,
+			      Context);
+  }
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("FatxWriteFAT() failed with status 0x%.08x\n", Status);
+      return Status;
+    }
+
+  Status = FatxWriteRootDirectory (FileHandle,
+				   FATSectors,
+				   Context);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("FatxWriteRootDirectory() failed with status 0x%.08x\n", Status);
+    }
+
+  if (!QuickFormat)
+    {
+      /* FIXME: Fill remaining sectors */
+    }
+
+  return Status;
+}

Added: trunk/reactos/lib/fslib/vfatxlib/vfatxlib.c
--- trunk/reactos/lib/fslib/vfatxlib/vfatxlib.c	2005-01-25 21:16:19 UTC (rev 13285)
+++ trunk/reactos/lib/fslib/vfatxlib/vfatxlib.c	2005-01-25 22:10:39 UTC (rev 13286)
@@ -0,0 +1,198 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS VFATx filesystem library
+ * FILE:        vfatxlib.c
+ * PURPOSE:     Main API
+ * PROGRAMMERS: Hartmut Birr
+ * REVISIONS:
+ *   CSH 05/04-2003 Created
+ */
+#define NTOS_MODE_USER
+#include <ntos.h>
+#include <ddk/ntddscsi.h>
+#include <fslib/vfatxlib.h>
+#include "vfatxlib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+NTSTATUS
+VfatxInitialize(VOID)
+{
+  DPRINT("VfatxInitialize()\n");
+
+  return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+VfatxFormat (PUNICODE_STRING DriveRoot,
+	    ULONG MediaFlag,
+	    BOOLEAN QuickFormat,
+	    PFMIFSCALLBACK Callback)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  DISK_GEOMETRY DiskGeometry;
+  IO_STATUS_BLOCK Iosb;
+  HANDLE FileHandle;
+  PARTITION_INFORMATION PartitionInfo;
+  FORMAT_CONTEXT Context;
+  NTSTATUS Status;
+
+  DPRINT("VfatxFormat(DriveRoot '%wZ')\n", DriveRoot);
+
+  Context.TotalSectorCount = 0;
+  Context.CurrentSectorCount = 0;
+  Context.Callback = Callback;
+  Context.Success = FALSE;
+  Context.Percent = 0;
+
+  InitializeObjectAttributes(&ObjectAttributes,
+    DriveRoot,
+    0,
+    NULL,
+    NULL);
+
+  Status = NtOpenFile(&FileHandle,
+    FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
+    &ObjectAttributes,
+    &Iosb,
+    FILE_SHARE_READ,
+    FILE_SYNCHRONOUS_IO_ALERT);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status);
+      return Status;
+    }
+
+  Status = NtDeviceIoControlFile(FileHandle,
+    NULL,
+    NULL,
+    NULL,
+    &Iosb,
+    IOCTL_DISK_GET_DRIVE_GEOMETRY,
+    NULL,
+    0,
+    &DiskGeometry,
+    sizeof(DISK_GEOMETRY));
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
+      NtClose(FileHandle);
+      return Status;
+    }
+
+  if (DiskGeometry.MediaType == FixedMedia)
+    {
+      DPRINT("Cylinders %I64d\n", DiskGeometry.Cylinders.QuadPart);
+      DPRINT("TracksPerCylinder %ld\n", DiskGeometry.TracksPerCylinder);
+      DPRINT("SectorsPerTrack %ld\n", DiskGeometry.SectorsPerTrack);
+      DPRINT("BytesPerSector %ld\n", DiskGeometry.BytesPerSector);
+      DPRINT("DiskSize %I64d\n",
+        DiskGeometry.Cylinders.QuadPart *
+        (ULONGLONG)DiskGeometry.TracksPerCylinder *
+        (ULONGLONG)DiskGeometry.SectorsPerTrack *
+        (ULONGLONG)DiskGeometry.BytesPerSector);
+
+      Status = NtDeviceIoControlFile(FileHandle,
+        NULL,
+        NULL,
+        NULL,
+        &Iosb,
+        IOCTL_DISK_GET_PARTITION_INFO,
+        NULL,
+        0,
+        &PartitionInfo,
+        sizeof(PARTITION_INFORMATION));
+      if (!NT_SUCCESS(Status))
+        {
+          DPRINT("IOCTL_DISK_GET_PARTITION_INFO failed with status 0x%.08x\n", Status);
+          NtClose(FileHandle);
+          return Status;
+        }
+
+      /*
+       * FIXME: This is a hack!
+       *        Partitioning software MUST set the correct number of hidden sectors!
+       */
+      PartitionInfo.HiddenSectors = DiskGeometry.SectorsPerTrack;
+    }
+  else
+    {
+      PartitionInfo.PartitionType = 0;
+      PartitionInfo.StartingOffset.QuadPart = 0ULL;
+      PartitionInfo.PartitionLength.QuadPart =
+	DiskGeometry.Cylinders.QuadPart *
+	(ULONGLONG)DiskGeometry.TracksPerCylinder *
+	(ULONGLONG)DiskGeometry.SectorsPerTrack *
+	(ULONGLONG)DiskGeometry.BytesPerSector;
+      PartitionInfo.HiddenSectors = 0;
+      PartitionInfo.PartitionNumber = 0;
+      PartitionInfo.BootIndicator = FALSE;
+      PartitionInfo.RewritePartition = FALSE;
+      PartitionInfo.RecognizedPartition = FALSE;
+    }
+
+  DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
+  DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset.QuadPart);
+  DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength.QuadPart);
+  DPRINT("HiddenSectors %lu\n", PartitionInfo.HiddenSectors);
+  DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
+  DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
+  DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
+  DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
+
+  if (Callback != NULL)
+    {
+      Context.Percent = 0;
+      Callback (PROGRESS, 0, (PVOID)&Context.Percent);
+    }
+
+  Status = FatxFormat (FileHandle,
+		       &PartitionInfo,
+		       &DiskGeometry,
+		       QuickFormat,
+		       &Context);
+  NtClose(FileHandle);
+
+  if (Callback != NULL)
+    {
+      Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
+      Callback (DONE, 0, (PVOID)&Context.Success);
+    }
+
+  DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
+
+  return Status;
+}
+
+
+NTSTATUS
+VfatxCleanup(VOID)
+{
+  DPRINT("VfatxCleanup()\n");
+
+  return STATUS_SUCCESS;
+}
+
+
+VOID
+VfatxUpdateProgress (PFORMAT_CONTEXT Context,
+		     ULONG Increment)
+{
+  ULONG NewPercent;
+
+  Context->CurrentSectorCount += (ULONGLONG)Increment;
+
+
+  NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
+
+  if (NewPercent > Context->Percent)
+    {
+      Context->Percent = NewPercent;
+      Context->Callback (PROGRESS, 0, &Context->Percent);
+    }
+}
+
+/* EOF */

Added: trunk/reactos/lib/fslib/vfatxlib/vfatxlib.h
--- trunk/reactos/lib/fslib/vfatxlib/vfatxlib.h	2005-01-25 21:16:19 UTC (rev 13285)
+++ trunk/reactos/lib/fslib/vfatxlib/vfatxlib.h	2005-01-25 22:10:39 UTC (rev 13286)
@@ -0,0 +1,45 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS VFAT filesystem library
+ * FILE:        vfatxlib.h
+ */
+#define NDEBUG
+#include <debug.h>
+#define NTOS_MODE_USER
+#include <ntos.h>
+#include <fslib/vfatlib.h>
+
+typedef struct _FATX_BOOT_SECTOR
+{
+   unsigned char SysType[4];        // 0
+   unsigned long VolumeID;          // 4
+   unsigned long SectorsPerCluster; // 8
+   unsigned short FATCount;         // 12
+   unsigned long Unknown;           // 14
+   unsigned char Unused[4078];      // 18
+} __attribute__((packed)) FATX_BOOT_SECTOR, *PFATX_BOOT_SECTOR;
+
+
+typedef struct _FORMAT_CONTEXT
+{
+  PFMIFSCALLBACK Callback;
+  ULONG TotalSectorCount;
+  ULONG CurrentSectorCount;
+  BOOLEAN Success;
+  ULONG Percent;
+} FORMAT_CONTEXT, *PFORMAT_CONTEXT;
+
+
+
+NTSTATUS
+FatxFormat (HANDLE FileHandle,
+	    PPARTITION_INFORMATION PartitionInfo,
+	    PDISK_GEOMETRY DiskGeometry,
+	    BOOLEAN QuickFormat,
+	    PFORMAT_CONTEXT Context);
+
+VOID
+UpdateProgress (PFORMAT_CONTEXT Context,
+		ULONG Increment);
+
+/* EOF */