mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- 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:
parent
710b4c97a6
commit
7a801d3bd8
7 changed files with 209 additions and 253 deletions
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue