[VFATLIB]

- Gather common code in one file instead of duplicating it everywhere.
- Implement full format for FAT12 and FAT16 (using the same function Fat1216WipeSectors), based on similar code for FAT32 implemented by Eric Kohl in revision 63693.

svn path=/trunk/; revision=70433
This commit is contained in:
Hermès Bélusca-Maïto 2015-12-27 00:57:51 +00:00
parent ccda8278da
commit c266fd3fb0
8 changed files with 214 additions and 126 deletions

View file

@ -7,6 +7,7 @@ list(APPEND SOURCE
check/file.c
check/io.c
check/lfn.c
common.c
fat12.c
fat16.c
fat32.c

View file

@ -0,0 +1,136 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS VFAT filesystem library
* FILE: lib\fslib\vfatlib\common.c
* PURPOSE: Common code for Fat support
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Eric Kohl
*/
/* INCLUDES *******************************************************************/
#include "vfatlib.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
ULONG
GetShiftCount(IN ULONG Value)
{
ULONG i = 1;
while (Value > 0)
{
i++;
Value /= 2;
}
return i - 2;
}
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;
}
/***** Wipe function for FAT12 and FAT16 formats, adapted from FAT32 code *****/
NTSTATUS
Fat1216WipeSectors(
IN HANDLE FileHandle,
IN PFAT16_BOOT_SECTOR BootSector,
IN OUT PFORMAT_CONTEXT Context)
{
IO_STATUS_BLOCK IoStatusBlock;
PUCHAR Buffer;
LARGE_INTEGER FileOffset;
ULONGLONG Sector;
ULONG SectorsHuge;
ULONG Length;
NTSTATUS Status;
/* Allocate buffer for the cluster */
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
BootSector->SectorsPerCluster * BootSector->BytesPerSector);
if (Buffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Sector = 0;
Length = BootSector->SectorsPerCluster * BootSector->BytesPerSector;
SectorsHuge = (BootSector->SectorsHuge != 0 ? BootSector->SectorsHuge : BootSector->Sectors);
while (Sector + BootSector->SectorsPerCluster < SectorsHuge)
{
FileOffset.QuadPart = Sector * BootSector->BytesPerSector;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
Length,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
goto done;
}
UpdateProgress(Context, (ULONG)BootSector->SectorsPerCluster);
Sector += BootSector->SectorsPerCluster;
}
if (Sector + BootSector->SectorsPerCluster > SectorsHuge)
{
DPRINT("Remaining sectors %lu\n", SectorsHuge - Sector);
FileOffset.QuadPart = Sector * BootSector->BytesPerSector;
Length = (SectorsHuge - Sector) * BootSector->BytesPerSector;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
Length,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
goto done;
}
UpdateProgress(Context, SectorsHuge - Sector);
}
done:
/* Free the buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return Status;
}
/* EOF */

View file

@ -0,0 +1,24 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS VFAT filesystem library
* FILE: lib\fslib\vfatlib\common.h
* PURPOSE: Common code for Fat support
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Eric Kohl
*/
#ifndef _VFATCOMMON_H_
#define _VFATCOMMON_H_
ULONG GetShiftCount(IN ULONG Value);
ULONG CalcVolumeSerialNumber(VOID);
NTSTATUS
Fat1216WipeSectors(
IN HANDLE FileHandle,
IN PFAT16_BOOT_SECTOR BootSector,
IN OUT PFORMAT_CONTEXT Context);
#endif /* _VFATCOMMON_H_ */
/* EOF */

View file

@ -5,49 +5,17 @@
* PURPOSE: Fat12 support
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Eric Kohl
* REVISIONS:
* EK 05/04-2003 Created
*/
/* INCLUDES *******************************************************************/
#include "vfatlib.h"
#define NDEBUG
#include <debug.h>
static ULONG
GetShiftCount(IN 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;
}
/* FUNCTIONS ******************************************************************/
static NTSTATUS
Fat12WriteBootSector(IN HANDLE FileHandle,
@ -323,7 +291,7 @@ Fat12Format(IN HANDLE FileHandle,
BootSector.Heads = DiskGeometry->TracksPerCylinder;
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
BootSector.Drive = DiskGeometry->MediaType == FixedMedia ? 0x80 : 0x00;
BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
BootSector.ExtBootSignature = 0x29;
BootSector.VolumeID = CalcVolumeSerialNumber();
if ((Label == NULL) || (Label->Buffer == NULL))
@ -357,6 +325,20 @@ Fat12Format(IN HANDLE FileHandle,
Context->TotalSectorCount =
1 + (BootSector.FATSectors * 2) + RootDirSectors;
if (!QuickFormat)
{
Context->TotalSectorCount += SectorCount;
Status = Fat1216WipeSectors(FileHandle,
&BootSector,
Context);
if (!NT_SUCCESS(Status))
{
DPRINT("Fat12WipeSectors() failed with status 0x%.08x\n", Status);
return Status;
}
}
Status = Fat12WriteBootSector(FileHandle,
&BootSector,
Context);
@ -396,10 +378,5 @@ Fat12Format(IN HANDLE FileHandle,
DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
}
if (!QuickFormat)
{
/* FIXME: Fill remaining sectors */
}
return Status;
}

View file

@ -5,49 +5,17 @@
* PURPOSE: Fat16 support
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Eric Kohl
* REVISIONS:
* EK 05/04-2003 Created
*/
/* INCLUDES *******************************************************************/
#include "vfatlib.h"
#define NDEBUG
#include <debug.h>
static ULONG
GetShiftCount(IN 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;
}
/* FUNCTIONS ******************************************************************/
static NTSTATUS
Fat16WriteBootSector(IN HANDLE FileHandle,
@ -330,7 +298,7 @@ Fat16Format(IN HANDLE FileHandle,
BootSector.Heads = DiskGeometry->TracksPerCylinder;
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
BootSector.Drive = DiskGeometry->MediaType == FixedMedia ? 0x80 : 0x00;
BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
BootSector.ExtBootSignature = 0x29;
BootSector.VolumeID = CalcVolumeSerialNumber();
if ((Label == NULL) || (Label->Buffer == NULL))
@ -365,6 +333,20 @@ Fat16Format(IN HANDLE FileHandle,
Context->TotalSectorCount =
1 + (BootSector.FATSectors * 2) + RootDirSectors;
if (!QuickFormat)
{
Context->TotalSectorCount += SectorCount;
Status = Fat1216WipeSectors(FileHandle,
&BootSector,
Context);
if (!NT_SUCCESS(Status))
{
DPRINT("Fat16WipeSectors() failed with status 0x%.08x\n", Status);
return Status;
}
}
Status = Fat16WriteBootSector(FileHandle,
&BootSector,
Context);
@ -404,10 +386,5 @@ Fat16Format(IN HANDLE FileHandle,
DPRINT("Fat16WriteRootDirectory() failed with status 0x%.08x\n", Status);
}
if (!QuickFormat)
{
/* FIXME: Fill remaining sectors */
}
return Status;
}

View file

@ -5,49 +5,17 @@
* PURPOSE: Fat32 support
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Eric Kohl
* REVISIONS:
* EK 05/04-2003 Created
*/
/* INCLUDES *******************************************************************/
#include "vfatlib.h"
#define NDEBUG
#include <debug.h>
static ULONG
GetShiftCount(IN 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;
}
/* FUNCTIONS ******************************************************************/
static NTSTATUS
Fat32WriteBootSector(IN HANDLE FileHandle,
@ -490,7 +458,7 @@ Fat32Format(IN HANDLE FileHandle,
BootSector.BootBackup = 6;
BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
BootSector.ExtBootSignature = 0x29;
BootSector.VolumeID = CalcVolumeSerialNumber ();
BootSector.VolumeID = CalcVolumeSerialNumber();
if ((Label == NULL) || (Label->Buffer == NULL))
{
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);

View file

@ -4,14 +4,18 @@
* FILE: lib\fslib\vfatlib\vfatlib.c
* PURPOSE: Main API
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 05/04-2003 Created
*/
/* INCLUDES *******************************************************************/
#include "vfatlib.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS & FUNCTIONS ********************************************************/
PFMIFSCALLBACK ChkdskCallback = NULL;
PVOID FsCheckMemQueue;
ULONG FsCheckFlags;
@ -282,7 +286,7 @@ VfatFormat(IN PUNICODE_STRING DriveRoot,
if (Callback != NULL)
{
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
Callback (DONE, 0, (PVOID)&Context.Success);
Callback(DONE, 0, (PVOID)&Context.Success);
}
DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
@ -307,7 +311,7 @@ UpdateProgress(PFORMAT_CONTEXT Context,
Context->Percent = NewPercent;
if (Context->Callback != NULL)
{
Context->Callback (PROGRESS, 0, &Context->Percent);
Context->Callback(PROGRESS, 0, &Context->Percent);
}
}
}

View file

@ -57,7 +57,6 @@ typedef struct _FAT16_BOOT_SECTOR
unsigned long Signature1; // 508
} FAT16_BOOT_SECTOR, *PFAT16_BOOT_SECTOR;
typedef struct _FAT32_BOOT_SECTOR
{
unsigned char magic0; // 0
@ -114,6 +113,8 @@ typedef struct _FORMAT_CONTEXT
ULONG Percent;
} FORMAT_CONTEXT, *PFORMAT_CONTEXT;
#include "common.h"
NTSTATUS
Fat12Format(HANDLE FileHandle,