mirror of
https://github.com/reactos/reactos.git
synced 2024-07-06 20:55:16 +00:00
Moved FAT32 code to a sepatate file.
Added hack for HiddenSectors value. This is needed to boot FreeLoader. svn path=/trunk/; revision=5752
This commit is contained in:
parent
b8eace220f
commit
c07929b227
|
@ -1,4 +1,4 @@
|
||||||
# $Id: Makefile,v 1.3 2003/08/21 15:33:48 ekohl Exp $
|
# $Id: Makefile,v 1.4 2003/08/22 13:53:02 ekohl Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../../..
|
PATH_TO_TOP = ../../..
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ TARGET_CFLAGS += -D_DISABLE_TIDENTS
|
||||||
|
|
||||||
TARGET_OBJECTS = \
|
TARGET_OBJECTS = \
|
||||||
fat16.o \
|
fat16.o \
|
||||||
|
fat32.o \
|
||||||
vfatlib.o
|
vfatlib.o
|
||||||
|
|
||||||
include $(PATH_TO_TOP)/rules.mak
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
|
@ -297,7 +297,7 @@ Fat16Format (HANDLE FileHandle,
|
||||||
BootSector.FATSectors = 0; /* Set later. See below. */
|
BootSector.FATSectors = 0; /* Set later. See below. */
|
||||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
BootSector.HiddenSectors = DiskGeometry->SectorsPerTrack; //PartitionInfo->HiddenSectors; /* FIXME: Hack! */
|
||||||
BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
|
BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
|
||||||
GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
|
GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||||
|
|
463
reactos/lib/fslib/vfatlib/fat32.c
Normal file
463
reactos/lib/fslib/vfatlib/fat32.c
Normal file
|
@ -0,0 +1,463 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS VFAT filesystem library
|
||||||
|
* FILE: fat16.c
|
||||||
|
* PURPOSE: Fat16 support
|
||||||
|
* PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
|
||||||
|
* REVISIONS:
|
||||||
|
* EK 05/04-2003 Created
|
||||||
|
*/
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
#define NTOS_MODE_USER
|
||||||
|
#include <ntos.h>
|
||||||
|
#include <ddk/ntddscsi.h>
|
||||||
|
#include "vfatlib.h"
|
||||||
|
|
||||||
|
|
||||||
|
static ULONG
|
||||||
|
GetShiftCount(ULONG Value)
|
||||||
|
{
|
||||||
|
ULONG i = 1;
|
||||||
|
while (Value > 0)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
Value /= 2;
|
||||||
|
}
|
||||||
|
return i - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
Fat32WriteBootSector(IN HANDLE FileHandle,
|
||||||
|
IN PFAT32_BOOT_SECTOR BootSector)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUCHAR NewBootSector;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
|
||||||
|
/* Allocate buffer for new bootsector */
|
||||||
|
NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
SECTORSIZE);
|
||||||
|
if (NewBootSector == NULL)
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
|
/* Zero the new bootsector */
|
||||||
|
memset(NewBootSector, 0, SECTORSIZE);
|
||||||
|
|
||||||
|
/* Copy FAT32 BPB to new bootsector */
|
||||||
|
memcpy((NewBootSector + 3),
|
||||||
|
&BootSector->OEMName[0],
|
||||||
|
87); /* FAT32 BPB length (up to (not including) Res2) */
|
||||||
|
|
||||||
|
/* Write sector 0 */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector,
|
||||||
|
SECTORSIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write backup boot sector */
|
||||||
|
if (BootSector->BootBackup != 0x0000)
|
||||||
|
{
|
||||||
|
FileOffset.QuadPart = (ULONGLONG)((ULONG) BootSector->BootBackup * SECTORSIZE);
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector,
|
||||||
|
SECTORSIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the new boot sector */
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
Fat32WriteFsInfo(IN HANDLE FileHandle,
|
||||||
|
IN PFAT32_BOOT_SECTOR BootSector)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PFAT32_FSINFO FsInfo;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
|
||||||
|
/* Allocate buffer for new sector */
|
||||||
|
FsInfo = (PFAT32_FSINFO)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
BootSector->BytesPerSector);
|
||||||
|
if (FsInfo == NULL)
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
|
/* Zero the new sector */
|
||||||
|
memset(FsInfo, 0, BootSector->BytesPerSector);
|
||||||
|
|
||||||
|
FsInfo->LeadSig = 0x41615252;
|
||||||
|
FsInfo->StrucSig = 0x61417272;
|
||||||
|
FsInfo->FreeCount = 0xffffffff;
|
||||||
|
FsInfo->NextFree = 0xffffffff;
|
||||||
|
FsInfo->TrailSig = 0xaa550000;
|
||||||
|
|
||||||
|
/* Write sector */
|
||||||
|
FileOffset.QuadPart = BootSector->FSInfoSector * BootSector->BytesPerSector;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FsInfo,
|
||||||
|
BootSector->BytesPerSector,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the new sector buffer */
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
Fat32WriteFAT(IN HANDLE FileHandle,
|
||||||
|
ULONG SectorOffset,
|
||||||
|
IN PFAT32_BOOT_SECTOR BootSector)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUCHAR Buffer;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
ULONG i;
|
||||||
|
ULONG Size;
|
||||||
|
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;
|
||||||
|
/* FAT cluster 2 */
|
||||||
|
Buffer[8] = 0xff; /* End of root directory */
|
||||||
|
Buffer[9] = 0xff;
|
||||||
|
Buffer[10] = 0xff;
|
||||||
|
Buffer[11] = 0x0f;
|
||||||
|
|
||||||
|
/* Write first sector of the FAT */
|
||||||
|
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Buffer,
|
||||||
|
BootSector->BytesPerSector,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero the begin of the buffer */
|
||||||
|
memset(Buffer, 0, 12);
|
||||||
|
|
||||||
|
/* Zero the rest of the FAT */
|
||||||
|
Sectors = 64 * 1024 / BootSector->BytesPerSector;
|
||||||
|
for (i = 1; i < BootSector->FATSectors32; i += Sectors)
|
||||||
|
{
|
||||||
|
/* Zero some sectors of the FAT */
|
||||||
|
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||||
|
Size = BootSector->FATSectors32 - i;
|
||||||
|
if (Size > Sectors)
|
||||||
|
{
|
||||||
|
Size = Sectors;
|
||||||
|
}
|
||||||
|
Size *= BootSector->BytesPerSector;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Buffer,
|
||||||
|
Size,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the buffer */
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
Fat32WriteRootDirectory(IN HANDLE FileHandle,
|
||||||
|
IN PFAT32_BOOT_SECTOR BootSector)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUCHAR Buffer;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
ULONGLONG FirstDataSector;
|
||||||
|
ULONGLONG FirstRootDirSector;
|
||||||
|
|
||||||
|
/* Allocate buffer for the cluster */
|
||||||
|
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
BootSector->SectorsPerCluster * BootSector->BytesPerSector);
|
||||||
|
if (Buffer == NULL)
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
|
/* Zero the buffer */
|
||||||
|
memset(Buffer, 0, BootSector->SectorsPerCluster * BootSector->BytesPerSector);
|
||||||
|
|
||||||
|
DPRINT("BootSector->ReservedSectors = %lu\n", BootSector->ReservedSectors);
|
||||||
|
DPRINT("BootSector->FATSectors32 = %lu\n", BootSector->FATSectors32);
|
||||||
|
DPRINT("BootSector->RootCluster = %lu\n", BootSector->RootCluster);
|
||||||
|
DPRINT("BootSector->SectorsPerCluster = %lu\n", BootSector->SectorsPerCluster);
|
||||||
|
|
||||||
|
/* Write cluster */
|
||||||
|
FirstDataSector = BootSector->ReservedSectors +
|
||||||
|
(BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
|
||||||
|
|
||||||
|
DPRINT("FirstDataSector = %lu\n", FirstDataSector);
|
||||||
|
|
||||||
|
FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
|
||||||
|
FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
|
||||||
|
|
||||||
|
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||||
|
DPRINT("FileOffset = %lu\n", FileOffset.QuadPart);
|
||||||
|
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Buffer,
|
||||||
|
BootSector->SectorsPerCluster * BootSector->BytesPerSector,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the buffer */
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Fat32Format (HANDLE FileHandle,
|
||||||
|
PPARTITION_INFORMATION PartitionInfo,
|
||||||
|
PDISK_GEOMETRY DiskGeometry,
|
||||||
|
PUNICODE_STRING Label,
|
||||||
|
BOOL QuickFormat,
|
||||||
|
DWORD ClusterSize,
|
||||||
|
PFMIFSCALLBACK Callback)
|
||||||
|
{
|
||||||
|
FAT32_BOOT_SECTOR BootSector;
|
||||||
|
ANSI_STRING VolumeLabel;
|
||||||
|
ULONG RootDirSectors;
|
||||||
|
ULONG TmpVal1;
|
||||||
|
ULONG TmpVal2;
|
||||||
|
ULONG TmpVal3;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Calculate cluster size */
|
||||||
|
if (ClusterSize == 0)
|
||||||
|
{
|
||||||
|
if (PartitionInfo->PartitionLength.QuadPart < 8ULL * 1024ULL * 1024ULL * 1024ULL)
|
||||||
|
{
|
||||||
|
/* Partition < 8GB ==> 4KB Cluster */
|
||||||
|
ClusterSize = 4096;
|
||||||
|
}
|
||||||
|
else if (PartitionInfo->PartitionLength.QuadPart < 16ULL * 1024ULL * 1024ULL * 1024ULL)
|
||||||
|
{
|
||||||
|
/* Partition 8GB - 16GB ==> 8KB Cluster */
|
||||||
|
ClusterSize = 8192;
|
||||||
|
}
|
||||||
|
else if (PartitionInfo->PartitionLength.QuadPart < 32ULL * 1024ULL * 1024ULL * 1024ULL)
|
||||||
|
{
|
||||||
|
/* Partition 16GB - 32GB ==> 16KB Cluster */
|
||||||
|
ClusterSize = 16384;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Partition >= 32GB ==> 32KB Cluster */
|
||||||
|
ClusterSize = 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&BootSector, 0, sizeof(FAT32_BOOT_SECTOR));
|
||||||
|
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
||||||
|
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
||||||
|
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
||||||
|
BootSector.ReservedSectors = 32;
|
||||||
|
BootSector.FATCount = 2;
|
||||||
|
BootSector.RootEntries = 0;
|
||||||
|
BootSector.Sectors = 0;
|
||||||
|
BootSector.Media = 0xf8;
|
||||||
|
BootSector.FATSectors = 0;
|
||||||
|
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||||
|
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||||
|
BootSector.HiddenSectors = DiskGeometry->SectorsPerTrack; //PartitionInfo->HiddenSectors; /* FIXME: Hack! */
|
||||||
|
BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
|
||||||
|
GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||||
|
BootSector.FATSectors32 = 0; /* Set later */
|
||||||
|
BootSector.ExtFlag = 0; /* Mirror all FATs */
|
||||||
|
BootSector.FSVersion = 0x0000; /* 0:0 */
|
||||||
|
BootSector.RootCluster = 2;
|
||||||
|
BootSector.FSInfoSector = 1;
|
||||||
|
BootSector.BootBackup = 6;
|
||||||
|
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||||
|
BootSector.ExtBootSignature = 0x29;
|
||||||
|
BootSector.VolumeID = 0x45768798; /* FIXME: */
|
||||||
|
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||||
|
{
|
||||||
|
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlUnicodeStringToAnsiString(&VolumeLabel, Label, TRUE);
|
||||||
|
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||||
|
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||||
|
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||||
|
RtlFreeAnsiString(&VolumeLabel);
|
||||||
|
}
|
||||||
|
memcpy(&BootSector.SysType[0], "FAT32 ", 8);
|
||||||
|
|
||||||
|
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||||
|
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||||
|
TmpVal1 = BootSector.SectorsHuge - (BootSector.ReservedSectors + RootDirSectors);
|
||||||
|
TmpVal2 = (256 * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||||
|
if (TRUE /* FAT32 */)
|
||||||
|
{
|
||||||
|
TmpVal2 = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (TmpVal2 == 0)
|
||||||
|
{
|
||||||
|
TmpVal3 = 0xffffffff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TmpVal3 = TmpVal2;
|
||||||
|
}
|
||||||
|
TmpVal2 = ((TmpVal1 - TmpVal2 * BootSector.FATCount) / BootSector.SectorsPerCluster) + 2;
|
||||||
|
TmpVal2 = (sizeof(ULONG) * TmpVal2 + BootSector.BytesPerSector - 1) / BootSector.BytesPerSector;
|
||||||
|
}
|
||||||
|
while (TmpVal3 > TmpVal2);
|
||||||
|
BootSector.FATSectors32 = TmpVal2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Fat32WriteBootSector(FileHandle,
|
||||||
|
&BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Fat32WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Fat32WriteFsInfo(FileHandle,
|
||||||
|
&BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Fat32WriteFsInfo() failed with status 0x%.08x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write first FAT copy */
|
||||||
|
Status = Fat32WriteFAT(FileHandle,
|
||||||
|
0,
|
||||||
|
&BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Fat32WriteFAT() failed with status 0x%.08x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write second FAT copy */
|
||||||
|
Status = Fat32WriteFAT(FileHandle,
|
||||||
|
BootSector.FATSectors32,
|
||||||
|
&BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Fat32WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Fat32WriteRootDirectory(FileHandle,
|
||||||
|
&BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Fat32WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
|
@ -16,456 +16,8 @@
|
||||||
#include "vfatlib.h"
|
#include "vfatlib.h"
|
||||||
|
|
||||||
|
|
||||||
static ULONG
|
|
||||||
GetShiftCount(ULONG Value)
|
|
||||||
{
|
|
||||||
ULONG i = 1;
|
|
||||||
while (Value > 0)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
Value /= 2;
|
|
||||||
}
|
|
||||||
return i - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
VfatWriteBootSector(IN HANDLE FileHandle,
|
|
||||||
IN PFAT32_BOOT_SECTOR BootSector)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PUCHAR NewBootSector;
|
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
|
|
||||||
/* Allocate buffer for new bootsector */
|
|
||||||
NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
0,
|
|
||||||
SECTORSIZE);
|
|
||||||
if (NewBootSector == NULL)
|
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
|
|
||||||
/* Zero the new bootsector */
|
|
||||||
memset(NewBootSector, 0, SECTORSIZE);
|
|
||||||
|
|
||||||
/* Copy FAT32 BPB to new bootsector */
|
|
||||||
memcpy((NewBootSector + 3),
|
|
||||||
&BootSector->OEMName[0],
|
|
||||||
87); /* FAT32 BPB length (up to (not including) Res2) */
|
|
||||||
|
|
||||||
/* Write sector 0 */
|
|
||||||
FileOffset.QuadPart = 0ULL;
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
NewBootSector,
|
|
||||||
SECTORSIZE,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write backup boot sector */
|
|
||||||
if (BootSector->BootBackup != 0x0000)
|
|
||||||
{
|
|
||||||
FileOffset.QuadPart = (ULONGLONG)((ULONG) BootSector->BootBackup * SECTORSIZE);
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
NewBootSector,
|
|
||||||
SECTORSIZE,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the new boot sector */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
VfatWriteFsInfo(IN HANDLE FileHandle,
|
|
||||||
IN PFAT32_BOOT_SECTOR BootSector)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PFAT32_FSINFO FsInfo;
|
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
|
|
||||||
/* Allocate buffer for new sector */
|
|
||||||
FsInfo = (PFAT32_FSINFO)RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
0,
|
|
||||||
BootSector->BytesPerSector);
|
|
||||||
if (FsInfo == NULL)
|
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
|
|
||||||
/* Zero the new sector */
|
|
||||||
memset(FsInfo, 0, BootSector->BytesPerSector);
|
|
||||||
|
|
||||||
FsInfo->LeadSig = 0x41615252;
|
|
||||||
FsInfo->StrucSig = 0x61417272;
|
|
||||||
FsInfo->FreeCount = 0xffffffff;
|
|
||||||
FsInfo->NextFree = 0xffffffff;
|
|
||||||
FsInfo->TrailSig = 0xaa550000;
|
|
||||||
|
|
||||||
/* Write sector */
|
|
||||||
FileOffset.QuadPart = BootSector->FSInfoSector * BootSector->BytesPerSector;
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
FsInfo,
|
|
||||||
BootSector->BytesPerSector,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the new sector buffer */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
VfatWriteFAT(IN HANDLE FileHandle,
|
|
||||||
ULONG SectorOffset,
|
|
||||||
IN PFAT32_BOOT_SECTOR BootSector)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PUCHAR Buffer;
|
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
ULONG i;
|
|
||||||
ULONG Size;
|
|
||||||
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;
|
|
||||||
/* FAT cluster 2 */
|
|
||||||
Buffer[8] = 0xff; /* End of root directory */
|
|
||||||
Buffer[9] = 0xff;
|
|
||||||
Buffer[10] = 0xff;
|
|
||||||
Buffer[11] = 0x0f;
|
|
||||||
|
|
||||||
/* Write first sector of the FAT */
|
|
||||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
Buffer,
|
|
||||||
BootSector->BytesPerSector,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero the begin of the buffer */
|
|
||||||
memset(Buffer, 0, 12);
|
|
||||||
|
|
||||||
/* Zero the rest of the FAT */
|
|
||||||
Sectors = 64 * 1024 / BootSector->BytesPerSector;
|
|
||||||
for (i = 1; i < BootSector->FATSectors32; i += Sectors)
|
|
||||||
{
|
|
||||||
/* Zero some sectors of the FAT */
|
|
||||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
|
||||||
Size = BootSector->FATSectors32 - i;
|
|
||||||
if (Size > Sectors)
|
|
||||||
{
|
|
||||||
Size = Sectors;
|
|
||||||
}
|
|
||||||
Size *= BootSector->BytesPerSector;
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
Buffer,
|
|
||||||
Size,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the buffer */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
VfatWriteRootDirectory(IN HANDLE FileHandle,
|
|
||||||
IN PFAT32_BOOT_SECTOR BootSector)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PUCHAR Buffer;
|
|
||||||
LARGE_INTEGER FileOffset;
|
|
||||||
ULONGLONG FirstDataSector;
|
|
||||||
ULONGLONG FirstRootDirSector;
|
|
||||||
|
|
||||||
/* Allocate buffer for the cluster */
|
|
||||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
0,
|
|
||||||
BootSector->SectorsPerCluster * BootSector->BytesPerSector);
|
|
||||||
if (Buffer == NULL)
|
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
|
|
||||||
/* Zero the buffer */
|
|
||||||
memset(Buffer, 0, BootSector->SectorsPerCluster * BootSector->BytesPerSector);
|
|
||||||
|
|
||||||
DPRINT("BootSector->ReservedSectors = %lu\n", BootSector->ReservedSectors);
|
|
||||||
DPRINT("BootSector->FATSectors32 = %lu\n", BootSector->FATSectors32);
|
|
||||||
DPRINT("BootSector->RootCluster = %lu\n", BootSector->RootCluster);
|
|
||||||
DPRINT("BootSector->SectorsPerCluster = %lu\n", BootSector->SectorsPerCluster);
|
|
||||||
|
|
||||||
/* Write cluster */
|
|
||||||
FirstDataSector = BootSector->ReservedSectors +
|
|
||||||
(BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
|
|
||||||
|
|
||||||
DPRINT("FirstDataSector = %lu\n", FirstDataSector);
|
|
||||||
|
|
||||||
FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
|
|
||||||
FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
|
|
||||||
|
|
||||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
|
||||||
DPRINT("FileOffset = %lu\n", FileOffset.QuadPart);
|
|
||||||
|
|
||||||
Status = NtWriteFile(FileHandle,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
Buffer,
|
|
||||||
BootSector->SectorsPerCluster * BootSector->BytesPerSector,
|
|
||||||
&FileOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the buffer */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
VfatFormatFat32 (HANDLE FileHandle,
|
|
||||||
PPARTITION_INFORMATION PartitionInfo,
|
|
||||||
PDISK_GEOMETRY DiskGeometry,
|
|
||||||
PUNICODE_STRING Label,
|
|
||||||
BOOL QuickFormat,
|
|
||||||
DWORD ClusterSize,
|
|
||||||
PFMIFSCALLBACK Callback)
|
|
||||||
{
|
|
||||||
FAT32_BOOT_SECTOR BootSector;
|
|
||||||
ANSI_STRING VolumeLabel;
|
|
||||||
ULONG RootDirSectors;
|
|
||||||
ULONG TmpVal1;
|
|
||||||
ULONG TmpVal2;
|
|
||||||
ULONG TmpVal3;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
/* Calculate cluster size */
|
|
||||||
if (ClusterSize == 0)
|
|
||||||
{
|
|
||||||
if (PartitionInfo->PartitionLength.QuadPart < 8ULL * 1024ULL * 1024ULL * 1024ULL)
|
|
||||||
{
|
|
||||||
/* Partition < 8GB ==> 4KB Cluster */
|
|
||||||
ClusterSize = 4096;
|
|
||||||
}
|
|
||||||
else if (PartitionInfo->PartitionLength.QuadPart < 16ULL * 1024ULL * 1024ULL * 1024ULL)
|
|
||||||
{
|
|
||||||
/* Partition 8GB - 16GB ==> 8KB Cluster */
|
|
||||||
ClusterSize = 8192;
|
|
||||||
}
|
|
||||||
else if (PartitionInfo->PartitionLength.QuadPart < 32ULL * 1024ULL * 1024ULL * 1024ULL)
|
|
||||||
{
|
|
||||||
/* Partition 16GB - 32GB ==> 16KB Cluster */
|
|
||||||
ClusterSize = 16384;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Partition >= 32GB ==> 32KB Cluster */
|
|
||||||
ClusterSize = 32768;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&BootSector, 0, sizeof(FAT32_BOOT_SECTOR));
|
|
||||||
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
|
||||||
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
|
||||||
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
|
||||||
BootSector.ReservedSectors = 32;
|
|
||||||
BootSector.FATCount = 2;
|
|
||||||
BootSector.RootEntries = 0;
|
|
||||||
BootSector.Sectors = 0;
|
|
||||||
BootSector.Media = 0xf8;
|
|
||||||
BootSector.FATSectors = 0;
|
|
||||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
|
||||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
|
||||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
|
||||||
BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
|
|
||||||
GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
|
|
||||||
BootSector.FATSectors32 = 0; /* Set later */
|
|
||||||
BootSector.ExtFlag = 0; /* Mirror all FATs */
|
|
||||||
BootSector.FSVersion = 0x0000; /* 0:0 */
|
|
||||||
BootSector.RootCluster = 2;
|
|
||||||
BootSector.FSInfoSector = 1;
|
|
||||||
BootSector.BootBackup = 6;
|
|
||||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
|
||||||
BootSector.ExtBootSignature = 0x29;
|
|
||||||
BootSector.VolumeID = 0x45768798; /* FIXME: */
|
|
||||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
|
||||||
{
|
|
||||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlUnicodeStringToAnsiString(&VolumeLabel, Label, TRUE);
|
|
||||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
|
||||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
|
||||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
|
||||||
RtlFreeAnsiString(&VolumeLabel);
|
|
||||||
}
|
|
||||||
memcpy(&BootSector.SysType[0], "FAT32 ", 8);
|
|
||||||
|
|
||||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
|
||||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
|
||||||
TmpVal1 = BootSector.SectorsHuge - (BootSector.ReservedSectors + RootDirSectors);
|
|
||||||
TmpVal2 = (256 * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
|
||||||
if (TRUE /* FAT32 */)
|
|
||||||
{
|
|
||||||
TmpVal2 = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (TmpVal2 == 0)
|
|
||||||
{
|
|
||||||
TmpVal3 = 0xffffffff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TmpVal3 = TmpVal2;
|
|
||||||
}
|
|
||||||
TmpVal2 = ((TmpVal1 - TmpVal2 * BootSector.FATCount) / BootSector.SectorsPerCluster) + 2;
|
|
||||||
TmpVal2 = (sizeof(ULONG) * TmpVal2 + BootSector.BytesPerSector - 1) / BootSector.BytesPerSector;
|
|
||||||
}
|
|
||||||
while (TmpVal3 > TmpVal2);
|
|
||||||
BootSector.FATSectors32 = TmpVal2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = VfatWriteBootSector(FileHandle,
|
|
||||||
&BootSector);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("VfatWriteBootSector() failed with status 0x%.08x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = VfatWriteFsInfo(FileHandle,
|
|
||||||
&BootSector);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("VfatWriteFsInfo() failed with status 0x%.08x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write first FAT copy */
|
|
||||||
Status = VfatWriteFAT(FileHandle,
|
|
||||||
0,
|
|
||||||
&BootSector);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("VfatWriteFAT() failed with status 0x%.08x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write second FAT copy */
|
|
||||||
Status = VfatWriteFAT(FileHandle,
|
|
||||||
BootSector.FATSectors32,
|
|
||||||
&BootSector);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("VfatWriteFAT() failed with status 0x%.08x.\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = VfatWriteRootDirectory(FileHandle,
|
|
||||||
&BootSector);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("VfatWriteRootDirectory() failed with status 0x%.08x\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatInitialize()
|
VfatInitialize(VOID)
|
||||||
{
|
{
|
||||||
DPRINT("VfatInitialize()\n");
|
DPRINT("VfatInitialize()\n");
|
||||||
|
|
||||||
|
@ -556,41 +108,55 @@ VfatFormat(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
|
DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
|
||||||
DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset);
|
DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset);
|
||||||
DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength);
|
DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength);
|
||||||
DPRINT("HiddenSectors %d\n", PartitionInfo.HiddenSectors);
|
DPRINT("HiddenSectors %d\n", PartitionInfo.HiddenSectors);
|
||||||
DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
|
DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
|
||||||
DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
|
DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
|
||||||
DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
|
DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
|
||||||
DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
|
DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("FIXME: Removable media is not supported\n");
|
|
||||||
NtClose(FileHandle);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PartitionInfo.PartitionLength.QuadPart < 512ULL * 1024ULL * 1024ULL)
|
|
||||||
{
|
if (PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 ||
|
||||||
Status = Fat16Format (FileHandle,
|
PartitionInfo.PartitionType == PARTITION_FAT32)
|
||||||
&PartitionInfo,
|
{
|
||||||
&DiskGeometry,
|
Status = Fat32Format (FileHandle,
|
||||||
Label,
|
|
||||||
QuickFormat,
|
|
||||||
ClusterSize,
|
|
||||||
Callback);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = VfatFormatFat32 (FileHandle,
|
|
||||||
&PartitionInfo,
|
&PartitionInfo,
|
||||||
&DiskGeometry,
|
&DiskGeometry,
|
||||||
Label,
|
Label,
|
||||||
QuickFormat,
|
QuickFormat,
|
||||||
ClusterSize,
|
ClusterSize,
|
||||||
Callback);
|
Callback);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
else if (PartitionInfo.PartitionType == PARTITION_FAT12)
|
||||||
|
{
|
||||||
|
Status = Fat12Format (FileHandle,
|
||||||
|
&PartitionInfo,
|
||||||
|
&DiskGeometry,
|
||||||
|
Label,
|
||||||
|
QuickFormat,
|
||||||
|
ClusterSize,
|
||||||
|
Callback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = Fat16Format (FileHandle,
|
||||||
|
&PartitionInfo,
|
||||||
|
&DiskGeometry,
|
||||||
|
Label,
|
||||||
|
QuickFormat,
|
||||||
|
ClusterSize,
|
||||||
|
Callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("FIXME: Removable media is not supported\n");
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NtClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
|
@ -602,7 +168,7 @@ VfatFormat(
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatCleanup()
|
VfatCleanup(VOID)
|
||||||
{
|
{
|
||||||
DPRINT("VfatCleanup()\n");
|
DPRINT("VfatCleanup()\n");
|
||||||
|
|
||||||
|
|
|
@ -95,3 +95,12 @@ Fat16Format (HANDLE FileHandle,
|
||||||
BOOL QuickFormat,
|
BOOL QuickFormat,
|
||||||
DWORD ClusterSize,
|
DWORD ClusterSize,
|
||||||
PFMIFSCALLBACK Callback);
|
PFMIFSCALLBACK Callback);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Fat32Format (HANDLE FileHandle,
|
||||||
|
PPARTITION_INFORMATION PartitionInfo,
|
||||||
|
PDISK_GEOMETRY DiskGeometry,
|
||||||
|
PUNICODE_STRING Label,
|
||||||
|
BOOL QuickFormat,
|
||||||
|
DWORD ClusterSize,
|
||||||
|
PFMIFSCALLBACK Callback);
|
||||||
|
|
Loading…
Reference in a new issue