From 035f768d4aea79b91403acef5f8142513f64d44a Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Tue, 15 Jan 2002 21:54:51 +0000 Subject: [PATCH] Added some fixes for accessing the page file. svn path=/trunk/; revision=2519 --- reactos/drivers/fs/vfat/create.c | 41 ++++++--- reactos/drivers/fs/vfat/fcb.c | 4 +- reactos/drivers/fs/vfat/rw.c | 147 ++++++++++++++++++++++++++++--- 3 files changed, 168 insertions(+), 24 deletions(-) diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index a1896c81bb6..aa67ad5540d 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $ +/* $Id: create.c,v 1.36 2002/01/15 21:54:51 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -643,7 +643,19 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) (Stack->Parameters. Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS)); if (NT_SUCCESS (Status)) + { + if (PagingFileCreate) + { + DPRINT("Creating a new paging file.\n"); + pCcb = FileObject->FsContext2; + pFcb = pCcb->pFcb; + pFcb->Flags |= FCB_IS_PAGE_FILE; + pFcb->FatChainSize = 0; + pFcb->FatChain = NULL; + } + Irp->IoStatus.Information = FILE_CREATED; + } /* FIXME set size if AllocationSize requested */ /* FIXME set extended attributes? */ /* FIXME set share access */ @@ -703,12 +715,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) if (PagingFileCreate) { ULONG CurrentCluster, NextCluster, i; - + DPRINT("Open an existing paging file\n"); pFcb->Flags |= FCB_IS_PAGE_FILE; pFcb->FatChainSize = - ((pFcb->entry.FileSize / DeviceExt->BytesPerCluster) + 2); - pFcb->FatChain = ExAllocatePool(NonPagedPool, + ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) / DeviceExt->BytesPerCluster); + if (pFcb->FatChainSize) + { + pFcb->FatChain = ExAllocatePool(NonPagedPool, pFcb->FatChainSize * sizeof(ULONG)); + } if (DeviceExt->FatType == FAT32) { @@ -721,16 +736,18 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) } i = 0; - while (CurrentCluster != 0xffffffff) - { - Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, + if (pFcb->FatChainSize) + { + while (CurrentCluster != 0xffffffff) + { + pFcb->FatChain[i] = CurrentCluster; + Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, FALSE); - pFcb->FatChain[i] = NextCluster; - i++; - CurrentCluster = NextCluster; - } - pFcb->FatChain[i] = 0xFFFFFFFF; + i++; + CurrentCluster = NextCluster; + } } + } /* * Check the file has the requested attributes diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index b3ff4b04c8b..0baee0a7624 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -1,4 +1,4 @@ -/* $Id: fcb.c,v 1.12 2002/01/08 00:49:01 dwelch Exp $ +/* $Id: fcb.c,v 1.13 2002/01/15 21:54:51 hbirr Exp $ * * * FILE: fcb.c @@ -58,6 +58,8 @@ vfatDestroyFCB(PVFATFCB pFCB) { ExDeleteResourceLite(&pFCB->PagingIoResource); ExDeleteResourceLite(&pFCB->MainResource); + if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize) + ExFreePool(pFCB->FatChain); ExFreePool (pFCB); } diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index 1ed7984b695..874a5ea73f3 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $ +/* $Id: rw.c,v 1.36 2002/01/15 21:54:51 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -40,10 +40,79 @@ NextCluster(PDEVICE_EXTENSION DeviceExt, { if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE) { - ULONG NextCluster; - NextCluster = Fcb->FatChain[(*CurrentCluster)]; - (*CurrentCluster) = NextCluster; - return(STATUS_SUCCESS); + 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) + { + return STATUS_UNSUCCESSFUL; + } + 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_UNSUCCESSFUL; + } + 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_UNSUCCESSFUL; + } + } + *CurrentCluster = Fcb->FatChain[i + 1]; + return STATUS_SUCCESS; + } } if (FirstCluster == 1) { @@ -90,19 +159,75 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster; ULONG i; NTSTATUS Status; + DPRINT("OffsetToCluster(DeviceExt %x, Fcb %x, FirstCluster %x," + " FileOffset %x, Cluster %x, Extend %d)\n", DeviceExt, + Fcb, FirstCluster, FileOffset, Cluster, Extend); + if (FirstCluster == 0) + { + DbgPrint("OffsetToCluster is called with FirstCluster = 0!\n"); + KeBugCheck(0); + } if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE) { ULONG NCluster; ULONG Offset = FileOffset / DeviceExt->BytesPerCluster; - if (Offset == 0) - { - (*Cluster) = FirstCluster; - } + 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 { - (*Cluster) = Fcb->FatChain[Offset - 1]; - } + 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) -- 2.17.1