mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- Added vfatxlib.
svn path=/trunk/; revision=13286
This commit is contained in:
parent
ce143bb72c
commit
85d156faef
5 changed files with 716 additions and 0 deletions
24
reactos/include/fslib/vfatxlib.h
Normal file
24
reactos/include/fslib/vfatxlib.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS VFAT filesystem library
|
||||
* FILE: include/fslib/vfatlib.h
|
||||
* PURPOSE: Public definitions for vfat filesystem library
|
||||
*/
|
||||
#ifndef __VFATXLIB_H
|
||||
#define __VFATXLIB_H
|
||||
|
||||
#include <fmifs.h>
|
||||
|
||||
NTSTATUS
|
||||
VfatxInitialize (VOID);
|
||||
|
||||
NTSTATUS
|
||||
VfatxCleanup (VOID);
|
||||
|
||||
NTSTATUS
|
||||
VfatxFormat (PUNICODE_STRING DriveRoot,
|
||||
ULONG MediaFlag,
|
||||
BOOLEAN QuickFormat,
|
||||
PFMIFSCALLBACK Callback);
|
||||
|
||||
#endif /*__VFATLIB_H */
|
18
reactos/lib/fslib/vfatxlib/Makefile
Normal file
18
reactos/lib/fslib/vfatxlib/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
# $Id$
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_TYPE = library
|
||||
|
||||
TARGET_NAME = vfatxlib
|
||||
|
||||
# require os code to explicitly request A/W version of structs/functions
|
||||
TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall -Werror
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
fatx.o \
|
||||
vfatxlib.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
431
reactos/lib/fslib/vfatxlib/fatx.c
Normal file
431
reactos/lib/fslib/vfatxlib/fatx.c
Normal file
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS VFATX filesystem library
|
||||
* FILE: fatx.c
|
||||
* PURPOSE: Fatx support
|
||||
* PROGRAMMERS: Hartmut Birr
|
||||
* REVISIONS:
|
||||
*/
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <ddk/ntddscsi.h>
|
||||
#include <mem.h>
|
||||
#include "vfatxlib.h"
|
||||
|
||||
|
||||
static ULONG
|
||||
GetShiftCount(ULONG Value)
|
||||
{
|
||||
ULONG i = 1;
|
||||
while (Value > 0)
|
||||
{
|
||||
i++;
|
||||
Value /= 2;
|
||||
}
|
||||
return i - 2;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
CalcVolumeSerialNumber(VOID)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
ULONG Serial;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
|
||||
Buffer = (PUCHAR)&Serial;
|
||||
Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
|
||||
Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
|
||||
Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
|
||||
Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
|
||||
|
||||
return Serial;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FatxWriteBootSector (IN HANDLE FileHandle,
|
||||
IN PFATX_BOOT_SECTOR BootSector,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR NewBootSector;
|
||||
LARGE_INTEGER FileOffset;
|
||||
|
||||
/* Allocate buffer for new bootsector */
|
||||
NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(FATX_BOOT_SECTOR));
|
||||
if (NewBootSector == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
/* Zero the new bootsector */
|
||||
memset(NewBootSector, 0, sizeof(FATX_BOOT_SECTOR));
|
||||
|
||||
/* Copy FAT16 BPB to new bootsector */
|
||||
memcpy(NewBootSector, BootSector, 18); /* FAT16 BPB length (up to (not including) Res2) */
|
||||
|
||||
/* Write sector 0 */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
NewBootSector,
|
||||
sizeof(FATX_BOOT_SECTOR),
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
|
||||
/* Free the new boot sector */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
Fatx16WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Sectors;
|
||||
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
32 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 32 * 1024);
|
||||
|
||||
/* FAT cluster 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
|
||||
/* FAT cluster 1 */
|
||||
Buffer[2] = 0xff; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
|
||||
Buffer[3] = 0xff;
|
||||
|
||||
/* Write first sector of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset * 512) + sizeof(FATX_BOOT_SECTOR);
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 4);
|
||||
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 32 * 1024 / 512;
|
||||
for (i = 1; i < FATSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR) ;
|
||||
if ((FATSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = FATSectors - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * 512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
Fatx32WriteFAT (IN HANDLE FileHandle,
|
||||
IN ULONG SectorOffset,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i;
|
||||
ULONG Sectors;
|
||||
|
||||
/* Allocate buffer */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
64 * 1024);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0, 64 * 1024);
|
||||
|
||||
/* FAT cluster 0 */
|
||||
Buffer[0] = 0xf8; /* Media type */
|
||||
Buffer[1] = 0xff;
|
||||
Buffer[2] = 0xff;
|
||||
Buffer[3] = 0x0f;
|
||||
/* FAT cluster 1 */
|
||||
Buffer[4] = 0xff; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
|
||||
Buffer[5] = 0xff;
|
||||
Buffer[6] = 0xff;
|
||||
Buffer[7] = 0x0f;
|
||||
|
||||
/* Write first sector of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset * 512) + sizeof(FATX_BOOT_SECTOR);
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
UpdateProgress (Context, 1);
|
||||
|
||||
/* Zero the begin of the buffer */
|
||||
memset(Buffer, 0, 8);
|
||||
|
||||
/* Zero the rest of the FAT */
|
||||
Sectors = 64 * 1024 / 512;
|
||||
for (i = 1; i < FATSectors; i += Sectors)
|
||||
{
|
||||
/* Zero some sectors of the FAT */
|
||||
FileOffset.QuadPart = (SectorOffset + i) * 512 + sizeof(FATX_BOOT_SECTOR);
|
||||
|
||||
if ((FATSectors - i) <= Sectors)
|
||||
{
|
||||
Sectors = FATSectors - i;
|
||||
}
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
Sectors * 512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
UpdateProgress (Context, Sectors);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
FatxWriteRootDirectory (IN HANDLE FileHandle,
|
||||
IN ULONG FATSectors,
|
||||
IN OUT PFORMAT_CONTEXT Context)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUCHAR Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG FirstRootDirSector;
|
||||
ULONG RootDirSectors;
|
||||
|
||||
/* Write cluster */
|
||||
RootDirSectors = 256 * 64 / 512;
|
||||
FirstRootDirSector = sizeof(FATX_BOOT_SECTOR) / 512 + FATSectors;
|
||||
|
||||
DPRINT("RootDirSectors = %lu\n", RootDirSectors);
|
||||
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
|
||||
|
||||
/* Allocate buffer for the cluster */
|
||||
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
RootDirSectors * 512);
|
||||
if (Buffer == NULL)
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
|
||||
/* Zero the buffer */
|
||||
memset(Buffer, 0xff, RootDirSectors * 512);
|
||||
|
||||
/* Zero some sectors of the root directory */
|
||||
FileOffset.QuadPart = FirstRootDirSector * 512;
|
||||
|
||||
Status = NtWriteFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Buffer,
|
||||
RootDirSectors * 512,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FatxFormat (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
BOOLEAN QuickFormat,
|
||||
PFORMAT_CONTEXT Context)
|
||||
{
|
||||
FATX_BOOT_SECTOR BootSector;
|
||||
ULONGLONG SectorCount;
|
||||
ULONG ClusterCount;
|
||||
ULONG RootDirSectors;
|
||||
ULONG FATSectors;
|
||||
|
||||
NTSTATUS Status;
|
||||
|
||||
SectorCount = PartitionInfo->PartitionLength.QuadPart >> GetShiftCount(512); /* Use shifting to avoid 64-bit division */
|
||||
|
||||
memset(&BootSector, 0, sizeof(FATX_BOOT_SECTOR));
|
||||
memcpy(&BootSector.SysType[0], "FATX", 4);
|
||||
BootSector.SectorsPerCluster = 32;
|
||||
BootSector.FATCount = 1;
|
||||
BootSector.VolumeID = CalcVolumeSerialNumber();
|
||||
RootDirSectors = 256 * 64 / 512;
|
||||
|
||||
/* Calculate number of FAT sectors */
|
||||
ClusterCount = SectorCount >> GetShiftCount(32);
|
||||
|
||||
if (ClusterCount > 65525)
|
||||
{
|
||||
FATSectors = (((ClusterCount * 4) + 4095) & ~4095) >> GetShiftCount(512);
|
||||
}
|
||||
else
|
||||
{
|
||||
FATSectors = (((ClusterCount * 2) + 4095) & ~4095) >> GetShiftCount(512);
|
||||
}
|
||||
DPRINT("FATSectors = %hu\n", FATSectors);
|
||||
|
||||
/* Init context data */
|
||||
if (QuickFormat)
|
||||
{
|
||||
Context->TotalSectorCount =
|
||||
1 + FATSectors + RootDirSectors;
|
||||
}
|
||||
else
|
||||
{
|
||||
Context->TotalSectorCount = SectorCount;
|
||||
}
|
||||
|
||||
Status = FatxWriteBootSector (FileHandle,
|
||||
&BootSector,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("FatxWriteBootSector() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Write first FAT copy */
|
||||
if (ClusterCount > 65525)
|
||||
{
|
||||
Status = Fatx32WriteFAT (FileHandle,
|
||||
0,
|
||||
FATSectors,
|
||||
Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Fatx16WriteFAT (FileHandle,
|
||||
0,
|
||||
FATSectors,
|
||||
Context);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("FatxWriteFAT() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = FatxWriteRootDirectory (FileHandle,
|
||||
FATSectors,
|
||||
Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("FatxWriteRootDirectory() failed with status 0x%.08x\n", Status);
|
||||
}
|
||||
|
||||
if (!QuickFormat)
|
||||
{
|
||||
/* FIXME: Fill remaining sectors */
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
198
reactos/lib/fslib/vfatxlib/vfatxlib.c
Normal file
198
reactos/lib/fslib/vfatxlib/vfatxlib.c
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS VFATx filesystem library
|
||||
* FILE: vfatxlib.c
|
||||
* PURPOSE: Main API
|
||||
* PROGRAMMERS: Hartmut Birr
|
||||
* REVISIONS:
|
||||
* CSH 05/04-2003 Created
|
||||
*/
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <ddk/ntddscsi.h>
|
||||
#include <fslib/vfatxlib.h>
|
||||
#include "vfatxlib.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
NTSTATUS
|
||||
VfatxInitialize(VOID)
|
||||
{
|
||||
DPRINT("VfatxInitialize()\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
VfatxFormat (PUNICODE_STRING DriveRoot,
|
||||
ULONG MediaFlag,
|
||||
BOOLEAN QuickFormat,
|
||||
PFMIFSCALLBACK Callback)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
DISK_GEOMETRY DiskGeometry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
HANDLE FileHandle;
|
||||
PARTITION_INFORMATION PartitionInfo;
|
||||
FORMAT_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("VfatxFormat(DriveRoot '%wZ')\n", DriveRoot);
|
||||
|
||||
Context.TotalSectorCount = 0;
|
||||
Context.CurrentSectorCount = 0;
|
||||
Context.Callback = Callback;
|
||||
Context.Success = FALSE;
|
||||
Context.Percent = 0;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DriveRoot,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = NtDeviceIoControlFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
||||
NULL,
|
||||
0,
|
||||
&DiskGeometry,
|
||||
sizeof(DISK_GEOMETRY));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (DiskGeometry.MediaType == FixedMedia)
|
||||
{
|
||||
DPRINT("Cylinders %I64d\n", DiskGeometry.Cylinders.QuadPart);
|
||||
DPRINT("TracksPerCylinder %ld\n", DiskGeometry.TracksPerCylinder);
|
||||
DPRINT("SectorsPerTrack %ld\n", DiskGeometry.SectorsPerTrack);
|
||||
DPRINT("BytesPerSector %ld\n", DiskGeometry.BytesPerSector);
|
||||
DPRINT("DiskSize %I64d\n",
|
||||
DiskGeometry.Cylinders.QuadPart *
|
||||
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
||||
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
||||
(ULONGLONG)DiskGeometry.BytesPerSector);
|
||||
|
||||
Status = NtDeviceIoControlFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
IOCTL_DISK_GET_PARTITION_INFO,
|
||||
NULL,
|
||||
0,
|
||||
&PartitionInfo,
|
||||
sizeof(PARTITION_INFORMATION));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IOCTL_DISK_GET_PARTITION_INFO failed with status 0x%.08x\n", Status);
|
||||
NtClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: This is a hack!
|
||||
* Partitioning software MUST set the correct number of hidden sectors!
|
||||
*/
|
||||
PartitionInfo.HiddenSectors = DiskGeometry.SectorsPerTrack;
|
||||
}
|
||||
else
|
||||
{
|
||||
PartitionInfo.PartitionType = 0;
|
||||
PartitionInfo.StartingOffset.QuadPart = 0ULL;
|
||||
PartitionInfo.PartitionLength.QuadPart =
|
||||
DiskGeometry.Cylinders.QuadPart *
|
||||
(ULONGLONG)DiskGeometry.TracksPerCylinder *
|
||||
(ULONGLONG)DiskGeometry.SectorsPerTrack *
|
||||
(ULONGLONG)DiskGeometry.BytesPerSector;
|
||||
PartitionInfo.HiddenSectors = 0;
|
||||
PartitionInfo.PartitionNumber = 0;
|
||||
PartitionInfo.BootIndicator = FALSE;
|
||||
PartitionInfo.RewritePartition = FALSE;
|
||||
PartitionInfo.RecognizedPartition = FALSE;
|
||||
}
|
||||
|
||||
DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
|
||||
DPRINT("StartingOffset %I64d\n", PartitionInfo.StartingOffset.QuadPart);
|
||||
DPRINT("PartitionLength %I64d\n", PartitionInfo.PartitionLength.QuadPart);
|
||||
DPRINT("HiddenSectors %lu\n", PartitionInfo.HiddenSectors);
|
||||
DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
|
||||
DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
|
||||
DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
|
||||
DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
|
||||
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Percent = 0;
|
||||
Callback (PROGRESS, 0, (PVOID)&Context.Percent);
|
||||
}
|
||||
|
||||
Status = FatxFormat (FileHandle,
|
||||
&PartitionInfo,
|
||||
&DiskGeometry,
|
||||
QuickFormat,
|
||||
&Context);
|
||||
NtClose(FileHandle);
|
||||
|
||||
if (Callback != NULL)
|
||||
{
|
||||
Context.Success = (BOOLEAN)(NT_SUCCESS(Status));
|
||||
Callback (DONE, 0, (PVOID)&Context.Success);
|
||||
}
|
||||
|
||||
DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
VfatxCleanup(VOID)
|
||||
{
|
||||
DPRINT("VfatxCleanup()\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
VfatxUpdateProgress (PFORMAT_CONTEXT Context,
|
||||
ULONG Increment)
|
||||
{
|
||||
ULONG NewPercent;
|
||||
|
||||
Context->CurrentSectorCount += (ULONGLONG)Increment;
|
||||
|
||||
|
||||
NewPercent = (Context->CurrentSectorCount * 100ULL) / Context->TotalSectorCount;
|
||||
|
||||
if (NewPercent > Context->Percent)
|
||||
{
|
||||
Context->Percent = NewPercent;
|
||||
Context->Callback (PROGRESS, 0, &Context->Percent);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
45
reactos/lib/fslib/vfatxlib/vfatxlib.h
Normal file
45
reactos/lib/fslib/vfatxlib/vfatxlib.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS VFAT filesystem library
|
||||
* FILE: vfatxlib.h
|
||||
*/
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <fslib/vfatlib.h>
|
||||
|
||||
typedef struct _FATX_BOOT_SECTOR
|
||||
{
|
||||
unsigned char SysType[4]; // 0
|
||||
unsigned long VolumeID; // 4
|
||||
unsigned long SectorsPerCluster; // 8
|
||||
unsigned short FATCount; // 12
|
||||
unsigned long Unknown; // 14
|
||||
unsigned char Unused[4078]; // 18
|
||||
} __attribute__((packed)) FATX_BOOT_SECTOR, *PFATX_BOOT_SECTOR;
|
||||
|
||||
|
||||
typedef struct _FORMAT_CONTEXT
|
||||
{
|
||||
PFMIFSCALLBACK Callback;
|
||||
ULONG TotalSectorCount;
|
||||
ULONG CurrentSectorCount;
|
||||
BOOLEAN Success;
|
||||
ULONG Percent;
|
||||
} FORMAT_CONTEXT, *PFORMAT_CONTEXT;
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FatxFormat (HANDLE FileHandle,
|
||||
PPARTITION_INFORMATION PartitionInfo,
|
||||
PDISK_GEOMETRY DiskGeometry,
|
||||
BOOLEAN QuickFormat,
|
||||
PFORMAT_CONTEXT Context);
|
||||
|
||||
VOID
|
||||
UpdateProgress (PFORMAT_CONTEXT Context,
|
||||
ULONG Increment);
|
||||
|
||||
/* EOF */
|
Loading…
Reference in a new issue