#include <wchar.h>
#include <ntos/minmax.h>
+#include <ntos.h>
+
#define NDEBUG
#include <debug.h>
NTSTATUS
NextCluster(PDEVICE_EXTENSION DeviceExt,
- PVFATFCB Fcb,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend)
* 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);
NTSTATUS
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
- PVFATFCB Fcb,
ULONG FirstCluster,
ULONG FileOffset,
PULONG Cluster,
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);
+ 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 */
{
CurrentCluster = Ccb->LastCluster;
}
- Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
+ Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE);
if (!NT_SUCCESS(Status))
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",
if (NT_SUCCESS(Status))
{
*LengthRead += BytesDone;
+/* GCC allows arithmetics on the void type. Conforming compilers do not. */
+#ifdef __GNUC__
Buffer += BytesDone;
+#else
+ {
+ char* pBuf = (char*)Buffer + BytesDone;
+ Buffer = (PVOID)pBuf;
+ }
+#endif
Length -= BytesDone;
ReadOffset.u.LowPart += BytesDone;
}
CurrentCluster = Ccb->LastCluster;
}
- Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
+ Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(WriteOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE);
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",
Status = VfatWriteDisk (DeviceExt->StorageDevice, &StartOffset, BytesDone, Buffer);
if (NT_SUCCESS(Status))
{
+/* GCC allows arithmetics on the void type. Conforming compilers do not. */
+#ifdef __GNUC__
Buffer += BytesDone;
+#else
+ {
+ char* pBuf = (char*)Buffer + BytesDone;
+ Buffer = (PVOID)pBuf;
+ }
+#endif
Length -= BytesDone;
WriteOffset.u.LowPart += BytesDone;
}
PERESOURCE Resource = NULL;
LARGE_INTEGER ByteOffset;
PVOID Buffer;
- PDEVICE_OBJECT DeviceToVerify;
+ /*PDEVICE_OBJECT DeviceToVerify;*/
ULONG BytesPerSector;
assert(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;
{
Resource = &Fcb->MainResource;
}
- if (!ExAcquireResourceSharedLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ if (!ExAcquireResourceSharedLite(Resource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
Resource = NULL;
Status = STATUS_PENDING;
CcRosInitializeFileCache(IrpContext->FileObject, CacheSize);
}
if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length,
- IrpContext->Flags & IRPCONTEXT_CANWAIT, Buffer,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT), Buffer,
&IrpContext->Irp->IoStatus))
{
Status = STATUS_PENDING;
CHECKPOINT;
if (ByteOffset.QuadPart + Length > ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector))
{
- Length = ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart;
+ Length = (ULONG)(ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart);
}
Buffer = VfatGetUserBuffer(IrpContext->Irp);
}
IoCompleteRequest(IrpContext->Irp,
- NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+ (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
}
DPRINT("%x\n", Status);
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;
if (Fcb->Flags & FCB_IS_PAGE_FILE)
{
- if (!ExAcquireResourceSharedLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ if (!ExAcquireResourceSharedLite(Resource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
Resource = NULL;
Status = STATUS_PENDING;
}
else
{
- if (!ExAcquireResourceExclusiveLite(Resource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ if (!ExAcquireResourceExclusiveLite(Resource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
Resource = NULL;
Status = STATUS_PENDING;
}
IoCompleteRequest(IrpContext->Irp,
- NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+ (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
}
DPRINT("%x\n", Status);