reactos/drivers/fs/vfat
diff -u -r1.31 -r1.32
--- blockdev.c 20 Apr 2004 19:02:36 -0000 1.31
+++ blockdev.c 15 May 2004 23:00:02 -0000 1.32
@@ -38,12 +38,53 @@
}
*Irp->UserIosb = Irp->IoStatus;
- KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
+ if (Irp->PendingReturned)
+ {
+ KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
+ }
+
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
+NTSTATUS STDCALL
+VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ PVFAT_IRP_CONTEXT IrpContext;
+ PMDL Mdl;
+
+ DPRINT("VfatReadWritePartialCompletion() called\n");
+
+ IrpContext = (PVFAT_IRP_CONTEXT)Context;
+
+ while ((Mdl = Irp->MdlAddress))
+ {
+ Irp->MdlAddress = Mdl->Next;
+ IoFreeMdl(Mdl);
+ }
+ if (Irp->PendingReturned)
+ {
+ IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
+ }
+ if (!NT_SUCCESS(Irp->IoStatus.Status))
+ {
+ IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
+ }
+ if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
+ IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED)
+ {
+ KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
+ }
+ IoFreeIrp(Irp);
+
+ DPRINT("VfatReadWritePartialCompletion() done\n");
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
NTSTATUS
VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject,
IN PLARGE_INTEGER ReadOffset,
@@ -113,29 +154,100 @@
}
NTSTATUS
-VfatWriteDisk (IN PDEVICE_OBJECT pDeviceObject,
- IN PLARGE_INTEGER WriteOffset,
- IN ULONG WriteLength,
- IN PUCHAR Buffer)
+VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
+ IN PLARGE_INTEGER ReadOffset,
+ IN ULONG ReadLength,
+ ULONG BufferOffset,
+ IN BOOLEAN Wait)
{
PIRP Irp;
- IO_STATUS_BLOCK IoStatus;
- KEVENT event;
NTSTATUS Status;
+ PVOID Buffer;
- DPRINT ("VfatWriteSectors(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
- pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
+ DPRINT ("VfatReadDiskPartial(IrpContext %x, ReadOffset %I64x, ReadLength %d, BufferOffset %x, Wait %d)\n",
+ IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
- KeInitializeEvent (&event, NotificationEvent, FALSE);
+ DPRINT ("Building synchronous FSD Request...\n");
+
+ Buffer = MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
+
+ Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
+ IrpContext->DeviceExt->StorageDevice,
+ NULL,
+ ReadLength,
+ ReadOffset,
+ NULL,
+ NULL);
+ if (Irp == NULL)
+ {
+ DPRINT("IoBuildSynchronousFsdRequest failed\n");
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
+ {
+ DPRINT("IoAllocateMdl failed\n");
+ IoFreeIrp(Irp);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
+
+ IoSetCompletionRoutine(Irp,
+ VfatReadWritePartialCompletion,
+ IrpContext,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ if (Wait)
+ {
+ KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
+ IrpContext->RefCount = 1;
+ }
+ else
+ {
+ InterlockedIncrement((PLONG)&IrpContext->RefCount);
+ }
+
+ DPRINT ("Calling IO Driver... with irp %x\n", Irp);
+ Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
+
+ if (Wait && Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
+ Status = IrpContext->Irp->IoStatus.Status;
+ }
+
+ DPRINT("%x\n", Status);
+ return Status;
+}
+
+
+NTSTATUS
+VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
+ IN PLARGE_INTEGER WriteOffset,
+ IN ULONG WriteLength,
+ IN ULONG BufferOffset,
+ IN BOOLEAN Wait)
+{
+ PIRP Irp;
+ NTSTATUS Status;
+ PVOID Buffer;
+
+ DPRINT ("VfatWriteDiskPartial(IrpContext %x, WriteOffset %I64x, WriteLength %d, BufferOffset %x, Wait %d)\n",
+ IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
+
+ Buffer = MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_WRITE,
- pDeviceObject,
- Buffer,
+ IrpContext->DeviceExt->StorageDevice,
+ NULL,
WriteLength,
WriteOffset,
- &event,
- &IoStatus);
+ NULL,
+ NULL);
if (!Irp)
{
@@ -143,32 +255,41 @@
return (STATUS_UNSUCCESSFUL);
}
+ if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
+ {
+ DPRINT("IoAllocateMdl failed\n");
+ IoFreeIrp(Irp);
+ return STATUS_UNSUCCESSFUL;
+ }
+ IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
+
IoSetCompletionRoutine(Irp,
- VfatReadWriteCompletion,
- NULL,
+ VfatReadWritePartialCompletion,
+ IrpContext,
TRUE,
TRUE,
TRUE);
- DPRINT ("Calling IO Driver...\n");
- Status = IoCallDriver (pDeviceObject, Irp);
-
- DPRINT ("Waiting for IO Operation...\n");
- if (Status == STATUS_PENDING)
+ if (Wait)
{
- KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL);
- DPRINT ("Getting IO Status...\n");
- Status = IoStatus.Status;
+ KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
+ IrpContext->RefCount = 1;
+ }
+ else
+ {
+ InterlockedIncrement((PLONG)&IrpContext->RefCount);
}
- if (!NT_SUCCESS (Status))
+
+ DPRINT ("Calling IO Driver...\n");
+ Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
+ if (Wait && Status == STATUS_PENDING)
{
- DPRINT ("IO failed!!! VfatWriteSectors : Error code: %x\n", Status);
- return (Status);
+ KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
+ Status = IrpContext->Irp->IoStatus.Status;
}
- DPRINT ("Block request succeeded\n");
- return (STATUS_SUCCESS);
+ return Status;
}
NTSTATUS
@@ -188,9 +309,9 @@
DPRINT("VfatBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
"InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
- "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
- InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
- pOutputBufferSize ? *pOutputBufferSize : 0);
+ "OutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
+ InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
+ OutputBufferSize ? *OutputBufferSize : 0);
KeInitializeEvent (&Event, NotificationEvent, FALSE);
reactos/drivers/fs/vfat
diff -u -r1.65 -r1.66
--- rw.c 31 Mar 2004 03:30:36 -0000 1.65
+++ rw.c 15 May 2004 23:00:02 -0000 1.66
@@ -1,5 +1,5 @@
-/* $Id: rw.c,v 1.65 2004/03/31 03:30:36 jimtabor Exp $
+/* $Id: rw.c,v 1.66 2004/05/15 23:00:02 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -114,8 +114,10 @@
}
NTSTATUS
-VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer,
- ULONG Length, LARGE_INTEGER ReadOffset, PULONG LengthRead)
+VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
+ ULONG Length,
+ LARGE_INTEGER ReadOffset,
+ PULONG LengthRead)
/*
* FUNCTION: Reads data from a file
*/
@@ -133,6 +135,7 @@
ULONG BytesDone;
ULONG BytesPerSector;
ULONG BytesPerCluster;
+ ULONG Count;
/* PRECONDITION */
assert (IrpContext);
@@ -142,9 +145,9 @@
assert (IrpContext->FileObject);
assert (IrpContext->FileObject->FsContext2 != NULL);
- DPRINT("VfatReadFileData(DeviceExt %x, FileObject %x, Buffer %x, "
+ DPRINT("VfatReadFileData(DeviceExt %x, FileObject %x, "
"Length %d, ReadOffset 0x%I64x)\n", DeviceExt,
- IrpContext->FileObject, Buffer, Length, ReadOffset.QuadPart);
+ IrpContext->FileObject, Length, ReadOffset.QuadPart);
*LengthRead = 0;
@@ -161,7 +164,7 @@
if (Fcb->Flags & FCB_IS_FAT)
{
ReadOffset.QuadPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
- Status = VfatReadDisk(DeviceExt->StorageDevice, &ReadOffset, Length, Buffer, FALSE);
+ Status = VfatReadDiskPartial(IrpContext, &ReadOffset, Length, 0, TRUE);
if (NT_SUCCESS(Status))
{
@@ -176,7 +179,7 @@
/* Is this a read of the Volume ? */
if (Fcb->Flags & FCB_IS_VOLUME)
{
- Status = VfatReadDisk(DeviceExt->StorageDevice, &ReadOffset, Length, Buffer, FALSE);
+ Status = VfatReadDiskPartial(IrpContext, &ReadOffset, Length, 0, TRUE);
if (NT_SUCCESS(Status))
{
*LengthRead = Length;
@@ -206,10 +209,10 @@
// Fire up the read command
- Status = VfatReadDisk (DeviceExt->StorageDevice, &ReadOffset, Length, Buffer, FALSE);
+ Status = VfatReadDiskPartial (IrpContext, &ReadOffset, Length, 0, TRUE);
if (NT_SUCCESS(Status))
{
- *LengthRead += Length;
+ *LengthRead = Length;
}
return Status;
}
@@ -231,7 +234,11 @@
Ccb->LastCluster = CurrentCluster;
Ccb->LastOffset = ROUND_DOWN (ReadOffset.u.LowPart, BytesPerCluster);
- while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
+ IrpContext->RefCount = 1;
+ Count = 0;
+
+ while (Length > 0 && CurrentCluster != 0xffffffff)
{
StartCluster = CurrentCluster;
StartOffset.QuadPart = ClusterToSector(DeviceExt, StartCluster) * BytesPerSector;
@@ -267,32 +274,40 @@
Ccb->LastCluster = StartCluster + (ClusterCount - 1);
Ccb->LastOffset = ReadOffset.u.LowPart + (ClusterCount - 1) * BytesPerCluster;
- // Fire up the read command
- Status = VfatReadDisk (DeviceExt->StorageDevice, &StartOffset, BytesDone, Buffer, FALSE);
+ Count++;
- if (NT_SUCCESS(Status))
- {
- *LengthRead += BytesDone;
-/* GCC allows arithmetics on the void type. Conforming compilers do not. */
-#ifdef __GNUC__
- Buffer += BytesDone;
-#else
+ // Fire up the read command
+ Status = VfatReadDiskPartial (IrpContext, &StartOffset, BytesDone, *LengthRead, FALSE);
+ if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{
- char* pBuf = (char*)Buffer + BytesDone;
- Buffer = (PVOID)pBuf;
+ break;
}
-#endif
- Length -= BytesDone;
- ReadOffset.u.LowPart += BytesDone;
- }
+ *LengthRead += BytesDone;
+ Length -= BytesDone;
+ ReadOffset.u.LowPart += BytesDone;
}
+ if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
+ {
+ KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
+ }
+ if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
+ {
+ if (Length > 0)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ Status = IrpContext->Irp->IoStatus.Status;
+ }
+ }
return Status;
}
-NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
- PVOID Buffer,
- ULONG Length,
- LARGE_INTEGER WriteOffset)
+NTSTATUS
+VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
+ ULONG Length,
+ LARGE_INTEGER WriteOffset)
{
PDEVICE_EXTENSION DeviceExt;
PVFATFCB Fcb;
@@ -308,6 +323,7 @@
ULONG BytesPerSector;
ULONG BytesPerCluster;
LARGE_INTEGER StartOffset;
+ ULONG BufferOffset;
/* PRECONDITION */
assert (IrpContext);
@@ -322,9 +338,9 @@
BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster;
BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
- DPRINT("VfatWriteFileData(DeviceExt %x, FileObject %x, Buffer %x, "
+ DPRINT("VfatWriteFileData(DeviceExt %x, FileObject %x, "
"Length %d, WriteOffset 0x%I64x), '%wZ'\n", DeviceExt,
- IrpContext->FileObject, Buffer, Length, WriteOffset,
+ IrpContext->FileObject, Length, WriteOffset,
&Fcb->PathNameU);
assert(WriteOffset.QuadPart + Length <= Fcb->RFCB.AllocationSize.QuadPart);
@@ -334,7 +350,7 @@
// Is this a write of the volume ?
if (Fcb->Flags & FCB_IS_VOLUME)
{
- Status = VfatWriteDisk(DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
+ Status = VfatWriteDiskPartial(IrpContext, &WriteOffset, Length, 0, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Volume writing failed, Status %x\n", Status);
@@ -346,15 +362,25 @@
if (Fcb->Flags & FCB_IS_FAT)
{
WriteOffset.u.LowPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
+ IrpContext->RefCount = 1;
for (Count = 0; Count < DeviceExt->FatInfo.FATCount; Count++)
{
- Status = VfatWriteDisk(DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
- if (!NT_SUCCESS(Status))
+ Status = VfatWriteDiskPartial(IrpContext, &WriteOffset, Length, 0, FALSE);
+ if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{
DPRINT1("FAT writing failed, Status %x\n", Status);
+ break;
}
WriteOffset.u.LowPart += Fcb->RFCB.FileSize.u.LowPart;
}
+ if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
+ {
+ KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
+ }
+ if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
+ {
+ Status = IrpContext->Irp->IoStatus.Status;
+ }
return Status;
}
@@ -370,7 +396,7 @@
// Directory of FAT12/16 needs a special handling
WriteOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
// Fire up the write command
- Status = VfatWriteDisk (DeviceExt->StorageDevice, &WriteOffset, Length, Buffer);
+ Status = VfatWriteDiskPartial (IrpContext, &WriteOffset, Length, 0, TRUE);
return Status;
}
@@ -394,7 +420,11 @@
Ccb->LastCluster = CurrentCluster;
Ccb->LastOffset = ROUND_DOWN (WriteOffset.u.LowPart, BytesPerCluster);
- while (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ IrpContext->RefCount = 1;
+ Count = 0;
+ BufferOffset = 0;
+
+ while (Length > 0 && CurrentCluster != 0xffffffff)
{
StartCluster = CurrentCluster;
StartOffset.QuadPart = ClusterToSector(DeviceExt, StartCluster) * BytesPerSector;
@@ -431,22 +461,31 @@
Ccb->LastOffset = WriteOffset.u.LowPart + (ClusterCount - 1) * BytesPerCluster;
// Fire up the write command
- 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;
- }
+ Status = VfatWriteDiskPartial (IrpContext, &StartOffset, BytesDone, BufferOffset, FALSE);
+ Count++;
+ if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
+ {
+ break;
+ }
+ BufferOffset += BytesDone;
+ Length -= BytesDone;
+ WriteOffset.u.LowPart += BytesDone;
}
+ if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
+ {
+ KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
+ }
+ if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
+ {
+ if (Length > 0)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ Status = IrpContext->Irp->IoStatus.Status;
+ }
+ }
return Status;
}
@@ -486,12 +525,10 @@
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);
+ IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
+ IoSkipCurrentIrpStackLocation(IrpContext->Irp);
+ DPRINT("Read from page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status;
@@ -527,7 +564,7 @@
if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
{
DPRINT("%d %d\n", ByteOffset.u.LowPart, Length);
- // non chached read must be sector aligned
+ // non cached read must be sector aligned
Status = STATUS_INVALID_PARAMETER;
goto ByeBye;
}
@@ -569,6 +606,13 @@
}
}
+ Buffer = VfatGetUserBuffer(IrpContext->Irp);
+ if (!Buffer)
+ {
+ Status = STATUS_INVALID_USER_BUFFER;
+ goto ByeBye;
+ }
+
if (!(IrpContext->Irp->Flags & (IRP_NOCACHE|IRP_PAGING_IO)) &&
!(Fcb->Flags & (FCB_IS_PAGE_FILE|FCB_IS_VOLUME)))
{
@@ -581,13 +625,6 @@
Status = /*STATUS_END_OF_FILE*/STATUS_SUCCESS;
}
- Buffer = VfatGetUserBuffer(IrpContext->Irp);
- if (!Buffer)
- {
- Status = STATUS_INVALID_USER_BUFFER;
- goto ByeBye;
- }
-
CHECKPOINT;
if (IrpContext->FileObject->PrivateCacheMap == NULL)
{
@@ -621,14 +658,13 @@
Length = (ULONG)(ROUND_UP(Fcb->RFCB.FileSize.QuadPart, BytesPerSector) - ByteOffset.QuadPart);
}
- Buffer = VfatGetUserBuffer(IrpContext->Irp);
- if (!Buffer)
- {
- Status = STATUS_INVALID_USER_BUFFER;
- goto ByeBye;
- }
+ Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoWriteAccess);
+ if (!NT_SUCCESS(Status))
+ {
+ goto ByeBye;
+ }
- Status = VfatReadFileData(IrpContext, Buffer, Length, ByteOffset, &ReturnedLength);
+ Status = VfatReadFileData(IrpContext, Length, ByteOffset, &ReturnedLength);
/**/
if (Status == STATUS_VERIFY_REQUIRED)
{
@@ -639,7 +675,7 @@
if (NT_SUCCESS(Status))
{
- Status = VfatReadFileData(IrpContext, Buffer, Length,
+ Status = VfatReadFileData(IrpContext, Length,
ByteOffset, &ReturnedLength);
}
@@ -725,12 +761,10 @@
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);
+ IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
+ IoSkipCurrentIrpStackLocation(IrpContext->Irp);
+ DPRINT("Write to page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status;
@@ -768,7 +802,7 @@
{
if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
{
- // non chached write must be sector aligned
+ // non cached write must be sector aligned
Status = STATUS_INVALID_PARAMETER;
goto ByeBye;
}
@@ -776,6 +810,9 @@
if (Length == 0)
{
+ /* FIXME:
+ * Update last write time
+ */
IrpContext->Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
goto ByeBye;
@@ -850,6 +887,14 @@
OldFileSize = Fcb->RFCB.FileSize;
OldAllocationSize = Fcb->RFCB.AllocationSize.u.LowPart;
+ Buffer = VfatGetUserBuffer(IrpContext->Irp);
+ if (!Buffer)
+ {
+ Status = STATUS_INVALID_USER_BUFFER;
+ goto ByeBye;
+ }
+
+
if (!(Fcb->Flags & (FCB_IS_FAT|FCB_IS_VOLUME)) &&
!(IrpContext->Irp->Flags & IRP_PAGING_IO) &&
ByteOffset.u.LowPart + Length > Fcb->RFCB.FileSize.u.LowPart)
@@ -872,13 +917,6 @@
// cached write
CHECKPOINT;
- Buffer = VfatGetUserBuffer(IrpContext->Irp);
- if (!Buffer)
- {
- Status = STATUS_INVALID_USER_BUFFER;
- goto ByeBye;
- }
- CHECKPOINT;
if (IrpContext->FileObject->PrivateCacheMap == NULL)
{
ULONG CacheSize;
@@ -914,14 +952,14 @@
{
CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
}
- Buffer = VfatGetUserBuffer(IrpContext->Irp);
- if (!Buffer)
- {
- Status = STATUS_INVALID_USER_BUFFER;
- goto ByeBye;
- }
- Status = VfatWriteFileData(IrpContext, Buffer, Length, ByteOffset);
+ Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoReadAccess);
+ if (!NT_SUCCESS(Status))
+ {
+ goto ByeBye;
+ }
+
+ Status = VfatWriteFileData(IrpContext, Length, ByteOffset);
if (NT_SUCCESS(Status))
{
IrpContext->Irp->IoStatus.Information = Length;