Added some fixes for accessing the page file.

svn path=/trunk/; revision=2519
This commit is contained in:
Hartmut Birr 2002-01-15 21:54:51 +00:00
parent 550ffd05d5
commit 035f768d4a
3 changed files with 168 additions and 24 deletions

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -643,7 +643,19 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
(Stack->Parameters. (Stack->Parameters.
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS)); Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
if (NT_SUCCESS (Status)) 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; Irp->IoStatus.Information = FILE_CREATED;
}
/* FIXME set size if AllocationSize requested */ /* FIXME set size if AllocationSize requested */
/* FIXME set extended attributes? */ /* FIXME set extended attributes? */
/* FIXME set share access */ /* FIXME set share access */
@ -703,12 +715,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
if (PagingFileCreate) if (PagingFileCreate)
{ {
ULONG CurrentCluster, NextCluster, i; ULONG CurrentCluster, NextCluster, i;
DPRINT("Open an existing paging file\n");
pFcb->Flags |= FCB_IS_PAGE_FILE; pFcb->Flags |= FCB_IS_PAGE_FILE;
pFcb->FatChainSize = pFcb->FatChainSize =
((pFcb->entry.FileSize / DeviceExt->BytesPerCluster) + 2); ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) / DeviceExt->BytesPerCluster);
pFcb->FatChain = ExAllocatePool(NonPagedPool, if (pFcb->FatChainSize)
{
pFcb->FatChain = ExAllocatePool(NonPagedPool,
pFcb->FatChainSize * sizeof(ULONG)); pFcb->FatChainSize * sizeof(ULONG));
}
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
{ {
@ -721,16 +736,18 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
} }
i = 0; i = 0;
while (CurrentCluster != 0xffffffff) if (pFcb->FatChainSize)
{ {
Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, while (CurrentCluster != 0xffffffff)
{
pFcb->FatChain[i] = CurrentCluster;
Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster,
FALSE); FALSE);
pFcb->FatChain[i] = NextCluster; i++;
i++; CurrentCluster = NextCluster;
CurrentCluster = NextCluster; }
}
pFcb->FatChain[i] = 0xFFFFFFFF;
} }
}
/* /*
* Check the file has the requested attributes * Check the file has the requested attributes

View file

@ -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 * FILE: fcb.c
@ -58,6 +58,8 @@ vfatDestroyFCB(PVFATFCB pFCB)
{ {
ExDeleteResourceLite(&pFCB->PagingIoResource); ExDeleteResourceLite(&pFCB->PagingIoResource);
ExDeleteResourceLite(&pFCB->MainResource); ExDeleteResourceLite(&pFCB->MainResource);
if ((pFCB->Flags & FCB_IS_PAGE_FILE) && pFCB->FatChainSize)
ExFreePool(pFCB->FatChain);
ExFreePool (pFCB); ExFreePool (pFCB);
} }

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -40,10 +40,79 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
{ {
if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE) if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
{ {
ULONG NextCluster; ULONG i;
NextCluster = Fcb->FatChain[(*CurrentCluster)]; PULONG FatChain;
(*CurrentCluster) = NextCluster; NTSTATUS Status;
return(STATUS_SUCCESS); 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) if (FirstCluster == 1)
{ {
@ -90,19 +159,75 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG i; ULONG i;
NTSTATUS Status; 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) if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
{ {
ULONG NCluster; ULONG NCluster;
ULONG Offset = FileOffset / DeviceExt->BytesPerCluster; ULONG Offset = FileOffset / DeviceExt->BytesPerCluster;
if (Offset == 0) PULONG FatChain;
{ int i;
(*Cluster) = FirstCluster; 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 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); return(STATUS_SUCCESS);
} }
if (FirstCluster == 1) if (FirstCluster == 1)