Changed the sector size from BLOCKSIZE to the size from the boot sector.

svn path=/trunk/; revision=3148
This commit is contained in:
Hartmut Birr 2002-06-26 18:36:41 +00:00
parent 40fe11fc2b
commit 518b1b7a13
8 changed files with 116 additions and 210 deletions

View file

@ -19,37 +19,27 @@
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
NTSTATUS NTSTATUS
VfatReadSectors (IN PDEVICE_OBJECT pDeviceObject, VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector, IN PLARGE_INTEGER ReadOffset,
IN ULONG SectorCount, IN ULONG ReadLength,
IN OUT PUCHAR Buffer) IN OUT PUCHAR Buffer)
{ {
LARGE_INTEGER sectorNumber;
PIRP Irp; PIRP Irp;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KEVENT event; KEVENT event;
NTSTATUS Status; NTSTATUS Status;
ULONG sectorSize;
sectorNumber.u.LowPart = DiskSector << 9;
sectorNumber.u.HighPart = DiskSector >> 23;
KeInitializeEvent (&event, NotificationEvent, FALSE); KeInitializeEvent (&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE * SectorCount;
DPRINT ("VfatReadSectors(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject, DiskSector, Buffer);
DPRINT ("sectorNumber %08lx:%08lx sectorSize %ld\n",
(unsigned long int) sectorNumber.u.LowPart,
(unsigned long int) sectorNumber.u.HighPart, sectorSize);
DPRINT ("VfatReadSectors(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
DPRINT ("Building synchronous FSD Request...\n"); DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ, Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
pDeviceObject, pDeviceObject,
Buffer, Buffer,
sectorSize, ReadLength,
&sectorNumber, ReadOffset,
&event, &event,
&IoStatus); &IoStatus);
@ -74,9 +64,8 @@ VfatReadSectors (IN PDEVICE_OBJECT pDeviceObject,
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("IO failed!!! VfatReadSectors : Error code: %x\n", Status); DPRINT ("IO failed!!! VfatReadSectors : Error code: %x\n", Status);
DPRINT ("(pDeviceObject %x, DiskSector %x, Buffer %x, offset 0x%x%x)\n", DPRINT ("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
pDeviceObject, DiskSector, Buffer, sectorNumber.u.HighPart, pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
sectorNumber.u.LowPart);
return (Status); return (Status);
} }
DPRINT ("Block request succeeded for %x\n", Irp); DPRINT ("Block request succeeded for %x\n", Irp);
@ -84,34 +73,27 @@ VfatReadSectors (IN PDEVICE_OBJECT pDeviceObject,
} }
NTSTATUS NTSTATUS
VfatWriteSectors (IN PDEVICE_OBJECT pDeviceObject, VfatWriteDisk (IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector, IN PLARGE_INTEGER WriteOffset,
IN ULONG SectorCount, IN ULONG WriteLength,
IN PUCHAR Buffer) IN PUCHAR Buffer)
{ {
LARGE_INTEGER sectorNumber;
PIRP Irp; PIRP Irp;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KEVENT event; KEVENT event;
NTSTATUS Status; NTSTATUS Status;
ULONG sectorSize;
DPRINT ("VfatWriteSectors(pDeviceObject %x, DiskSector %d, Buffer %x)\n", DPRINT ("VfatWriteSectors(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
pDeviceObject, DiskSector, Buffer); pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
sectorNumber.u.LowPart = DiskSector << 9;
sectorNumber.u.HighPart = DiskSector >> 23;
KeInitializeEvent (&event, NotificationEvent, FALSE); KeInitializeEvent (&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE * SectorCount;
DPRINT ("Building synchronous FSD Request...\n"); DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_WRITE, Irp = IoBuildSynchronousFsdRequest (IRP_MJ_WRITE,
pDeviceObject, pDeviceObject,
Buffer, Buffer,
sectorSize, WriteLength,
&sectorNumber, WriteOffset,
&event, &event,
&IoStatus); &IoStatus);

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.41 2002/05/15 18:05:00 ekohl Exp $ /* $Id: create.c,v 1.42 2002/06/26 18:36:41 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -346,7 +346,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
CHECKPOINT; CHECKPOINT;
Fcb->PathName[0]='\\'; Fcb->PathName[0]='\\';
Fcb->ObjectName = &Fcb->PathName[1]; Fcb->ObjectName = &Fcb->PathName[1];
Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE; Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector;
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
if (DeviceExt->FatInfo.FatType == FAT32) if (DeviceExt->FatInfo.FatType == FAT32)
{ {

View file

@ -1,5 +1,5 @@
/* /*
* $Id: fat.c,v 1.36 2002/03/18 22:37:12 hbirr Exp $ * $Id: fat.c,v 1.37 2002/06/26 18:36:41 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -110,7 +110,7 @@ Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
*NextCluster = 0; *NextCluster = 0;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -216,9 +216,9 @@ FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
*Cluster = 0; *Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster; StartCluster = DeviceExt->LastAvailableCluster;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{ {
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * BLOCKSIZE); DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -328,7 +328,7 @@ FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
PUSHORT CBlock; PUSHORT CBlock;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -494,7 +494,7 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -518,7 +518,7 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
CBlock[FATOffset + 1] = NewValue >> 4; CBlock[FATOffset + 1] = NewValue >> 4;
} }
/* Write the changed FAT sector(s) to disk */ /* Write the changed FAT sector(s) to disk */
FATsector = FATOffset / BLOCKSIZE; FATsector = FATOffset / DeviceExt->FatInfo.BytesPerSector;
CcSetDirtyPinnedData(Context, NULL); CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context); CcUnpinData(Context);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -644,63 +644,6 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt,
((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster); ((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
} }
NTSTATUS
VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PVOID Buffer,
ULONG Cluster,
ULONG Count)
/*
* FUNCTION: Load one ore more continus clusters from the physical device
*/
{
if (FirstCluster == 1)
{
return VfatReadSectors(DeviceExt->StorageDevice, Cluster,
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
else
{
ULONG Sector;
Sector = ClusterToSector(DeviceExt, Cluster);
return VfatReadSectors(DeviceExt->StorageDevice, Sector,
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
}
NTSTATUS
VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PVOID Buffer,
ULONG Cluster,
ULONG Count)
/*
* FUNCTION: Write a cluster to the physical device
*/
{
ULONG Sector;
NTSTATUS Status;
DPRINT("VfatWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt, Buffer, Cluster);
if (FirstCluster == 1)
{
Status = VfatWriteSectors(DeviceExt->StorageDevice, Cluster,
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
else
{
Sector = ClusterToSector(DeviceExt, Cluster);
Status = VfatWriteSectors(DeviceExt->StorageDevice, Sector,
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
return(Status);
}
NTSTATUS NTSTATUS
GetNextCluster(PDEVICE_EXTENSION DeviceExt, GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster, ULONG CurrentCluster,

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.14 2002/03/18 22:37:12 hbirr Exp $ /* $Id: fcb.c,v 1.15 2002/06/26 18:36:41 hbirr Exp $
* *
* *
* FILE: fcb.c * FILE: fcb.c
@ -206,7 +206,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
FCB = vfatNewFCB(L"\\"); FCB = vfatNewFCB(L"\\");
memset(FCB->entry.Filename, ' ', 11); memset(FCB->entry.Filename, ' ', 11);
FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE; FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
if (pVCB->FatInfo.FatType == FAT32) if (pVCB->FatInfo.FatType == FAT32)
{ {
@ -224,7 +224,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
else else
{ {
FCB->entry.FirstCluster = 1; FCB->entry.FirstCluster = 1;
Size = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE; Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
} }
FCB->RefCount = 1; FCB->RefCount = 1;
FCB->dirIndex = 0; FCB->dirIndex = 0;
@ -296,7 +296,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry); FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
if (FirstCluster == 1) if (FirstCluster == 1)
{ {
Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE; Size = vcb->FatInfo.rootDirectorySectors * vcb->FatInfo.BytesPerSector;
} }
else else
{ {

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: fsctl.c,v 1.7 2002/06/07 16:53:18 hbirr Exp $ /* $Id: fsctl.c,v 1.8 2002/06/26 18:36:41 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -51,6 +51,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
FATINFO FatInfo; FATINFO FatInfo;
ULONG Size; ULONG Size;
ULONG Sectors; ULONG Sectors;
LARGE_INTEGER Offset;
struct _BootSector* Boot; struct _BootSector* Boot;
*RecognizedFS = FALSE; *RecognizedFS = FALSE;
@ -111,14 +112,15 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
ReadSector:
Boot = ExAllocatePool(NonPagedPool, BLOCKSIZE); Boot = ExAllocatePool(NonPagedPool, DiskGeometry.BytesPerSector);
if (Boot == NULL) if (Boot == NULL)
{ {
*RecognizedFS=FALSE; *RecognizedFS=FALSE;
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
Status = VfatReadSectors(DeviceToMount, 0, 1, (PUCHAR) Boot); Offset.QuadPart = 0;
Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
FatInfo.VolumeID = Boot->VolumeID; FatInfo.VolumeID = Boot->VolumeID;
@ -311,7 +313,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
Fcb->Flags = FCB_IS_FAT; Fcb->Flags = FCB_IS_FAT;
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE; Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize; Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize; Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
@ -344,7 +346,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
wcscpy(VolumeFcb->PathName, L"$$Volume$$"); wcscpy(VolumeFcb->PathName, L"$$Volume$$");
VolumeFcb->ObjectName = VolumeFcb->PathName; VolumeFcb->ObjectName = VolumeFcb->PathName;
VolumeFcb->Flags = FCB_IS_VOLUME; VolumeFcb->Flags = FCB_IS_VOLUME;
VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * BLOCKSIZE; VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector;
VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize; VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize; VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
VolumeFcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; VolumeFcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.38 2002/03/18 22:37:13 hbirr Exp $ # $Id: makefile,v 1.39 2002/06/26 18:36:41 hbirr Exp $
PATH_TO_TOP = ../../.. PATH_TO_TOP = ../../..
@ -6,6 +6,8 @@ TARGET_TYPE = driver
TARGET_NAME = vfatfs TARGET_NAME = vfatfs
TARGET_GCCLIBS = gcc
TARGET_OBJECTS = \ TARGET_OBJECTS = \
blockdev.o \ blockdev.o \
cleanup.o \ cleanup.o \
@ -27,6 +29,8 @@ TARGET_OBJECTS = \
DEP_OBJECTS = $(TARGET_OBJECTS) DEP_OBJECTS = $(TARGET_OBJECTS)
TARGET_CLEAN = $(DEP_FILES) *.o *.sys *.sym
TARGET_CFLAGS = -g TARGET_CFLAGS = -g
include $(PATH_TO_TOP)/rules.mak include $(PATH_TO_TOP)/rules.mak

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.42 2002/06/10 21:17:57 hbirr Exp $ /* $Id: rw.c,v 1.43 2002/06/26 18:36:41 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -270,14 +270,15 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
ULONG FirstCluster; ULONG FirstCluster;
ULONG StartCluster; ULONG StartCluster;
ULONG ClusterCount; ULONG ClusterCount;
ULONG StartSector; LARGE_INTEGER StartOffset;
ULONG SectorCount;
PDEVICE_EXTENSION DeviceExt; PDEVICE_EXTENSION DeviceExt;
BOOLEAN First = TRUE; BOOLEAN First = TRUE;
PVFATFCB Fcb; PVFATFCB Fcb;
PVFATCCB Ccb; PVFATCCB Ccb;
NTSTATUS Status; NTSTATUS Status;
ULONG BytesDone; ULONG BytesDone;
ULONG BytesPerSector;
ULONG BytesPerCluster;
/* PRECONDITION */ /* PRECONDITION */
assert (IrpContext); assert (IrpContext);
@ -295,17 +296,18 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2;
Fcb = Ccb->pFcb; Fcb = Ccb->pFcb;
BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster;
assert(ReadOffset.QuadPart + Length <= ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BLOCKSIZE)); assert(ReadOffset.QuadPart + Length <= ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector));
assert(ReadOffset.QuadPart % BLOCKSIZE == 0); assert(ReadOffset.u.LowPart % BytesPerSector == 0);
assert(Length % BLOCKSIZE == 0); assert(Length % BytesPerSector == 0);
/* Is this a read of the FAT? */ /* Is this a read of the FAT? */
if (Fcb->Flags & FCB_IS_FAT) if (Fcb->Flags & FCB_IS_FAT)
{ {
Status = VfatReadSectors(DeviceExt->StorageDevice, ReadOffset.QuadPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
DeviceExt->FatInfo.FATStart + ReadOffset.u.LowPart / BLOCKSIZE, Status = VfatReadDisk(DeviceExt->StorageDevice, &ReadOffset, Length, Buffer);
Length / BLOCKSIZE, Buffer);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
@ -317,12 +319,10 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
} }
return Status; return Status;
} }
/* Is this a read of the Volume */ /* Is this a read of the Volume ? */
if (Fcb->Flags & FCB_IS_VOLUME) if (Fcb->Flags & FCB_IS_VOLUME)
{ {
Status = VfatReadSectors(DeviceExt->StorageDevice, Status = VfatReadDisk(DeviceExt->StorageDevice, &ReadOffset, Length, Buffer);
ReadOffset.QuadPart / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
*LengthRead = Length; *LengthRead = Length;
@ -344,16 +344,15 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
{ {
// Directory of FAT12/16 needs a special handling // Directory of FAT12/16 needs a special handling
CHECKPOINT; CHECKPOINT;
if (ReadOffset.u.LowPart + Length > DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE) if (ReadOffset.u.LowPart + Length > DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector)
{ {
Length = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE - ReadOffset.u.LowPart; Length = DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector - ReadOffset.u.LowPart;
} }
StartSector = DeviceExt->FatInfo.rootStart + ReadOffset.u.LowPart / BLOCKSIZE; ReadOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
SectorCount = Length / BLOCKSIZE;
// Fire up the read command // Fire up the read command
Status = VfatReadSectors (DeviceExt->StorageDevice, StartSector,
SectorCount, Buffer); Status = VfatReadDisk (DeviceExt->StorageDevice, &ReadOffset, Length, Buffer);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
*LengthRead += Length; *LengthRead += Length;
@ -368,7 +367,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
CurrentCluster = Ccb->LastCluster; CurrentCluster = Ccb->LastCluster;
} }
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster, Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
ROUND_DOWN(ReadOffset.u.LowPart, DeviceExt->FatInfo.BytesPerCluster), ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE); &CurrentCluster, FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -376,13 +375,12 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
} }
Ccb->LastCluster = CurrentCluster; Ccb->LastCluster = CurrentCluster;
Ccb->LastOffset = ROUND_DOWN (ReadOffset.u.LowPart, DeviceExt->FatInfo.BytesPerCluster); Ccb->LastOffset = ROUND_DOWN (ReadOffset.u.LowPart, BytesPerCluster);
while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{ {
StartCluster = CurrentCluster; StartCluster = CurrentCluster;
StartSector = ClusterToSector(DeviceExt, StartCluster); StartOffset.QuadPart = ClusterToSector(DeviceExt, StartCluster) * BytesPerSector;
SectorCount = 0;
BytesDone = 0; BytesDone = 0;
ClusterCount = 0; ClusterCount = 0;
@ -391,21 +389,18 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
ClusterCount++; ClusterCount++;
if (First) if (First)
{ {
BytesDone = min (Length, DeviceExt->FatInfo.BytesPerCluster - (ReadOffset.u.LowPart % DeviceExt->FatInfo.BytesPerCluster)); BytesDone = min (Length, BytesPerCluster - (ReadOffset.u.LowPart % BytesPerCluster));
SectorCount += BytesDone / BLOCKSIZE; StartOffset.QuadPart += ReadOffset.u.LowPart % BytesPerCluster;
StartSector += (ReadOffset.u.LowPart % DeviceExt->FatInfo.BytesPerCluster) / BLOCKSIZE;
First = FALSE; First = FALSE;
} }
else else
{ {
if (Length - BytesDone > DeviceExt->FatInfo.BytesPerCluster) if (Length - BytesDone > BytesPerCluster)
{ {
BytesDone += DeviceExt->FatInfo.BytesPerCluster; BytesDone += BytesPerCluster;
SectorCount += DeviceExt->FatInfo.BytesPerCluster / BLOCKSIZE;
} }
else else
{ {
SectorCount += (Length - BytesDone) / BLOCKSIZE;
BytesDone = Length; BytesDone = Length;
} }
} }
@ -416,11 +411,10 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
StartCluster, CurrentCluster, ClusterCount); StartCluster, CurrentCluster, ClusterCount);
Ccb->LastCluster = StartCluster + (ClusterCount - 1); Ccb->LastCluster = StartCluster + (ClusterCount - 1);
Ccb->LastOffset = ReadOffset.u.LowPart + (ClusterCount - 1) * DeviceExt->FatInfo.BytesPerCluster; Ccb->LastOffset = ReadOffset.u.LowPart + (ClusterCount - 1) * BytesPerCluster;
// Fire up the read command // Fire up the read command
Status = VfatReadSectors (DeviceExt->StorageDevice, StartSector, Status = VfatReadDisk (DeviceExt->StorageDevice, &StartOffset, BytesDone, Buffer);
SectorCount, Buffer);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
@ -444,13 +438,14 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
ULONG Count; ULONG Count;
ULONG FirstCluster; ULONG FirstCluster;
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG StartSector;
ULONG SectorCount;
ULONG BytesDone; ULONG BytesDone;
ULONG StartCluster; ULONG StartCluster;
ULONG ClusterCount; ULONG ClusterCount;
NTSTATUS Status; NTSTATUS Status;
BOOLEAN First = TRUE; BOOLEAN First = TRUE;
ULONG BytesPerSector;
ULONG BytesPerCluster;
LARGE_INTEGER StartOffset;
/* PRECONDITION */ /* PRECONDITION */
assert (IrpContext); assert (IrpContext);
@ -462,22 +457,22 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2;
Fcb = Ccb->pFcb; Fcb = Ccb->pFcb;
BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster;
BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
DPRINT("VfatWriteFileData(DeviceExt %x, FileObject %x, Buffer %x, " DPRINT("VfatWriteFileData(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, WriteOffset 0x%I64x), '%S'\n", DeviceExt, "Length %d, WriteOffset 0x%I64x), '%S'\n", DeviceExt,
IrpContext->FileObject, Buffer, Length, WriteOffset, IrpContext->FileObject, Buffer, Length, WriteOffset,
Fcb->PathName); Fcb->PathName);
assert(WriteOffset.QuadPart + Length <= ROUND_UP(Fcb->RFCB.AllocationSize.QuadPart, BLOCKSIZE)); assert(WriteOffset.QuadPart + Length <= Fcb->RFCB.AllocationSize.QuadPart);
assert(WriteOffset.u.LowPart % BLOCKSIZE == 0); assert(WriteOffset.u.LowPart % BytesPerSector == 0);
assert(Length % BLOCKSIZE == 0) assert(Length % BytesPerSector == 0)
// Is this a write of the volume ? // Is this a write of the volume ?
if (Fcb->Flags & FCB_IS_VOLUME) if (Fcb->Flags & FCB_IS_VOLUME)
{ {
Status = VfatWriteSectors(DeviceExt->StorageDevice, Status = VfatWriteDisk(DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
WriteOffset.QuadPart / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Volume writing failed, Status %x\n", Status); DPRINT1("Volume writing failed, Status %x\n", Status);
@ -488,15 +483,15 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
// Is this a write to the FAT ? // Is this a write to the FAT ?
if (Fcb->Flags & FCB_IS_FAT) if (Fcb->Flags & FCB_IS_FAT)
{ {
WriteOffset.u.LowPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
for (Count = 0; Count < DeviceExt->FatInfo.FATCount; Count++) for (Count = 0; Count < DeviceExt->FatInfo.FATCount; Count++)
{ {
Status = VfatWriteSectors(DeviceExt->StorageDevice, Status = VfatWriteDisk(DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
DeviceExt->FatInfo.FATStart + (Count * (ULONG)Fcb->RFCB.FileSize.u.LowPart + WriteOffset.u.LowPart) / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("FAT writing failed, Status %x\n", Status); DPRINT1("FAT writing failed, Status %x\n", Status);
} }
WriteOffset.u.LowPart += Fcb->RFCB.FileSize.u.LowPart;
} }
return Status; return Status;
} }
@ -509,14 +504,11 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
if (FirstCluster == 1) if (FirstCluster == 1)
{ {
assert(WriteOffset.u.LowPart + Length <= DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE); assert(WriteOffset.u.LowPart + Length <= DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector);
// Directory of FAT12/16 needs a special handling // Directory of FAT12/16 needs a special handling
StartSector = DeviceExt->FatInfo.rootStart + WriteOffset.u.LowPart / BLOCKSIZE; WriteOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
SectorCount = Length / BLOCKSIZE;
// Fire up the write command // Fire up the write command
Status = VfatWriteSectors (DeviceExt->StorageDevice, StartSector, Status = VfatWriteDisk (DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
SectorCount, Buffer);
return Status; return Status;
} }
@ -529,7 +521,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
} }
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster, Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
ROUND_DOWN(WriteOffset.u.LowPart, DeviceExt->FatInfo.BytesPerCluster), ROUND_DOWN(WriteOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE); &CurrentCluster, FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -538,13 +530,12 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
} }
Ccb->LastCluster = CurrentCluster; Ccb->LastCluster = CurrentCluster;
Ccb->LastOffset = ROUND_DOWN (WriteOffset.u.LowPart, DeviceExt->FatInfo.BytesPerCluster); Ccb->LastOffset = ROUND_DOWN (WriteOffset.u.LowPart, BytesPerCluster);
while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{ {
StartCluster = CurrentCluster; StartCluster = CurrentCluster;
StartSector = ClusterToSector(DeviceExt, StartCluster); StartOffset.QuadPart = ClusterToSector(DeviceExt, StartCluster) * BytesPerSector;
SectorCount = 0;
BytesDone = 0; BytesDone = 0;
ClusterCount = 0; ClusterCount = 0;
@ -553,21 +544,18 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
ClusterCount++; ClusterCount++;
if (First) if (First)
{ {
BytesDone = min (Length, DeviceExt->FatInfo.BytesPerCluster - (WriteOffset.u.LowPart % DeviceExt->FatInfo.BytesPerCluster)); BytesDone = min (Length, BytesPerCluster - (WriteOffset.u.LowPart % BytesPerCluster));
SectorCount += BytesDone / BLOCKSIZE; StartOffset.QuadPart += WriteOffset.u.LowPart % BytesPerCluster;
StartSector += (WriteOffset.u.LowPart % DeviceExt->FatInfo.BytesPerCluster) / BLOCKSIZE;
First = FALSE; First = FALSE;
} }
else else
{ {
if (Length - BytesDone > DeviceExt->FatInfo.BytesPerCluster) if (Length - BytesDone > BytesPerCluster)
{ {
BytesDone += DeviceExt->FatInfo.BytesPerCluster; BytesDone += BytesPerCluster;
SectorCount += DeviceExt->FatInfo.BytesPerCluster / BLOCKSIZE;
} }
else else
{ {
SectorCount += (Length - BytesDone) / BLOCKSIZE;
BytesDone = Length; BytesDone = Length;
} }
} }
@ -578,11 +566,10 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
StartCluster, CurrentCluster, ClusterCount); StartCluster, CurrentCluster, ClusterCount);
Ccb->LastCluster = StartCluster + (ClusterCount - 1); Ccb->LastCluster = StartCluster + (ClusterCount - 1);
Ccb->LastOffset = WriteOffset.u.LowPart + (ClusterCount - 1) * DeviceExt->FatInfo.BytesPerCluster; Ccb->LastOffset = WriteOffset.u.LowPart + (ClusterCount - 1) * BytesPerCluster;
// Fire up the write command // Fire up the write command
Status = VfatWriteSectors (DeviceExt->StorageDevice, StartSector, Status = VfatWriteDisk (DeviceExt->StorageDevice, &StartOffset, BytesDone, Buffer);
SectorCount, Buffer);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Buffer += BytesDone; Buffer += BytesDone;
@ -722,6 +709,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
LARGE_INTEGER ByteOffset; LARGE_INTEGER ByteOffset;
PVOID Buffer; PVOID Buffer;
PDEVICE_OBJECT DeviceToVerify; PDEVICE_OBJECT DeviceToVerify;
ULONG BytesPerSector;
assert(IrpContext); assert(IrpContext);
@ -748,6 +736,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset; ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
Length = IrpContext->Stack->Parameters.Read.Length; Length = IrpContext->Stack->Parameters.Read.Length;
BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
/* fail if file is a directory and no paged read */ /* fail if file is a directory and no paged read */
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO)) if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
@ -772,7 +761,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
} }
if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME)) if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME))
{ {
if (ByteOffset.u.LowPart % BLOCKSIZE != 0 || Length % BLOCKSIZE != 0) if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
{ {
DPRINT("%d %d\n", ByteOffset.u.LowPart, Length); DPRINT("%d %d\n", ByteOffset.u.LowPart, Length);
// non chached read must be sector aligned // non chached read must be sector aligned
@ -842,9 +831,9 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
{ {
// non cached read // non cached read
CHECKPOINT; CHECKPOINT;
if (ByteOffset.QuadPart + Length > ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BLOCKSIZE)) if (ByteOffset.QuadPart + Length > ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector))
{ {
Length = ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BLOCKSIZE) - ByteOffset.QuadPart; Length = ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart;
} }
Buffer = VfatGetUserBuffer(IrpContext->Irp); Buffer = VfatGetUserBuffer(IrpContext->Irp);
@ -854,8 +843,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
goto ByeBye; goto ByeBye;
} }
Status = VfatReadFileData(IrpContext, Buffer, Length, Status = VfatReadFileData(IrpContext, Buffer, Length, ByteOffset, &ReturnedLength);
ByteOffset, &ReturnedLength);
/* /*
if (Status == STATUS_VERIFY_REQUIRED) if (Status == STATUS_VERIFY_REQUIRED)
{ {
@ -927,6 +915,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
ULONG Length; ULONG Length;
ULONG OldAllocationSize; ULONG OldAllocationSize;
PVOID Buffer; PVOID Buffer;
ULONG BytesPerSector;
assert (IrpContext); assert (IrpContext);
@ -960,6 +949,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
ByteOffset = IrpContext->Stack->Parameters.Write.ByteOffset; ByteOffset = IrpContext->Stack->Parameters.Write.ByteOffset;
Length = IrpContext->Stack->Parameters.Write.Length; Length = IrpContext->Stack->Parameters.Write.Length;
BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
if (ByteOffset.u.HighPart && !(Fcb->Flags & FCB_IS_VOLUME)) if (ByteOffset.u.HighPart && !(Fcb->Flags & FCB_IS_VOLUME))
{ {
@ -967,7 +957,6 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
goto ByeBye; goto ByeBye;
} }
if (Fcb->Flags & (FCB_IS_FAT | FCB_IS_VOLUME) || if (Fcb->Flags & (FCB_IS_FAT | FCB_IS_VOLUME) ||
1 == vfatDirEntryGetFirstCluster (IrpContext->DeviceExt, &Fcb->entry)) 1 == vfatDirEntryGetFirstCluster (IrpContext->DeviceExt, &Fcb->entry))
{ {
@ -981,7 +970,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
if (IrpContext->Irp->Flags & (IRP_PAGING_IO|IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME)) if (IrpContext->Irp->Flags & (IRP_PAGING_IO|IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME))
{ {
if (ByteOffset.u.LowPart % BLOCKSIZE != 0 || Length % BLOCKSIZE != 0) if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
{ {
// non chached write must be sector aligned // non chached write must be sector aligned
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
@ -1003,9 +992,9 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto ByeBye; goto ByeBye;
} }
if (ByteOffset.u.LowPart + Length > ROUND_UP(Fcb->RFCB.AllocationSize.u.LowPart, BLOCKSIZE)) if (ByteOffset.u.LowPart + Length > ROUND_UP(Fcb->RFCB.AllocationSize.u.LowPart, BytesPerSector))
{ {
Length = ROUND_UP(Fcb->RFCB.FileSize.u.LowPart, BLOCKSIZE) - ByteOffset.u.LowPart; Length = ROUND_UP(Fcb->RFCB.FileSize.u.LowPart, BytesPerSector) - ByteOffset.u.LowPart;
} }
} }
@ -1108,9 +1097,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
goto ByeBye; goto ByeBye;
} }
Status = VfatWriteFileData(IrpContext, Buffer, Length, Status = VfatWriteFileData(IrpContext, Buffer, Length, ByteOffset);
ByteOffset);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
IrpContext->Irp->IoStatus.Information = Length; IrpContext->Irp->IoStatus.Information = Length;

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.42 2002/06/10 21:15:58 hbirr Exp $ */ /* $Id: vfat.h,v 1.43 2002/06/26 18:36:41 hbirr Exp $ */
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
@ -248,15 +248,15 @@ NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
/* ------------------------------------------------------ blockdev.c */ /* ------------------------------------------------------ blockdev.c */
NTSTATUS VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject, NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector, IN PLARGE_INTEGER ReadOffset,
IN ULONG SectorCount, IN ULONG ReadLength,
IN PUCHAR Buffer); IN PUCHAR Buffer);
NTSTATUS VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject, NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector, IN PLARGE_INTEGER WriteOffset,
IN ULONG SectorCount, IN ULONG WriteLength,
IN PUCHAR Buffer); IN PUCHAR Buffer);
NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
IN ULONG CtlCode, IN ULONG CtlCode,
@ -398,18 +398,6 @@ NTSTATUS GetNextSector (PDEVICE_EXTENSION DeviceExt,
PULONG NextSector, PULONG NextSector,
BOOLEAN Extend); BOOLEAN Extend);
NTSTATUS VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PVOID Buffer,
ULONG Cluster,
ULONG Count);
NTSTATUS VfatRawWriteCluster (PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PVOID Buffer,
ULONG Cluster,
ULONG Count);
NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt, NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
PLARGE_INTEGER Clusters); PLARGE_INTEGER Clusters);