[FASTFAT]

Bring in initiated work on IRPs in NTFS (and complete it).
This simplifies the way IRPs and their context are handled in the driver.
Only VfatDispatchRequest() is responsible of completing IRPs (if required), freeing the IRP context (if required), and queueing the IRP for later completion (if required).
This allows removing duplicated code, hacks, and so on. It might help reducing IRP leaks, or memory leaks.

By default, VfatDispatchRequest() will complete the IRP and delete the IRP context.
In case you don't want it to complete the IRP (because you passed it down, for instance), remove the IRPCONTEXT_COMPLETE flag. See for instance: VfatDeviceControl().
In case you want to queue the IRP (you previously called: VfatQueueRequest()), call the newly introduced VfatMarkIrpContextForQueue() function that will prepare it.

svn path=/trunk/; revision=67743
This commit is contained in:
Pierre Schweitzer 2015-05-15 16:03:29 +00:00
parent 45e50d10a0
commit 3b6a55716f
12 changed files with 148 additions and 150 deletions

View file

@ -152,14 +152,14 @@ VfatCleanup(
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
Status = STATUS_SUCCESS; IrpContext->Irp->IoStatus.Information = 0;
goto ByeBye; return STATUS_SUCCESS;
} }
if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
Status = VfatCleanupFile(IrpContext); Status = VfatCleanupFile(IrpContext);
@ -168,15 +168,10 @@ VfatCleanup(
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -83,8 +83,8 @@ VfatClose(
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
DPRINT("Closing file system\n"); DPRINT("Closing file system\n");
Status = STATUS_SUCCESS; IrpContext->Irp->IoStatus.Information = 0;
goto ByeBye; return STATUS_SUCCESS;
} }
#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
@ -94,17 +94,13 @@ VfatClose(
if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE)) if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE))
#endif #endif
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject); Status = VfatCloseFile(IrpContext->DeviceExt, IrpContext->FileObject);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -941,15 +941,14 @@ VfatCreate(
/* DeviceObject represents FileSystem instead of logical volume */ /* DeviceObject represents FileSystem instead of logical volume */
DPRINT ("FsdCreate called with file system\n"); DPRINT ("FsdCreate called with file system\n");
IrpContext->Irp->IoStatus.Information = FILE_OPENED; IrpContext->Irp->IoStatus.Information = FILE_OPENED;
IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS; IrpContext->PriorityBoost = IO_DISK_INCREMENT;
IoCompleteRequest(IrpContext->Irp, IO_DISK_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT)) if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
{ {
return(VfatQueueRequest(IrpContext)); return VfatMarkIrpContextForQueue(IrpContext);
} }
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
@ -957,10 +956,9 @@ VfatCreate(
Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp); Status = VfatCreateFile(IrpContext->DeviceObject, IrpContext->Irp);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
IrpContext->Irp->IoStatus.Status = Status; if (NT_SUCCESS(Status))
IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost = IO_DISK_INCREMENT;
(CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -508,7 +508,7 @@ DoQuery(
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
ExReleaseResourceLite(&pFcb->MainResource); ExReleaseResourceLite(&pFcb->MainResource);
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
while ((Status == STATUS_SUCCESS) && (BufferLength > 0)) while ((Status == STATUS_SUCCESS) && (BufferLength > 0))
@ -592,29 +592,28 @@ DoQuery(
return Status; return Status;
} }
NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT * IrpContext) NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT IrpContext)
{ {
PVCB pVcb; PVCB pVcb;
PVFATFCB pFcb; PVFATFCB pFcb;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
Stack = (*IrpContext)->Stack; Stack = IrpContext->Stack;
pVcb = (*IrpContext)->DeviceExt; pVcb = IrpContext->DeviceExt;
pFcb = (PVFATFCB) (*IrpContext)->FileObject->FsContext; pFcb = (PVFATFCB) IrpContext->FileObject->FsContext;
FsRtlNotifyFullChangeDirectory(pVcb->NotifySync, FsRtlNotifyFullChangeDirectory(pVcb->NotifySync,
&(pVcb->NotifyList), &(pVcb->NotifyList),
(*IrpContext)->FileObject->FsContext2, IrpContext->FileObject->FsContext2,
(PSTRING)&(pFcb->PathNameU), (PSTRING)&(pFcb->PathNameU),
BooleanFlagOn(Stack->Flags, SL_WATCH_TREE), BooleanFlagOn(Stack->Flags, SL_WATCH_TREE),
FALSE, FALSE,
Stack->Parameters.NotifyDirectory.CompletionFilter, Stack->Parameters.NotifyDirectory.CompletionFilter,
(*IrpContext)->Irp, IrpContext->Irp,
NULL, NULL,
NULL); NULL);
/* We don't need the IRP context as we won't handle IRP completion */ /* We won't handle IRP completion */
VfatFreeIrpContext(*IrpContext); IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
*IrpContext = NULL;
return STATUS_PENDING; return STATUS_PENDING;
} }
@ -637,7 +636,7 @@ VfatDirectoryControl(
break; break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY: case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
Status = VfatNotifyChangeDirectory(&IrpContext); Status = VfatNotifyChangeDirectory(IrpContext);
break; break;
default: default:
@ -648,19 +647,9 @@ VfatDirectoryControl(
break; break;
} }
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING && IrpContext->Flags & IRPCONTEXT_COMPLETE)
{ {
/* Only queue if there's IRP context */ return VfatMarkIrpContextForQueue(IrpContext);
if (IrpContext)
{
Status = VfatQueueRequest(IrpContext);
}
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
} }
return Status; return Status;

View file

@ -1381,7 +1381,7 @@ VfatQueryInformation(
if (!ExAcquireResourceSharedLite(&FCB->MainResource, if (!ExAcquireResourceSharedLite(&FCB->MainResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
} }
@ -1459,14 +1459,11 @@ VfatQueryInformation(
ExReleaseResourceLite(&FCB->MainResource); ExReleaseResourceLite(&FCB->MainResource);
} }
IrpContext->Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
IrpContext->Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
IrpContext->Stack->Parameters.QueryFile.Length - BufferLength; IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
else else
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }
@ -1510,10 +1507,7 @@ VfatSetInformation(
(PLARGE_INTEGER)SystemBuffer)) (PLARGE_INTEGER)SystemBuffer))
{ {
DPRINT("Couldn't set file size!\n"); DPRINT("Couldn't set file size!\n");
IrpContext->Irp->IoStatus.Status = STATUS_USER_MAPPED_FILE;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_USER_MAPPED_FILE; return STATUS_USER_MAPPED_FILE;
} }
DPRINT("Can set file size\n"); DPRINT("Can set file size\n");
@ -1524,7 +1518,7 @@ VfatSetInformation(
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
} }
@ -1537,7 +1531,8 @@ VfatSetInformation(
{ {
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
} }
return VfatQueueRequest(IrpContext);
return VfatMarkIrpContextForQueue(IrpContext);
} }
} }
@ -1592,11 +1587,7 @@ VfatSetInformation(
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
} }
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -150,8 +150,8 @@ VfatFlush(
/* This request is not allowed on the main device object. */ /* This request is not allowed on the main device object. */
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
Status = STATUS_INVALID_DEVICE_REQUEST; IrpContext->Irp->IoStatus.Information = 0;
goto ByeBye; return STATUS_INVALID_DEVICE_REQUEST;
} }
Fcb = (PVFATFCB)IrpContext->FileObject->FsContext; Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
@ -170,12 +170,7 @@ VfatFlush(
ExReleaseResourceLite (&Fcb->MainResource); ExReleaseResourceLite (&Fcb->MainResource);
} }
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -1066,9 +1066,5 @@ VfatFileSystemControl(
break; break;
} }
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -51,6 +51,10 @@ const char* MajorFunctionNames[] =
static LONG QueueCount = 0; static LONG QueueCount = 0;
static VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT);
static PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT, PIRP);
static NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT);
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static static
@ -69,28 +73,21 @@ VfatLockControl(
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{ {
Status = STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
goto Fail;
} }
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{ {
Status = STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
goto Fail;
} }
IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
Status = FsRtlProcessFileLock(&Fcb->FileLock, Status = FsRtlProcessFileLock(&Fcb->FileLock,
IrpContext->Irp, IrpContext->Irp,
NULL); NULL);
VfatFreeIrpContext(IrpContext); VfatFreeIrpContext(IrpContext);
return Status; 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 static
@ -100,6 +97,8 @@ VfatDeviceControl(
{ {
IoSkipCurrentIrpStackLocation(IrpContext->Irp); IoSkipCurrentIrpStackLocation(IrpContext->Irp);
IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp); return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
} }
@ -108,6 +107,8 @@ NTSTATUS
VfatDispatchRequest( VfatDispatchRequest(
IN PVFAT_IRP_CONTEXT IrpContext) IN PVFAT_IRP_CONTEXT IrpContext)
{ {
NTSTATUS Status;
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]);
@ -116,42 +117,94 @@ VfatDispatchRequest(
switch (IrpContext->MajorFunction) switch (IrpContext->MajorFunction)
{ {
case IRP_MJ_CLOSE: case IRP_MJ_CLOSE:
return VfatClose(IrpContext); Status = VfatClose(IrpContext);
break;
case IRP_MJ_CREATE: case IRP_MJ_CREATE:
return VfatCreate(IrpContext); Status = VfatCreate(IrpContext);
break;
case IRP_MJ_READ: case IRP_MJ_READ:
return VfatRead (IrpContext); Status = VfatRead(IrpContext);
break;
case IRP_MJ_WRITE: case IRP_MJ_WRITE:
return VfatWrite (IrpContext); Status = VfatWrite (IrpContext);
break;
case IRP_MJ_FILE_SYSTEM_CONTROL: case IRP_MJ_FILE_SYSTEM_CONTROL:
return VfatFileSystemControl(IrpContext); Status = VfatFileSystemControl(IrpContext);
break;
case IRP_MJ_QUERY_INFORMATION: case IRP_MJ_QUERY_INFORMATION:
return VfatQueryInformation (IrpContext); Status = VfatQueryInformation (IrpContext);
break;
case IRP_MJ_SET_INFORMATION: case IRP_MJ_SET_INFORMATION:
return VfatSetInformation (IrpContext); Status = VfatSetInformation (IrpContext);
break;
case IRP_MJ_DIRECTORY_CONTROL: case IRP_MJ_DIRECTORY_CONTROL:
return VfatDirectoryControl(IrpContext); Status = VfatDirectoryControl(IrpContext);
break;
case IRP_MJ_QUERY_VOLUME_INFORMATION: case IRP_MJ_QUERY_VOLUME_INFORMATION:
return VfatQueryVolumeInformation(IrpContext); Status = VfatQueryVolumeInformation(IrpContext);
break;
case IRP_MJ_SET_VOLUME_INFORMATION: case IRP_MJ_SET_VOLUME_INFORMATION:
return VfatSetVolumeInformation(IrpContext); Status = VfatSetVolumeInformation(IrpContext);
break;
case IRP_MJ_LOCK_CONTROL: case IRP_MJ_LOCK_CONTROL:
return VfatLockControl(IrpContext); Status = VfatLockControl(IrpContext);
break;
case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_DEVICE_CONTROL:
return VfatDeviceControl(IrpContext); Status = VfatDeviceControl(IrpContext);
break;
case IRP_MJ_CLEANUP: case IRP_MJ_CLEANUP:
return VfatCleanup(IrpContext); Status = VfatCleanup(IrpContext);
break;
case IRP_MJ_FLUSH_BUFFERS: case IRP_MJ_FLUSH_BUFFERS:
return VfatFlush(IrpContext); Status = VfatFlush(IrpContext);
break;
case IRP_MJ_PNP: case IRP_MJ_PNP:
return VfatPnp(IrpContext); Status = VfatPnp(IrpContext);
break;
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; Status = STATUS_DRIVER_INTERNAL_ERROR;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_DRIVER_INTERNAL_ERROR;
} }
ASSERT((!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
((IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
(!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && (IrpContext->Flags & IRPCONTEXT_QUEUE)));
if (IrpContext->Flags & IRPCONTEXT_COMPLETE)
{
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
}
if (IrpContext->Flags & IRPCONTEXT_QUEUE)
{
/* Reset our status flags before queueing the IRP */
IrpContext->Flags |= IRPCONTEXT_COMPLETE;
IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
Status = VfatQueueRequest(IrpContext);
}
else
{
/* Unless the IRP was queued, always free the IRP context */
VfatFreeIrpContext(IrpContext);
}
return Status;
} }
NTSTATUS NTSTATUS
@ -184,6 +237,7 @@ VfatBuildRequest(
return Status; return Status;
} }
static
VOID VOID
VfatFreeIrpContext( VfatFreeIrpContext(
PVFAT_IRP_CONTEXT IrpContext) PVFAT_IRP_CONTEXT IrpContext)
@ -192,6 +246,7 @@ VfatFreeIrpContext(
ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext); ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
} }
static
PVFAT_IRP_CONTEXT PVFAT_IRP_CONTEXT
VfatAllocateIrpContext( VfatAllocateIrpContext(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
@ -218,7 +273,7 @@ VfatAllocateIrpContext(
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction; MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction; IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
IrpContext->FileObject = IrpContext->Stack->FileObject; IrpContext->FileObject = IrpContext->Stack->FileObject;
IrpContext->Flags = 0; IrpContext->Flags = IRPCONTEXT_COMPLETE;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL || if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
MajorFunction == IRP_MJ_DEVICE_CONTROL || MajorFunction == IRP_MJ_DEVICE_CONTROL ||
MajorFunction == IRP_MJ_SHUTDOWN) MajorFunction == IRP_MJ_SHUTDOWN)
@ -233,6 +288,7 @@ VfatAllocateIrpContext(
} }
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE); KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 0; IrpContext->RefCount = 0;
IrpContext->PriorityBoost = IO_NO_INCREMENT;
} }
return IrpContext; return IrpContext;
} }
@ -253,6 +309,7 @@ VfatDoRequest(
FsRtlExitFileSystem(); FsRtlExitFileSystem();
} }
static
NTSTATUS NTSTATUS
VfatQueueRequest( VfatQueueRequest(
PVFAT_IRP_CONTEXT IrpContext) PVFAT_IRP_CONTEXT IrpContext)

View file

@ -33,17 +33,14 @@ VfatPnp(
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;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
break; break;
default: default:
IoSkipCurrentIrpStackLocation(IrpContext->Irp); IoSkipCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension; Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp); Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
} }
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -572,9 +572,9 @@ VfatRead(
PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo; PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector; IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
IoSkipCurrentIrpStackLocation(IrpContext->Irp); IoSkipCurrentIrpStackLocation(IrpContext->Irp);
IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
DPRINT("Read from page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart); DPRINT("Read from page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Read.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp); Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }
@ -740,13 +740,7 @@ ByeBye:
Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoWriteAccess); Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoWriteAccess);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = VfatQueueRequest(IrpContext); Status = VfatMarkIrpContextForQueue(IrpContext);
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
} }
} }
else else
@ -760,9 +754,8 @@ ByeBye:
ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information; ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
} }
IoCompleteRequest(IrpContext->Irp, if (NT_SUCCESS(Status))
(CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)); IrpContext->PriorityBoost = IO_DISK_INCREMENT;
VfatFreeIrpContext(IrpContext);
} }
DPRINT("%x\n", Status); DPRINT("%x\n", Status);
return Status; return Status;
@ -805,9 +798,9 @@ VfatWrite(
PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo; PFATINFO FatInfo = &IrpContext->DeviceExt->FatInfo;
IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector; IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart += FatInfo->dataStart * FatInfo->BytesPerSector;
IoSkipCurrentIrpStackLocation(IrpContext->Irp); IoSkipCurrentIrpStackLocation(IrpContext->Irp);
IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
DPRINT("Write to page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart); DPRINT("Write to page file, disk offset %I64x\n", IrpContext->Stack->Parameters.Write.ByteOffset.QuadPart);
Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp); Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }
@ -1074,13 +1067,7 @@ ByeBye:
Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoReadAccess); Status = VfatLockUserBuffer(IrpContext->Irp, Length, IoReadAccess);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = VfatQueueRequest(IrpContext); Status = VfatMarkIrpContextForQueue(IrpContext);
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
} }
} }
else else
@ -1093,9 +1080,8 @@ ByeBye:
ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information; ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
} }
IoCompleteRequest(IrpContext->Irp, if (NT_SUCCESS(Status))
(CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)); IrpContext->PriorityBoost = IO_DISK_INCREMENT;
VfatFreeIrpContext(IrpContext);
} }
DPRINT("%x\n", Status); DPRINT("%x\n", Status);
return Status; return Status;

View file

@ -446,8 +446,10 @@ typedef struct __DOSDATE
} }
DOSDATE, *PDOSDATE; DOSDATE, *PDOSDATE;
#define IRPCONTEXT_CANWAIT 0x0001 #define IRPCONTEXT_CANWAIT 0x0001
#define IRPCONTEXT_PENDINGRETURNED 0x0002 #define IRPCONTEXT_COMPLETE 0x0002
#define IRPCONTEXT_QUEUE 0x0004
#define IRPCONTEXT_PENDINGRETURNED 0x0008
typedef struct typedef struct
{ {
@ -462,6 +464,7 @@ typedef struct
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
ULONG RefCount; ULONG RefCount;
KEVENT Event; KEVENT Event;
CCHAR PriorityBoost;
} VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT; } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
typedef struct _VFAT_DIRENTRY_CONTEXT typedef struct _VFAT_DIRENTRY_CONTEXT
@ -481,6 +484,18 @@ typedef struct _VFAT_MOVE_CONTEXT
USHORT CreationTime; USHORT CreationTime;
} VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT; } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
FORCEINLINE
NTSTATUS
VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
{
PULONG Flags = &IrpContext->Flags;
*Flags &= ~IRPCONTEXT_COMPLETE;
*Flags |= IRPCONTEXT_QUEUE;
return STATUS_PENDING;
}
/* blockdev.c */ /* blockdev.c */
NTSTATUS NTSTATUS
@ -902,19 +917,6 @@ DriverEntry(
/* misc.c */ /* misc.c */
NTSTATUS
VfatQueueRequest(
PVFAT_IRP_CONTEXT IrpContext);
PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(
PDEVICE_OBJECT DeviceObject,
PIRP Irp);
VOID
VfatFreeIrpContext(
PVFAT_IRP_CONTEXT IrpContext);
DRIVER_DISPATCH DRIVER_DISPATCH
VfatBuildRequest; VfatBuildRequest;

View file

@ -363,7 +363,8 @@ VfatQueryVolumeInformation(
if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest(IrpContext); DPRINT1("DirResource failed!\n");
return VfatMarkIrpContextForQueue(IrpContext);
} }
/* INITIALIZATION */ /* INITIALIZATION */
@ -405,14 +406,12 @@ VfatQueryVolumeInformation(
} }
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
IrpContext->Irp->IoStatus.Status = RC;
if (NT_SUCCESS(RC)) if (NT_SUCCESS(RC))
IrpContext->Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength; IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
else else
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return RC; return RC;
} }
@ -439,7 +438,7 @@ VfatSetVolumeInformation(
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{ {
return VfatQueueRequest(IrpContext); return VfatMarkIrpContextForQueue(IrpContext);
} }
FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass; FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass;
@ -462,10 +461,7 @@ VfatSetVolumeInformation(
} }
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }