From c07929b227595a626d1cb1398be6af3ef280250c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 22 Aug 2003 13:53:02 +0000 Subject: [PATCH] Moved FAT32 code to a sepatate file. Added hack for HiddenSectors value. This is needed to boot FreeLoader. svn path=/trunk/; revision=5752 --- reactos/lib/fslib/vfatlib/Makefile | 3 +- reactos/lib/fslib/vfatlib/fat16.c | 2 +- reactos/lib/fslib/vfatlib/fat32.c | 463 ++++++++++++++++++++++++ reactos/lib/fslib/vfatlib/vfatlib.c | 522 +++------------------------- reactos/lib/fslib/vfatlib/vfatlib.h | 9 + 5 files changed, 519 insertions(+), 480 deletions(-) create mode 100644 reactos/lib/fslib/vfatlib/fat32.c diff --git a/reactos/lib/fslib/vfatlib/Makefile b/reactos/lib/fslib/vfatlib/Makefile index 8df9de9e748..36f0c199254 100755 --- a/reactos/lib/fslib/vfatlib/Makefile +++ b/reactos/lib/fslib/vfatlib/Makefile @@ -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 = ../../.. @@ -11,6 +11,7 @@ TARGET_CFLAGS += -D_DISABLE_TIDENTS TARGET_OBJECTS = \ fat16.o \ + fat32.o \ vfatlib.o include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/lib/fslib/vfatlib/fat16.c b/reactos/lib/fslib/vfatlib/fat16.c index 61081868c2c..bc54d45733a 100644 --- a/reactos/lib/fslib/vfatlib/fat16.c +++ b/reactos/lib/fslib/vfatlib/fat16.c @@ -297,7 +297,7 @@ Fat16Format (HANDLE FileHandle, BootSector.FATSectors = 0; /* Set later. See below. */ BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack; BootSector.Heads = DiskGeometry->TracksPerCylinder; - BootSector.HiddenSectors = PartitionInfo->HiddenSectors; + BootSector.HiddenSectors = DiskGeometry->SectorsPerTrack; //PartitionInfo->HiddenSectors; /* FIXME: Hack! */ BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >> GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */ BootSector.Drive = 0xff; /* No BIOS boot drive available */ diff --git a/reactos/lib/fslib/vfatlib/fat32.c b/reactos/lib/fslib/vfatlib/fat32.c new file mode 100644 index 00000000000..e44e80cb94b --- /dev/null +++ b/reactos/lib/fslib/vfatlib/fat32.c @@ -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 +#define NTOS_MODE_USER +#include +#include +#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; +} diff --git a/reactos/lib/fslib/vfatlib/vfatlib.c b/reactos/lib/fslib/vfatlib/vfatlib.c index 215af8ac1e7..a620775673a 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.c +++ b/reactos/lib/fslib/vfatlib/vfatlib.c @@ -16,456 +16,8 @@ #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 -VfatInitialize() +VfatInitialize(VOID) { DPRINT("VfatInitialize()\n"); @@ -556,41 +108,55 @@ VfatFormat( return Status; } - DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType); - DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset); - DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength); - DPRINT("HiddenSectors %d\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); - } - else - { - DPRINT1("FIXME: Removable media is not supported\n"); - NtClose(FileHandle); - return Status; - } + DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType); + DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset); + DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength); + DPRINT("HiddenSectors %d\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 (PartitionInfo.PartitionLength.QuadPart < 512ULL * 1024ULL * 1024ULL) - { - Status = Fat16Format (FileHandle, - &PartitionInfo, - &DiskGeometry, - Label, - QuickFormat, - ClusterSize, - Callback); - } - else - { - Status = VfatFormatFat32 (FileHandle, + + if (PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 || + PartitionInfo.PartitionType == PARTITION_FAT32) + { + Status = Fat32Format (FileHandle, &PartitionInfo, &DiskGeometry, Label, QuickFormat, ClusterSize, 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); @@ -602,7 +168,7 @@ VfatFormat( NTSTATUS -VfatCleanup() +VfatCleanup(VOID) { DPRINT("VfatCleanup()\n"); diff --git a/reactos/lib/fslib/vfatlib/vfatlib.h b/reactos/lib/fslib/vfatlib/vfatlib.h index f7543db3926..15c4faf6577 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.h +++ b/reactos/lib/fslib/vfatlib/vfatlib.h @@ -95,3 +95,12 @@ Fat16Format (HANDLE FileHandle, BOOL QuickFormat, DWORD ClusterSize, PFMIFSCALLBACK Callback); + +NTSTATUS +Fat32Format (HANDLE FileHandle, + PPARTITION_INFORMATION PartitionInfo, + PDISK_GEOMETRY DiskGeometry, + PUNICODE_STRING Label, + BOOL QuickFormat, + DWORD ClusterSize, + PFMIFSCALLBACK Callback); -- 2.17.1