[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 ***************************************************************/ /* FUNCTIONS ***************************************************************/
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion; static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
static NTSTATUS NTAPI
VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject, static
IN PIRP Irp, NTSTATUS
IN PVOID Context) NTAPI
VfatReadWritePartialCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{ {
PVFAT_IRP_CONTEXT IrpContext; PVFAT_IRP_CONTEXT IrpContext;
PMDL Mdl; 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; Irp->MdlAddress = Mdl->Next;
IoFreeMdl(Mdl); 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 NTSTATUS
VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject, VfatReadDisk(
IN PLARGE_INTEGER ReadOffset, IN PDEVICE_OBJECT pDeviceObject,
IN ULONG ReadLength, IN PLARGE_INTEGER ReadOffset,
IN OUT PUCHAR Buffer, IN ULONG ReadLength,
IN BOOLEAN Override) IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
{ {
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)
{ {
Stack = IoGetNextIrpStackLocation(Irp); Stack = IoGetNextIrpStackLocation(Irp);
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;
} }
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. */ /* 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 PLARGE_INTEGER ReadOffset, IN PVFAT_IRP_CONTEXT IrpContext,
IN ULONG ReadLength, IN PLARGE_INTEGER ReadOffset,
ULONG BufferOffset, IN ULONG ReadLength,
IN BOOLEAN Wait) ULONG BufferOffset,
IN BOOLEAN Wait)
{ {
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
NTSTATUS Status; NTSTATUS Status;
PVOID Buffer; PVOID Buffer;
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;
again: again:
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;
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_READ; StackPtr->MajorFunction = IRP_MJ_READ;
StackPtr->MinorFunction = 0; StackPtr->MinorFunction = 0;
StackPtr->Flags = 0; StackPtr->Flags = 0;
StackPtr->Control = 0; StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice; StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL; StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL; StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = ReadLength; StackPtr->Parameters.Read.Length = ReadLength;
StackPtr->Parameters.Read.ByteOffset = *ReadOffset; StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp)) if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
{ {
DPRINT("IoAllocateMdl failed\n"); DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp); IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength); IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
IoSetCompletionRoutine(Irp, IoSetCompletionRoutine(Irp,
VfatReadWritePartialCompletion, VfatReadWritePartialCompletion,
IrpContext, IrpContext,
TRUE, TRUE,
TRUE, TRUE,
TRUE); TRUE);
if (Wait) if (Wait)
{ {
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE); KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 1; IrpContext->RefCount = 1;
} }
else else
{ {
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)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
Status = IrpContext->Irp->IoStatus.Status; 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. */ /* 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;
} }
} }
DPRINT("%x\n", Status); DPRINT("%x\n", Status);
return Status; return Status;
} }
NTSTATUS NTSTATUS
VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, VfatWriteDiskPartial(
IN PLARGE_INTEGER WriteOffset, IN PVFAT_IRP_CONTEXT IrpContext,
IN ULONG WriteLength, IN PLARGE_INTEGER WriteOffset,
IN ULONG BufferOffset, IN ULONG WriteLength,
IN BOOLEAN Wait) IN ULONG BufferOffset,
IN BOOLEAN Wait)
{ {
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
NTSTATUS Status; NTSTATUS Status;
PVOID Buffer; PVOID Buffer;
DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n", DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait); IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
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;
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_WRITE; StackPtr->MajorFunction = IRP_MJ_WRITE;
StackPtr->MinorFunction = 0; StackPtr->MinorFunction = 0;
StackPtr->Flags = 0; StackPtr->Flags = 0;
StackPtr->Control = 0; StackPtr->Control = 0;
StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice; StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
StackPtr->FileObject = NULL; StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL; StackPtr->CompletionRoutine = NULL;
StackPtr->Parameters.Read.Length = WriteLength; StackPtr->Parameters.Read.Length = WriteLength;
StackPtr->Parameters.Read.ByteOffset = *WriteOffset; StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp)) if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
{ {
DPRINT("IoAllocateMdl failed\n"); DPRINT("IoAllocateMdl failed\n");
IoFreeIrp(Irp); IoFreeIrp(Irp);
return STATUS_UNSUCCESSFUL; 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);
} }
IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
DPRINT ("Calling IO Driver...\n"); IoSetCompletionRoutine(Irp,
Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp); VfatReadWritePartialCompletion,
if (Wait && Status == STATUS_PENDING) IrpContext,
TRUE,
TRUE,
TRUE);
if (Wait)
{ {
KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL); KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
Status = IrpContext->Irp->IoStatus.Status; 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. */ DPRINT1("Media change detected!\n");
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 write request\n"); DPRINT1("Volume verification successful; Reissuing write request\n");
goto again; goto again;
} }
} }
return Status; return Status;
} }
NTSTATUS NTSTATUS
VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, VfatBlockDeviceIoControl(
IN ULONG CtlCode, IN PDEVICE_OBJECT DeviceObject,
IN PVOID InputBuffer OPTIONAL, IN ULONG CtlCode,
IN ULONG InputBufferSize, IN PVOID InputBuffer OPTIONAL,
IN OUT PVOID OutputBuffer OPTIONAL, IN ULONG InputBufferSize,
IN OUT PULONG OutputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL,
IN BOOLEAN Override) IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override)
{ {
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
KEVENT Event; KEVENT Event;
PIRP Irp; PIRP Irp;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
NTSTATUS Status; NTSTATUS Status;
DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, " DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
"InputBuffer %p, InputBufferSize %x, OutputBuffer %p, " "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
"OutputBufferSize %p (%x)\n", DeviceObject, CtlCode, "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
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,
DeviceObject, DeviceObject,
InputBuffer, InputBuffer,
InputBufferSize, InputBufferSize,
OutputBuffer, OutputBuffer,
(OutputBufferSize) ? *OutputBufferSize : 0, (OutputBufferSize) ? *OutputBufferSize : 0,
FALSE, FALSE,
&Event, &Event,
&IoStatus); &IoStatus);
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT("IoBuildDeviceIoControlRequest failed\n"); DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
if (Override) if (Override)
{ {
Stack = IoGetNextIrpStackLocation(Irp); Stack = IoGetNextIrpStackLocation(Irp);
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;
} }
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. */ /* 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;
} }
} }
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 ****************************************************************/ /* 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? */
pCcb = (PVFATCCB) (FileObject->FsContext2); pCcb = (PVFATCCB) (FileObject->FsContext2);
pFcb = (PVFATFCB) (FileObject->FsContext); pFcb = (PVFATFCB) (FileObject->FsContext);
if (pFcb == NULL) 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->Flags & FCB_DELETE_PENDING) return STATUS_SUCCESS;
{
VfatDelEntry (DeviceExt, pFcb);
}
else
{
Status = STATUS_DELETE_PENDING;
}
} }
vfatReleaseFCB (DeviceExt, pFcb);
}
FileObject->FsContext2 = NULL; if (pFcb->Flags & FCB_IS_VOLUME)
FileObject->FsContext = NULL; {
FileObject->SectionObjectPointer = NULL; 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) vfatReleaseFCB (DeviceExt, pFcb);
{ }
vfatDestroyCCB(pCcb);
}
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 * 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"); DPRINT("Closing file system\n");
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
goto ByeBye; goto ByeBye;
} }
#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;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return (Status); return Status;
} }
/* EOF */ /* EOF */

View file

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

View file

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

View file

@ -19,166 +19,178 @@
/* 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;
ULONG ChunkSize; ULONG ChunkSize;
PVOID Context; PVOID Context;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
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;
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff) CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
CurrentCluster = 0xffffffff; if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CcUnpinData(Context); CurrentCluster = 0xffffffff;
*NextCluster = CurrentCluster;
return (STATUS_SUCCESS); 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 * 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;
ULONG ChunkSize; ULONG ChunkSize;
PVOID Context; PVOID Context;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
ChunkSize = CACHEPAGESIZE(DeviceExt); ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = CurrentCluster * 2; FATOffset = CurrentCluster * 2;
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize); Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress)) if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
CurrentCluster = 0xffffffff; if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CcUnpinData(Context); CurrentCluster = 0xffffffff;
*NextCluster = CurrentCluster; CcUnpinData(Context);
return (STATUS_SUCCESS); *NextCluster = CurrentCluster;
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;
PVOID BaseAddress; PVOID BaseAddress;
PVOID Context; PVOID Context;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
*NextCluster = 0;
*NextCluster = 0; Offset.QuadPart = 0;
if (!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
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)
{ {
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); else
if (Entry >= 0xff8 && Entry <= 0xfff) {
Entry = 0xffffffff; Entry = *CBlock >> 4;
// DPRINT("Returning %x\n",Entry); }
*NextCluster = Entry;
CcUnpinData(Context); // DPRINT("Entry %x\n",Entry);
// return Entry == 0xffffffff ? STATUS_END_OF_FILE : STATUS_SUCCESS; if (Entry >= 0xff8 && Entry <= 0xfff)
return STATUS_SUCCESS; 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 * 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;
ULONG i, j; ULONG i, j;
PVOID BaseAddress; PVOID BaseAddress;
ULONG ChunkSize; ULONG ChunkSize;
PVOID Context = 0; PVOID Context = 0;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
PUSHORT Block; PUSHORT Block;
PUSHORT BlockEnd; PUSHORT BlockEnd;
ChunkSize = CACHEPAGESIZE(DeviceExt); ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2); FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
*Cluster = 0; *Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster; StartCluster = DeviceExt->LastAvailableCluster;
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{
for (i = StartCluster; i < FatLength; )
{ {
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize); for (i = StartCluster; i < FatLength;)
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); Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
DeviceExt->LastAvailableCluster = *Cluster = i; if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
*Block = 0xffff; {
CcSetDirtyPinnedData(Context, NULL); DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
CcUnpinData(Context); return STATUS_UNSUCCESSFUL;
if (DeviceExt->AvailableClustersValid) }
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
return(STATUS_SUCCESS); 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++; FatLength = StartCluster;
i++; StartCluster = 2;
}
CcUnpinData(Context);
} }
FatLength = StartCluster;
StartCluster = 2; return STATUS_DISK_FULL;
}
return(STATUS_DISK_FULL);
} }
NTSTATUS NTSTATUS

File diff suppressed because it is too large Load diff

View file

@ -13,128 +13,138 @@
/* 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;
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); CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
if (IoStatus.Status == STATUS_INVALID_PARAMETER) if (IoStatus.Status == STATUS_INVALID_PARAMETER)
{ {
/* 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); {
if (!NT_SUCCESS(Status)) Status = VfatUpdateEntry(Fcb);
{ if (!NT_SUCCESS(Status))
IoStatus.Status = Status; {
} IoStatus.Status = Status;
} }
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;
NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; 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; ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead) while (ListEntry != &DeviceExt->FcbListHead)
{ {
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry); Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
if (!vfatFCBIsDirectory(Fcb)) if (!vfatFCBIsDirectory(Fcb))
{ {
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb); Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource); ExReleaseResourceLite (&Fcb->MainResource);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("VfatFlushFile failed, status = %x\n", Status); DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status; ReturnStatus = Status;
} }
} }
/* 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;
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); Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite(&DeviceExt->FatResource);
/* FIXME: Flush the buffers from storage device */ ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite(&DeviceExt->FatResource);
if (!NT_SUCCESS(Status)) /* FIXME: Flush the buffers from storage device */
{
DPRINT1("VfatFlushFile failed, status = %x\n", Status);
ReturnStatus = Status;
}
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; NTSTATUS Status;
PVFATFCB Fcb; PVFATFCB Fcb;
/*
* This request is not allowed on the main device object.
*/
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext; /* This request is not allowed on the main device object. */
ASSERT(Fcb); if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
if (Fcb->Flags & FCB_IS_VOLUME) Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
{ ASSERT(Fcb);
ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb); if (Fcb->Flags & FCB_IS_VOLUME)
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); {
} ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
else Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
{ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); }
Status = VfatFlushFile(IrpContext->DeviceExt, Fcb); else
ExReleaseResourceLite (&Fcb->MainResource); {
} ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
}
ByeBye: ByeBye:
IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return (Status); return Status;
} }
/* EOF */ /* EOF */

View file

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

View file

@ -34,9 +34,6 @@ PVFAT_GLOBAL_DATA VfatGlobalData;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/* /*
* FUNCTION: Called by the system to initialize the driver * FUNCTION: Called by the system to initialize the driver
* ARGUMENTS: * ARGUMENTS:
@ -44,91 +41,90 @@ 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");
NTSTATUS Status; NTSTATUS Status;
UNREFERENCED_PARAMETER(RegistryPath); UNREFERENCED_PARAMETER(RegistryPath);
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA), sizeof(VFAT_GLOBAL_DATA),
&DeviceName, &DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_DISK_FILE_SYSTEM,
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)
{ {
/* Try an other name, if 'Fat' is already in use. 'Fat' is also used by fastfat.sys on W2K */ /* Try an other name, if 'Fat' is already in use. 'Fat' is also used by fastfat.sys on W2K */
RtlInitUnicodeString(&DeviceName, L"\\RosFat"); RtlInitUnicodeString(&DeviceName, L"\\RosFat");
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(DriverObject,
sizeof(VFAT_GLOBAL_DATA), sizeof(VFAT_GLOBAL_DATA),
&DeviceName, &DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_DISK_FILE_SYSTEM,
0, 0,
FALSE, FALSE,
&DeviceObject); &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)) DeviceObject->Flags |= DO_DIRECT_IO;
{ DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
return (Status); 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; DriverObject->DriverUnload = NULL;
RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
VfatGlobalData->DriverObject = DriverObject;
VfatGlobalData->DeviceObject = DeviceObject;
DeviceObject->Flags |= DO_DIRECT_IO; /* Cache manager */
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest; VfatGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = VfatAcquireForLazyWrite;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest; VfatGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = VfatReleaseFromLazyWrite;
DriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest; VfatGlobalData->CacheMgrCallbacks.AcquireForReadAhead = VfatAcquireForReadAhead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest; VfatGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = VfatReleaseFromReadAhead;
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;
DriverObject->DriverUnload = NULL; /* Fast I/O */
VfatInitFastIoRoutines(&VfatGlobalData->FastIoDispatch);
DriverObject->FastIoDispatch = &VfatGlobalData->FastIoDispatch;
/* Cache manager */ /* Private lists */
VfatGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = VfatAcquireForLazyWrite; ExInitializeNPagedLookasideList(&VfatGlobalData->FcbLookasideList,
VfatGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = VfatReleaseFromLazyWrite; NULL, NULL, 0, sizeof(VFATFCB), TAG_FCB, 0);
VfatGlobalData->CacheMgrCallbacks.AcquireForReadAhead = VfatAcquireForReadAhead; ExInitializeNPagedLookasideList(&VfatGlobalData->CcbLookasideList,
VfatGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = VfatReleaseFromReadAhead; NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0);
ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList,
NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0);
/* Fast I/O */ ExInitializeResourceLite(&VfatGlobalData->VolumeListLock);
VfatInitFastIoRoutines(&VfatGlobalData->FastIoDispatch); InitializeListHead(&VfatGlobalData->VolumeListHead);
DriverObject->FastIoDispatch = &VfatGlobalData->FastIoDispatch; IoRegisterFileSystem(DeviceObject);
return STATUS_SUCCESS;
/* 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);
} }
/* EOF */ /* EOF */

View file

@ -16,263 +16,286 @@
const char* MajorFunctionNames[] = const char* MajorFunctionNames[] =
{ {
"IRP_MJ_CREATE", "IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE", "IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE", "IRP_MJ_CLOSE",
"IRP_MJ_READ", "IRP_MJ_READ",
"IRP_MJ_WRITE", "IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION", "IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION", "IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA", "IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA", "IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS", "IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION", "IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION", "IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL", "IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL", "IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL", "IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL", "IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN", "IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL", "IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP", "IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT", "IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY", "IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY", "IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER", "IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL", "IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE", "IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA", "IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA", "IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP", "IRP_MJ_PNP",
"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;
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) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
goto Fail; goto Fail;
} }
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{ {
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto Fail; goto Fail;
} }
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);
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:
return VfatWrite (IrpContext); return VfatWrite (IrpContext);
case IRP_MJ_FILE_SYSTEM_CONTROL: case IRP_MJ_FILE_SYSTEM_CONTROL:
return VfatFileSystemControl(IrpContext); return VfatFileSystemControl(IrpContext);
case IRP_MJ_QUERY_INFORMATION: case IRP_MJ_QUERY_INFORMATION:
return VfatQueryInformation (IrpContext); return VfatQueryInformation (IrpContext);
case IRP_MJ_SET_INFORMATION: case IRP_MJ_SET_INFORMATION:
return VfatSetInformation (IrpContext); return VfatSetInformation (IrpContext);
case IRP_MJ_DIRECTORY_CONTROL: case IRP_MJ_DIRECTORY_CONTROL:
return VfatDirectoryControl(IrpContext); return VfatDirectoryControl(IrpContext);
case IRP_MJ_QUERY_VOLUME_INFORMATION: case IRP_MJ_QUERY_VOLUME_INFORMATION:
return VfatQueryVolumeInformation(IrpContext); return VfatQueryVolumeInformation(IrpContext);
case IRP_MJ_SET_VOLUME_INFORMATION: case IRP_MJ_SET_VOLUME_INFORMATION:
return VfatSetVolumeInformation(IrpContext); return VfatSetVolumeInformation(IrpContext);
case IRP_MJ_LOCK_CONTROL: case IRP_MJ_LOCK_CONTROL:
return VfatLockControl(IrpContext); return VfatLockControl(IrpContext);
case IRP_MJ_CLEANUP: case IRP_MJ_CLEANUP:
return VfatCleanup(IrpContext); return VfatCleanup(IrpContext);
case IRP_MJ_FLUSH_BUFFERS: case IRP_MJ_FLUSH_BUFFERS:
return VfatFlush(IrpContext); return VfatFlush(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);
return STATUS_DRIVER_INTERNAL_ERROR; return STATUS_DRIVER_INTERNAL_ERROR;
} }
} }
NTSTATUS NTAPI VfatBuildRequest ( NTSTATUS
IN PDEVICE_OBJECT DeviceObject, NTAPI
IN PIRP Irp) VfatBuildRequest(
IN PDEVICE_OBJECT DeviceObject,
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);
if (IrpContext == NULL) IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
{ if (IrpContext == NULL)
Status = STATUS_INSUFFICIENT_RESOURCES; {
Irp->IoStatus.Status = Status; Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest (Irp, IO_NO_INCREMENT); Irp->IoStatus.Status = Status;
} IoCompleteRequest (Irp, IO_NO_INCREMENT);
else }
{ else
FsRtlEnterFileSystem(); {
Status = VfatDispatchRequest (IrpContext); FsRtlEnterFileSystem();
FsRtlExitFileSystem(); Status = VfatDispatchRequest (IrpContext);
} FsRtlExitFileSystem();
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);
ASSERT(DeviceObject); DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
ASSERT(Irp);
IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList); ASSERT(DeviceObject);
if (IrpContext) ASSERT(Irp);
{
RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT)); IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
IrpContext->Irp = Irp; if (IrpContext)
IrpContext->DeviceObject = DeviceObject; {
IrpContext->DeviceExt = DeviceObject->DeviceExtension; RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT));
IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp); IrpContext->Irp = Irp;
ASSERT(IrpContext->Stack); IrpContext->DeviceObject = DeviceObject;
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction; IrpContext->DeviceExt = DeviceObject->DeviceExtension;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction; IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
IrpContext->FileObject = IrpContext->Stack->FileObject; ASSERT(IrpContext->Stack);
IrpContext->Flags = 0; MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL || IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
MajorFunction == IRP_MJ_DEVICE_CONTROL || IrpContext->FileObject = IrpContext->Stack->FileObject;
MajorFunction == IRP_MJ_SHUTDOWN) IrpContext->Flags = 0;
{ if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
IrpContext->Flags |= IRPCONTEXT_CANWAIT; MajorFunction == IRP_MJ_DEVICE_CONTROL ||
} MajorFunction == IRP_MJ_SHUTDOWN)
else if (MajorFunction != IRP_MJ_CLEANUP && {
MajorFunction != IRP_MJ_CLOSE && IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoIsOperationSynchronous(Irp)) }
{ else if (MajorFunction != IRP_MJ_CLEANUP &&
IrpContext->Flags |= IRPCONTEXT_CANWAIT; MajorFunction != IRP_MJ_CLOSE &&
} IoIsOperationSynchronous(Irp))
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE); {
IrpContext->RefCount = 0; IrpContext->Flags |= IRPCONTEXT_CANWAIT;
} }
return IrpContext; KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 0;
}
return IrpContext;
} }
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",
FsRtlEnterFileSystem(); IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext); FsRtlEnterFileSystem();
FsRtlExitFileSystem(); VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
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);
if (Irp->MdlAddress) if (Irp->MdlAddress)
{ {
/* This call may be in the paging path, so use maximum priority */ /* This call may be in the paging path, so use maximum priority */
/* FIXME: call with normal priority in the non-paging path */ /* FIXME: call with normal priority in the non-paging path */
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority); return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
} }
else else
{ {
return Irp->UserBuffer; 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) if (Irp->MdlAddress)
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp); IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
if (!Irp->MdlAddress) if (!Irp->MdlAddress)
{ {
return STATUS_INSUFFICIENT_RESOURCES; 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 ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext) NTSTATUS
VfatPnp(
PVFAT_IRP_CONTEXT IrpContext)
{ {
PVCB Vcb = NULL; PVCB Vcb = NULL;
NTSTATUS Status; NTSTATUS Status;
/* PRECONDITION */ /* PRECONDITION */
ASSERT(IrpContext); ASSERT(IrpContext);
switch (IrpContext->Stack->MinorFunction) switch (IrpContext->Stack->MinorFunction)
{ {
case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL: case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_REMOVE_DEVICE: case IRP_MN_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
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:
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
}
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 ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS static
VfatDiskShutDown(PVCB Vcb) NTSTATUS
VfatDiskShutDown(
PVCB Vcb)
{ {
PIRP Irp; PIRP Irp;
KEVENT Event; KEVENT Event;
NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
NULL, 0, NULL, &Event, &IoStatus); NULL, 0, NULL, &Event, &IoStatus);
if (Irp) if (Irp)
{ {
Status = IoCallDriver(Vcb->StorageDevice, Irp); Status = IoCallDriver(Vcb->StorageDevice, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status; Status = IoStatus.Status;
} }
} }
else else
{ {
Status = IoStatus.Status; 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; NTSTATUS Status;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt; PDEVICE_EXTENSION DeviceExt;
ULONG eocMark; 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) if (DeviceObject == VfatGlobalData->DeviceObject)
{ {
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
ListEntry = VfatGlobalData->VolumeListHead.Flink; ListEntry = VfatGlobalData->VolumeListHead.Flink;
while (ListEntry != &VfatGlobalData->VolumeListHead) while (ListEntry != &VfatGlobalData->VolumeListHead)
{ {
DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry); DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
{ {
/* set clean shutdown bit */ /* set clean shutdown bit */
Status = GetNextCluster(DeviceExt, 1, &eocMark); 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)) if (NT_SUCCESS(Status))
{ {
eocMark |= DeviceExt->CleanShutBitMask; Status = VfatDiskShutDown(DeviceExt);
if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark))) if (!NT_SUCCESS(Status))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; {
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
}
} }
} else
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); {
if (NT_SUCCESS(Status)) DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
{ }
Status = VfatDiskShutDown(DeviceExt); ExReleaseResourceLite(&DeviceExt->DirResource);
/* FIXME: Unmount the logical volume */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status); Irp->IoStatus.Status = Status;
} }
else ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
{
DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
}
ExReleaseResourceLite(&DeviceExt->DirResource);
/* FIXME: Unmount the logical volume */ /* FIXME: Free all global acquired resources */
if (!NT_SUCCESS(Status)) Status = Irp->IoStatus.Status;
Irp->IoStatus.Status = Status; }
} else
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); {
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; FsRtlExitFileSystem();
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Information = 0; return Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
FsRtlExitFileSystem();
return(Status);
} }
/* EOF */ /* EOF */

View file

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

View file

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