[FASTFAT]

Fix coding style and indentation. No code changes!

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

View file

@ -15,410 +15,419 @@
/* FUNCTIONS ***************************************************************/
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
static NTSTATUS NTAPI
VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
static
NTSTATUS
NTAPI
VfatReadWritePartialCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PVFAT_IRP_CONTEXT IrpContext;
PMDL Mdl;
PVFAT_IRP_CONTEXT IrpContext;
PMDL Mdl;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(DeviceObject);
DPRINT("VfatReadWritePartialCompletion() called\n");
DPRINT("VfatReadWritePartialCompletion() called\n");
IrpContext = (PVFAT_IRP_CONTEXT)Context;
IrpContext = (PVFAT_IRP_CONTEXT)Context;
while ((Mdl = Irp->MdlAddress))
while ((Mdl = Irp->MdlAddress))
{
Irp->MdlAddress = Mdl->Next;
IoFreeMdl(Mdl);
Irp->MdlAddress = Mdl->Next;
IoFreeMdl(Mdl);
}
if (Irp->PendingReturned)
{
IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
}
else
{
IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
}
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
}
if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED)
{
KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
}
IoFreeIrp(Irp);
DPRINT("VfatReadWritePartialCompletion() done\n");
if (Irp->PendingReturned)
{
IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
}
else
{
IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
}
return STATUS_MORE_PROCESSING_REQUIRED;
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
}
if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED)
{
KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
}
IoFreeIrp(Irp);
DPRINT("VfatReadWritePartialCompletion() done\n");
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject,
IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
VfatReadDisk(
IN PDEVICE_OBJECT pDeviceObject,
IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
KEVENT event;
NTSTATUS Status;
PIO_STACK_LOCATION Stack;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
NTSTATUS Status;
again:
KeInitializeEvent (&event, NotificationEvent, FALSE);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
pDeviceObject,
Buffer,
ReadLength,
ReadOffset,
&event,
&IoStatus);
if (Irp == NULL)
DPRINT ("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
pDeviceObject,
Buffer,
ReadLength,
ReadOffset,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return(STATUS_UNSUCCESSFUL);
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return STATUS_UNSUCCESSFUL;
}
if (Override)
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT ("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver (pDeviceObject, Irp);
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver (pDeviceObject, Irp);
DPRINT ("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT ("Operation pending\n");
KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status;
DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status;
}
if (Status == STATUS_VERIFY_REQUIRED)
if (Status == STATUS_VERIFY_REQUIRED)
{
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. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
Status = IoVerifyVolume (DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
/* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume(DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
{
DPRINT1 ("Volume verification successful; Reissuing read request\n");
goto again;
DPRINT1("Volume verification successful; Reissuing read request\n");
goto again;
}
}
if (!NT_SUCCESS (Status))
if (!NT_SUCCESS(Status))
{
DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
return (Status);
DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
return Status;
}
DPRINT ("Block request succeeded for %p\n", Irp);
return (STATUS_SUCCESS);
DPRINT("Block request succeeded for %p\n", Irp);
return STATUS_SUCCESS;
}
NTSTATUS
VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength,
ULONG BufferOffset,
IN BOOLEAN Wait)
VfatReadDiskPartial(
IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER ReadOffset,
IN ULONG ReadLength,
ULONG BufferOffset,
IN BOOLEAN Wait)
{
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PVOID Buffer;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PVOID Buffer;
DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
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;
again:
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
if (Irp == NULL)
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
if (Irp == NULL)
{
DPRINT("IoAllocateIrp failed\n");
return(STATUS_UNSUCCESSFUL);
DPRINT("IoAllocateIrp failed\n");
return STATUS_UNSUCCESSFUL;
}
Irp->UserIosb = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->UserIosb = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_READ;
StackPtr->MinorFunction = 0;
StackPtr->Flags = 0;
StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = ReadLength;
StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_READ;
StackPtr->MinorFunction = 0;
StackPtr->Flags = 0;
StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = ReadLength;
StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
{
DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL;
DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL;
}
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
IoSetCompletionRoutine(Irp,
VfatReadWritePartialCompletion,
IrpContext,
TRUE,
TRUE,
TRUE);
IoSetCompletionRoutine(Irp,
VfatReadWritePartialCompletion,
IrpContext,
TRUE,
TRUE,
TRUE);
if (Wait)
if (Wait)
{
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 1;
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 1;
}
else
else
{
InterlockedIncrement((PLONG)&IrpContext->RefCount);
InterlockedIncrement((PLONG)&IrpContext->RefCount);
}
DPRINT ("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
if (Wait && Status == STATUS_PENDING)
if (Wait && Status == STATUS_PENDING)
{
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
Status = IrpContext->Irp->IoStatus.Status;
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
Status = IrpContext->Irp->IoStatus.Status;
}
if (Status == STATUS_VERIFY_REQUIRED)
if (Status == STATUS_VERIFY_REQUIRED)
{
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. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
Status = IoVerifyVolume (DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
/* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume(DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
{
DPRINT1 ("Volume verification successful; Reissuing read request\n");
goto again;
DPRINT1("Volume verification successful; Reissuing read request\n");
goto again;
}
}
DPRINT("%x\n", Status);
return Status;
DPRINT("%x\n", Status);
return Status;
}
NTSTATUS
VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER WriteOffset,
IN ULONG WriteLength,
IN ULONG BufferOffset,
IN BOOLEAN Wait)
VfatWriteDiskPartial(
IN PVFAT_IRP_CONTEXT IrpContext,
IN PLARGE_INTEGER WriteOffset,
IN ULONG WriteLength,
IN ULONG BufferOffset,
IN BOOLEAN Wait)
{
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PVOID Buffer;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PVOID Buffer;
DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
again:
DPRINT ("Building asynchronous FSD Request...\n");
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
if (Irp == NULL)
DPRINT("Building asynchronous FSD Request...\n");
Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
if (Irp == NULL)
{
DPRINT("IoAllocateIrp failed\n");
return(STATUS_UNSUCCESSFUL);
DPRINT("IoAllocateIrp failed\n");
return STATUS_UNSUCCESSFUL;
}
Irp->UserIosb = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->UserIosb = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_WRITE;
StackPtr->MinorFunction = 0;
StackPtr->Flags = 0;
StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = WriteLength;
StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_WRITE;
StackPtr->MinorFunction = 0;
StackPtr->Flags = 0;
StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = WriteLength;
StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
{
DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL;
}
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
IoSetCompletionRoutine(Irp,
VfatReadWritePartialCompletion,
IrpContext,
TRUE,
TRUE,
TRUE);
if (Wait)
{
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 1;
}
else
{
InterlockedIncrement((PLONG)&IrpContext->RefCount);
DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL;
}
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
DPRINT ("Calling IO Driver...\n");
Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
if (Wait && Status == STATUS_PENDING)
IoSetCompletionRoutine(Irp,
VfatReadWritePartialCompletion,
IrpContext,
TRUE,
TRUE,
TRUE);
if (Wait)
{
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
Status = IrpContext->Irp->IoStatus.Status;
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 1;
}
else
{
InterlockedIncrement((PLONG)&IrpContext->RefCount);
}
if (Status == STATUS_VERIFY_REQUIRED)
DPRINT("Calling IO Driver...\n");
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
if (Wait && Status == STATUS_PENDING)
{
PDEVICE_OBJECT DeviceToVerify;
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
Status = IrpContext->Irp->IoStatus.Status;
}
DPRINT1 ("Media change detected!\n");
if (Status == STATUS_VERIFY_REQUIRED)
{
PDEVICE_OBJECT DeviceToVerify;
/* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
Status = IoVerifyVolume (DeviceToVerify,
FALSE);
DPRINT1("Media change detected!\n");
if (NT_SUCCESS(Status))
/* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume(DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
{
DPRINT1 ("Volume verification successful; Reissuing write request\n");
goto again;
DPRINT1("Volume verification successful; Reissuing write request\n");
goto again;
}
}
return Status;
return Status;
}
NTSTATUS
VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
IN ULONG CtlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer OPTIONAL,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override)
VfatBlockDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG CtlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer OPTIONAL,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
KEVENT Event;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
PIO_STACK_LOCATION Stack;
KEVENT Event;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
"InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
"OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
OutputBufferSize ? *OutputBufferSize : 0);
DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
"InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
"OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
OutputBufferSize ? *OutputBufferSize : 0);
again:
KeInitializeEvent (&Event, NotificationEvent, FALSE);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(CtlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
(OutputBufferSize) ? *OutputBufferSize : 0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(CtlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
(OutputBufferSize) ? *OutputBufferSize : 0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Override)
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT ("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT ("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT ("Operation pending\n");
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %p\n", Irp);
DPRINT("Operation pending\n");
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status;
Status = IoStatus.Status;
}
if (Status == STATUS_VERIFY_REQUIRED)
if (Status == STATUS_VERIFY_REQUIRED)
{
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. */
DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
Status = IoVerifyVolume (DeviceToVerify,
FALSE);
/* Find the device to verify and reset the thread field to empty value again. */
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume(DeviceToVerify,
FALSE);
if (NT_SUCCESS(Status))
if (NT_SUCCESS(Status))
{
DPRINT1 ("Volume verification successful; Reissuing IOCTL request\n");
goto again;
DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
goto again;
}
}
if (OutputBufferSize)
if (OutputBufferSize)
{
*OutputBufferSize = IoStatus.Information;
*OutputBufferSize = IoStatus.Information;
}
DPRINT("Returning Status %x\n", Status);
DPRINT("Returning Status %x\n", Status);
return Status;
return Status;
}

View file

@ -13,98 +13,103 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS
VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
NTSTATUS
VfatCloseFile(
PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject)
{
PVFATFCB pFcb;
PVFATCCB pCcb;
NTSTATUS Status = STATUS_SUCCESS;
PVFATFCB pFcb;
PVFATCCB pCcb;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT ("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
DeviceExt, FileObject);
DPRINT("VfatCloseFile(DeviceExt %p, FileObject %p)\n",
DeviceExt, FileObject);
/* FIXME : update entry in directory? */
pCcb = (PVFATCCB) (FileObject->FsContext2);
pFcb = (PVFATFCB) (FileObject->FsContext);
/* FIXME : update entry in directory? */
pCcb = (PVFATCCB) (FileObject->FsContext2);
pFcb = (PVFATFCB) (FileObject->FsContext);
if (pFcb == NULL)
{
return STATUS_SUCCESS;
}
if (pFcb->Flags & FCB_IS_VOLUME)
{
DPRINT1("Volume\n");
pFcb->RefCount--;
FileObject->FsContext2 = NULL;
}
else
{
if (FileObject->DeletePending)
if (pFcb == NULL)
{
if (pFcb->Flags & FCB_DELETE_PENDING)
{
VfatDelEntry (DeviceExt, pFcb);
}
else
{
Status = STATUS_DELETE_PENDING;
}
return STATUS_SUCCESS;
}
vfatReleaseFCB (DeviceExt, pFcb);
}
FileObject->FsContext2 = NULL;
FileObject->FsContext = NULL;
FileObject->SectionObjectPointer = NULL;
if (pFcb->Flags & FCB_IS_VOLUME)
{
DPRINT1("Volume\n");
pFcb->RefCount--;
FileObject->FsContext2 = NULL;
}
else
{
if (FileObject->DeletePending)
{
if (pFcb->Flags & FCB_DELETE_PENDING)
{
VfatDelEntry (DeviceExt, pFcb);
}
else
{
Status = STATUS_DELETE_PENDING;
}
}
if (pCcb)
{
vfatDestroyCCB(pCcb);
}
vfatReleaseFCB (DeviceExt, pFcb);
}
return Status;
FileObject->FsContext2 = NULL;
FileObject->FsContext = NULL;
FileObject->SectionObjectPointer = NULL;
if (pCcb)
{
vfatDestroyCCB(pCcb);
}
return Status;
}
NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
/*
* 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)
{
DPRINT("Closing file system\n");
Status = STATUS_SUCCESS;
goto ByeBye;
DPRINT("Closing file system\n");
Status = STATUS_SUCCESS;
goto ByeBye;
}
#if 0
/* There occurs a dead look at the call to CcRosDeleteFileCache/ObDereferenceObject/VfatClose
in CmLazyCloseThreadMain if VfatClose is execute asynchronous in a worker thread. */
if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
/* There occurs a dead look at the call to CcRosDeleteFileCache/ObDereferenceObject/VfatClose
in CmLazyCloseThreadMain if VfatClose is execute asynchronous in a worker thread. */
if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
#else
if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE))
if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE))
#endif
{
return VfatQueueRequest (IrpContext);
}
{
return VfatQueueRequest(IrpContext);
}
Status = VfatCloseFile (IrpContext->DeviceExt, IrpContext->FileObject);
ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return (Status);
return Status;
}
/* EOF */

View file

@ -30,34 +30,37 @@
/* FUNCTIONS *****************************************************************/
void
vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
VOID
vfat8Dot3ToString(
PFAT_DIR_ENTRY pEntry,
PUNICODE_STRING NameU)
{
OEM_STRING StringA;
USHORT Length;
CHAR cString[12];
OEM_STRING StringA;
USHORT Length;
CHAR cString[12];
RtlCopyMemory(cString, pEntry->ShortName, 11);
cString[11] = 0;
if (cString[0] == 0x05)
{
cString[0] = 0xe5;
}
RtlCopyMemory(cString, pEntry->ShortName, 11);
cString[11] = 0;
if (cString[0] == 0x05)
{
cString[0] = 0xe5;
}
StringA.Buffer = cString;
for (StringA.Length = 0;
StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
StringA.Length++);
StringA.MaximumLength = StringA.Length;
StringA.Buffer = cString;
for (StringA.Length = 0;
StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
StringA.Length++);
StringA.MaximumLength = StringA.Length;
RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
if (pEntry->lCase & VFAT_CASE_LOWER_BASE)
{
RtlDowncaseUnicodeString(NameU, NameU, FALSE);
}
if (cString[8] != ' ')
{
if (pEntry->lCase & VFAT_CASE_LOWER_BASE)
{
RtlDowncaseUnicodeString(NameU, NameU, FALSE);
}
if (cString[8] != ' ')
{
Length = NameU->Length;
NameU->Buffer += Length / sizeof(WCHAR);
if (!FAT_ENTRY_VOLUME(pEntry))
@ -83,8 +86,9 @@ vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
NameU->Length += Length;
NameU->MaximumLength += Length;
}
NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
DPRINT("'%wZ'\n", NameU);
NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
DPRINT("'%wZ'\n", NameU);
}
NTSTATUS

View file

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

View file

@ -19,166 +19,178 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS
FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
* disk read
*/
NTSTATUS
FAT32GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * sizeof(ULONG);
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return (STATUS_SUCCESS);
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * sizeof(ULONG);
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return STATUS_SUCCESS;
}
NTSTATUS
FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table
*/
NTSTATUS
FAT16GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PVOID BaseAddress;
ULONG FATOffset;
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return (STATUS_SUCCESS);
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff;
CcUnpinData(Context);
*NextCluster = CurrentCluster;
return STATUS_SUCCESS;
}
NTSTATUS
FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
/*
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
*/
NTSTATUS
FAT12GetNextCluster(
PDEVICE_EXTENSION DeviceExt,
ULONG CurrentCluster,
PULONG NextCluster)
{
PUSHORT CBlock;
ULONG Entry;
PVOID BaseAddress;
PVOID Context;
LARGE_INTEGER Offset;
PUSHORT CBlock;
ULONG Entry;
PVOID BaseAddress;
PVOID Context;
LARGE_INTEGER Offset;
*NextCluster = 0;
*NextCluster = 0;
Offset.QuadPart = 0;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
if ((CurrentCluster % 2) == 0)
Offset.QuadPart = 0;
if (!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
{
Entry = *CBlock & 0x0fff;
return STATUS_UNSUCCESSFUL;
}
else
CBlock = (PUSHORT)((char*)BaseAddress + (CurrentCluster * 12) / 8);
if ((CurrentCluster % 2) == 0)
{
Entry = *CBlock >> 4;
Entry = *CBlock & 0x0fff;
}
// DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff;
// DPRINT("Returning %x\n",Entry);
*NextCluster = Entry;
CcUnpinData(Context);
// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS;
return STATUS_SUCCESS;
else
{
Entry = *CBlock >> 4;
}
// DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff;
// DPRINT("Returning %x\n",Entry);
*NextCluster = Entry;
CcUnpinData(Context);
// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS
FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt,
PULONG Cluster)
/*
* FUNCTION: Finds the first available cluster in a FAT16 table
*/
NTSTATUS
FAT16FindAndMarkAvailableCluster(
PDEVICE_EXTENSION DeviceExt,
PULONG Cluster)
{
ULONG FatLength;
ULONG StartCluster;
ULONG i, j;
PVOID BaseAddress;
ULONG ChunkSize;
PVOID Context = 0;
LARGE_INTEGER Offset;
PUSHORT Block;
PUSHORT BlockEnd;
ULONG FatLength;
ULONG StartCluster;
ULONG i, j;
PVOID BaseAddress;
ULONG ChunkSize;
PVOID Context = 0;
LARGE_INTEGER Offset;
PUSHORT Block;
PUSHORT BlockEnd;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
for (j = 0; j < 2; j++)
{
for (i = StartCluster; i < FatLength; )
for (j = 0; j < 2; j++)
{
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
if (*Block == 0)
for (i = StartCluster; i < FatLength;)
{
DPRINT("Found available cluster 0x%x\n", i);
DeviceExt->LastAvailableCluster = *Cluster = i;
*Block = 0xffff;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
return(STATUS_SUCCESS);
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
/* Now process the whole block */
while (Block < BlockEnd && i < FatLength)
{
if (*Block == 0)
{
DPRINT("Found available cluster 0x%x\n", i);
DeviceExt->LastAvailableCluster = *Cluster = i;
*Block = 0xffff;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
if (DeviceExt->AvailableClustersValid)
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
return STATUS_SUCCESS;
}
Block++;
i++;
}
CcUnpinData(Context);
}
Block++;
i++;
}
CcUnpinData(Context);
FatLength = StartCluster;
StartCluster = 2;
}
FatLength = StartCluster;
StartCluster = 2;
}
return(STATUS_DISK_FULL);
return STATUS_DISK_FULL;
}
NTSTATUS

File diff suppressed because it is too large Load diff

View file

@ -13,128 +13,138 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
static
NTSTATUS
VfatFlushFile(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb)
{
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt, Fcb, &Fcb->PathNameU);
DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt, Fcb, &Fcb->PathNameU);
CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
if (IoStatus.Status == STATUS_INVALID_PARAMETER)
{
/* FIXME: Caching was possible not initialized */
IoStatus.Status = STATUS_SUCCESS;
}
if (Fcb->Flags & FCB_IS_DIRTY)
{
Status = VfatUpdateEntry(Fcb);
if (!NT_SUCCESS(Status))
{
IoStatus.Status = Status;
}
}
return IoStatus.Status;
CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
if (IoStatus.Status == STATUS_INVALID_PARAMETER)
{
/* FIXME: Caching was possible not initialized */
IoStatus.Status = STATUS_SUCCESS;
}
if (Fcb->Flags & FCB_IS_DIRTY)
{
Status = VfatUpdateEntry(Fcb);
if (!NT_SUCCESS(Status))
{
IoStatus.Status = Status;
}
}
return IoStatus.Status;
}
NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
NTSTATUS
VfatFlushVolume(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB VolumeFcb)
{
PLIST_ENTRY ListEntry;
PVFATFCB Fcb;
NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
PLIST_ENTRY ListEntry;
PVFATFCB Fcb;
NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead)
{
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
ListEntry = ListEntry->Flink;
if (!vfatFCBIsDirectory(Fcb))
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
}
/* FIXME: Stop flushing if this is a removable media and the media was removed */
}
ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead)
{
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
ListEntry = ListEntry->Flink;
if (vfatFCBIsDirectory(Fcb))
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
}
/* FIXME: Stop flushing if this is a removable media and the media was removed */
}
ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead)
{
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
ListEntry = ListEntry->Flink;
if (!vfatFCBIsDirectory(Fcb))
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
}
/* FIXME: Stop flushing if this is a removable media and the media was removed */
}
Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead)
{
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
ListEntry = ListEntry->Flink;
if (vfatFCBIsDirectory(Fcb))
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
}
/* FIXME: Stop flushing if this is a removable media and the media was removed */
}
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite(&DeviceExt->FatResource);
Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
/* FIXME: Flush the buffers from storage device */
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite(&DeviceExt->FatResource);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
/* FIXME: Flush the buffers from storage device */
return ReturnStatus;
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
return ReturnStatus;
}
NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
NTSTATUS
VfatFlush(
PVFAT_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
PVFATFCB Fcb;
/*
* This request is not allowed on the main device object.
*/
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
NTSTATUS Status;
PVFATFCB Fcb;
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
ASSERT(Fcb);
/* This request is not allowed on the main device object. */
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
if (Fcb->Flags & FCB_IS_VOLUME)
{
ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
}
else
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
}
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
ASSERT(Fcb);
if (Fcb->Flags & FCB_IS_VOLUME)
{
ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
}
else
{
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
}
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return (Status);
return Status;
}
/* EOF */

View file

@ -33,303 +33,309 @@
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
static NTSTATUS
VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
PBOOLEAN RecognizedFS,
PFATINFO pFatInfo)
static
NTSTATUS
VfatHasFileSystem(
PDEVICE_OBJECT DeviceToMount,
PBOOLEAN RecognizedFS,
PFATINFO pFatInfo)
{
NTSTATUS Status;
PARTITION_INFORMATION PartitionInfo;
DISK_GEOMETRY DiskGeometry;
FATINFO FatInfo;
ULONG Size;
ULONG Sectors;
LARGE_INTEGER Offset;
struct _BootSector* Boot;
struct _BootSectorFatX* BootFatX;
BOOLEAN PartitionInfoIsValid = FALSE;
NTSTATUS Status;
PARTITION_INFORMATION PartitionInfo;
DISK_GEOMETRY DiskGeometry;
FATINFO FatInfo;
ULONG Size;
ULONG Sectors;
LARGE_INTEGER Offset;
struct _BootSector* Boot;
struct _BootSectorFatX* BootFatX;
BOOLEAN PartitionInfoIsValid = FALSE;
DPRINT("VfatHasFileSystem\n");
DPRINT("VfatHasFileSystem\n");
*RecognizedFS = FALSE;
*RecognizedFS = FALSE;
Size = sizeof(DISK_GEOMETRY);
Status = VfatBlockDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&Size,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status;
}
FatInfo.FixedMedia = DiskGeometry.MediaType == FixedMedia ? TRUE : FALSE;
if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia)
{
// We have found a hard disk
Size = sizeof(PARTITION_INFORMATION);
Status = VfatBlockDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&PartitionInfo,
&Size,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status;
}
PartitionInfoIsValid = TRUE;
DPRINT("Partition Information:\n");
DPRINT("StartingOffset %I64x\n", PartitionInfo.StartingOffset.QuadPart / 512);
DPRINT("PartitionLength %I64x\n", PartitionInfo.PartitionLength.QuadPart / 512);
DPRINT("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
DPRINT("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
DPRINT("PartitionType %u\n", PartitionInfo.PartitionType);
DPRINT("BootIndicator %u\n", PartitionInfo.BootIndicator);
DPRINT("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
DPRINT("RewritePartition %u\n", PartitionInfo.RewritePartition);
if (PartitionInfo.PartitionType)
{
if (PartitionInfo.PartitionType == PARTITION_FAT_12 ||
PartitionInfo.PartitionType == PARTITION_FAT_16 ||
PartitionInfo.PartitionType == PARTITION_HUGE ||
PartitionInfo.PartitionType == PARTITION_FAT32 ||
PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 ||
PartitionInfo.PartitionType == PARTITION_XINT13)
{
Size = sizeof(DISK_GEOMETRY);
Status = VfatBlockDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&Size,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status;
}
FatInfo.FixedMedia = DiskGeometry.MediaType == FixedMedia ? TRUE : FALSE;
if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia)
{
// We have found a hard disk
Size = sizeof(PARTITION_INFORMATION);
Status = VfatBlockDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&PartitionInfo,
&Size,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
return Status;
}
PartitionInfoIsValid = TRUE;
DPRINT("Partition Information:\n");
DPRINT("StartingOffset %I64x\n", PartitionInfo.StartingOffset.QuadPart / 512);
DPRINT("PartitionLength %I64x\n", PartitionInfo.PartitionLength.QuadPart / 512);
DPRINT("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
DPRINT("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
DPRINT("PartitionType %u\n", PartitionInfo.PartitionType);
DPRINT("BootIndicator %u\n", PartitionInfo.BootIndicator);
DPRINT("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
DPRINT("RewritePartition %u\n", PartitionInfo.RewritePartition);
if (PartitionInfo.PartitionType)
{
if (PartitionInfo.PartitionType == PARTITION_FAT_12 ||
PartitionInfo.PartitionType == PARTITION_FAT_16 ||
PartitionInfo.PartitionType == PARTITION_HUGE ||
PartitionInfo.PartitionType == PARTITION_FAT32 ||
PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 ||
PartitionInfo.PartitionType == PARTITION_XINT13)
{
*RecognizedFS = TRUE;
}
}
else if (DiskGeometry.MediaType == RemovableMedia &&
PartitionInfo.PartitionNumber > 0 &&
PartitionInfo.StartingOffset.QuadPart == 0 &&
PartitionInfo.PartitionLength.QuadPart > 0)
{
/* This is possible a removable media formated as super floppy */
*RecognizedFS = TRUE;
}
}
else if (DiskGeometry.MediaType == RemovableMedia &&
PartitionInfo.PartitionNumber > 0 &&
PartitionInfo.StartingOffset.QuadPart == 0 &&
PartitionInfo.PartitionLength.QuadPart > 0)
{
/* This is possible a removable media formated as super floppy */
*RecognizedFS = TRUE;
}
}
else if (DiskGeometry.MediaType == Unknown)
{
/*
* Floppy disk driver can return Unknown as media type if it
* doesn't know yet what floppy in the drive really is. This is
* perfectly correct to do under Windows.
*/
*RecognizedFS = TRUE;
DiskGeometry.BytesPerSector = 512;
}
else
{
*RecognizedFS = TRUE;
}
if (*RecognizedFS)
{
}
}
else if (DiskGeometry.MediaType == Unknown)
{
/*
* Floppy disk driver can return Unknown as media type if it
* doesn't know yet what floppy in the drive really is. This is
* perfectly correct to do under Windows.
*/
*RecognizedFS = TRUE;
DiskGeometry.BytesPerSector = 512;
}
else
{
*RecognizedFS = TRUE;
}
Boot = ExAllocatePoolWithTag(NonPagedPool, DiskGeometry.BytesPerSector, TAG_VFAT);
if (Boot == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
if (*RecognizedFS)
{
Boot = ExAllocatePoolWithTag(NonPagedPool, DiskGeometry.BytesPerSector, TAG_VFAT);
if (Boot == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Offset.QuadPart = 0;
Offset.QuadPart = 0;
/* Try to recognize FAT12/FAT16/FAT32 partitions */
Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot, FALSE);
if (NT_SUCCESS(Status))
{
if (Boot->Signatur1 != 0xaa55)
{
*RecognizedFS = FALSE;
}
if (*RecognizedFS &&
Boot->BytesPerSector != 512 &&
Boot->BytesPerSector != 1024 &&
Boot->BytesPerSector != 2048 &&
Boot->BytesPerSector != 4096)
{
DPRINT1("BytesPerSector %u\n", Boot->BytesPerSector);
*RecognizedFS = FALSE;
}
if (*RecognizedFS &&
Boot->FATCount != 1 &&
Boot->FATCount != 2)
{
DPRINT1("FATCount %u\n", Boot->FATCount);
*RecognizedFS = FALSE;
}
if (*RecognizedFS &&
Boot->Media != 0xf0 &&
Boot->Media != 0xf8 &&
Boot->Media != 0xf9 &&
Boot->Media != 0xfa &&
Boot->Media != 0xfb &&
Boot->Media != 0xfc &&
Boot->Media != 0xfd &&
Boot->Media != 0xfe &&
Boot->Media != 0xff)
{
DPRINT1("Media %02x\n", Boot->Media);
*RecognizedFS = FALSE;
}
if (*RecognizedFS &&
Boot->SectorsPerCluster != 1 &&
Boot->SectorsPerCluster != 2 &&
Boot->SectorsPerCluster != 4 &&
Boot->SectorsPerCluster != 8 &&
Boot->SectorsPerCluster != 16 &&
Boot->SectorsPerCluster != 32 &&
Boot->SectorsPerCluster != 64 &&
Boot->SectorsPerCluster != 128)
{
DPRINT1("SectorsPerCluster %02x\n", Boot->SectorsPerCluster);
*RecognizedFS = FALSE;
}
if (*RecognizedFS &&
Boot->BytesPerSector * Boot->SectorsPerCluster > 32 * 1024)
{
DPRINT1("ClusterSize %dx\n", Boot->BytesPerSector * Boot->SectorsPerCluster);
*RecognizedFS = FALSE;
}
if (*RecognizedFS)
{
FatInfo.VolumeID = Boot->VolumeID;
FatInfo.FATStart = Boot->ReservedSectors;
FatInfo.FATCount = Boot->FATCount;
FatInfo.FATSectors = Boot->FATSectors ? Boot->FATSectors : ((struct _BootSector32*) Boot)->FATSectors32;
FatInfo.BytesPerSector = Boot->BytesPerSector;
FatInfo.SectorsPerCluster = Boot->SectorsPerCluster;
FatInfo.BytesPerCluster = FatInfo.BytesPerSector * FatInfo.SectorsPerCluster;
FatInfo.rootDirectorySectors = ((Boot->RootEntries * 32) + Boot->BytesPerSector - 1) / Boot->BytesPerSector;
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
FatInfo.Sectors = Sectors = Boot->Sectors ? Boot->Sectors : Boot->SectorsHuge;
Sectors -= Boot->ReservedSectors + FatInfo.FATCount * FatInfo.FATSectors + FatInfo.rootDirectorySectors;
FatInfo.NumberOfClusters = Sectors / Boot->SectorsPerCluster;
if (FatInfo.NumberOfClusters < 4085)
/* Try to recognize FAT12/FAT16/FAT32 partitions */
Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot, FALSE);
if (NT_SUCCESS(Status))
{
if (Boot->Signatur1 != 0xaa55)
{
DPRINT("FAT12\n");
FatInfo.FatType = FAT12;
FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;
}
else if (FatInfo.NumberOfClusters >= 65525)
{
DPRINT("FAT32\n");
FatInfo.FatType = FAT32;
FatInfo.RootCluster = ((struct _BootSector32*) Boot)->RootCluster;
FatInfo.rootStart = FatInfo.dataStart + ((FatInfo.RootCluster - 2) * FatInfo.SectorsPerCluster);
FatInfo.VolumeID = ((struct _BootSector32*) Boot)->VolumeID;
}
else
{
DPRINT("FAT16\n");
FatInfo.FatType = FAT16;
FatInfo.RootCluster = FatInfo.rootStart / FatInfo.SectorsPerCluster;
}
if (PartitionInfoIsValid &&
FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
{
*RecognizedFS = FALSE;
*RecognizedFS = FALSE;
}
if (pFatInfo && *RecognizedFS)
if (*RecognizedFS &&
Boot->BytesPerSector != 512 &&
Boot->BytesPerSector != 1024 &&
Boot->BytesPerSector != 2048 &&
Boot->BytesPerSector != 4096)
{
*pFatInfo = FatInfo;
DPRINT1("BytesPerSector %u\n", Boot->BytesPerSector);
*RecognizedFS = FALSE;
}
}
}
ExFreePool(Boot);
}
if (*RecognizedFS &&
Boot->FATCount != 1 &&
Boot->FATCount != 2)
{
DPRINT1("FATCount %u\n", Boot->FATCount);
*RecognizedFS = FALSE;
}
if (!*RecognizedFS && PartitionInfoIsValid)
{
BootFatX = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _BootSectorFatX), TAG_VFAT);
if (BootFatX == NULL)
{
*RecognizedFS=FALSE;
return STATUS_INSUFFICIENT_RESOURCES;
}
if (*RecognizedFS &&
Boot->Media != 0xf0 &&
Boot->Media != 0xf8 &&
Boot->Media != 0xf9 &&
Boot->Media != 0xfa &&
Boot->Media != 0xfb &&
Boot->Media != 0xfc &&
Boot->Media != 0xfd &&
Boot->Media != 0xfe &&
Boot->Media != 0xff)
{
DPRINT1("Media %02x\n", Boot->Media);
*RecognizedFS = FALSE;
}
Offset.QuadPart = 0;
if (*RecognizedFS &&
Boot->SectorsPerCluster != 1 &&
Boot->SectorsPerCluster != 2 &&
Boot->SectorsPerCluster != 4 &&
Boot->SectorsPerCluster != 8 &&
Boot->SectorsPerCluster != 16 &&
Boot->SectorsPerCluster != 32 &&
Boot->SectorsPerCluster != 64 &&
Boot->SectorsPerCluster != 128)
{
DPRINT1("SectorsPerCluster %02x\n", Boot->SectorsPerCluster);
*RecognizedFS = FALSE;
}
/* Try to recognize FATX16/FATX32 partitions (Xbox) */
Status = VfatReadDisk(DeviceToMount, &Offset, sizeof(struct _BootSectorFatX), (PUCHAR) BootFatX, FALSE);
if (NT_SUCCESS(Status))
{
*RecognizedFS = TRUE;
if (BootFatX->SysType[0] != 'F' ||
BootFatX->SysType[1] != 'A' ||
BootFatX->SysType[2] != 'T' ||
BootFatX->SysType[3] != 'X')
{
DPRINT1("SysType %c%c%c%c\n", BootFatX->SysType[0], BootFatX->SysType[1], BootFatX->SysType[2], BootFatX->SysType[3]);
if (*RecognizedFS &&
Boot->BytesPerSector * Boot->SectorsPerCluster > 32 * 1024)
{
DPRINT1("ClusterSize %dx\n", Boot->BytesPerSector * Boot->SectorsPerCluster);
*RecognizedFS = FALSE;
}
if (*RecognizedFS)
{
FatInfo.VolumeID = Boot->VolumeID;
FatInfo.FATStart = Boot->ReservedSectors;
FatInfo.FATCount = Boot->FATCount;
FatInfo.FATSectors = Boot->FATSectors ? Boot->FATSectors : ((struct _BootSector32*) Boot)->FATSectors32;
FatInfo.BytesPerSector = Boot->BytesPerSector;
FatInfo.SectorsPerCluster = Boot->SectorsPerCluster;
FatInfo.BytesPerCluster = FatInfo.BytesPerSector * FatInfo.SectorsPerCluster;
FatInfo.rootDirectorySectors = ((Boot->RootEntries * 32) + Boot->BytesPerSector - 1) / Boot->BytesPerSector;
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
FatInfo.Sectors = Sectors = Boot->Sectors ? Boot->Sectors : Boot->SectorsHuge;
Sectors -= Boot->ReservedSectors + FatInfo.FATCount * FatInfo.FATSectors + FatInfo.rootDirectorySectors;
FatInfo.NumberOfClusters = Sectors / Boot->SectorsPerCluster;
if (FatInfo.NumberOfClusters < 4085)
{
DPRINT("FAT12\n");
FatInfo.FatType = FAT12;
FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;
}
else if (FatInfo.NumberOfClusters >= 65525)
{
DPRINT("FAT32\n");
FatInfo.FatType = FAT32;
FatInfo.RootCluster = ((struct _BootSector32*) Boot)->RootCluster;
FatInfo.rootStart = FatInfo.dataStart + ((FatInfo.RootCluster - 2) * FatInfo.SectorsPerCluster);
FatInfo.VolumeID = ((struct _BootSector32*) Boot)->VolumeID;
}
else
{
DPRINT("FAT16\n");
FatInfo.FatType = FAT16;
FatInfo.RootCluster = FatInfo.rootStart / FatInfo.SectorsPerCluster;
}
if (PartitionInfoIsValid &&
FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
{
*RecognizedFS = FALSE;
}
if (pFatInfo && *RecognizedFS)
{
*pFatInfo = FatInfo;
}
}
}
ExFreePool(Boot);
}
if (!*RecognizedFS && PartitionInfoIsValid)
{
BootFatX = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _BootSectorFatX), TAG_VFAT);
if (BootFatX == NULL)
{
*RecognizedFS=FALSE;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
if (*RecognizedFS &&
BootFatX->SectorsPerCluster != 1 &&
BootFatX->SectorsPerCluster != 2 &&
BootFatX->SectorsPerCluster != 4 &&
BootFatX->SectorsPerCluster != 8 &&
BootFatX->SectorsPerCluster != 16 &&
BootFatX->SectorsPerCluster != 32 &&
BootFatX->SectorsPerCluster != 64 &&
BootFatX->SectorsPerCluster != 128)
{
DPRINT1("SectorsPerCluster %lu\n", BootFatX->SectorsPerCluster);
*RecognizedFS=FALSE;
}
Offset.QuadPart = 0;
if (*RecognizedFS)
{
FatInfo.BytesPerSector = DiskGeometry.BytesPerSector;
FatInfo.SectorsPerCluster = BootFatX->SectorsPerCluster;
FatInfo.rootDirectorySectors = BootFatX->SectorsPerCluster;
FatInfo.BytesPerCluster = BootFatX->SectorsPerCluster * DiskGeometry.BytesPerSector;
FatInfo.Sectors = (ULONG)(PartitionInfo.PartitionLength.QuadPart / DiskGeometry.BytesPerSector);
if (FatInfo.Sectors / FatInfo.SectorsPerCluster < 65525)
/* Try to recognize FATX16/FATX32 partitions (Xbox) */
Status = VfatReadDisk(DeviceToMount, &Offset, sizeof(struct _BootSectorFatX), (PUCHAR) BootFatX, FALSE);
if (NT_SUCCESS(Status))
{
*RecognizedFS = TRUE;
if (BootFatX->SysType[0] != 'F' ||
BootFatX->SysType[1] != 'A' ||
BootFatX->SysType[2] != 'T' ||
BootFatX->SysType[3] != 'X')
{
DPRINT("FATX16\n");
FatInfo.FatType = FATX16;
DPRINT1("SysType %c%c%c%c\n", BootFatX->SysType[0], BootFatX->SysType[1], BootFatX->SysType[2], BootFatX->SysType[3]);
*RecognizedFS=FALSE;
}
else
{
DPRINT("FATX32\n");
FatInfo.FatType = FATX32;
}
FatInfo.VolumeID = BootFatX->VolumeID;
FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;
FatInfo.FATCount = BootFatX->FATCount;
FatInfo.FATSectors =
ROUND_UP(FatInfo.Sectors / FatInfo.SectorsPerCluster * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /
FatInfo.BytesPerSector;
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
FatInfo.NumberOfClusters = (FatInfo.Sectors - FatInfo.dataStart) / FatInfo.SectorsPerCluster;
if (pFatInfo && *RecognizedFS)
if (*RecognizedFS &&
BootFatX->SectorsPerCluster != 1 &&
BootFatX->SectorsPerCluster != 2 &&
BootFatX->SectorsPerCluster != 4 &&
BootFatX->SectorsPerCluster != 8 &&
BootFatX->SectorsPerCluster != 16 &&
BootFatX->SectorsPerCluster != 32 &&
BootFatX->SectorsPerCluster != 64 &&
BootFatX->SectorsPerCluster != 128)
{
*pFatInfo = FatInfo;
DPRINT1("SectorsPerCluster %lu\n", BootFatX->SectorsPerCluster);
*RecognizedFS=FALSE;
}
}
}
ExFreePool(BootFatX);
}
DPRINT("VfatHasFileSystem done\n");
return Status;
if (*RecognizedFS)
{
FatInfo.BytesPerSector = DiskGeometry.BytesPerSector;
FatInfo.SectorsPerCluster = BootFatX->SectorsPerCluster;
FatInfo.rootDirectorySectors = BootFatX->SectorsPerCluster;
FatInfo.BytesPerCluster = BootFatX->SectorsPerCluster * DiskGeometry.BytesPerSector;
FatInfo.Sectors = (ULONG)(PartitionInfo.PartitionLength.QuadPart / DiskGeometry.BytesPerSector);
if (FatInfo.Sectors / FatInfo.SectorsPerCluster < 65525)
{
DPRINT("FATX16\n");
FatInfo.FatType = FATX16;
}
else
{
DPRINT("FATX32\n");
FatInfo.FatType = FATX32;
}
FatInfo.VolumeID = BootFatX->VolumeID;
FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;
FatInfo.FATCount = BootFatX->FATCount;
FatInfo.FATSectors =
ROUND_UP(FatInfo.Sectors / FatInfo.SectorsPerCluster * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /
FatInfo.BytesPerSector;
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
FatInfo.RootCluster = (FatInfo.rootStart - 1) / FatInfo.SectorsPerCluster;
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
FatInfo.NumberOfClusters = (FatInfo.Sectors - FatInfo.dataStart) / FatInfo.SectorsPerCluster;
if (pFatInfo && *RecognizedFS)
{
*pFatInfo = FatInfo;
}
}
}
ExFreePool(BootFatX);
}
DPRINT("VfatHasFileSystem done\n");
return Status;
}
static NTSTATUS

View file

@ -34,9 +34,6 @@ PVFAT_GLOBAL_DATA VfatGlobalData;
/* FUNCTIONS ****************************************************************/
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initialize the driver
* ARGUMENTS:
@ -44,91 +41,90 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
NTSTATUS
NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat");
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat");
NTSTATUS Status;
UNREFERENCED_PARAMETER(RegistryPath);
UNREFERENCED_PARAMETER(RegistryPath);
Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (Status == STATUS_OBJECT_NAME_EXISTS ||
Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (Status == STATUS_OBJECT_NAME_EXISTS ||
Status == STATUS_OBJECT_NAME_COLLISION)
{
/* Try an other name, if 'Fat' is already in use. 'Fat' is also used by fastfat.sys on W2K */
RtlInitUnicodeString(&DeviceName, L"\\RosFat");
Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
}
{
/* Try an other name, if 'Fat' is already in use. 'Fat' is also used by fastfat.sys on W2K */
RtlInitUnicodeString(&DeviceName, L"\\RosFat");
Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
}
if (!NT_SUCCESS(Status))
{
return Status;
}
VfatGlobalData = DeviceObject->DeviceExtension;
RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
VfatGlobalData->DriverObject = DriverObject;
VfatGlobalData->DeviceObject = DeviceObject;
if (!NT_SUCCESS(Status))
{
return (Status);
}
DeviceObject->Flags |= DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_PNP] = VfatBuildRequest;
VfatGlobalData = DeviceObject->DeviceExtension;
RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
VfatGlobalData->DriverObject = DriverObject;
VfatGlobalData->DeviceObject = DeviceObject;
DriverObject->DriverUnload = NULL;
DeviceObject->Flags |= DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_PNP] = VfatBuildRequest;
/* Cache manager */
VfatGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = VfatAcquireForLazyWrite;
VfatGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = VfatReleaseFromLazyWrite;
VfatGlobalData->CacheMgrCallbacks.AcquireForReadAhead = VfatAcquireForReadAhead;
VfatGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = VfatReleaseFromReadAhead;
DriverObject->DriverUnload = NULL;
/* Fast I/O */
VfatInitFastIoRoutines(&VfatGlobalData->FastIoDispatch);
DriverObject->FastIoDispatch = &VfatGlobalData->FastIoDispatch;
/* Cache manager */
VfatGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = VfatAcquireForLazyWrite;
VfatGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = VfatReleaseFromLazyWrite;
VfatGlobalData->CacheMgrCallbacks.AcquireForReadAhead = VfatAcquireForReadAhead;
VfatGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = VfatReleaseFromReadAhead;
/* Private lists */
ExInitializeNPagedLookasideList(&VfatGlobalData->FcbLookasideList,
NULL, NULL, 0, sizeof(VFATFCB), TAG_FCB, 0);
ExInitializeNPagedLookasideList(&VfatGlobalData->CcbLookasideList,
NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0);
ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList,
NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0);
/* Fast I/O */
VfatInitFastIoRoutines(&VfatGlobalData->FastIoDispatch);
DriverObject->FastIoDispatch = &VfatGlobalData->FastIoDispatch;
/* Private lists */
ExInitializeNPagedLookasideList(&VfatGlobalData->FcbLookasideList,
NULL, NULL, 0, sizeof(VFATFCB), TAG_FCB, 0);
ExInitializeNPagedLookasideList(&VfatGlobalData->CcbLookasideList,
NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0);
ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList,
NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0);
ExInitializeResourceLite(&VfatGlobalData->VolumeListLock);
InitializeListHead(&VfatGlobalData->VolumeListHead);
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
ExInitializeResourceLite(&VfatGlobalData->VolumeListLock);
InitializeListHead(&VfatGlobalData->VolumeListHead);
IoRegisterFileSystem(DeviceObject);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -16,263 +16,286 @@
const char* MajorFunctionNames[] =
{
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
"IRP_MJ_MAXIMUM_FUNCTION"
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
"IRP_MJ_MAXIMUM_FUNCTION"
};
/* FUNCTIONS ****************************************************************/
static LONG QueueCount = 0;
static NTSTATUS VfatLockControl(
IN PVFAT_IRP_CONTEXT IrpContext
)
/* FUNCTIONS ****************************************************************/
static
NTSTATUS
VfatLockControl(
IN PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB Fcb;
NTSTATUS Status;
PVFATFCB Fcb;
NTSTATUS Status;
DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext);
DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext);
ASSERT(IrpContext);
ASSERT(IrpContext);
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto Fail;
}
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto Fail;
}
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
Status = STATUS_INVALID_PARAMETER;
goto Fail;
}
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
Status = STATUS_INVALID_PARAMETER;
goto Fail;
}
Status = FsRtlProcessFileLock(&Fcb->FileLock,
IrpContext->Irp,
NULL
);
Status = FsRtlProcessFileLock(&Fcb->FileLock,
IrpContext->Irp,
NULL);
VfatFreeIrpContext(IrpContext);
return Status;
VfatFreeIrpContext(IrpContext);
return Status;
Fail:;
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
return Status;
Fail:
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
return Status;
}
static NTSTATUS
VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
static
NTSTATUS
VfatDispatchRequest(
IN PVFAT_IRP_CONTEXT IrpContext)
{
DPRINT ("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
ASSERT(IrpContext);
ASSERT(IrpContext);
switch (IrpContext->MajorFunction)
{
case IRP_MJ_CLOSE:
return VfatClose (IrpContext);
case IRP_MJ_CREATE:
return VfatCreate (IrpContext);
case IRP_MJ_READ:
return VfatRead (IrpContext);
case IRP_MJ_WRITE:
return VfatWrite (IrpContext);
case IRP_MJ_FILE_SYSTEM_CONTROL:
return VfatFileSystemControl(IrpContext);
case IRP_MJ_QUERY_INFORMATION:
return VfatQueryInformation (IrpContext);
case IRP_MJ_SET_INFORMATION:
return VfatSetInformation (IrpContext);
case IRP_MJ_DIRECTORY_CONTROL:
return VfatDirectoryControl(IrpContext);
case IRP_MJ_QUERY_VOLUME_INFORMATION:
return VfatQueryVolumeInformation(IrpContext);
case IRP_MJ_SET_VOLUME_INFORMATION:
return VfatSetVolumeInformation(IrpContext);
case IRP_MJ_LOCK_CONTROL:
return VfatLockControl(IrpContext);
case IRP_MJ_CLEANUP:
return VfatCleanup(IrpContext);
case IRP_MJ_FLUSH_BUFFERS:
return VfatFlush(IrpContext);
case IRP_MJ_PNP:
return VfatPnp(IrpContext);
default:
DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_DRIVER_INTERNAL_ERROR;
}
switch (IrpContext->MajorFunction)
{
case IRP_MJ_CLOSE:
return VfatClose(IrpContext);
case IRP_MJ_CREATE:
return VfatCreate(IrpContext);
case IRP_MJ_READ:
return VfatRead (IrpContext);
case IRP_MJ_WRITE:
return VfatWrite (IrpContext);
case IRP_MJ_FILE_SYSTEM_CONTROL:
return VfatFileSystemControl(IrpContext);
case IRP_MJ_QUERY_INFORMATION:
return VfatQueryInformation (IrpContext);
case IRP_MJ_SET_INFORMATION:
return VfatSetInformation (IrpContext);
case IRP_MJ_DIRECTORY_CONTROL:
return VfatDirectoryControl(IrpContext);
case IRP_MJ_QUERY_VOLUME_INFORMATION:
return VfatQueryVolumeInformation(IrpContext);
case IRP_MJ_SET_VOLUME_INFORMATION:
return VfatSetVolumeInformation(IrpContext);
case IRP_MJ_LOCK_CONTROL:
return VfatLockControl(IrpContext);
case IRP_MJ_CLEANUP:
return VfatCleanup(IrpContext);
case IRP_MJ_FLUSH_BUFFERS:
return VfatFlush(IrpContext);
case IRP_MJ_PNP:
return VfatPnp(IrpContext);
default:
DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_DRIVER_INTERNAL_ERROR;
}
}
NTSTATUS NTAPI VfatBuildRequest (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
NTSTATUS
NTAPI
VfatBuildRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
PVFAT_IRP_CONTEXT IrpContext;
NTSTATUS Status;
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(Irp);
IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
if (IrpContext == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
}
else
{
FsRtlEnterFileSystem();
Status = VfatDispatchRequest (IrpContext);
FsRtlExitFileSystem();
}
return Status;
ASSERT(DeviceObject);
ASSERT(Irp);
IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
if (IrpContext == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
}
else
{
FsRtlEnterFileSystem();
Status = VfatDispatchRequest (IrpContext);
FsRtlExitFileSystem();
}
return Status;
}
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
VOID
VfatFreeIrpContext(
PVFAT_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext);
ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
ASSERT(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;
/*PIO_STACK_LOCATION Stack;*/
UCHAR MajorFunction;
DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
PVFAT_IRP_CONTEXT IrpContext;
/*PIO_STACK_LOCATION Stack;*/
UCHAR MajorFunction;
ASSERT(DeviceObject);
ASSERT(Irp);
DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
if (IrpContext)
{
RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT));
IrpContext->Irp = Irp;
IrpContext->DeviceObject = DeviceObject;
IrpContext->DeviceExt = DeviceObject->DeviceExtension;
IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IrpContext->Stack);
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
IrpContext->FileObject = IrpContext->Stack->FileObject;
IrpContext->Flags = 0;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
MajorFunction == IRP_MJ_DEVICE_CONTROL ||
MajorFunction == IRP_MJ_SHUTDOWN)
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
else if (MajorFunction != IRP_MJ_CLEANUP &&
MajorFunction != IRP_MJ_CLOSE &&
IoIsOperationSynchronous(Irp))
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 0;
}
return IrpContext;
ASSERT(DeviceObject);
ASSERT(Irp);
IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
if (IrpContext)
{
RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT));
IrpContext->Irp = Irp;
IrpContext->DeviceObject = DeviceObject;
IrpContext->DeviceExt = DeviceObject->DeviceExtension;
IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IrpContext->Stack);
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
IrpContext->FileObject = IrpContext->Stack->FileObject;
IrpContext->Flags = 0;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
MajorFunction == IRP_MJ_DEVICE_CONTROL ||
MajorFunction == IRP_MJ_SHUTDOWN)
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
else if (MajorFunction != IRP_MJ_CLEANUP &&
MajorFunction != IRP_MJ_CLOSE &&
IoIsOperationSynchronous(Irp))
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 0;
}
return IrpContext;
}
static WORKER_THREAD_ROUTINE VfatDoRequest;
static VOID NTAPI VfatDoRequest (PVOID IrpContext)
static
VOID
NTAPI
VfatDoRequest(
PVOID IrpContext)
{
InterlockedDecrement(&QueueCount);
DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
FsRtlEnterFileSystem();
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
FsRtlExitFileSystem();
InterlockedDecrement(&QueueCount);
DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
FsRtlEnterFileSystem();
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
FsRtlExitFileSystem();
}
NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
NTSTATUS
VfatQueueRequest(
PVFAT_IRP_CONTEXT IrpContext)
{
InterlockedIncrement(&QueueCount);
DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext, QueueCount);
InterlockedIncrement(&QueueCount);
DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
ASSERT(IrpContext != NULL);
ASSERT(IrpContext->Irp != NULL);
ASSERT(IrpContext != NULL);
ASSERT(IrpContext->Irp != NULL);
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoMarkIrpPending (IrpContext->Irp);
ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
return STATUS_PENDING;
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoMarkIrpPending(IrpContext->Irp);
ExInitializeWorkItem(&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
return STATUS_PENDING;
}
PVOID VfatGetUserBuffer(IN PIRP Irp)
PVOID
VfatGetUserBuffer(
IN PIRP Irp)
{
ASSERT(Irp);
ASSERT(Irp);
if (Irp->MdlAddress)
{
/* This call may be in the paging path, so use maximum priority */
/* FIXME: call with normal priority in the non-paging path */
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
}
else
{
return Irp->UserBuffer;
}
if (Irp->MdlAddress)
{
/* This call may be in the paging path, so use maximum priority */
/* FIXME: call with normal priority in the non-paging path */
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
}
else
{
return Irp->UserBuffer;
}
}
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);
if (Irp->MdlAddress)
{
return STATUS_SUCCESS;
}
if (Irp->MdlAddress)
{
return STATUS_SUCCESS;
}
IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
if (!Irp->MdlAddress)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
if (!Irp->MdlAddress)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}

View file

@ -14,31 +14,34 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
NTSTATUS
VfatPnp(
PVFAT_IRP_CONTEXT IrpContext)
{
PVCB Vcb = NULL;
NTSTATUS Status;
PVCB Vcb = NULL;
NTSTATUS Status;
/* PRECONDITION */
ASSERT(IrpContext);
/* PRECONDITION */
ASSERT(IrpContext);
switch (IrpContext->Stack->MinorFunction)
{
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
break;
default:
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
}
switch (IrpContext->Stack->MinorFunction)
{
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
break;
VfatFreeIrpContext(IrpContext);
default:
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
}
return Status;
VfatFreeIrpContext(IrpContext);
return Status;
}

File diff suppressed because it is too large Load diff

View file

@ -13,106 +13,115 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
VfatDiskShutDown(PVCB Vcb)
static
NTSTATUS
VfatDiskShutDown(
PVCB Vcb)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
NULL, 0, NULL, &Event, &IoStatus);
if (Irp)
{
Status = IoCallDriver(Vcb->StorageDevice, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
}
else
{
Status = IoStatus.Status;
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
NULL, 0, NULL, &Event, &IoStatus);
if (Irp)
{
Status = IoCallDriver(Vcb->StorageDevice, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
}
else
{
Status = IoStatus.Status;
}
return Status;
return Status;
}
NTSTATUS NTAPI
VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
VfatShutdown(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
NTSTATUS Status;
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
ULONG eocMark;
NTSTATUS Status;
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
ULONG eocMark;
DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
FsRtlEnterFileSystem();
FsRtlEnterFileSystem();
/* FIXME: block new mount requests */
/* FIXME: block new mount requests */
if (DeviceObject == VfatGlobalData->DeviceObject)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
ListEntry = VfatGlobalData->VolumeListHead.Flink;
while (ListEntry != &VfatGlobalData->VolumeListHead)
{
DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
ListEntry = ListEntry->Flink;
if (DeviceObject == VfatGlobalData->DeviceObject)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
ListEntry = VfatGlobalData->VolumeListHead.Flink;
while (ListEntry != &VfatGlobalData->VolumeListHead)
{
DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
ListEntry = ListEntry->Flink;
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
{
/* set clean shutdown bit */
Status = GetNextCluster(DeviceExt, 1, &eocMark);
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
{
/* set clean shutdown bit */
Status = GetNextCluster(DeviceExt, 1, &eocMark);
if (NT_SUCCESS(Status))
{
eocMark |= DeviceExt->CleanShutBitMask;
if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
}
}
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
if (NT_SUCCESS(Status))
{
eocMark |= DeviceExt->CleanShutBitMask;
if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
Status = VfatDiskShutDown(DeviceExt);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
}
}
}
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
if (NT_SUCCESS(Status))
{
Status = VfatDiskShutDown(DeviceExt);
else
{
DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
}
ExReleaseResourceLite(&DeviceExt->DirResource);
/* FIXME: Unmount the logical volume */
if (!NT_SUCCESS(Status))
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
}
else
{
DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
}
ExReleaseResourceLite(&DeviceExt->DirResource);
Irp->IoStatus.Status = Status;
}
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
/* FIXME: Unmount the logical volume */
/* FIXME: Free all global acquired resources */
if (!NT_SUCCESS(Status))
Irp->IoStatus.Status = Status;
}
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
Status = Irp->IoStatus.Status;
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Status = STATUS_INVALID_DEVICE_REQUEST;
}
/* FIXME: Free all global acquired resources */
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
Status = Irp->IoStatus.Status;
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Status = STATUS_INVALID_DEVICE_REQUEST;
}
FsRtlExitFileSystem();
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
FsRtlExitFileSystem();
return(Status);
return Status;
}
/* EOF */

View file

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

View file

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