mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 11:46:50 +00:00
[FORMATTING]
Fix indentation. No code changes. svn path=/trunk/; revision=47764
This commit is contained in:
parent
78b0fb4a21
commit
0c8457631d
9 changed files with 1644 additions and 1617 deletions
|
@ -798,14 +798,14 @@ Ext2TotalBlocks(PEXT2_FILESYS Ext2Sys, ULONG DataBlocks)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
Ext2Format(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
Ext2Format(IN PUNICODE_STRING DriveRoot,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
BOOLEAN bRet = FALSE;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
@ -1002,15 +1002,15 @@ clean_up:
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI
|
||||
Ext2Chkdsk(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
Ext2Chkdsk(IN PUNICODE_STRING DriveRoot,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -11,15 +11,15 @@
|
|||
#include <debug.h>
|
||||
|
||||
NTSTATUS NTAPI
|
||||
NtfsFormat(PUNICODE_STRING DriveRoot,
|
||||
FMIFS_MEDIA_FLAG MediaFlag,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFMIFSCALLBACK Callback)
|
||||
NtfsFormat(IN PUNICODE_STRING DriveRoot,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,6 @@ NtfsChkdsk(IN PUNICODE_STRING DriveRoot,
|
|||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -14,376 +14,381 @@
|
|||
#include <debug.h>
|
||||
|
||||
static ULONG
|
||||
GetShiftCount(ULONG Value)
|
||||
GetShiftCount(IN ULONG Value)
|
||||
{
|
||||
ULONG i = 1;
|
||||
while (Value > 0)
|
||||
ULONG i = 1;
|
||||
|
||||
while (Value > 0)
|
||||
{
|
||||
i++;
|
||||
Value /= 2;
|
||||
i++;
|
||||
Value /= 2;
|
||||
}
|
||||
return i - 2;
|
||||
|
||||
return i - 2;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
CalcVolumeSerialNumber(VOID)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
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);
|
||||
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;
|
||||
return Serial;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat12WriteBootSector (IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat12WriteBootSector(IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR NewBootSector;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
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);
|
||||
/* 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);
|
||||
/* Zero the new bootsector */
|
||||
memset(NewBootSector, 0, SECTORSIZE);
|
||||
|
||||
/* Copy FAT16 BPB to new bootsector */
|
||||
memcpy((NewBootSector + 3),
|
||||
&BootSector->OEMName[0],
|
||||
59); /* FAT16 BPB length (up to (not including) Res2) */
|
||||
/* Copy FAT16 BPB to new bootsector */
|
||||
memcpy((NewBootSector + 3),
|
||||
&BootSector->OEMName[0],
|
||||
59); /* FAT16 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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat12WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat12WriteFAT(IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Size;
|
||||
ULONG Sectors;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Size;
|
||||
ULONG Sectors;
|
||||
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
/* FAT cluster 0 & 1*/
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
Buffer[2] = 0xff;
|
||||
/* FAT cluster 0 & 1*/
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
Buffer[2] = 0xff;
|
||||
|
||||
/* 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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 3);
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 3);
|
||||
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||
if (((ULONG)BootSector->FATSectors - i) <= Sectors)
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||
if (((ULONG)BootSector->FATSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = (ULONG)BootSector->FATSectors - i;
|
||||
Sectors = (ULONG)BootSector->FATSectors - i;
|
||||
}
|
||||
|
||||
Size = Sectors * BootSector->BytesPerSector;
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Size,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Size = Sectors * 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
UpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat12WriteRootDirectory (IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat12WriteRootDirectory(IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FirstRootDirSector;
|
||||
ULONG RootDirSectors;
|
||||
ULONG Sectors;
|
||||
ULONG Size;
|
||||
ULONG i;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FirstRootDirSector;
|
||||
ULONG RootDirSectors;
|
||||
ULONG Sectors;
|
||||
ULONG Size;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
|
||||
DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
|
||||
DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
|
||||
DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
|
||||
DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
|
||||
DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
|
||||
|
||||
/* Write cluster */
|
||||
RootDirSectors = ((BootSector->RootEntries * 32) +
|
||||
(BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
|
||||
FirstRootDirSector =
|
||||
BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
|
||||
/* Write cluster */
|
||||
RootDirSectors = ((BootSector->RootEntries * 32) +
|
||||
(BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
|
||||
FirstRootDirSector =
|
||||
BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
|
||||
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
|
||||
/* Allocate buffer for the cluster */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
/* Allocate buffer for the cluster */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 0; i < RootDirSectors; i += Sectors)
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 0; i < RootDirSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
|
||||
|
||||
if ((RootDirSectors - i) <= Sectors)
|
||||
if ((RootDirSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = RootDirSectors - i;
|
||||
Sectors = RootDirSectors - i;
|
||||
}
|
||||
Size = Sectors * 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);
|
||||
}
|
||||
UpdateProgress (Context, Sectors);
|
||||
Size = Sectors * 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;
|
||||
}
|
||||
|
||||
UpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Fat12Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context)
|
||||
Fat12Format(IN HANDLE FileHandle,
|
||||
IN PPARTITION_INFORMATION PartitionInfo,
|
||||
IN PDISK_GEOMETRY DiskGeometry,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
FAT16_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG SectorCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
ULONG TmpVal3;
|
||||
NTSTATUS Status;
|
||||
FAT16_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG SectorCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
ULONG TmpVal3;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
{
|
||||
/* 4KB Cluster (Harddisk only) */
|
||||
ClusterSize = 4096;
|
||||
/* 4KB Cluster (Harddisk only) */
|
||||
ClusterSize = 4096;
|
||||
}
|
||||
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >>
|
||||
GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >>
|
||||
GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||
|
||||
DPRINT("SectorCount = %lu\n", SectorCount);
|
||||
DPRINT("SectorCount = %lu\n", SectorCount);
|
||||
|
||||
memset(&BootSector, 0, sizeof(FAT16_BOOT_SECTOR));
|
||||
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
||||
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
||||
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
||||
BootSector.ReservedSectors = 1;
|
||||
BootSector.FATCount = 2;
|
||||
BootSector.RootEntries = 512;
|
||||
BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
|
||||
BootSector.Media = 0xf8;
|
||||
BootSector.FATSectors = 0; /* Set later. See below. */
|
||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
||||
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
|
||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||
BootSector.ExtBootSignature = 0x29;
|
||||
BootSector.VolumeID = CalcVolumeSerialNumber();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
memset(&BootSector, 0, sizeof(FAT16_BOOT_SECTOR));
|
||||
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
||||
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
||||
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
||||
BootSector.ReservedSectors = 1;
|
||||
BootSector.FATCount = 2;
|
||||
BootSector.RootEntries = 512;
|
||||
BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
|
||||
BootSector.Media = 0xf8;
|
||||
BootSector.FATSectors = 0; /* Set later. See below. */
|
||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
||||
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
|
||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||
BootSector.ExtBootSignature = 0x29;
|
||||
BootSector.VolumeID = CalcVolumeSerialNumber();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
{
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
memcpy(&BootSector.SysType[0], "FAT12 ", 8);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* ((BootSector.BytesPerSector * 2) / 3) FAT entries (12bit) fit into one sector */
|
||||
TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
|
||||
TmpVal2 = (((BootSector.BytesPerSector * 2) / 3) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
|
||||
|
||||
DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
1 + (BootSector.FATSectors * 2) + RootDirSectors;
|
||||
|
||||
Status = Fat12WriteBootSector (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat12WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
|
||||
/* Write first FAT copy */
|
||||
Status = Fat12WriteFAT (FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
memcpy(&BootSector.SysType[0], "FAT12 ", 8);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* ((BootSector.BytesPerSector * 2) / 3) FAT entries (12bit) fit into one sector */
|
||||
TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
|
||||
TmpVal2 = (((BootSector.BytesPerSector * 2) / 3) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
|
||||
|
||||
DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
1 + (BootSector.FATSectors * 2) + RootDirSectors;
|
||||
|
||||
Status = Fat12WriteBootSector(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat12WriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat12WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write second FAT copy */
|
||||
Status = Fat12WriteFAT (FileHandle,
|
||||
(ULONG)BootSector.FATSectors,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Write first FAT copy */
|
||||
Status = Fat12WriteFAT(FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat12WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat12WriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = Fat12WriteRootDirectory (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Write second FAT copy */
|
||||
Status = Fat12WriteFAT(FileHandle,
|
||||
(ULONG)BootSector.FATSectors,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
DPRINT("Fat12WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!QuickFormat)
|
||||
Status = Fat12WriteRootDirectory(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
if (!QuickFormat)
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -14,394 +14,397 @@
|
|||
#include <debug.h>
|
||||
|
||||
static ULONG
|
||||
GetShiftCount(ULONG Value)
|
||||
GetShiftCount(IN ULONG Value)
|
||||
{
|
||||
ULONG i = 1;
|
||||
while (Value > 0)
|
||||
ULONG i = 1;
|
||||
|
||||
while (Value > 0)
|
||||
{
|
||||
i++;
|
||||
Value /= 2;
|
||||
i++;
|
||||
Value /= 2;
|
||||
}
|
||||
return i - 2;
|
||||
|
||||
return i - 2;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
CalcVolumeSerialNumber(VOID)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
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);
|
||||
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;
|
||||
return Serial;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat16WriteBootSector (IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat16WriteBootSector(IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR NewBootSector;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
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);
|
||||
/* 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);
|
||||
/* Zero the new bootsector */
|
||||
memset(NewBootSector, 0, SECTORSIZE);
|
||||
|
||||
/* Copy FAT16 BPB to new bootsector */
|
||||
memcpy((NewBootSector + 3),
|
||||
&BootSector->OEMName[0],
|
||||
59); /* FAT16 BPB length (up to (not including) Res2) */
|
||||
/* Copy FAT16 BPB to new bootsector */
|
||||
memcpy((NewBootSector + 3),
|
||||
&BootSector->OEMName[0],
|
||||
59); /* FAT16 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))
|
||||
/* 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;
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat16WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat16WriteFAT(IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Sectors;
|
||||
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);
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
/* FAT cluster 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
/* 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;
|
||||
/* 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 + BootSector->ReservedSectors) * BootSector->BytesPerSector;
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 4);
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 4);
|
||||
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||
|
||||
if (((ULONG)BootSector->FATSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = (ULONG)BootSector->FATSectors - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (((ULONG)BootSector->FATSectors - i) <= Sectors)
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
Sectors = (ULONG)BootSector->FATSectors - i;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&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);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat16WriteRootDirectory (IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat16WriteRootDirectory(IN HANDLE FileHandle,
|
||||
IN PFAT16_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FirstRootDirSector;
|
||||
ULONG RootDirSectors;
|
||||
ULONG Sectors;
|
||||
ULONG i;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FirstRootDirSector;
|
||||
ULONG RootDirSectors;
|
||||
ULONG Sectors;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
|
||||
DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
|
||||
DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
|
||||
DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
|
||||
DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
|
||||
DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
|
||||
|
||||
/* Write cluster */
|
||||
RootDirSectors = ((BootSector->RootEntries * 32) +
|
||||
(BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
|
||||
FirstRootDirSector =
|
||||
BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
|
||||
/* Write cluster */
|
||||
RootDirSectors = ((BootSector->RootEntries * 32) +
|
||||
(BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
|
||||
FirstRootDirSector =
|
||||
BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
|
||||
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
|
||||
/* Allocate buffer for the cluster */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
/* Allocate buffer for the cluster */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 0; i < RootDirSectors; i += Sectors)
|
||||
Sectors = 32 * 1024 / BootSector->BytesPerSector;
|
||||
for (i = 0; i < RootDirSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
|
||||
|
||||
if ((RootDirSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = RootDirSectors - i;
|
||||
}
|
||||
if ((RootDirSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = RootDirSectors - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
}
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
UpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Fat16Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context)
|
||||
Fat16Format(IN HANDLE FileHandle,
|
||||
IN PPARTITION_INFORMATION PartitionInfo,
|
||||
IN PDISK_GEOMETRY DiskGeometry,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
FAT16_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG SectorCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
ULONG TmpVal3;
|
||||
NTSTATUS Status;
|
||||
FAT16_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG SectorCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
ULONG TmpVal3;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
{
|
||||
if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 16MB ==> 1KB Cluster */
|
||||
ClusterSize = 1024;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 128LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 128MB ==> 2KB Cluster */
|
||||
ClusterSize = 2048;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 256LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 256MB ==> 4KB Cluster */
|
||||
ClusterSize = 4096;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Partition >= 256MB (< 512MB) ==> 8KB Cluster */
|
||||
ClusterSize = 8192;
|
||||
}
|
||||
if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 16MB ==> 1KB Cluster */
|
||||
ClusterSize = 1024;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 128LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 128MB ==> 2KB Cluster */
|
||||
ClusterSize = 2048;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 256LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 256MB ==> 4KB Cluster */
|
||||
ClusterSize = 4096;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Partition >= 256MB (< 512MB) ==> 8KB Cluster */
|
||||
ClusterSize = 8192;
|
||||
}
|
||||
}
|
||||
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >>
|
||||
GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >>
|
||||
GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
|
||||
|
||||
memset(&BootSector, 0, sizeof(FAT16_BOOT_SECTOR));
|
||||
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
||||
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
||||
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
||||
BootSector.ReservedSectors = 1;
|
||||
BootSector.FATCount = 2;
|
||||
BootSector.RootEntries = 512;
|
||||
BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
|
||||
BootSector.Media = 0xf8;
|
||||
BootSector.FATSectors = 0; /* Set later. See below. */
|
||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
||||
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
|
||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||
BootSector.ExtBootSignature = 0x29;
|
||||
BootSector.VolumeID = CalcVolumeSerialNumber();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
memset(&BootSector, 0, sizeof(FAT16_BOOT_SECTOR));
|
||||
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
|
||||
BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
|
||||
BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
|
||||
BootSector.ReservedSectors = 1;
|
||||
BootSector.FATCount = 2;
|
||||
BootSector.RootEntries = 512;
|
||||
BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
|
||||
BootSector.Media = 0xf8;
|
||||
BootSector.FATSectors = 0; /* Set later. See below. */
|
||||
BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
|
||||
BootSector.Heads = DiskGeometry->TracksPerCylinder;
|
||||
BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
|
||||
BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
|
||||
BootSector.Drive = 0xff; /* No BIOS boot drive available */
|
||||
BootSector.ExtBootSignature = 0x29;
|
||||
BootSector.VolumeID = CalcVolumeSerialNumber();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
{
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
memcpy(&BootSector.SysType[0], "FAT16 ", 8);
|
||||
|
||||
DPRINT("BootSector.SectorsHuge = %lx\n", BootSector.SectorsHuge);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* (BootSector.BytesPerSector / 2) FAT entries (16bit) fit into one sector */
|
||||
TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
|
||||
TmpVal2 = ((BootSector.BytesPerSector / 2) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
|
||||
DPRINT("BootSector.FATSectors = %hu\n", BootSector.FATSectors);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
1 + (BootSector.FATSectors * 2) + RootDirSectors;
|
||||
|
||||
Status = Fat16WriteBootSector (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat16WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
|
||||
/* Write first FAT copy */
|
||||
Status = Fat16WriteFAT (FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
memcpy(&BootSector.SysType[0], "FAT16 ", 8);
|
||||
|
||||
DPRINT("BootSector.SectorsHuge = %lx\n", BootSector.SectorsHuge);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* (BootSector.BytesPerSector / 2) FAT entries (16bit) fit into one sector */
|
||||
TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
|
||||
TmpVal2 = ((BootSector.BytesPerSector / 2) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
|
||||
DPRINT("BootSector.FATSectors = %hu\n", BootSector.FATSectors);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
1 + (BootSector.FATSectors * 2) + RootDirSectors;
|
||||
|
||||
Status = Fat16WriteBootSector(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat16WriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat16WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write second FAT copy */
|
||||
Status = Fat16WriteFAT (FileHandle,
|
||||
(ULONG)BootSector.FATSectors,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Write first FAT copy */
|
||||
Status = Fat16WriteFAT(FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat16WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat16WriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = Fat16WriteRootDirectory (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Write second FAT copy */
|
||||
Status = Fat16WriteFAT(FileHandle,
|
||||
(ULONG)BootSector.FATSectors,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat16WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
DPRINT("Fat16WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!QuickFormat)
|
||||
Status = Fat16WriteRootDirectory(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
DPRINT("Fat16WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
if (!QuickFormat)
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -14,478 +14,483 @@
|
|||
#include <debug.h>
|
||||
|
||||
static ULONG
|
||||
GetShiftCount(ULONG Value)
|
||||
GetShiftCount(IN ULONG Value)
|
||||
{
|
||||
ULONG i = 1;
|
||||
while (Value > 0)
|
||||
ULONG i = 1;
|
||||
|
||||
while (Value > 0)
|
||||
{
|
||||
i++;
|
||||
Value /= 2;
|
||||
i++;
|
||||
Value /= 2;
|
||||
}
|
||||
return i - 2;
|
||||
|
||||
return i - 2;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
CalcVolumeSerialNumber(VOID)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
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);
|
||||
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;
|
||||
return Serial;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat32WriteBootSector (IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat32WriteBootSector(IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR NewBootSector;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
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);
|
||||
/* 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);
|
||||
/* 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) */
|
||||
/* 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))
|
||||
/* 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;
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Write backup boot sector */
|
||||
if (BootSector->BootBackup != 0x0000)
|
||||
/* 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))
|
||||
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;
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
}
|
||||
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat32WriteFsInfo (IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat32WriteFsInfo(IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PFAT32_FSINFO FsInfo;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
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);
|
||||
/* 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);
|
||||
/* Zero the new sector */
|
||||
memset(FsInfo, 0, BootSector->BytesPerSector);
|
||||
|
||||
FsInfo->LeadSig = 0x41615252;
|
||||
FsInfo->StrucSig = 0x61417272;
|
||||
FsInfo->FreeCount = 0xffffffff;
|
||||
FsInfo->NextFree = 0xffffffff;
|
||||
FsInfo->TrailSig = 0xaa550000;
|
||||
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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Free the new sector buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
||||
/* Free the new sector buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat32WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat32WriteFAT(IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Sectors;
|
||||
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);
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
64 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 64 * 1024);
|
||||
/* 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;
|
||||
/* FAT cluster 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
Buffer[2] = 0xff;
|
||||
Buffer[3] = 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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
UpdateProgress(Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 12);
|
||||
/* 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 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;
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
|
||||
|
||||
if ((BootSector->FATSectors32 - i) <= Sectors)
|
||||
if ((BootSector->FATSectors32 - i) <= Sectors)
|
||||
{
|
||||
Sectors = BootSector->FATSectors32 - i;
|
||||
Sectors = BootSector->FATSectors32 - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * BootSector->BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
UpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fat32WriteRootDirectory (IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
Fat32WriteRootDirectory(IN HANDLE FileHandle,
|
||||
IN PFAT32_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONGLONG FirstDataSector;
|
||||
ULONGLONG FirstRootDirSector;
|
||||
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);
|
||||
/* 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);
|
||||
/* 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);
|
||||
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 */;
|
||||
/* Write cluster */
|
||||
FirstDataSector = BootSector->ReservedSectors +
|
||||
(BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
|
||||
|
||||
DPRINT("FirstDataSector = %lu\n", FirstDataSector);
|
||||
DPRINT("FirstDataSector = %lu\n", FirstDataSector);
|
||||
|
||||
FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
|
||||
FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
|
||||
FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
|
||||
FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
|
||||
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
DPRINT("FileOffset = %lu\n", FileOffset.QuadPart);
|
||||
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))
|
||||
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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, (ULONG)BootSector->SectorsPerCluster);
|
||||
UpdateProgress(Context, (ULONG)BootSector->SectorsPerCluster);
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Fat32Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context)
|
||||
Fat32Format(IN HANDLE FileHandle,
|
||||
IN PPARTITION_INFORMATION PartitionInfo,
|
||||
IN PDISK_GEOMETRY DiskGeometry,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
FAT32_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
NTSTATUS Status;
|
||||
FAT32_BOOT_SECTOR BootSector;
|
||||
OEM_STRING VolumeLabel;
|
||||
ULONG RootDirSectors;
|
||||
ULONG TmpVal1;
|
||||
ULONG TmpVal2;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
/* Calculate cluster size */
|
||||
if (ClusterSize == 0)
|
||||
{
|
||||
if (PartitionInfo->PartitionLength.QuadPart < 8LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 8GB ==> 4KB Cluster */
|
||||
ClusterSize = 4096;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition 8GB - 16GB ==> 8KB Cluster */
|
||||
ClusterSize = 8192;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 32LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition 16GB - 32GB ==> 16KB Cluster */
|
||||
ClusterSize = 16384;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Partition >= 32GB ==> 32KB Cluster */
|
||||
ClusterSize = 32768;
|
||||
}
|
||||
if (PartitionInfo->PartitionLength.QuadPart < 8LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition < 8GB ==> 4KB Cluster */
|
||||
ClusterSize = 4096;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* Partition 8GB - 16GB ==> 8KB Cluster */
|
||||
ClusterSize = 8192;
|
||||
}
|
||||
else if (PartitionInfo->PartitionLength.QuadPart < 32LL * 1024LL * 1024LL * 1024LL)
|
||||
{
|
||||
/* 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 = CalcVolumeSerialNumber ();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
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 = CalcVolumeSerialNumber ();
|
||||
if ((Label == NULL) || (Label->Buffer == NULL))
|
||||
{
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
memcpy(&BootSector.SysType[0], "FAT32 ", 8);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* (BytesPerSector / 4) FAT entries (32bit) fit into one sector */
|
||||
TmpVal1 = BootSector.SectorsHuge - BootSector.ReservedSectors;
|
||||
TmpVal2 = ((BootSector.BytesPerSector / 4) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
DPRINT("FATSectors32 = %lu\n", BootSector.FATSectors32);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster;
|
||||
|
||||
Status = Fat32WriteBootSector (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat32WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
|
||||
memset(&BootSector.VolumeLabel[0], ' ', 11);
|
||||
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
|
||||
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
|
||||
RtlFreeOemString(&VolumeLabel);
|
||||
}
|
||||
|
||||
Status = Fat32WriteFsInfo (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
memcpy(&BootSector.SysType[0], "FAT32 ", 8);
|
||||
|
||||
RootDirSectors = ((BootSector.RootEntries * 32) +
|
||||
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
/* (BytesPerSector / 4) FAT entries (32bit) fit into one sector */
|
||||
TmpVal1 = BootSector.SectorsHuge - BootSector.ReservedSectors;
|
||||
TmpVal2 = ((BootSector.BytesPerSector / 4) * BootSector.SectorsPerCluster) + BootSector.FATCount;
|
||||
BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
||||
DPRINT("FATSectors32 = %lu\n", BootSector.FATSectors32);
|
||||
|
||||
/* Init context data */
|
||||
Context->TotalSectorCount =
|
||||
2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster;
|
||||
|
||||
Status = Fat32WriteBootSector(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat32WriteFsInfo() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat32WriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write first FAT copy */
|
||||
Status = Fat32WriteFAT (FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = Fat32WriteFsInfo(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat32WriteFsInfo() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write first FAT copy */
|
||||
Status = Fat32WriteFAT(FileHandle,
|
||||
0,
|
||||
&BootSector,
|
||||
Context);
|
||||
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,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Write second FAT copy */
|
||||
Status = Fat32WriteFAT(FileHandle,
|
||||
BootSector.FATSectors32,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat32WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
DPRINT("Fat32WriteFAT() failed with status 0x%.08x.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = Fat32WriteRootDirectory (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = Fat32WriteRootDirectory(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Fat32WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
DPRINT("Fat32WriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
}
|
||||
|
||||
if (!QuickFormat)
|
||||
if (!QuickFormat)
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
/* FIXME: Fill remaining sectors */
|
||||
}
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS VFAT filesystem library
|
||||
* FILE: vfatlib.c
|
||||
* FILE: lib\fslib\vfatlib\vfatlib.c
|
||||
* PURPOSE: Main API
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
|
@ -17,197 +17,199 @@ PVOID FsCheckMemQueue;
|
|||
ULONG FsCheckFlags;
|
||||
ULONG FsCheckTotalFiles;
|
||||
|
||||
NTSTATUS NTAPI
|
||||
VfatFormat (PUNICODE_STRING DriveRoot,
|
||||
FMIFS_MEDIA_FLAG MediaFlag,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFMIFSCALLBACK Callback)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatFormat(IN PUNICODE_STRING DriveRoot,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
HANDLE FileHandle;
|
||||
PARTITION_INFORMATION PartitionInfo;
|
||||
FORMAT_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
HANDLE FileHandle;
|
||||
PARTITION_INFORMATION PartitionInfo;
|
||||
FORMAT_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("VfatFormat(DriveRoot '%wZ')\n", DriveRoot);
|
||||
DPRINT("VfatFormat(DriveRoot '%wZ')\n", DriveRoot);
|
||||
|
||||
Context.TotalSectorCount = 0;
|
||||
Context.CurrentSectorCount = 0;
|
||||
Context.Callback = Callback;
|
||||
Context.Success = FALSE;
|
||||
Context.Percent = 0;
|
||||
Context.TotalSectorCount = 0;
|
||||
Context.CurrentSectorCount = 0;
|
||||
Context.Callback = Callback;
|
||||
Context.Success = FALSE;
|
||||
Context.Percent = 0;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DriveRoot,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DriveRoot,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenFile() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
DPRINT1("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))
|
||||
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;
|
||||
DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (DiskGeometry.MediaType == FixedMedia)
|
||||
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);
|
||||
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))
|
||||
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;
|
||||
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;
|
||||
/*
|
||||
* FIXME: This is a hack!
|
||||
* Partitioning software MUST set the correct number of hidden sectors!
|
||||
*/
|
||||
PartitionInfo.HiddenSectors = DiskGeometry.SectorsPerTrack;
|
||||
}
|
||||
else
|
||||
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;
|
||||
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);
|
||||
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)
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Percent = 0;
|
||||
Callback (PROGRESS, 0, (PVOID)&Context.Percent);
|
||||
Context.Percent = 0;
|
||||
Callback (PROGRESS, 0, (PVOID)&Context.Percent);
|
||||
}
|
||||
|
||||
if (PartitionInfo.PartitionLength.QuadPart < (4200LL * 1024LL))
|
||||
if (PartitionInfo.PartitionLength.QuadPart < (4200LL * 1024LL))
|
||||
{
|
||||
/* FAT12 (volume is smaller than 4.1MB) */
|
||||
Status = Fat12Format (FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
/* FAT12 (volume is smaller than 4.1MB) */
|
||||
Status = Fat12Format(FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
}
|
||||
else if (PartitionInfo.PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
|
||||
else if (PartitionInfo.PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
|
||||
{
|
||||
/* FAT16 (volume is smaller than 512MB) */
|
||||
Status = Fat16Format (FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
/* FAT16 (volume is smaller than 512MB) */
|
||||
Status = Fat16Format(FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* FAT32 (volume is 512MB or larger) */
|
||||
Status = Fat32Format (FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
/* FAT32 (volume is 512MB or larger) */
|
||||
Status = Fat32Format(FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
Label,
|
||||
QuickFormat,
|
||||
ClusterSize,
|
||||
&Context);
|
||||
}
|
||||
|
||||
NtClose(FileHandle);
|
||||
NtClose(FileHandle);
|
||||
|
||||
if (Callback != NULL)
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
|
||||
Callback (DONE, 0, (PVOID)&Context.Success);
|
||||
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
|
||||
Callback (DONE, 0, (PVOID)&Context.Success);
|
||||
}
|
||||
|
||||
DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
|
||||
DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
UpdateProgress (PFORMAT_CONTEXT Context,
|
||||
ULONG Increment)
|
||||
UpdateProgress(PFORMAT_CONTEXT Context,
|
||||
ULONG Increment)
|
||||
{
|
||||
ULONG NewPercent;
|
||||
ULONG NewPercent;
|
||||
|
||||
Context->CurrentSectorCount += (ULONGLONG)Increment;
|
||||
Context->CurrentSectorCount += (ULONGLONG)Increment;
|
||||
|
||||
|
||||
NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
|
||||
NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
|
||||
|
||||
if (NewPercent > Context->Percent)
|
||||
if (NewPercent > Context->Percent)
|
||||
{
|
||||
Context->Percent = NewPercent;
|
||||
Context->Callback (PROGRESS, 0, &Context->Percent);
|
||||
Context->Percent = NewPercent;
|
||||
Context->Callback (PROGRESS, 0, &Context->Percent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
VfatPrint(PCHAR Format, ...)
|
||||
{
|
||||
|
@ -224,17 +226,19 @@ VfatPrint(PCHAR Format, ...)
|
|||
TextOut.Output = TextBuf;
|
||||
|
||||
/* Do the callback */
|
||||
if (ChkdskCallback) ChkdskCallback(OUTPUT, 0, &TextOut);
|
||||
if (ChkdskCallback)
|
||||
ChkdskCallback(OUTPUT, 0, &TextOut);
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI
|
||||
VfatChkdsk(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
VfatChkdsk(IN PUNICODE_STRING DriveRoot,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
BOOLEAN verify, salvage_files;
|
||||
//ULONG free_clusters;
|
||||
|
@ -246,7 +250,8 @@ VfatChkdsk(
|
|||
|
||||
/* Set parameters */
|
||||
FsCheckFlags = 0;
|
||||
if (Verbose) FsCheckFlags |= FSCHECK_VERBOSE;
|
||||
if (Verbose)
|
||||
FsCheckFlags |= FSCHECK_VERBOSE;
|
||||
|
||||
FsCheckTotalFiles = 0;
|
||||
|
||||
|
@ -263,13 +268,20 @@ VfatChkdsk(
|
|||
}
|
||||
|
||||
read_boot(&fs);
|
||||
if (verify) VfatPrint("Starting check/repair pass.\n");
|
||||
while (read_fat(&fs), scan_root(&fs)) qfree(&FsCheckMemQueue);
|
||||
if (ScanDrive) fix_bad(&fs);
|
||||
if (verify)
|
||||
VfatPrint("Starting check/repair pass.\n");
|
||||
|
||||
while (read_fat(&fs), scan_root(&fs))
|
||||
qfree(&FsCheckMemQueue);
|
||||
|
||||
if (ScanDrive)
|
||||
fix_bad(&fs);
|
||||
|
||||
if (salvage_files)
|
||||
reclaim_file(&fs);
|
||||
else
|
||||
reclaim_free(&fs);
|
||||
|
||||
free_clusters = update_free(&fs);
|
||||
file_unused();
|
||||
qfree(&FsCheckMemQueue);
|
||||
|
|
|
@ -24,120 +24,120 @@
|
|||
#include <pshpack1.h>
|
||||
typedef struct _FAT16_BOOT_SECTOR
|
||||
{
|
||||
unsigned char magic0; // 0
|
||||
unsigned char res0; // 1
|
||||
unsigned char magic1; // 2
|
||||
unsigned char OEMName[8]; // 3
|
||||
unsigned short BytesPerSector; // 11
|
||||
unsigned char SectorsPerCluster; // 13
|
||||
unsigned short ReservedSectors; // 14
|
||||
unsigned char FATCount; // 16
|
||||
unsigned short RootEntries; // 17
|
||||
unsigned short Sectors; // 19
|
||||
unsigned char Media; // 21
|
||||
unsigned short FATSectors; // 22
|
||||
unsigned short SectorsPerTrack; // 24
|
||||
unsigned short Heads; // 26
|
||||
unsigned long HiddenSectors; // 28
|
||||
unsigned long SectorsHuge; // 32
|
||||
unsigned char Drive; // 36
|
||||
unsigned char Res1; // 37
|
||||
unsigned char ExtBootSignature; // 38
|
||||
unsigned long VolumeID; // 39
|
||||
unsigned char VolumeLabel[11]; // 43
|
||||
unsigned char SysType[8]; // 54
|
||||
unsigned char Res2[446]; // 62
|
||||
unsigned long Signature1; // 508
|
||||
unsigned char magic0; // 0
|
||||
unsigned char res0; // 1
|
||||
unsigned char magic1; // 2
|
||||
unsigned char OEMName[8]; // 3
|
||||
unsigned short BytesPerSector; // 11
|
||||
unsigned char SectorsPerCluster; // 13
|
||||
unsigned short ReservedSectors; // 14
|
||||
unsigned char FATCount; // 16
|
||||
unsigned short RootEntries; // 17
|
||||
unsigned short Sectors; // 19
|
||||
unsigned char Media; // 21
|
||||
unsigned short FATSectors; // 22
|
||||
unsigned short SectorsPerTrack; // 24
|
||||
unsigned short Heads; // 26
|
||||
unsigned long HiddenSectors; // 28
|
||||
unsigned long SectorsHuge; // 32
|
||||
unsigned char Drive; // 36
|
||||
unsigned char Res1; // 37
|
||||
unsigned char ExtBootSignature; // 38
|
||||
unsigned long VolumeID; // 39
|
||||
unsigned char VolumeLabel[11]; // 43
|
||||
unsigned char SysType[8]; // 54
|
||||
unsigned char Res2[446]; // 62
|
||||
unsigned long Signature1; // 508
|
||||
} FAT16_BOOT_SECTOR, *PFAT16_BOOT_SECTOR;
|
||||
|
||||
|
||||
typedef struct _FAT32_BOOT_SECTOR
|
||||
{
|
||||
unsigned char magic0; // 0
|
||||
unsigned char res0; // 1
|
||||
unsigned char magic1; // 2
|
||||
unsigned char OEMName[8]; // 3
|
||||
unsigned short BytesPerSector; // 11
|
||||
unsigned char SectorsPerCluster; // 13
|
||||
unsigned short ReservedSectors; // 14
|
||||
unsigned char FATCount; // 16
|
||||
unsigned short RootEntries; // 17
|
||||
unsigned short Sectors; // 19
|
||||
unsigned char Media; // 21
|
||||
unsigned short FATSectors; // 22
|
||||
unsigned short SectorsPerTrack; // 24
|
||||
unsigned short Heads; // 26
|
||||
unsigned long HiddenSectors; // 28
|
||||
unsigned long SectorsHuge; // 32
|
||||
unsigned long FATSectors32; // 36
|
||||
unsigned short ExtFlag; // 40
|
||||
unsigned short FSVersion; // 42
|
||||
unsigned long RootCluster; // 44
|
||||
unsigned short FSInfoSector; // 48
|
||||
unsigned short BootBackup; // 50
|
||||
unsigned char Res3[12]; // 52
|
||||
unsigned char Drive; // 64
|
||||
unsigned char Res4; // 65
|
||||
unsigned char ExtBootSignature; // 66
|
||||
unsigned long VolumeID; // 67
|
||||
unsigned char VolumeLabel[11]; // 71
|
||||
unsigned char SysType[8]; // 82
|
||||
unsigned char Res2[418]; // 90
|
||||
unsigned long Signature1; // 508
|
||||
unsigned char magic0; // 0
|
||||
unsigned char res0; // 1
|
||||
unsigned char magic1; // 2
|
||||
unsigned char OEMName[8]; // 3
|
||||
unsigned short BytesPerSector; // 11
|
||||
unsigned char SectorsPerCluster; // 13
|
||||
unsigned short ReservedSectors; // 14
|
||||
unsigned char FATCount; // 16
|
||||
unsigned short RootEntries; // 17
|
||||
unsigned short Sectors; // 19
|
||||
unsigned char Media; // 21
|
||||
unsigned short FATSectors; // 22
|
||||
unsigned short SectorsPerTrack; // 24
|
||||
unsigned short Heads; // 26
|
||||
unsigned long HiddenSectors; // 28
|
||||
unsigned long SectorsHuge; // 32
|
||||
unsigned long FATSectors32; // 36
|
||||
unsigned short ExtFlag; // 40
|
||||
unsigned short FSVersion; // 42
|
||||
unsigned long RootCluster; // 44
|
||||
unsigned short FSInfoSector; // 48
|
||||
unsigned short BootBackup; // 50
|
||||
unsigned char Res3[12]; // 52
|
||||
unsigned char Drive; // 64
|
||||
unsigned char Res4; // 65
|
||||
unsigned char ExtBootSignature; // 66
|
||||
unsigned long VolumeID; // 67
|
||||
unsigned char VolumeLabel[11]; // 71
|
||||
unsigned char SysType[8]; // 82
|
||||
unsigned char Res2[418]; // 90
|
||||
unsigned long Signature1; // 508
|
||||
} FAT32_BOOT_SECTOR, *PFAT32_BOOT_SECTOR;
|
||||
|
||||
typedef struct _FAT32_FSINFO
|
||||
{
|
||||
unsigned long LeadSig; // 0
|
||||
unsigned char Res1[480]; // 4
|
||||
unsigned long StrucSig; // 484
|
||||
unsigned long FreeCount; // 488
|
||||
unsigned long NextFree; // 492
|
||||
unsigned long Res2[3]; // 496
|
||||
unsigned long TrailSig; // 508
|
||||
unsigned long LeadSig; // 0
|
||||
unsigned char Res1[480]; // 4
|
||||
unsigned long StrucSig; // 484
|
||||
unsigned long FreeCount; // 488
|
||||
unsigned long NextFree; // 492
|
||||
unsigned long Res2[3]; // 496
|
||||
unsigned long TrailSig; // 508
|
||||
} FAT32_FSINFO, *PFAT32_FSINFO;
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct _FORMAT_CONTEXT
|
||||
{
|
||||
PFMIFSCALLBACK Callback;
|
||||
ULONG TotalSectorCount;
|
||||
ULONG CurrentSectorCount;
|
||||
BOOLEAN Success;
|
||||
ULONG Percent;
|
||||
PFMIFSCALLBACK Callback;
|
||||
ULONG TotalSectorCount;
|
||||
ULONG CurrentSectorCount;
|
||||
BOOLEAN Success;
|
||||
ULONG Percent;
|
||||
} FORMAT_CONTEXT, *PFORMAT_CONTEXT;
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Fat12Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
Fat12Format(HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
|
||||
NTSTATUS
|
||||
Fat16Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
Fat16Format(HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
|
||||
NTSTATUS
|
||||
Fat32Format (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
Fat32Format(HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFORMAT_CONTEXT Context);
|
||||
|
||||
VOID
|
||||
UpdateProgress (PFORMAT_CONTEXT Context,
|
||||
ULONG Increment);
|
||||
UpdateProgress(PFORMAT_CONTEXT Context,
|
||||
ULONG Increment);
|
||||
|
||||
VOID
|
||||
VfatPrint(PCHAR Format, ...);
|
||||
|
|
|
@ -12,416 +12,419 @@
|
|||
#include <debug.h>
|
||||
|
||||
static ULONG
|
||||
GetShiftCount(ULONG Value)
|
||||
GetShiftCount(IN ULONG Value)
|
||||
{
|
||||
ULONG i = 1;
|
||||
while (Value > 0)
|
||||
ULONG i = 1;
|
||||
|
||||
while (Value > 0)
|
||||
{
|
||||
i++;
|
||||
Value /= 2;
|
||||
i++;
|
||||
Value /= 2;
|
||||
}
|
||||
return i - 2;
|
||||
|
||||
return i - 2;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
CalcVolumeSerialNumber(VOID)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
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);
|
||||
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;
|
||||
return Serial;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FatxWriteBootSector (IN HANDLE FileHandle,
|
||||
IN PFATX_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
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;
|
||||
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);
|
||||
/* 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));
|
||||
/* 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) */
|
||||
/* 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))
|
||||
/* 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;
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress (Context, 1);
|
||||
VfatxUpdateProgress(Context, 1);
|
||||
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fatx16WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
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;
|
||||
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);
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
/* FAT cluster 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
/* 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;
|
||||
/* 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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress (Context, 1);
|
||||
VfatxUpdateProgress(Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 4);
|
||||
/* 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 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))
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR) ;
|
||||
if ((FATSectors - i) <= Sectors)
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
Sectors = FATSectors - i;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress (Context, Sectors);
|
||||
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;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
Fatx32WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
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;
|
||||
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);
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
64 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 64 * 1024);
|
||||
/* 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 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
Buffer[2] = 0xff;
|
||||
Buffer[3] = 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))
|
||||
/* 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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress (Context, 1);
|
||||
VfatxUpdateProgress(Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 8);
|
||||
/* 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 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);
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR);
|
||||
|
||||
if ((FATSectors - i) <= Sectors)
|
||||
if ((FATSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = FATSectors - i;
|
||||
Sectors = FATSectors - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * 512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
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);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VfatxUpdateProgress (Context, Sectors);
|
||||
VfatxUpdateProgress(Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
FatxWriteRootDirectory (IN HANDLE FileHandle,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
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;
|
||||
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;
|
||||
/* Write cluster */
|
||||
RootDirSectors = 256 * 64 / 512;
|
||||
FirstRootDirSector = sizeof(FATX_BOOT_SECTOR) / 512 + FATSectors;
|
||||
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
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);
|
||||
/* 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 the buffer */
|
||||
memset(Buffer, 0xff, RootDirSectors * 512);
|
||||
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = FirstRootDirSector * 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))
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
RootDirSectors * 512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FatxFormat (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
BOOLEAN QuickFormat,
|
||||
PFORMAT_CONTEXT Context)
|
||||
FatxFormat(IN HANDLE FileHandle,
|
||||
IN PPARTITION_INFORMATION PartitionInfo,
|
||||
IN PDISK_GEOMETRY DiskGeometry,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
FATX_BOOT_SECTOR BootSector;
|
||||
ULONGLONG SectorCount;
|
||||
ULONG ClusterCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG FATSectors;
|
||||
FATX_BOOT_SECTOR BootSector;
|
||||
ULONGLONG SectorCount;
|
||||
ULONG ClusterCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG FATSectors;
|
||||
NTSTATUS Status;
|
||||
|
||||
NTSTATUS Status;
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >> GetShiftCount(512); /* Use shifting to avoid 64-bit division */
|
||||
|
||||
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;
|
||||
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);
|
||||
/* 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)
|
||||
if (ClusterCount > 65525)
|
||||
{
|
||||
Context->TotalSectorCount =
|
||||
1 + FATSectors + RootDirSectors;
|
||||
FATSectors = (((ClusterCount * 4) + 4095) & ~4095) >> GetShiftCount(512);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
Context->TotalSectorCount = SectorCount;
|
||||
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))
|
||||
Status = FatxWriteBootSector(FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("FatxWriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return 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))
|
||||
/* Write first FAT copy */
|
||||
if (ClusterCount > 65525)
|
||||
{
|
||||
DPRINT("FatxWriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
Status = Fatx32WriteFAT(FileHandle,
|
||||
0,
|
||||
FATSectors,
|
||||
Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Fatx16WriteFAT(FileHandle,
|
||||
0,
|
||||
FATSectors,
|
||||
Context);
|
||||
}
|
||||
|
||||
Status = FatxWriteRootDirectory (FileHandle,
|
||||
FATSectors,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("FatxWriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
DPRINT("FatxWriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!QuickFormat)
|
||||
Status = FatxWriteRootDirectory(FileHandle,
|
||||
FATSectors,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
DPRINT("FatxWriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
if (!QuickFormat)
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -13,164 +13,163 @@
|
|||
#include <debug.h>
|
||||
|
||||
NTSTATUS NTAPI
|
||||
VfatxFormat (PUNICODE_STRING DriveRoot,
|
||||
FMIFS_MEDIA_FLAG MediaFlag,
|
||||
PUNICODE_STRING Label,
|
||||
BOOLEAN QuickFormat,
|
||||
ULONG ClusterSize,
|
||||
PFMIFSCALLBACK Callback)
|
||||
VfatxFormat(IN PUNICODE_STRING DriveRoot,
|
||||
IN FMIFS_MEDIA_FLAG MediaFlag,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN ULONG ClusterSize,
|
||||
IN PFMIFSCALLBACK Callback)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
HANDLE FileHandle;
|
||||
PARTITION_INFORMATION PartitionInfo;
|
||||
FORMAT_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
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);
|
||||
DPRINT("VfatxFormat(DriveRoot '%wZ')\n", DriveRoot);
|
||||
|
||||
Context.TotalSectorCount = 0;
|
||||
Context.CurrentSectorCount = 0;
|
||||
Context.Callback = Callback;
|
||||
Context.Success = FALSE;
|
||||
Context.Percent = 0;
|
||||
Context.TotalSectorCount = 0;
|
||||
Context.CurrentSectorCount = 0;
|
||||
Context.Callback = Callback;
|
||||
Context.Success = FALSE;
|
||||
Context.Percent = 0;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DriveRoot,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DriveRoot,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status);
|
||||
return 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))
|
||||
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;
|
||||
DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (DiskGeometry.MediaType == FixedMedia)
|
||||
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);
|
||||
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))
|
||||
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;
|
||||
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;
|
||||
/*
|
||||
* FIXME: This is a hack!
|
||||
* Partitioning software MUST set the correct number of hidden sectors!
|
||||
*/
|
||||
PartitionInfo.HiddenSectors = DiskGeometry.SectorsPerTrack;
|
||||
}
|
||||
else
|
||||
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;
|
||||
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);
|
||||
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)
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Percent = 0;
|
||||
Callback (PROGRESS, 0, (PVOID)&Context.Percent);
|
||||
Context.Percent = 0;
|
||||
Callback(PROGRESS, 0, (PVOID)&Context.Percent);
|
||||
}
|
||||
|
||||
Status = FatxFormat (FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
QuickFormat,
|
||||
&Context);
|
||||
NtClose(FileHandle);
|
||||
Status = FatxFormat(FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
QuickFormat,
|
||||
&Context);
|
||||
NtClose(FileHandle);
|
||||
|
||||
if (Callback != NULL)
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
|
||||
Callback (DONE, 0, (PVOID)&Context.Success);
|
||||
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
|
||||
Callback(DONE, 0, (PVOID)&Context.Success);
|
||||
}
|
||||
|
||||
DPRINT("VfatxFormat() done. Status 0x%.08x\n", Status);
|
||||
DPRINT("VfatxFormat() done. Status 0x%.08x\n", Status);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
VfatxUpdateProgress (PFORMAT_CONTEXT Context,
|
||||
ULONG Increment)
|
||||
VfatxUpdateProgress(IN PFORMAT_CONTEXT Context,
|
||||
IN ULONG Increment)
|
||||
{
|
||||
ULONG NewPercent;
|
||||
ULONG NewPercent;
|
||||
|
||||
Context->CurrentSectorCount += (ULONGLONG)Increment;
|
||||
Context->CurrentSectorCount += (ULONGLONG)Increment;
|
||||
|
||||
NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
|
||||
|
||||
NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
|
||||
|
||||
if (NewPercent > Context->Percent)
|
||||
if (NewPercent > Context->Percent)
|
||||
{
|
||||
Context->Percent = NewPercent;
|
||||
Context->Callback (PROGRESS, 0, &Context->Percent);
|
||||
Context->Percent = NewPercent;
|
||||
Context->Callback(PROGRESS, 0, &Context->Percent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue