mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:13:03 +00:00
[FASTFAT]
Fix coding style and indentation. No code changes! svn path=/trunk/; revision=61252
This commit is contained in:
parent
5a02327fd0
commit
3f339ec7b9
15 changed files with 3195 additions and 3051 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue