[FASTFAT]

Fix coding style and indentation. No code changes!

svn path=/trunk/; revision=61252
This commit is contained in:
Eric Kohl 2013-12-09 10:35:15 +00:00
parent 5a02327fd0
commit 3f339ec7b9
15 changed files with 3195 additions and 3051 deletions

View file

@ -15,8 +15,12 @@
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion; static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
static NTSTATUS NTAPI
VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject, static
NTSTATUS
NTAPI
VfatReadWritePartialCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PIRP Irp,
IN PVOID Context) IN PVOID Context)
{ {
@ -34,6 +38,7 @@ VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
Irp->MdlAddress = Mdl->Next; Irp->MdlAddress = Mdl->Next;
IoFreeMdl(Mdl); IoFreeMdl(Mdl);
} }
if (Irp->PendingReturned) if (Irp->PendingReturned)
{ {
IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED; IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
@ -42,15 +47,18 @@ VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
{ {
IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED; IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
} }
if (!NT_SUCCESS(Irp->IoStatus.Status)) if (!NT_SUCCESS(Irp->IoStatus.Status))
{ {
IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status; IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
} }
if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) && if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED) IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED)
{ {
KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
} }
IoFreeIrp(Irp); IoFreeIrp(Irp);
DPRINT("VfatReadWritePartialCompletion() done\n"); DPRINT("VfatReadWritePartialCompletion() done\n");
@ -59,7 +67,8 @@ VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
} }
NTSTATUS NTSTATUS
VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject, VfatReadDisk(
IN PDEVICE_OBJECT pDeviceObject,
IN PLARGE_INTEGER ReadOffset, IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength, IN ULONG ReadLength,
IN OUT PUCHAR Buffer, IN OUT PUCHAR Buffer,
@ -68,27 +77,27 @@ VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject,
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
PIRP Irp; PIRP Irp;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KEVENT event; KEVENT Event;
NTSTATUS Status; NTSTATUS Status;
again: again:
KeInitializeEvent (&event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n", DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer); pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
DPRINT ("Building synchronous FSD Request...\n"); DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
pDeviceObject, pDeviceObject,
Buffer, Buffer,
ReadLength, ReadLength,
ReadOffset, ReadOffset,
&event, &Event,
&IoStatus); &IoStatus);
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT("IoBuildSynchronousFsdRequest failed\n"); DPRINT("IoBuildSynchronousFsdRequest failed\n");
return(STATUS_UNSUCCESSFUL); return STATUS_UNSUCCESSFUL;
} }
if (Override) if (Override)
@ -97,15 +106,15 @@ again:
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
} }
DPRINT ("Calling IO Driver... with irp %p\n", Irp); DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver (pDeviceObject, Irp); Status = IoCallDriver (pDeviceObject, Irp);
DPRINT ("Waiting for IO Operation for %p\n", Irp); DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
DPRINT ("Operation pending\n"); DPRINT("Operation pending\n");
KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %p\n", Irp); DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status; Status = IoStatus.Status;
} }
@ -116,31 +125,31 @@ again:
DPRINT1 ("Media change detected!\n"); DPRINT1 ("Media change detected!\n");
/* Find the device to verify and reset the thread field to empty value again. */ /* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ()); DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL); IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume (DeviceToVerify, Status = IoVerifyVolume(DeviceToVerify,
FALSE); FALSE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT1 ("Volume verification successful; Reissuing read request\n"); DPRINT1("Volume verification successful; Reissuing read request\n");
goto again; goto again;
} }
} }
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status); DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n", DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer); pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
return (Status); return Status;
} }
DPRINT ("Block request succeeded for %p\n", Irp); DPRINT("Block request succeeded for %p\n", Irp);
return (STATUS_SUCCESS); return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, VfatReadDiskPartial(
IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER ReadOffset, IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength, IN ULONG ReadLength,
ULONG BufferOffset, ULONG BufferOffset,
@ -154,7 +163,7 @@ VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n", DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait); IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
DPRINT ("Building asynchronous FSD Request...\n"); DPRINT("Building asynchronous FSD Request...\n");
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset; Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
@ -163,7 +172,7 @@ again:
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT("IoAllocateIrp failed\n"); DPRINT("IoAllocateIrp failed\n");
return(STATUS_UNSUCCESSFUL); return STATUS_UNSUCCESSFUL;
} }
Irp->UserIosb = NULL; Irp->UserIosb = NULL;
@ -206,8 +215,8 @@ again:
InterlockedIncrement((PLONG)&IrpContext->RefCount); InterlockedIncrement((PLONG)&IrpContext->RefCount);
} }
DPRINT ("Calling IO Driver... with irp %p\n", Irp); DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp); Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
if (Wait && Status == STATUS_PENDING) if (Wait && Status == STATUS_PENDING)
{ {
@ -219,17 +228,16 @@ again:
{ {
PDEVICE_OBJECT DeviceToVerify; PDEVICE_OBJECT DeviceToVerify;
DPRINT1 ("Media change detected!\n"); DPRINT1("Media change detected!\n");
/* Find the device to verify and reset the thread field to empty value again. */ /* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ()); DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL); IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume (DeviceToVerify, Status = IoVerifyVolume(DeviceToVerify,
FALSE); FALSE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT1 ("Volume verification successful; Reissuing read request\n"); DPRINT1("Volume verification successful; Reissuing read request\n");
goto again; goto again;
} }
} }
@ -240,7 +248,8 @@ again:
NTSTATUS NTSTATUS
VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, VfatWriteDiskPartial(
IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER WriteOffset, IN PLARGE_INTEGER WriteOffset,
IN ULONG WriteLength, IN ULONG WriteLength,
IN ULONG BufferOffset, IN ULONG BufferOffset,
@ -257,12 +266,12 @@ VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset; Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
again: again:
DPRINT ("Building asynchronous FSD Request...\n"); DPRINT("Building asynchronous FSD Request...\n");
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE); Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT("IoAllocateIrp failed\n"); DPRINT("IoAllocateIrp failed\n");
return(STATUS_UNSUCCESSFUL); return STATUS_UNSUCCESSFUL;
} }
Irp->UserIosb = NULL; Irp->UserIosb = NULL;
@ -285,6 +294,7 @@ again:
IoFreeIrp(Irp); IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength); IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
IoSetCompletionRoutine(Irp, IoSetCompletionRoutine(Irp,
@ -304,9 +314,8 @@ again:
InterlockedIncrement((PLONG)&IrpContext->RefCount); InterlockedIncrement((PLONG)&IrpContext->RefCount);
} }
DPRINT("Calling IO Driver...\n");
DPRINT ("Calling IO Driver...\n"); Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
if (Wait && Status == STATUS_PENDING) if (Wait && Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
@ -317,17 +326,16 @@ again:
{ {
PDEVICE_OBJECT DeviceToVerify; PDEVICE_OBJECT DeviceToVerify;
DPRINT1 ("Media change detected!\n"); DPRINT1("Media change detected!\n");
/* Find the device to verify and reset the thread field to empty value again. */ /* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ()); DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL); IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume (DeviceToVerify, Status = IoVerifyVolume(DeviceToVerify,
FALSE); FALSE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT1 ("Volume verification successful; Reissuing write request\n"); DPRINT1("Volume verification successful; Reissuing write request\n");
goto again; goto again;
} }
} }
@ -336,7 +344,8 @@ again:
} }
NTSTATUS NTSTATUS
VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, VfatBlockDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG CtlCode, IN ULONG CtlCode,
IN PVOID InputBuffer OPTIONAL, IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize, IN ULONG InputBufferSize,
@ -357,7 +366,7 @@ VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
OutputBufferSize ? *OutputBufferSize : 0); OutputBufferSize ? *OutputBufferSize : 0);
again: again:
KeInitializeEvent (&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n"); DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(CtlCode, Irp = IoBuildDeviceIoControlRequest(CtlCode,
@ -381,15 +390,15 @@ again:
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
} }
DPRINT ("Calling IO Driver... with irp %p\n", Irp); DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp); Status = IoCallDriver(DeviceObject, Irp);
DPRINT ("Waiting for IO Operation for %p\n", Irp); DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
DPRINT ("Operation pending\n"); DPRINT("Operation pending\n");
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL); KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %p\n", Irp); DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status; Status = IoStatus.Status;
} }
@ -398,17 +407,17 @@ again:
{ {
PDEVICE_OBJECT DeviceToVerify; PDEVICE_OBJECT DeviceToVerify;
DPRINT1 ("Media change detected!\n"); DPRINT1("Media change detected!\n");
/* Find the device to verify and reset the thread field to empty value again. */ /* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ()); DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL); IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume (DeviceToVerify, Status = IoVerifyVolume(DeviceToVerify,
FALSE); FALSE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT1 ("Volume verification successful; Reissuing IOCTL request\n"); DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
goto again; goto again;
} }
} }

View file

@ -13,17 +13,19 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS
VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/* /*
* FUNCTION: Closes a file * FUNCTION: Closes a file
*/ */
NTSTATUS
VfatCloseFile(
PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject)
{ {
PVFATFCB pFcb; PVFATFCB pFcb;
PVFATCCB pCcb; PVFATCCB pCcb;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT ("VfatCloseFile(DeviceExt %p, FileObject %p)\n", DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
DeviceExt, FileObject); DeviceExt, FileObject);
/* FIXME : update entry in directory? */ /* FIXME : update entry in directory? */
@ -54,6 +56,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Status = STATUS_DELETE_PENDING; Status = STATUS_DELETE_PENDING;
} }
} }
vfatReleaseFCB (DeviceExt, pFcb); vfatReleaseFCB (DeviceExt, pFcb);
} }
@ -69,14 +72,16 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
return Status; return Status;
} }
NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Closes a file * FUNCTION: Closes a file
*/ */
NTSTATUS
VfatClose(
PVFAT_IRP_CONTEXT IrpContext)
{ {
NTSTATUS Status; NTSTATUS Status;
DPRINT ("VfatClose(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp); DPRINT("VfatClose(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
@ -87,16 +92,16 @@ NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
#if 0 #if 0
/* There occurs a dead look at the call to CcRosDeleteFileCache/ObDereferenceObject/VfatClose /* There occurs a dead look at the call to CcRosDeleteFileCache/ObDereferenceObject/VfatClose
in CmLazyCloseThreadMain if VfatClose is execute asynchronous in a worker thread. */ in CmLazyCloseThreadMain if VfatClose is execute asynchronous in a worker thread. */
if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
#else #else
if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE)) if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE))
#endif #endif
{ {
return VfatQueueRequest (IrpContext); return VfatQueueRequest(IrpContext);
} }
Status = VfatCloseFile (IrpContext->DeviceExt, IrpContext->FileObject); Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
ByeBye: ByeBye:
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
@ -104,7 +109,7 @@ ByeBye:
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return (Status); return Status;
} }
/* EOF */ /* EOF */

View file

@ -30,8 +30,10 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
void VOID
vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU) vfat8Dot3ToString(
PFAT_DIR_ENTRY pEntry,
PUNICODE_STRING NameU)
{ {
OEM_STRING StringA; OEM_STRING StringA;
USHORT Length; USHORT Length;
@ -56,6 +58,7 @@ vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
{ {
RtlDowncaseUnicodeString(NameU, NameU, FALSE); RtlDowncaseUnicodeString(NameU, NameU, FALSE);
} }
if (cString[8] != ' ') if (cString[8] != ' ')
{ {
Length = NameU->Length; Length = NameU->Length;
@ -83,6 +86,7 @@ vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
NameU->Length += Length; NameU->Length += Length;
NameU->MaximumLength += Length; NameU->MaximumLength += Length;
} }
NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0; NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
DPRINT("'%wZ'\n", NameU); DPRINT("'%wZ'\n", NameU);
} }

View file

@ -21,7 +21,6 @@
* FILE: drivers/fs/vfat/ea.c * FILE: drivers/fs/vfat/ea.c
* PURPOSE: VFAT Filesystem * PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com) * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -32,7 +31,8 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS NTSTATUS
VfatSetExtendedAttributes(PFILE_OBJECT FileObject, VfatSetExtendedAttributes(
PFILE_OBJECT FileObject,
PVOID Ea, PVOID Ea,
ULONG EaLength) ULONG EaLength)
{ {
@ -40,5 +40,5 @@ VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
UNREFERENCED_PARAMETER(Ea); UNREFERENCED_PARAMETER(Ea);
UNREFERENCED_PARAMETER(EaLength); UNREFERENCED_PARAMETER(EaLength);
return(STATUS_EAS_NOT_SUPPORTED); return STATUS_EAS_NOT_SUPPORTED;
} }

View file

@ -19,14 +19,15 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS
FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/* /*
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical * FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
* disk read * disk read
*/ */
NTSTATUS
FAT32GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{ {
PVOID BaseAddress; PVOID BaseAddress;
ULONG FATOffset; ULONG FATOffset;
@ -37,25 +38,28 @@ FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ChunkSize = CACHEPAGESIZE(DeviceExt); ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * sizeof(ULONG); FATOffset = CurrentCluster * sizeof(ULONG);
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize); Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress)) if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff; CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff) if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0xffffffff; CurrentCluster = 0xffffffff;
CcUnpinData(Context); CcUnpinData(Context);
*NextCluster = CurrentCluster; *NextCluster = CurrentCluster;
return (STATUS_SUCCESS); return STATUS_SUCCESS;
} }
NTSTATUS
FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/* /*
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table * FUNCTION: Retrieve the next FAT16 cluster from the FAT table
*/ */
NTSTATUS
FAT16GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{ {
PVOID BaseAddress; PVOID BaseAddress;
ULONG FATOffset; ULONG FATOffset;
@ -70,21 +74,23 @@ FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt,
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize))); CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff; CurrentCluster = 0xffffffff;
CcUnpinData(Context); CcUnpinData(Context);
*NextCluster = CurrentCluster; *NextCluster = CurrentCluster;
return (STATUS_SUCCESS); return STATUS_SUCCESS;
} }
NTSTATUS
FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/* /*
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table * FUNCTION: Retrieve the next FAT12 cluster from the FAT table
*/ */
NTSTATUS
FAT12GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{ {
PUSHORT CBlock; PUSHORT CBlock;
ULONG Entry; ULONG Entry;
@ -92,14 +98,14 @@ FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
PVOID Context; PVOID Context;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
*NextCluster = 0; *NextCluster = 0;
Offset.QuadPart = 0; Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress)) if (!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8); CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
if ((CurrentCluster % 2) == 0) if ((CurrentCluster % 2) == 0)
{ {
@ -109,9 +115,11 @@ FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
{ {
Entry = *CBlock >> 4; Entry = *CBlock >> 4;
} }
// DPRINT("Entry %x\n",Entry); // DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff) if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff; Entry = 0xffffffff;
// DPRINT("Returning %x\n",Entry); // DPRINT("Returning %x\n",Entry);
*NextCluster = Entry; *NextCluster = Entry;
CcUnpinData(Context); CcUnpinData(Context);
@ -119,12 +127,13 @@ FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
PULONG Cluster)
/* /*
* FUNCTION: Finds the first available cluster in a FAT16 table * FUNCTION: Finds the first available cluster in a FAT16 table
*/ */
NTSTATUS
FAT16FindAndMarkAvailableCluster(
PDEVICE_EXTENSION DeviceExt,
PULONG Cluster)
{ {
ULONG FatLength; ULONG FatLength;
ULONG StartCluster; ULONG StartCluster;
@ -143,14 +152,15 @@ FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{ {
for (i = StartCluster; i < FatLength; ) for (i = StartCluster; i < FatLength;)
{ {
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize); Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress)) if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{ {
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize); DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize); Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize); BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
@ -166,7 +176,7 @@ FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
CcUnpinData(Context); CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid) if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters); InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
Block++; Block++;
@ -175,10 +185,12 @@ FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
CcUnpinData(Context); CcUnpinData(Context);
} }
FatLength = StartCluster; FatLength = StartCluster;
StartCluster = 2; StartCluster = 2;
} }
return(STATUS_DISK_FULL);
return STATUS_DISK_FULL;
} }
NTSTATUS NTSTATUS

View file

@ -63,15 +63,16 @@ const char* FileInformationClassNames[] =
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS
VfatGetStandardInformation(PVFATFCB FCB,
PFILE_STANDARD_INFORMATION StandardInfo,
PULONG BufferLength)
/* /*
* FUNCTION: Retrieve the standard file information * FUNCTION: Retrieve the standard file information
*/ */
static
NTSTATUS
VfatGetStandardInformation(
PVFATFCB FCB,
PFILE_STANDARD_INFORMATION StandardInfo,
PULONG BufferLength)
{ {
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION)) if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
@ -95,26 +96,30 @@ VfatGetStandardInformation(PVFATFCB FCB,
StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE; StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION); *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatSetPositionInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatSetPositionInformation(
PFILE_OBJECT FileObject,
PFILE_POSITION_INFORMATION PositionInfo) PFILE_POSITION_INFORMATION PositionInfo)
{ {
DPRINT ("FsdSetPositionInformation()\n"); DPRINT("FsdSetPositionInformation()\n");
DPRINT ("PositionInfo %p\n", PositionInfo); DPRINT("PositionInfo %p\n", PositionInfo);
DPRINT ("Setting position %u\n", PositionInfo->CurrentByteOffset.u.LowPart); DPRINT("Setting position %u\n", PositionInfo->CurrentByteOffset.u.LowPart);
FileObject->CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart =
PositionInfo->CurrentByteOffset.QuadPart; PositionInfo->CurrentByteOffset.QuadPart;
return (STATUS_SUCCESS); return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatGetPositionInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatGetPositionInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB, PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_POSITION_INFORMATION PositionInfo, PFILE_POSITION_INFORMATION PositionInfo,
@ -124,7 +129,7 @@ VfatGetPositionInformation(PFILE_OBJECT FileObject,
UNREFERENCED_PARAMETER(FCB); UNREFERENCED_PARAMETER(FCB);
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(DeviceObject);
DPRINT ("VfatGetPositionInformation()\n"); DPRINT("VfatGetPositionInformation()\n");
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION)) if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
@ -136,11 +141,13 @@ VfatGetPositionInformation(PFILE_OBJECT FileObject,
PositionInfo->CurrentByteOffset.QuadPart); PositionInfo->CurrentByteOffset.QuadPart);
*BufferLength -= sizeof(FILE_POSITION_INFORMATION); *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatSetBasicInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatSetBasicInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB, PVFATFCB FCB,
PDEVICE_EXTENSION DeviceExt, PDEVICE_EXTENSION DeviceExt,
PFILE_BASIC_INFORMATION BasicInfo) PFILE_BASIC_INFORMATION BasicInfo)
@ -221,11 +228,13 @@ VfatSetBasicInformation(PFILE_OBJECT FileObject,
VfatUpdateEntry(FCB); VfatUpdateEntry(FCB);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatGetBasicInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatGetBasicInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB, PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_BASIC_INFORMATION BasicInfo, PFILE_BASIC_INFORMATION BasicInfo,
@ -289,12 +298,14 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject,
DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes); DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
*BufferLength -= sizeof(FILE_BASIC_INFORMATION); *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatSetDispositionInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatSetDispositionInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB, PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_DISPOSITION_INFORMATION DispositionInfo) PFILE_DISPOSITION_INFORMATION DispositionInfo)
@ -303,7 +314,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
#endif #endif
DPRINT ("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile); DPRINT("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
ASSERT(DeviceExt != NULL); ASSERT(DeviceExt != NULL);
ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0); ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
@ -360,15 +371,17 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS /*
VfatGetNameInformation(PFILE_OBJECT FileObject, * FUNCTION: Retrieve the file name information
*/
static
NTSTATUS
VfatGetNameInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB, PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_NAME_INFORMATION NameInfo, PFILE_NAME_INFORMATION NameInfo,
PULONG BufferLength) PULONG BufferLength)
/*
* FUNCTION: Retrieve the file name information
*/
{ {
ULONG BytesToCopy; ULONG BytesToCopy;
@ -406,8 +419,10 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS static
VfatGetInternalInformation(PVFATFCB Fcb, NTSTATUS
VfatGetInternalInformation(
PVFATFCB Fcb,
PFILE_INTERNAL_INFORMATION InternalInfo, PFILE_INTERNAL_INFORMATION InternalInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
@ -423,14 +438,16 @@ VfatGetInternalInformation(PVFATFCB Fcb,
} }
static NTSTATUS
VfatGetNetworkOpenInformation(PVFATFCB Fcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
PULONG BufferLength)
/* /*
* FUNCTION: Retrieve the file network open information * FUNCTION: Retrieve the file network open information
*/ */
static
NTSTATUS
VfatGetNetworkOpenInformation(
PVFATFCB Fcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
PULONG BufferLength)
{ {
ASSERT(NetworkInfo); ASSERT(NetworkInfo);
ASSERT(Fcb); ASSERT(Fcb);
@ -470,6 +487,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
&NetworkInfo->LastWriteTime); &NetworkInfo->LastWriteTime);
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart; NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
} }
if (vfatFCBIsDirectory(Fcb)) if (vfatFCBIsDirectory(Fcb))
{ {
NetworkInfo->EndOfFile.QuadPart = 0L; NetworkInfo->EndOfFile.QuadPart = 0L;
@ -480,6 +498,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize; NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize; NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
} }
NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f; NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
/* Synthesize FILE_ATTRIBUTE_NORMAL */ /* Synthesize FILE_ATTRIBUTE_NORMAL */
if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
@ -497,8 +516,10 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
} }
static NTSTATUS static
VfatGetEaInformation(PFILE_OBJECT FileObject, NTSTATUS
VfatGetEaInformation(
PFILE_OBJECT FileObject,
PVFATFCB Fcb, PVFATFCB Fcb,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_EA_INFORMATION Info, PFILE_EA_INFORMATION Info,
@ -522,15 +543,17 @@ VfatGetEaInformation(PFILE_OBJECT FileObject,
} }
static NTSTATUS /*
VfatGetAllInformation(PFILE_OBJECT FileObject, * FUNCTION: Retrieve the all file information
*/
static
NTSTATUS
VfatGetAllInformation(
PFILE_OBJECT FileObject,
PVFATFCB Fcb, PVFATFCB Fcb,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_ALL_INFORMATION Info, PFILE_ALL_INFORMATION Info,
PULONG BufferLength) PULONG BufferLength)
/*
* FUNCTION: Retrieve the all file information
*/
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG InitialBufferLength = *BufferLength; ULONG InitialBufferLength = *BufferLength;
@ -567,7 +590,13 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG ClusterSize) static
VOID
UpdateFileSize(
PFILE_OBJECT FileObject,
PVFATFCB Fcb,
ULONG Size,
ULONG ClusterSize)
{ {
if (Size > 0) if (Size > 0)
{ {
@ -591,7 +620,8 @@ static VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, UL
} }
NTSTATUS NTSTATUS
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, VfatSetAllocationSizeInformation(
PFILE_OBJECT FileObject,
PVFATFCB Fcb, PVFATFCB Fcb,
PDEVICE_EXTENSION DeviceExt, PDEVICE_EXTENSION DeviceExt,
PLARGE_INTEGER AllocationSize) PLARGE_INTEGER AllocationSize)
@ -605,23 +635,25 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
ULONG NCluster; ULONG NCluster;
BOOLEAN AllocSizeChanged = FALSE; BOOLEAN AllocSizeChanged = FALSE;
DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n", &Fcb->PathNameU, DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
AllocationSize->HighPart, AllocationSize->LowPart); &Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
if (Fcb->Flags & FCB_IS_FATX_ENTRY) if (Fcb->Flags & FCB_IS_FATX_ENTRY)
OldSize = Fcb->entry.FatX.FileSize; OldSize = Fcb->entry.FatX.FileSize;
else else
OldSize = Fcb->entry.Fat.FileSize; OldSize = Fcb->entry.Fat.FileSize;
if (AllocationSize->u.HighPart > 0) if (AllocationSize->u.HighPart > 0)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (OldSize == NewSize) if (OldSize == NewSize)
{ {
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
FirstCluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry); FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart) if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
{ {
@ -629,16 +661,18 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
if (FirstCluster == 0) if (FirstCluster == 0)
{ {
Fcb->LastCluster = Fcb->LastOffset = 0; Fcb->LastCluster = Fcb->LastOffset = 0;
Status = NextCluster (DeviceExt, FirstCluster, &FirstCluster, TRUE); Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NextCluster failed. Status = %x\n", Status); DPRINT1("NextCluster failed. Status = %x\n", Status);
return Status; return Status;
} }
if (FirstCluster == 0xffffffff) if (FirstCluster == 0xffffffff)
{ {
return STATUS_DISK_FULL; return STATUS_DISK_FULL;
} }
Status = OffsetToCluster(DeviceExt, FirstCluster, Status = OffsetToCluster(DeviceExt, FirstCluster,
ROUND_DOWN(NewSize - 1, ClusterSize), ROUND_DOWN(NewSize - 1, ClusterSize),
&NCluster, TRUE); &NCluster, TRUE);
@ -649,12 +683,13 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1) while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
{ {
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0); WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster; Cluster = NCluster;
} }
return STATUS_DISK_FULL; return STATUS_DISK_FULL;
} }
if (Fcb->Flags & FCB_IS_FATX_ENTRY) if (Fcb->Flags & FCB_IS_FATX_ENTRY)
{ {
Fcb->entry.FatX.FirstCluster = FirstCluster; Fcb->entry.FatX.FirstCluster = FirstCluster;
@ -695,6 +730,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize, Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
&Cluster, FALSE); &Cluster, FALSE);
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
@ -712,13 +748,13 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
{ {
/* disk is full */ /* disk is full */
NCluster = Cluster; NCluster = Cluster;
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0xffffffff); WriteCluster(DeviceExt, Cluster, 0xffffffff);
Cluster = NCluster; Cluster = NCluster;
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1) while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
{ {
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0); WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster; Cluster = NCluster;
} }
return STATUS_DISK_FULL; return STATUS_DISK_FULL;
@ -728,10 +764,8 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
} }
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart) else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{ {
DPRINT("Check for the ability to set file size\n"); DPRINT("Check for the ability to set file size\n");
if (!MmCanFileBeTruncated if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
(FileObject->SectionObjectPointer,
(PLARGE_INTEGER)AllocationSize)) (PLARGE_INTEGER)AllocationSize))
{ {
DPRINT("Couldn't set file size!\n"); DPRINT("Couldn't set file size!\n");
@ -750,7 +784,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
&Cluster, FALSE); &Cluster, FALSE);
NCluster = Cluster; NCluster = Cluster;
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0xffffffff); WriteCluster(DeviceExt, Cluster, 0xffffffff);
Cluster = NCluster; Cluster = NCluster;
} }
@ -776,10 +810,11 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
NCluster = Cluster = FirstCluster; NCluster = Cluster = FirstCluster;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1) while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
{ {
Status = NextCluster (DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0); WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster; Cluster = NCluster;
} }
} }
@ -787,6 +822,7 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
{ {
UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize); UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize);
} }
/* Update the on-disk directory entry */ /* Update the on-disk directory entry */
Fcb->Flags |= FCB_IS_DIRTY; Fcb->Flags |= FCB_IS_DIRTY;
if (AllocSizeChanged) if (AllocSizeChanged)
@ -796,10 +832,12 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Retrieve the specified file information * FUNCTION: Retrieve the specified file information
*/ */
NTSTATUS
VfatQueryInformation(
PVFAT_IRP_CONTEXT IrpContext)
{ {
FILE_INFORMATION_CLASS FileInformationClass; FILE_INFORMATION_CLASS FileInformationClass;
PVFATFCB FCB = NULL; PVFATFCB FCB = NULL;
@ -827,11 +865,10 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
if (!ExAcquireResourceSharedLite(&FCB->MainResource, if (!ExAcquireResourceSharedLite(&FCB->MainResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest (IrpContext); return VfatQueueRequest(IrpContext);
} }
} }
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FileStandardInformation: case FileStandardInformation:
@ -839,6 +876,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FilePositionInformation: case FilePositionInformation:
Status = VfatGetPositionInformation(IrpContext->FileObject, Status = VfatGetPositionInformation(IrpContext->FileObject,
FCB, FCB,
@ -846,6 +884,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileBasicInformation: case FileBasicInformation:
Status = VfatGetBasicInformation(IrpContext->FileObject, Status = VfatGetBasicInformation(IrpContext->FileObject,
FCB, FCB,
@ -853,6 +892,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileNameInformation: case FileNameInformation:
Status = VfatGetNameInformation(IrpContext->FileObject, Status = VfatGetNameInformation(IrpContext->FileObject,
FCB, FCB,
@ -860,17 +900,20 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileInternalInformation: case FileInternalInformation:
Status = VfatGetInternalInformation(FCB, Status = VfatGetInternalInformation(FCB,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileNetworkOpenInformation: case FileNetworkOpenInformation:
Status = VfatGetNetworkOpenInformation(FCB, Status = VfatGetNetworkOpenInformation(FCB,
IrpContext->DeviceExt, IrpContext->DeviceExt,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileAllInformation: case FileAllInformation:
Status = VfatGetAllInformation(IrpContext->FileObject, Status = VfatGetAllInformation(IrpContext->FileObject,
FCB, FCB,
@ -890,6 +933,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
case FileAlternateNameInformation: case FileAlternateNameInformation:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
break; break;
default: default:
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
} }
@ -898,6 +942,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
{ {
ExReleaseResourceLite(&FCB->MainResource); ExReleaseResourceLite(&FCB->MainResource);
} }
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
IrpContext->Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
@ -910,10 +955,12 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
return Status; return Status;
} }
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Retrieve the specified file information * FUNCTION: Retrieve the specified file information
*/ */
NTSTATUS
VfatSetInformation(
PVFAT_IRP_CONTEXT IrpContext)
{ {
FILE_INFORMATION_CLASS FileInformationClass; FILE_INFORMATION_CLASS FileInformationClass;
PVFATFCB FCB = NULL; PVFATFCB FCB = NULL;
@ -944,8 +991,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
if (FileInformationClass == FileEndOfFileInformation) if (FileInformationClass == FileEndOfFileInformation)
{ {
DPRINT("Check for the ability to set file size\n"); DPRINT("Check for the ability to set file size\n");
if (!MmCanFileBeTruncated if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
(IrpContext->FileObject->SectionObjectPointer,
(PLARGE_INTEGER)SystemBuffer)) (PLARGE_INTEGER)SystemBuffer))
{ {
DPRINT("Couldn't set file size!\n"); DPRINT("Couldn't set file size!\n");
@ -963,7 +1009,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,
(BOOLEAN)CanWait)) (BOOLEAN)CanWait))
{ {
return(VfatQueueRequest (IrpContext)); return VfatQueueRequest(IrpContext);
} }
} }
@ -973,12 +1019,14 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
RC = VfatSetPositionInformation(IrpContext->FileObject, RC = VfatSetPositionInformation(IrpContext->FileObject,
SystemBuffer); SystemBuffer);
break; break;
case FileDispositionInformation: case FileDispositionInformation:
RC = VfatSetDispositionInformation(IrpContext->FileObject, RC = VfatSetDispositionInformation(IrpContext->FileObject,
FCB, FCB,
IrpContext->DeviceObject, IrpContext->DeviceObject,
SystemBuffer); SystemBuffer);
break; break;
case FileAllocationInformation: case FileAllocationInformation:
case FileEndOfFileInformation: case FileEndOfFileInformation:
RC = VfatSetAllocationSizeInformation(IrpContext->FileObject, RC = VfatSetAllocationSizeInformation(IrpContext->FileObject,
@ -986,15 +1034,18 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
IrpContext->DeviceExt, IrpContext->DeviceExt,
(PLARGE_INTEGER)SystemBuffer); (PLARGE_INTEGER)SystemBuffer);
break; break;
case FileBasicInformation: case FileBasicInformation:
RC = VfatSetBasicInformation(IrpContext->FileObject, RC = VfatSetBasicInformation(IrpContext->FileObject,
FCB, FCB,
IrpContext->DeviceExt, IrpContext->DeviceExt,
SystemBuffer); SystemBuffer);
break; break;
case FileRenameInformation: case FileRenameInformation:
RC = STATUS_NOT_IMPLEMENTED; RC = STATUS_NOT_IMPLEMENTED;
break; break;
default: default:
RC = STATUS_NOT_SUPPORTED; RC = STATUS_NOT_SUPPORTED;
} }

View file

@ -13,7 +13,11 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb) static
NTSTATUS
VfatFlushFile(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb)
{ {
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
NTSTATUS Status; NTSTATUS Status;
@ -26,6 +30,7 @@ static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
/* FIXME: Caching was possible not initialized */ /* FIXME: Caching was possible not initialized */
IoStatus.Status = STATUS_SUCCESS; IoStatus.Status = STATUS_SUCCESS;
} }
if (Fcb->Flags & FCB_IS_DIRTY) if (Fcb->Flags & FCB_IS_DIRTY)
{ {
Status = VfatUpdateEntry(Fcb); Status = VfatUpdateEntry(Fcb);
@ -37,7 +42,10 @@ static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
return IoStatus.Status; return IoStatus.Status;
} }
NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) NTSTATUS
VfatFlushVolume(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB VolumeFcb)
{ {
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PVFATFCB Fcb; PVFATFCB Fcb;
@ -63,6 +71,7 @@ NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
} }
/* FIXME: Stop flushing if this is a removable media and the media was removed */ /* FIXME: Stop flushing if this is a removable media and the media was removed */
} }
ListEntry = DeviceExt->FcbListHead.Flink; ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead) while (ListEntry != &DeviceExt->FcbListHead)
{ {
@ -99,13 +108,14 @@ NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
return ReturnStatus; return ReturnStatus;
} }
NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatFlush(
PVFAT_IRP_CONTEXT IrpContext)
{ {
NTSTATUS Status; NTSTATUS Status;
PVFATFCB Fcb; PVFATFCB Fcb;
/*
* This request is not allowed on the main device object. /* This request is not allowed on the main device object. */
*/
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
@ -134,7 +144,7 @@ ByeBye:
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return (Status); return Status;
} }
/* EOF */ /* EOF */

View file

@ -33,8 +33,10 @@
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ #define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
static NTSTATUS static
VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount, NTSTATUS
VfatHasFileSystem(
PDEVICE_OBJECT DeviceToMount,
PBOOLEAN RecognizedFS, PBOOLEAN RecognizedFS,
PFATINFO pFatInfo) PFATINFO pFatInfo)
{ {
@ -66,6 +68,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status); DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status; return Status;
} }
FatInfo.FixedMedia = DiskGeometry.MediaType == FixedMedia ? TRUE : FALSE; FatInfo.FixedMedia = DiskGeometry.MediaType == FixedMedia ? TRUE : FALSE;
if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia) if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia)
{ {
@ -83,6 +86,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status); DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status; return Status;
} }
PartitionInfoIsValid = TRUE; PartitionInfoIsValid = TRUE;
DPRINT("Partition Information:\n"); DPRINT("Partition Information:\n");
DPRINT("StartingOffset %I64x\n", PartitionInfo.StartingOffset.QuadPart / 512); DPRINT("StartingOffset %I64x\n", PartitionInfo.StartingOffset.QuadPart / 512);
@ -128,9 +132,9 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
{ {
*RecognizedFS = TRUE; *RecognizedFS = TRUE;
} }
if (*RecognizedFS) if (*RecognizedFS)
{ {
Boot = ExAllocatePoolWithTag(NonPagedPool, DiskGeometry.BytesPerSector, TAG_VFAT); Boot = ExAllocatePoolWithTag(NonPagedPool, DiskGeometry.BytesPerSector, TAG_VFAT);
if (Boot == NULL) if (Boot == NULL)
{ {
@ -147,6 +151,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
{ {
*RecognizedFS = FALSE; *RecognizedFS = FALSE;
} }
if (*RecognizedFS && if (*RecognizedFS &&
Boot->BytesPerSector != 512 && Boot->BytesPerSector != 512 &&
Boot->BytesPerSector != 1024 && Boot->BytesPerSector != 1024 &&
@ -236,6 +241,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
FatInfo.FatType = FAT16; FatInfo.FatType = FAT16;
FatInfo.RootCluster = FatInfo.rootStart / FatInfo.SectorsPerCluster; FatInfo.RootCluster = FatInfo.rootStart / FatInfo.SectorsPerCluster;
} }
if (PartitionInfoIsValid && if (PartitionInfoIsValid &&
FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector) FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
{ {

View file

@ -34,9 +34,6 @@ PVFAT_GLOBAL_DATA VfatGlobalData;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/* /*
* FUNCTION: Called by the system to initialize the driver * FUNCTION: Called by the system to initialize the driver
* ARGUMENTS: * ARGUMENTS:
@ -44,6 +41,11 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
* RegistryPath = path to our configuration entries * RegistryPath = path to our configuration entries
* RETURNS: Success or failure * RETURNS: Success or failure
*/ */
NTSTATUS
NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat"); UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat");
@ -58,7 +60,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
0, 0,
FALSE, FALSE,
&DeviceObject); &DeviceObject);
if (Status == STATUS_OBJECT_NAME_EXISTS || if (Status == STATUS_OBJECT_NAME_EXISTS ||
Status == STATUS_OBJECT_NAME_COLLISION) Status == STATUS_OBJECT_NAME_COLLISION)
{ {
@ -73,11 +74,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
&DeviceObject); &DeviceObject);
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return (Status); return Status;
} }
VfatGlobalData = DeviceObject->DeviceExtension; VfatGlobalData = DeviceObject->DeviceExtension;
@ -94,10 +93,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = VfatBuildRequest;
VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
@ -127,8 +124,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
ExInitializeResourceLite(&VfatGlobalData->VolumeListLock); ExInitializeResourceLite(&VfatGlobalData->VolumeListLock);
InitializeListHead(&VfatGlobalData->VolumeListHead); InitializeListHead(&VfatGlobalData->VolumeListHead);
IoRegisterFileSystem(DeviceObject); IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
/* EOF */ /* EOF */

View file

@ -47,13 +47,14 @@ const char* MajorFunctionNames[] =
"IRP_MJ_MAXIMUM_FUNCTION" "IRP_MJ_MAXIMUM_FUNCTION"
}; };
/* FUNCTIONS ****************************************************************/
static LONG QueueCount = 0; static LONG QueueCount = 0;
static NTSTATUS VfatLockControl( /* FUNCTIONS ****************************************************************/
IN PVFAT_IRP_CONTEXT IrpContext
) static
NTSTATUS
VfatLockControl(
IN PVFAT_IRP_CONTEXT IrpContext)
{ {
PVFATFCB Fcb; PVFATFCB Fcb;
NTSTATUS Status; NTSTATUS Status;
@ -78,23 +79,24 @@ static NTSTATUS VfatLockControl(
Status = FsRtlProcessFileLock(&Fcb->FileLock, Status = FsRtlProcessFileLock(&Fcb->FileLock,
IrpContext->Irp, IrpContext->Irp,
NULL NULL);
);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return Status; return Status;
Fail:; Fail:
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)); IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }
static NTSTATUS static
VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatDispatchRequest(
IN PVFAT_IRP_CONTEXT IrpContext)
{ {
DPRINT ("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext, DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]); IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
ASSERT(IrpContext); ASSERT(IrpContext);
@ -102,9 +104,9 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
switch (IrpContext->MajorFunction) switch (IrpContext->MajorFunction)
{ {
case IRP_MJ_CLOSE: case IRP_MJ_CLOSE:
return VfatClose (IrpContext); return VfatClose(IrpContext);
case IRP_MJ_CREATE: case IRP_MJ_CREATE:
return VfatCreate (IrpContext); return VfatCreate(IrpContext);
case IRP_MJ_READ: case IRP_MJ_READ:
return VfatRead (IrpContext); return VfatRead (IrpContext);
case IRP_MJ_WRITE: case IRP_MJ_WRITE:
@ -130,7 +132,7 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
case IRP_MJ_PNP: case IRP_MJ_PNP:
return VfatPnp(IrpContext); return VfatPnp(IrpContext);
default: default:
DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
@ -138,17 +140,20 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
} }
} }
NTSTATUS NTAPI VfatBuildRequest ( NTSTATUS
NTAPI
VfatBuildRequest(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
NTSTATUS Status; NTSTATUS Status;
PVFAT_IRP_CONTEXT IrpContext; PVFAT_IRP_CONTEXT IrpContext;
DPRINT ("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp); DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
ASSERT(DeviceObject); ASSERT(DeviceObject);
ASSERT(Irp); ASSERT(Irp);
IrpContext = VfatAllocateIrpContext(DeviceObject, Irp); IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
if (IrpContext == NULL) if (IrpContext == NULL)
{ {
@ -165,18 +170,24 @@ NTSTATUS NTAPI VfatBuildRequest (
return Status; return Status;
} }
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext) VOID
VfatFreeIrpContext(
PVFAT_IRP_CONTEXT IrpContext)
{ {
ASSERT(IrpContext); ASSERT(IrpContext);
ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext); ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
} }
PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{ {
PVFAT_IRP_CONTEXT IrpContext; PVFAT_IRP_CONTEXT IrpContext;
/*PIO_STACK_LOCATION Stack;*/ /*PIO_STACK_LOCATION Stack;*/
UCHAR MajorFunction; UCHAR MajorFunction;
DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
ASSERT(DeviceObject); ASSERT(DeviceObject);
ASSERT(Irp); ASSERT(Irp);
@ -214,32 +225,40 @@ PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
static WORKER_THREAD_ROUTINE VfatDoRequest; static WORKER_THREAD_ROUTINE VfatDoRequest;
static VOID NTAPI VfatDoRequest (PVOID IrpContext) static
VOID
NTAPI
VfatDoRequest(
PVOID IrpContext)
{ {
InterlockedDecrement(&QueueCount); InterlockedDecrement(&QueueCount);
DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount); DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
FsRtlEnterFileSystem(); FsRtlEnterFileSystem();
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext); VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
FsRtlExitFileSystem(); FsRtlExitFileSystem();
} }
NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatQueueRequest(
PVFAT_IRP_CONTEXT IrpContext)
{ {
InterlockedIncrement(&QueueCount); InterlockedIncrement(&QueueCount);
DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext, QueueCount); DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
ASSERT(IrpContext != NULL); ASSERT(IrpContext != NULL);
ASSERT(IrpContext->Irp != NULL); ASSERT(IrpContext->Irp != NULL);
IrpContext->Flags |= IRPCONTEXT_CANWAIT; IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoMarkIrpPending (IrpContext->Irp); IoMarkIrpPending(IrpContext->Irp);
ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext); ExInitializeWorkItem(&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
return STATUS_PENDING; return STATUS_PENDING;
} }
PVOID VfatGetUserBuffer(IN PIRP Irp) PVOID
VfatGetUserBuffer(
IN PIRP Irp)
{ {
ASSERT(Irp); ASSERT(Irp);
@ -255,7 +274,11 @@ PVOID VfatGetUserBuffer(IN PIRP Irp)
} }
} }
NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation) NTSTATUS
VfatLockUserBuffer(
IN PIRP Irp,
IN ULONG Length,
IN LOCK_OPERATION Operation)
{ {
ASSERT(Irp); ASSERT(Irp);

View file

@ -14,7 +14,9 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatPnp(
PVFAT_IRP_CONTEXT IrpContext)
{ {
PVCB Vcb = NULL; PVCB Vcb = NULL;
NTSTATUS Status; NTSTATUS Status;
@ -32,6 +34,7 @@ NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
break; break;
default: default:
IoSkipCurrentIrpStackLocation(IrpContext->Irp); IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension; Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;

View file

@ -23,20 +23,21 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS /*
NextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend)
/*
* Return the next cluster in a FAT chain, possibly extending the chain if * Return the next cluster in a FAT chain, possibly extending the chain if
* necessary * necessary
*/ */
NTSTATUS
NextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend)
{ {
if (FirstCluster == 1) if (FirstCluster == 1)
{ {
(*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster; (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
else else
{ {
@ -48,15 +49,12 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
} }
NTSTATUS NTSTATUS
OffsetToCluster(PDEVICE_EXTENSION DeviceExt, OffsetToCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG FirstCluster, ULONG FirstCluster,
ULONG FileOffset, ULONG FileOffset,
PULONG Cluster, PULONG Cluster,
BOOLEAN Extend) BOOLEAN Extend)
/*
* Return the cluster corresponding to an offset within a file,
* possibly extending the file if necessary
*/
{ {
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG i; ULONG i;
@ -77,7 +75,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
/* root of FAT16 or FAT12 */ /* root of FAT16 or FAT12 */
*Cluster = DeviceExt->FatInfo.rootStart + FileOffset *Cluster = DeviceExt->FatInfo.rootStart + FileOffset
/ (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster; / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
else else
{ {
@ -88,7 +86,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
{ {
Status = GetNextClusterExtend (DeviceExt, CurrentCluster, &CurrentCluster); Status = GetNextClusterExtend (DeviceExt, CurrentCluster, &CurrentCluster);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return(Status); return Status;
} }
*Cluster = CurrentCluster; *Cluster = CurrentCluster;
} }
@ -98,22 +96,24 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
{ {
Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster); Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return(Status); return Status;
} }
*Cluster = CurrentCluster; *Cluster = CurrentCluster;
} }
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }
} }
static NTSTATUS
VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
ULONG Length,
LARGE_INTEGER ReadOffset,
PULONG LengthRead)
/* /*
* FUNCTION: Reads data from a file * FUNCTION: Reads data from a file
*/ */
static
NTSTATUS
VfatReadFileData(
PVFAT_IRP_CONTEXT IrpContext,
ULONG Length,
LARGE_INTEGER ReadOffset,
PULONG LengthRead)
{ {
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG FirstCluster; ULONG FirstCluster;
@ -168,6 +168,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
} }
return Status; return Status;
} }
/* Is this a read of the Volume ? */ /* Is this a read of the Volume ? */
if (Fcb->Flags & FCB_IS_VOLUME) if (Fcb->Flags & FCB_IS_VOLUME)
{ {
@ -183,23 +184,20 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
return Status; return Status;
} }
/* /* Find the first cluster */
* Find the first cluster FirstCluster =
*/ CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
FirstCluster = CurrentCluster =
vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
if (FirstCluster == 1) if (FirstCluster == 1)
{ {
// Directory of FAT12/16 needs a special handling /* Directory of FAT12/16 needs a special handling */
if (ReadOffset.u.LowPart + Length > DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector) if (ReadOffset.u.LowPart + Length > DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector)
{ {
Length = DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector - ReadOffset.u.LowPart; Length = DeviceExt->FatInfo.rootDirectorySectors * BytesPerSector - ReadOffset.u.LowPart;
} }
ReadOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector; ReadOffset.u.LowPart += DeviceExt->FatInfo.rootStart * BytesPerSector;
// Fire up the read command /* Fire up the read command */
Status = VfatReadDiskPartial (IrpContext, &ReadOffset, Length, 0, TRUE); Status = VfatReadDiskPartial (IrpContext, &ReadOffset, Length, 0, TRUE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
@ -213,9 +211,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
LastOffset = Fcb->LastOffset; LastOffset = Fcb->LastOffset;
ExReleaseFastMutex(&Fcb->LastMutex); ExReleaseFastMutex(&Fcb->LastMutex);
/* /* Find the cluster to start the read from */
* Find the cluster to start the read from
*/
if (LastCluster > 0 && ReadOffset.u.LowPart >= LastOffset) if (LastCluster > 0 && ReadOffset.u.LowPart >= LastOffset)
{ {
Status = OffsetToCluster(DeviceExt, LastCluster, Status = OffsetToCluster(DeviceExt, LastCluster,
@ -240,9 +236,10 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster), ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster),
&CurrentCluster, FALSE); &CurrentCluster, FALSE);
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return Status;
} }
ExAcquireFastMutex(&Fcb->LastMutex); ExAcquireFastMutex(&Fcb->LastMutex);
@ -291,7 +288,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
Fcb->LastOffset = ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster) + (ClusterCount - 1) * BytesPerCluster; Fcb->LastOffset = ROUND_DOWN(ReadOffset.u.LowPart, BytesPerCluster) + (ClusterCount - 1) * BytesPerCluster;
ExReleaseFastMutex(&Fcb->LastMutex); ExReleaseFastMutex(&Fcb->LastMutex);
// Fire up the read command /* Fire up the read command */
Status = VfatReadDiskPartial (IrpContext, &StartOffset, BytesDone, *LengthRead, FALSE); Status = VfatReadDiskPartial (IrpContext, &StartOffset, BytesDone, *LengthRead, FALSE);
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{ {
@ -301,10 +298,12 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
Length -= BytesDone; Length -= BytesDone;
ReadOffset.u.LowPart += BytesDone; ReadOffset.u.LowPart += BytesDone;
} }
if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
if (InterlockedDecrement((PLONG)&IrpContext->RefCount) != 0)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
} }
if (NT_SUCCESS(Status) || Status == STATUS_PENDING) if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
{ {
if (Length > 0) if (Length > 0)
@ -316,11 +315,14 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext,
Status = IrpContext->Irp->IoStatus.Status; Status = IrpContext->Irp->IoStatus.Status;
} }
} }
return Status; return Status;
} }
static NTSTATUS static
VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext, NTSTATUS
VfatWriteFileData(
PVFAT_IRP_CONTEXT IrpContext,
ULONG Length, ULONG Length,
LARGE_INTEGER WriteOffset) LARGE_INTEGER WriteOffset)
{ {
@ -362,7 +364,7 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
ASSERT(WriteOffset.u.LowPart % BytesPerSector == 0); ASSERT(WriteOffset.u.LowPart % BytesPerSector == 0);
ASSERT(Length % BytesPerSector == 0); ASSERT(Length % BytesPerSector == 0);
// Is this a write of the volume ? /* Is this a write of the volume? */
if (Fcb->Flags & FCB_IS_VOLUME) if (Fcb->Flags & FCB_IS_VOLUME)
{ {
Status = VfatWriteDiskPartial(IrpContext, &WriteOffset, Length, 0, TRUE); Status = VfatWriteDiskPartial(IrpContext, &WriteOffset, Length, 0, TRUE);
@ -373,7 +375,7 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
return Status; return Status;
} }
// Is this a write to the FAT ? /* Is this a write to the FAT? */
if (Fcb->Flags & FCB_IS_FAT) if (Fcb->Flags & FCB_IS_FAT)
{ {
WriteOffset.u.LowPart += DeviceExt->FatInfo.FATStart * BytesPerSector; WriteOffset.u.LowPart += DeviceExt->FatInfo.FATStart * BytesPerSector;
@ -388,10 +390,12 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
} }
WriteOffset.u.LowPart += Fcb->RFCB.FileSize.u.LowPart; WriteOffset.u.LowPart += Fcb->RFCB.FileSize.u.LowPart;
} }
if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
if (InterlockedDecrement((PLONG)&IrpContext->RefCount) != 0)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
} }
if (NT_SUCCESS(Status) || Status == STATUS_PENDING) if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
{ {
Status = IrpContext->Irp->IoStatus.Status; Status = IrpContext->Irp->IoStatus.Status;
@ -402,8 +406,8 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
/* /*
* Find the first cluster * Find the first cluster
*/ */
FirstCluster = CurrentCluster = FirstCluster =
vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry); CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
if (FirstCluster == 1) if (FirstCluster == 1)
{ {
@ -450,7 +454,7 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return Status;
} }
ExAcquireFastMutex(&Fcb->LastMutex); ExAcquireFastMutex(&Fcb->LastMutex);
@ -509,10 +513,12 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
Length -= BytesDone; Length -= BytesDone;
WriteOffset.u.LowPart += BytesDone; WriteOffset.u.LowPart += BytesDone;
} }
if (0 != InterlockedDecrement((PLONG)&IrpContext->RefCount))
if (InterlockedDecrement((PLONG)&IrpContext->RefCount) != 0)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
} }
if (NT_SUCCESS(Status) || Status == STATUS_PENDING) if (NT_SUCCESS(Status) || Status == STATUS_PENDING)
{ {
if (Length > 0) if (Length > 0)
@ -528,7 +534,8 @@ VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
} }
NTSTATUS NTSTATUS
VfatRead(PVFAT_IRP_CONTEXT IrpContext) VfatRead(
PVFAT_IRP_CONTEXT IrpContext)
{ {
NTSTATUS Status; NTSTATUS Status;
PVFATFCB Fcb; PVFATFCB Fcb;
@ -582,7 +589,6 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
goto ByeBye; goto ByeBye;
} }
DPRINT("'%wZ', Offset: %u, Length %u\n", &Fcb->PathNameU, ByteOffset.u.LowPart, Length); DPRINT("'%wZ', Offset: %u, Length %u\n", &Fcb->PathNameU, ByteOffset.u.LowPart, Length);
if (ByteOffset.u.HighPart && !(Fcb->Flags & FCB_IS_VOLUME)) if (ByteOffset.u.HighPart && !(Fcb->Flags & FCB_IS_VOLUME))
@ -590,12 +596,14 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto ByeBye; goto ByeBye;
} }
if (ByteOffset.QuadPart >= Fcb->RFCB.FileSize.QuadPart) if (ByteOffset.QuadPart >= Fcb->RFCB.FileSize.QuadPart)
{ {
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
Status = STATUS_END_OF_FILE; Status = STATUS_END_OF_FILE;
goto ByeBye; goto ByeBye;
} }
if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME)) if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME))
{ {
if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0) if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
@ -606,6 +614,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
goto ByeBye; goto ByeBye;
} }
} }
if (Length == 0) if (Length == 0)
{ {
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
@ -625,6 +634,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
{ {
Resource = &Fcb->MainResource; Resource = &Fcb->MainResource;
} }
if (!ExAcquireResourceSharedLite(Resource, if (!ExAcquireResourceSharedLite(Resource,
IrpContext->Flags & IRPCONTEXT_CANWAIT ? TRUE : FALSE)) IrpContext->Flags & IRPCONTEXT_CANWAIT ? TRUE : FALSE))
{ {
@ -669,6 +679,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
&(VfatGlobalData->CacheMgrCallbacks), &(VfatGlobalData->CacheMgrCallbacks),
Fcb); Fcb);
} }
if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length, if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT), Buffer, (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT), Buffer,
&IrpContext->Irp->IoStatus)) &IrpContext->Irp->IoStatus))
@ -676,6 +687,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Status = STATUS_PENDING; Status = STATUS_PENDING;
goto ByeBye; goto ByeBye;
} }
if (!NT_SUCCESS(IrpContext->Irp->IoStatus.Status)) if (!NT_SUCCESS(IrpContext->Irp->IoStatus.Status))
{ {
Status = IrpContext->Irp->IoStatus.Status; Status = IrpContext->Irp->IoStatus.Status;
@ -727,7 +739,7 @@ ByeBye:
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO &&
!(IrpContext->Irp->Flags & IRP_PAGING_IO) && !(IrpContext->Irp->Flags & IRP_PAGING_IO) &&
(NT_SUCCESS(Status) || Status==STATUS_END_OF_FILE)) (NT_SUCCESS(Status) || Status == STATUS_END_OF_FILE))
{ {
IrpContext->FileObject->CurrentByteOffset.QuadPart = IrpContext->FileObject->CurrentByteOffset.QuadPart =
ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information; ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
@ -741,7 +753,9 @@ ByeBye:
return Status; return Status;
} }
NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatWrite(
PVFAT_IRP_CONTEXT IrpContext)
{ {
PVFATFCB Fcb; PVFATFCB Fcb;
PERESOURCE Resource = NULL; PERESOURCE Resource = NULL;
@ -807,7 +821,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
} }
if (Fcb->Flags & (FCB_IS_FAT | FCB_IS_VOLUME) || if (Fcb->Flags & (FCB_IS_FAT | FCB_IS_VOLUME) ||
1 == vfatDirEntryGetFirstCluster (IrpContext->DeviceExt, &Fcb->entry)) vfatDirEntryGetFirstCluster(IrpContext->DeviceExt, &Fcb->entry) == 1)
{ {
if (ByteOffset.QuadPart + Length > Fcb->RFCB.FileSize.QuadPart) if (ByteOffset.QuadPart + Length > Fcb->RFCB.FileSize.QuadPart)
{ {
@ -829,9 +843,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
if (Length == 0) if (Length == 0)
{ {
/* FIXME: /* FIXME: Update last write time */
* Update last write time
*/
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
goto ByeBye; goto ByeBye;
@ -844,6 +856,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto ByeBye; goto ByeBye;
} }
if (ByteOffset.u.LowPart + Length > ROUND_UP(Fcb->RFCB.AllocationSize.u.LowPart, BytesPerSector)) if (ByteOffset.u.LowPart + Length > ROUND_UP(Fcb->RFCB.AllocationSize.u.LowPart, BytesPerSector))
{ {
Length = ROUND_UP(Fcb->RFCB.FileSize.u.LowPart, BytesPerSector) - ByteOffset.u.LowPart; Length = ROUND_UP(Fcb->RFCB.FileSize.u.LowPart, BytesPerSector) - ByteOffset.u.LowPart;
@ -940,10 +953,12 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
&VfatGlobalData->CacheMgrCallbacks, &VfatGlobalData->CacheMgrCallbacks,
Fcb); Fcb);
} }
if (ByteOffset.QuadPart > OldFileSize.QuadPart) if (ByteOffset.QuadPart > OldFileSize.QuadPart)
{ {
CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE); CcZeroData(IrpContext->FileObject, &OldFileSize, &ByteOffset, TRUE);
} }
if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length, if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length,
1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer)) 1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer))
{ {
@ -987,7 +1002,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
KeQuerySystemTime (&SystemTime); KeQuerySystemTime (&SystemTime);
if (Fcb->Flags & FCB_IS_FATX_ENTRY) if (Fcb->Flags & FCB_IS_FATX_ENTRY)
{ {
FsdSystemTimeToDosDateTime (IrpContext->DeviceExt, FsdSystemTimeToDosDateTime(IrpContext->DeviceExt,
&SystemTime, &Fcb->entry.FatX.UpdateDate, &SystemTime, &Fcb->entry.FatX.UpdateDate,
&Fcb->entry.FatX.UpdateTime); &Fcb->entry.FatX.UpdateTime);
Fcb->entry.FatX.AccessDate = Fcb->entry.FatX.UpdateDate; Fcb->entry.FatX.AccessDate = Fcb->entry.FatX.UpdateDate;
@ -995,7 +1010,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
} }
else else
{ {
FsdSystemTimeToDosDateTime (IrpContext->DeviceExt, FsdSystemTimeToDosDateTime(IrpContext->DeviceExt,
&SystemTime, &Fcb->entry.Fat.UpdateDate, &SystemTime, &Fcb->entry.Fat.UpdateDate,
&Fcb->entry.Fat.UpdateTime); &Fcb->entry.Fat.UpdateTime);
Fcb->entry.Fat.AccessDate = Fcb->entry.Fat.UpdateDate; Fcb->entry.Fat.AccessDate = Fcb->entry.Fat.UpdateDate;

View file

@ -13,8 +13,10 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS static
VfatDiskShutDown(PVCB Vcb) NTSTATUS
VfatDiskShutDown(
PVCB Vcb)
{ {
PIRP Irp; PIRP Irp;
KEVENT Event; KEVENT Event;
@ -41,8 +43,12 @@ VfatDiskShutDown(PVCB Vcb)
return Status; return Status;
} }
NTSTATUS NTAPI
VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp) NTSTATUS
NTAPI
VfatShutdown(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{ {
NTSTATUS Status; NTSTATUS Status;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
@ -77,13 +83,16 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
} }
} }
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = VfatDiskShutDown(DeviceExt); Status = VfatDiskShutDown(DeviceExt);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status); DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
} }
}
else else
{ {
DPRINT1("VfatFlushVolume failed, status = %x\n", Status); DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
@ -112,7 +121,7 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
FsRtlExitFileSystem(); FsRtlExitFileSystem();
return(Status); return Status;
} }
/* EOF */ /* EOF */

View file

@ -17,7 +17,8 @@
const WCHAR *long_illegals = L"\"*\\<>/?:|"; const WCHAR *long_illegals = L"\"*\\<>/?:|";
BOOLEAN BOOLEAN
vfatIsLongIllegal(WCHAR c) vfatIsLongIllegal(
WCHAR c)
{ {
return wcschr(long_illegals, c) ? TRUE : FALSE; return wcschr(long_illegals, c) ? TRUE : FALSE;
} }

View file

@ -341,12 +341,12 @@ FsdSetFsLabelInformation(
} }
NTSTATUS
VfatQueryVolumeInformation(
PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Retrieve the specified volume information * FUNCTION: Retrieve the specified volume information
*/ */
NTSTATUS
VfatQueryVolumeInformation(
PVFAT_IRP_CONTEXT IrpContext)
{ {
FS_INFORMATION_CLASS FsInformationClass; FS_INFORMATION_CLASS FsInformationClass;
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
@ -416,12 +416,12 @@ VfatQueryVolumeInformation(
} }
NTSTATUS
VfatSetVolumeInformation(
PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Set the specified volume information * FUNCTION: Set the specified volume information
*/ */
NTSTATUS
VfatSetVolumeInformation(
PVFAT_IRP_CONTEXT IrpContext)
{ {
FS_INFORMATION_CLASS FsInformationClass; FS_INFORMATION_CLASS FsInformationClass;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;