- Implemented FSCTL_GET_RETRIVAL_POINTERS.

- Call the storage driver for read/write requests to pagefiles directly.

svn path=/trunk/; revision=4669
This commit is contained in:
Hartmut Birr 2003-05-11 09:51:26 +00:00
parent 710b4c97a6
commit 7a801d3bd8
7 changed files with 209 additions and 253 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: create.c,v 1.55 2003/03/23 10:45:56 hbirr Exp $
/* $Id: create.c,v 1.56 2003/05/11 09:51:26 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/create.c
@ -464,46 +464,6 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return Status;
}
VOID STATIC
VfatPagingFileCreate(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
{
ULONG CurrentCluster, NextCluster, i;
NTSTATUS Status;
Fcb->Flags |= FCB_IS_PAGE_FILE;
Fcb->FatChainSize =
((Fcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
DeviceExt->FatInfo.BytesPerCluster);
if (Fcb->FatChainSize)
{
Fcb->FatChain =
ExAllocatePool(NonPagedPool, Fcb->FatChainSize * sizeof(ULONG));
}
if (DeviceExt->FatInfo.FatType == FAT32)
{
CurrentCluster = Fcb->entry.FirstCluster +
Fcb->entry.FirstClusterHigh * 65536;
}
else
{
CurrentCluster = Fcb->entry.FirstCluster;
}
i = 0;
if (Fcb->FatChainSize)
{
while (CurrentCluster != 0xffffffff)
{
Fcb->FatChain[i] = CurrentCluster;
Status = GetNextCluster (DeviceExt, CurrentCluster,
&NextCluster, FALSE);
i++;
CurrentCluster = NextCluster;
}
}
}
VOID STATIC
VfatSupersedeFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVFATFCB Fcb)
@ -663,6 +623,11 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
Stack->Parameters.Create.ShareAccess,
FileObject,
&pFcb->FCBShareAccess);
if (PagingFileCreate)
{
pFcb->Flags |= FCB_IS_PAGE_FILE;
}
}
else
{
@ -702,19 +667,35 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
return(STATUS_NOT_A_DIRECTORY);
}
if ((PagingFileCreate && !(pFcb->Flags & FCB_IS_PAGE_FILE)) ||
(!PagingFileCreate && (pFcb->Flags & FCB_IS_PAGE_FILE)))
{
/* FIXME:
* Do more checking for page files. It is possible,
* that the file was opened and closed previously
* as a normal cached file. In this case, the cache
* manager has referenced the fileobject and the fcb
* is held in memory. Try to remove the fileobject
* from cache manager and use the fcb.
*/
VfatCloseFile(DeviceExt, FileObject);
return(STATUS_INVALID_PARAMETER);
}
if (RequestedDisposition == FILE_OVERWRITE ||
RequestedDisposition == FILE_OVERWRITE_IF)
{
AllocationSize.QuadPart = 0;
Status = VfatSetAllocationSizeInformation (FileObject,
pFcb,
DeviceExt,
&AllocationSize);
if (!NT_SUCCESS (Status))
{
VfatCloseFile (DeviceExt, FileObject);
return(Status);
}
AllocationSize.QuadPart = 0;
Status = VfatSetAllocationSizeInformation (FileObject,
pFcb,
DeviceExt,
&AllocationSize);
if (!NT_SUCCESS (Status))
{
VfatCloseFile (DeviceExt, FileObject);
return(Status);
}
}
@ -730,15 +711,6 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
}
/*
* If this create was for a paging file then make sure all the
* information needed to manipulate it is locked in memory.
*/
if (PagingFileCreate)
{
VfatPagingFileCreate(DeviceExt, pFcb);
}
/* FIXME : test share access */
/* FIXME : test write access if requested */

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.35 2003/02/13 22:24:16 hbirr Exp $
/* $Id: dirwr.c,v 1.36 2003/05/11 09:51:26 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -510,7 +510,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
if (RequestedOptions & FILE_DIRECTORY_FILE)
{
CurrentCluster = 0xffffffff;
Status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE);
Status = NextCluster (DeviceExt, 0, &CurrentCluster, TRUE);
if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
{
vfatReleaseFCB(DeviceExt, pDirFcb);

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.27 2003/02/13 22:24:16 hbirr Exp $
/* $Id: fcb.c,v 1.28 2003/05/11 09:51:26 hbirr Exp $
*
*
* FILE: fcb.c
@ -82,8 +82,6 @@ vfatDestroyFCB(PVFATFCB pFCB)
FsRtlUninitializeFileLock(&pFCB->FileLock);
ExDeleteResourceLite(&pFCB->PagingIoResource);
ExDeleteResourceLite(&pFCB->MainResource);
if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
ExFreePool(pFCB->FatChain);
ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
}
@ -331,7 +329,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
Size += pVCB->FatInfo.BytesPerCluster;
Status = NextCluster (pVCB, NULL, FirstCluster, &CurrentCluster, FALSE);
Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
}
}
else
@ -421,7 +419,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
while (CurrentCluster != 0xffffffff)
{
Size += vcb->FatInfo.BytesPerCluster;
Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
Status = NextCluster (vcb, FirstCluster, &CurrentCluster, FALSE);
}
}
}

View file

@ -1,4 +1,4 @@
/* $Id: finfo.c,v 1.27 2003/02/13 22:24:16 hbirr Exp $
/* $Id: finfo.c,v 1.28 2003/05/11 09:51:26 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -441,7 +441,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
{
if (FirstCluster == 0)
{
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &FirstCluster, TRUE);
Status = NextCluster (DeviceExt, FirstCluster, &FirstCluster, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NextCluster failed. Status = %x\n", Status);
@ -451,7 +451,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
{
return STATUS_DISK_FULL;
}
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(NewSize - 1, ClusterSize),
&NCluster, TRUE);
if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
@ -461,7 +461,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
Status = STATUS_SUCCESS;
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
{
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE);
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0);
Cluster = NCluster;
}
@ -472,24 +472,24 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
}
else
{
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
Status = OffsetToCluster(DeviceExt, FirstCluster,
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
&Cluster, FALSE);
/* FIXME: Check status */
/* Cluster points now to the last cluster within the chain */
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(NewSize - 1, ClusterSize),
&NCluster, TRUE);
if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
{
/* disk is full */
NCluster = Cluster;
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE);
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0xffffffff);
Cluster = NCluster;
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
{
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE);
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0);
Cluster = NCluster;
}
@ -503,12 +503,12 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize);
if (NewSize > 0)
{
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
Status = OffsetToCluster(DeviceExt, Cluster,
ROUND_DOWN(NewSize - 1, ClusterSize),
&Cluster, FALSE);
NCluster = Cluster;
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE);
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0xffffffff);
Cluster = NCluster;
}
@ -522,7 +522,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
}
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
{
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &NCluster, FALSE);
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0);
Cluster = NCluster;
}
@ -660,14 +660,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %x\n", SystemBuffer);
if (FCB->Flags & FCB_IS_PAGE_FILE)
{
if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, CanWait))
{
return(VfatQueueRequest (IrpContext));
}
}
else
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, CanWait))
{
@ -707,11 +700,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
RC = STATUS_NOT_SUPPORTED;
}
if (FCB->Flags & FCB_IS_PAGE_FILE)
{
ExReleaseResourceLite(&FCB->PagingIoResource);
}
else
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: fsctl.c,v 1.14 2003/02/13 22:24:17 hbirr Exp $
/* $Id: fsctl.c,v 1.15 2003/05/11 09:51:26 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -392,6 +392,112 @@ VfatVerify (PVFAT_IRP_CONTEXT IrpContext)
return(STATUS_INVALID_DEVICE_REQUEST);
}
static NTSTATUS
VfatGetVolumeBitmap(PVFAT_IRP_CONTEXT IrpContext)
{
DPRINT("VfatGetVolumeBitmap (IrpContext %x)\n", IrpContext);
return STATUS_INVALID_DEVICE_REQUEST;
}
static NTSTATUS
VfatGetRetrievalPointers(PVFAT_IRP_CONTEXT IrpContext)
{
PIO_STACK_LOCATION Stack;
LARGE_INTEGER Vcn;
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
PFILE_OBJECT FileObject;
ULONG MaxExtentCount;
PVFATFCB Fcb;
PDEVICE_EXTENSION DeviceExt;
ULONG FirstCluster;
ULONG CurrentCluster;
ULONG LastCluster;
NTSTATUS Status;
DPRINT("VfatGetRetrievalPointers(IrpContext %x)\n", IrpContext);
DeviceExt = IrpContext->DeviceExt;
FileObject = IrpContext->FileObject;
Stack = IrpContext->Stack;
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(LARGE_INTEGER) ||
Stack->Parameters.DeviceIoControl.Type3InputBuffer == NULL)
{
return STATUS_INVALID_PARAMETER;
}
if (IrpContext->Irp->UserBuffer == NULL ||
Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_RETRIEVAL_DESCRIPTOR) + sizeof(MAPPING_PAIR))
{
return STATUS_BUFFER_TOO_SMALL;
}
Fcb = FileObject->FsContext;
ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
Vcn = *(PLARGE_INTEGER)Stack->Parameters.DeviceIoControl.Type3InputBuffer;
RetrievalPointers = IrpContext->Irp->UserBuffer;
MaxExtentCount = ((Stack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(GET_RETRIEVAL_DESCRIPTOR)) / sizeof(MAPPING_PAIR));
if (Vcn.QuadPart >= Fcb->RFCB.FileSize.QuadPart / DeviceExt->FatInfo.BytesPerCluster)
{
Status = STATUS_INVALID_PARAMETER;
goto ByeBye;
}
CurrentCluster = FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
Status = OffsetToCluster(DeviceExt, FirstCluster,
Vcn.u.LowPart * DeviceExt->FatInfo.BytesPerCluster,
&CurrentCluster, FALSE);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
RetrievalPointers->StartVcn = Vcn.QuadPart;
RetrievalPointers->NumberOfPairs = 0;
RetrievalPointers->Pair[0].Lcn = CurrentCluster - 2;
LastCluster = 0;
while (CurrentCluster != 0xffffffff && RetrievalPointers->NumberOfPairs < MaxExtentCount)
{
LastCluster = CurrentCluster;
Status = NextCluster(DeviceExt, CurrentCluster, &CurrentCluster, FALSE);
Vcn.QuadPart++;
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
if (LastCluster + 1 != CurrentCluster)
{
RetrievalPointers->Pair[RetrievalPointers->NumberOfPairs].Vcn = Vcn.QuadPart;
RetrievalPointers->NumberOfPairs++;
if (RetrievalPointers->NumberOfPairs < MaxExtentCount)
{
RetrievalPointers->Pair[RetrievalPointers->NumberOfPairs].Lcn = CurrentCluster - 2;
}
}
}
IrpContext->Irp->IoStatus.Information = sizeof(GET_RETRIEVAL_DESCRIPTOR) + sizeof(MAPPING_PAIR) * RetrievalPointers->NumberOfPairs;
Status = STATUS_SUCCESS;
ByeBye:
ExReleaseResourceLite(&Fcb->MainResource);
return Status;
}
static NTSTATUS
VfatMoveFile(PVFAT_IRP_CONTEXT IrpContext)
{
DPRINT("VfatMoveFile(IrpContext %x)\n", IrpContext);
return STATUS_INVALID_DEVICE_REQUEST;
}
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
/*
@ -404,12 +510,28 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
assert (IrpContext);
assert (IrpContext->Irp);
assert (IrpContext->Stack);
IrpContext->Irp->IoStatus.Information = 0;
switch (IrpContext->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
switch(IrpContext->Stack->Parameters.DeviceIoControl.IoControlCode)
{
case FSCTL_GET_VOLUME_BITMAP:
Status = VfatGetVolumeBitmap(IrpContext);
break;
case FSCTL_GET_RETRIEVAL_POINTERS:
Status = VfatGetRetrievalPointers(IrpContext);
break;
case FSCTL_MOVE_FILE:
Status = VfatMoveFile(IrpContext);
break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
}
break;
case IRP_MN_MOUNT_VOLUME:
@ -427,7 +549,6 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
}
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.55 2003/02/13 22:24:17 hbirr Exp $
/* $Id: rw.c,v 1.56 2003/05/11 09:51:26 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -24,7 +24,6 @@
NTSTATUS
NextCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend)
@ -33,88 +32,7 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
* necessary
*/
{
if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
{
ULONG i;
PULONG FatChain;
NTSTATUS Status;
DPRINT("NextCluster(Fcb %x, FirstCluster %x, Extend %d)\n", Fcb,
FirstCluster, Extend);
if (Fcb->FatChainSize == 0)
{
/* Paging file with zero length. */
*CurrentCluster = 0xffffffff;
if (Extend)
{
Fcb->FatChain = ExAllocatePool(NonPagedPool, sizeof(ULONG));
if (Fcb->FatChain == NULL)
{
return(STATUS_NO_MEMORY);
}
Status = GetNextCluster(DeviceExt, 0, CurrentCluster, TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(Fcb->FatChain);
return(Status);
}
Fcb->FatChain[0] = *CurrentCluster;
Fcb->FatChainSize = 1;
return Status;
}
else
{
return STATUS_UNSUCCESSFUL;
}
}
else
{
for (i = 0; i < Fcb->FatChainSize; i++)
{
if (Fcb->FatChain[i] == *CurrentCluster)
break;
}
if (i >= Fcb->FatChainSize)
{
return STATUS_UNSUCCESSFUL;
}
if (i == Fcb->FatChainSize - 1)
{
if (Extend)
{
FatChain = ExAllocatePool(NonPagedPool,
(i + 2) * sizeof(ULONG));
if (!FatChain)
{
*CurrentCluster = 0xffffffff;
return STATUS_NO_MEMORY;
}
Status = GetNextCluster(DeviceExt, *CurrentCluster,
CurrentCluster, TRUE);
if (NT_SUCCESS(Status) && *CurrentCluster != 0xffffffff)
{
memcpy(FatChain, Fcb->FatChain, (i + 1) * sizeof(ULONG));
FatChain[i + 1] = *CurrentCluster;
ExFreePool(Fcb->FatChain);
Fcb->FatChain = FatChain;
Fcb->FatChainSize = i + 2;
}
else
{
ExFreePool(FatChain);
}
return Status;
}
else
{
*CurrentCluster = 0xffffffff;
return STATUS_SUCCESS;
}
}
*CurrentCluster = Fcb->FatChain[i + 1];
return STATUS_SUCCESS;
}
}
if (FirstCluster == 1)
if (FirstCluster == 1)
{
(*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS);
@ -146,7 +64,6 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
NTSTATUS
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
ULONG FileOffset,
PULONG Cluster,
@ -168,68 +85,6 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
KeBugCheck(0);
}
if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
{
ULONG NCluster;
ULONG Offset = FileOffset / DeviceExt->FatInfo.BytesPerCluster;
PULONG FatChain;
int i;
if (Fcb->FatChainSize == 0)
{
DbgPrint("OffsetToCluster is called with FirstCluster = %x"
" and Fcb->FatChainSize = 0!\n", FirstCluster);
KeBugCheck(0);
}
if (Offset < Fcb->FatChainSize)
{
*Cluster = Fcb->FatChain[Offset];
return STATUS_SUCCESS;
}
else
{
if (!Extend)
{
*Cluster = 0xffffffff;
return STATUS_UNSUCCESSFUL;
}
else
{
FatChain = ExAllocatePool(NonPagedPool, (Offset + 1) * sizeof(ULONG));
if (!FatChain)
{
*Cluster = 0xffffffff;
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = Fcb->FatChain[Fcb->FatChainSize - 1];
FatChain[Fcb->FatChainSize - 1] = CurrentCluster;
for (i = Fcb->FatChainSize; i < Offset + 1; i++)
{
Status = GetNextCluster(DeviceExt, CurrentCluster, &CurrentCluster, TRUE);
if (!NT_SUCCESS(Status) || CurrentCluster == 0xFFFFFFFF)
{
while (i >= Fcb->FatChainSize)
{
WriteCluster(DeviceExt, FatChain[i - 1], 0xFFFFFFFF);
i--;
}
*Cluster = 0xffffffff;
ExFreePool(FatChain);
if (!NT_SUCCESS(Status))
return Status;
return STATUS_UNSUCCESSFUL;
}
FatChain[i] = CurrentCluster;
}
memcpy (FatChain, Fcb->FatChain, Fcb->FatChainSize * sizeof(ULONG));
ExFreePool(Fcb->FatChain);
Fcb->FatChain = FatChain;
Fcb->FatChainSize = Offset + 1;
}
}
*Cluster = CurrentCluster;
return(STATUS_SUCCESS);
}
if (FirstCluster == 1)
{
/* root of FAT16 or FAT12 */
@ -361,7 +216,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
{
CurrentCluster = Ccb->LastCluster;
}
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE);
if (!NT_SUCCESS(Status))
@ -399,7 +254,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
BytesDone = Length;
}
}
Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE);
}
while (StartCluster + ClusterCount == CurrentCluster && NT_SUCCESS(Status) && Length > BytesDone);
DPRINT("start %08x, next %08x, count %d\n",
@ -515,7 +370,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
CurrentCluster = Ccb->LastCluster;
}
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(WriteOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE);
@ -554,7 +409,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
BytesDone = Length;
}
}
Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE);
}
while (StartCluster + ClusterCount == CurrentCluster && NT_SUCCESS(Status) && Length > BytesDone);
DPRINT("start %08x, next %08x, count %d\n",
@ -609,6 +464,19 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
DPRINT("<%S>\n", Fcb->PathName);
if (Fcb->Flags & FCB_IS_PAGE_FILE)
{
PIO_STACK_LOCATION Stack;
PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
Stack = IoGetNextIrpStackLocation(IrpContext->Irp);
Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
DPRINT("Read from page file, disk offset %I64x\n", Stack->Parameters.Read.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status;
}
ByteOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
Length = IrpContext->Stack->Parameters.Read.Length;
BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
@ -833,7 +701,20 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
DPRINT("<%S>\n", Fcb->PathName);
/* fail if file is a directory and no paged read */
if (Fcb->Flags & FCB_IS_PAGE_FILE)
{
PIO_STACK_LOCATION Stack;
PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
Stack = IoGetNextIrpStackLocation(IrpContext->Irp);
Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
DPRINT("Write to page file, disk offset %I64x\n", Stack->Parameters.Write.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status;
}
/* fail if file is a directory and no paged read */
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_INVALID_PARAMETER;

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.56 2003/02/13 22:24:17 hbirr Exp $ */
/* $Id: vfat.h,v 1.57 2003/05/11 09:51:26 hbirr Exp $ */
#include <ddk/ntifs.h>
@ -233,9 +233,6 @@ typedef struct _VFATFCB
/* List of byte-range locks for this file */
FILE_LOCK FileLock;
/* Structure members used only for paging files. */
ULONG FatChainSize;
PULONG FatChain;
} VFATFCB, *PVFATFCB;
typedef struct _VFATCCB
@ -420,7 +417,6 @@ BOOL vfatIsFileNameValid (PWCHAR pFileName);
/* ----------------------------------------------------------- fat.c */
NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
ULONG FileOffset,
PULONG Cluster,
@ -512,7 +508,6 @@ NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend);