mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: FspIopPostWorkRequest()
This commit is contained in:
parent
18025573a3
commit
0fb9de1ebd
@ -148,6 +148,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\fileobj.c" />
|
<ClCompile Include="..\..\src\sys\fileobj.c" />
|
||||||
<ClCompile Include="..\..\src\sys\flush.c" />
|
<ClCompile Include="..\..\src\sys\flush.c" />
|
||||||
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
<ClCompile Include="..\..\src\sys\fsctl.c" />
|
||||||
|
<ClCompile Include="..\..\src\sys\idevctl.c" />
|
||||||
<ClCompile Include="..\..\src\sys\iop.c" />
|
<ClCompile Include="..\..\src\sys\iop.c" />
|
||||||
<ClCompile Include="..\..\src\sys\ioq.c" />
|
<ClCompile Include="..\..\src\sys\ioq.c" />
|
||||||
<ClCompile Include="..\..\src\sys\lockctl.c" />
|
<ClCompile Include="..\..\src\sys\lockctl.c" />
|
||||||
|
@ -86,6 +86,9 @@
|
|||||||
<ClCompile Include="..\..\src\sys\fileobj.c">
|
<ClCompile Include="..\..\src\sys\fileobj.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\sys\idevctl.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -572,16 +572,16 @@ static VOID FspFsvolCreateClose(
|
|||||||
/*
|
/*
|
||||||
* This routine handles the case where we must close an open file,
|
* This routine handles the case where we must close an open file,
|
||||||
* because of a failure during Create completion. We simply create
|
* because of a failure during Create completion. We simply create
|
||||||
* a CreateClose request and we post it to our Ioq.
|
* a CreateClose request and we post it as a work item.
|
||||||
*
|
*
|
||||||
* Ideally there would be no failure modes for this routine. Reality is
|
* Ideally there would be no failure modes for this routine. Reality is
|
||||||
* different.
|
* different.
|
||||||
*
|
*
|
||||||
* The more serious (but perhaps non-existent in practice) failure is a
|
* The more serious (but perhaps non-existent in practice) failure is a
|
||||||
* memory allocation failure for the CreateClose request. In this case we
|
* memory allocation failure. In this case we will leak the user-mode
|
||||||
* will leak the user-mode file system handle!
|
* file system handle!
|
||||||
*
|
*
|
||||||
* This routine may also fail if the Ioq was stopped, which means that
|
* This routine may also fail if we cannot post a work item, which means that
|
||||||
* the virtual volume device and the file system volume device are being
|
* the virtual volume device and the file system volume device are being
|
||||||
* deleted. Because it is assumed that only the user-mode file system would
|
* deleted. Because it is assumed that only the user-mode file system would
|
||||||
* initiate a device deletion, this case is more benign (presumably the file
|
* initiate a device deletion, this case is more benign (presumably the file
|
||||||
@ -600,30 +600,29 @@ static VOID FspFsvolCreateClose(
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* create the user-mode file system request */
|
/* create the user-mode file system request */
|
||||||
Result = FspIopCreateRequest(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
|
Result = FspIopCreateRequest(0, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
goto leak_exit;
|
||||||
DEBUGLOG("FileObject=%p[%p:\"%wZ\"], UserContext=%llx, UserContext2=%p: "
|
|
||||||
"FspIopCreateRequest failed: the user-mode file system handle will be leaked!",
|
|
||||||
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName,
|
|
||||||
FsContext->UserContext, FileObject->FsContext2);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* populate the Create request */
|
/* populate the CreateClose request */
|
||||||
Request->Kind = FspFsctlTransactCreateCloseKind;
|
Request->Kind = FspFsctlTransactCreateCloseKind;
|
||||||
Request->Req.Close.UserContext = FsContext->UserContext;
|
Request->Req.Close.UserContext = FsContext->UserContext;
|
||||||
Request->Req.Close.UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
Request->Req.Close.UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
||||||
|
|
||||||
/*
|
/* post as a work request */
|
||||||
* Post the IRP to our Ioq.
|
if (!FspIopPostWorkRequest(DeviceObject, Request))
|
||||||
*/
|
/* no need to delete the request here as FspIopPostWorkRequest() will do so in all cases */
|
||||||
if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp))
|
goto leak_exit;
|
||||||
{
|
|
||||||
/* this can only happen if the Ioq was stopped */
|
|
||||||
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
leak_exit:;
|
||||||
|
#if DBG
|
||||||
|
DEBUGLOG("FileObject=%p[%p:\"%wZ\"], UserContext=%llx, UserContext2=%p: "
|
||||||
|
"error: the user-mode file system handle will be leaked!",
|
||||||
|
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName,
|
||||||
|
FsContext->UserContext, FileObject->FsContext2);
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
FspFileContextDelete(FsContext);
|
FspFileContextDelete(FsContext);
|
||||||
|
@ -167,6 +167,7 @@ const char *IoctlCodeSym(ULONG ControlCode)
|
|||||||
SYM(FSP_FSCTL_CREATE)
|
SYM(FSP_FSCTL_CREATE)
|
||||||
SYM(FSP_FSCTL_DELETE)
|
SYM(FSP_FSCTL_DELETE)
|
||||||
SYM(FSP_FSCTL_TRANSACT)
|
SYM(FSP_FSCTL_TRANSACT)
|
||||||
|
SYM(FSP_FSCTL_WORK)
|
||||||
default:
|
default:
|
||||||
return "IOCTL:Unknown";
|
return "IOCTL:Unknown";
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ NTSTATUS DriverEntry(
|
|||||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FspDirectoryControl;
|
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FspDirectoryControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFileSystemControl;
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFileSystemControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FspDeviceControl;
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FspDeviceControl;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = FspInternalDeviceControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FspShutdown;
|
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FspShutdown;
|
||||||
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FspLockControl;
|
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FspLockControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FspCleanup;
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FspCleanup;
|
||||||
@ -80,6 +81,7 @@ NTSTATUS DriverEntry(
|
|||||||
FspIopCompleteFunction[IRP_MJ_DIRECTORY_CONTROL] = FspDirectoryControlComplete;
|
FspIopCompleteFunction[IRP_MJ_DIRECTORY_CONTROL] = FspDirectoryControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFileSystemControlComplete;
|
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFileSystemControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspDeviceControlComplete;
|
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspDeviceControlComplete;
|
||||||
|
FspIopCompleteFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = FspFsvolInternalDeviceControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspShutdownComplete;
|
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspShutdownComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspLockControlComplete;
|
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspLockControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspCleanupComplete;
|
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspCleanupComplete;
|
||||||
|
@ -187,6 +187,7 @@ _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) FSP_DRIVER_DISPATCH FspDeviceControl;
|
|||||||
_Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) FSP_DRIVER_DISPATCH FspDirectoryControl;
|
_Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) FSP_DRIVER_DISPATCH FspDirectoryControl;
|
||||||
_Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL) FSP_DRIVER_DISPATCH FspFileSystemControl;
|
_Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL) FSP_DRIVER_DISPATCH FspFileSystemControl;
|
||||||
_Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) FSP_DRIVER_DISPATCH FspFlushBuffers;
|
_Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) FSP_DRIVER_DISPATCH FspFlushBuffers;
|
||||||
|
_Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL) FSP_DRIVER_DISPATCH FspInternalDeviceControl;
|
||||||
_Dispatch_type_(IRP_MJ_LOCK_CONTROL) FSP_DRIVER_DISPATCH FspLockControl;
|
_Dispatch_type_(IRP_MJ_LOCK_CONTROL) FSP_DRIVER_DISPATCH FspLockControl;
|
||||||
_Dispatch_type_(IRP_MJ_QUERY_EA) FSP_DRIVER_DISPATCH FspQueryEa;
|
_Dispatch_type_(IRP_MJ_QUERY_EA) FSP_DRIVER_DISPATCH FspQueryEa;
|
||||||
_Dispatch_type_(IRP_MJ_QUERY_INFORMATION) FSP_DRIVER_DISPATCH FspQueryInformation;
|
_Dispatch_type_(IRP_MJ_QUERY_INFORMATION) FSP_DRIVER_DISPATCH FspQueryInformation;
|
||||||
@ -217,6 +218,7 @@ FSP_IOCMPL_DISPATCH FspDeviceControlComplete;
|
|||||||
FSP_IOCMPL_DISPATCH FspDirectoryControlComplete;
|
FSP_IOCMPL_DISPATCH FspDirectoryControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFileSystemControlComplete;
|
FSP_IOCMPL_DISPATCH FspFileSystemControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFlushBuffersComplete;
|
FSP_IOCMPL_DISPATCH FspFlushBuffersComplete;
|
||||||
|
FSP_IOCMPL_DISPATCH FspFsvolInternalDeviceControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspLockControlComplete;
|
FSP_IOCMPL_DISPATCH FspLockControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspQueryEaComplete;
|
FSP_IOCMPL_DISPATCH FspQueryEaComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspQueryInformationComplete;
|
FSP_IOCMPL_DISPATCH FspQueryInformationComplete;
|
||||||
@ -259,8 +261,11 @@ BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
|||||||
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
||||||
|
|
||||||
/* I/O processing */
|
/* I/O processing */
|
||||||
|
#define FSP_FSCTL_WORK \
|
||||||
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'W', METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||||
NTSTATUS FspIopCreateRequest(
|
NTSTATUS FspIopCreateRequest(
|
||||||
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest);
|
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest);
|
||||||
|
NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease);
|
VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease);
|
||||||
static inline
|
static inline
|
||||||
VOID FspIopCompleteIrp(PIRP Irp, NTSTATUS Result)
|
VOID FspIopCompleteIrp(PIRP Irp, NTSTATUS Result)
|
||||||
|
98
src/sys/idevctl.c
Normal file
98
src/sys/idevctl.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* @file sys/idevctl.c
|
||||||
|
*
|
||||||
|
* @copyright 2015 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolInternalDeviceControl(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
FSP_IOCMPL_DISPATCH FspFsvolInternalDeviceControlComplete;
|
||||||
|
FSP_DRIVER_DISPATCH FspInternalDeviceControl;
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolInternalDeviceControl)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolInternalDeviceControlComplete)
|
||||||
|
#pragma alloc_text(PAGE, FspInternalDeviceControl)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolInternalDeviceControl(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
||||||
|
{
|
||||||
|
case FSP_FSCTL_WORK:
|
||||||
|
{
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
|
|
||||||
|
if (!FspDeviceRetain(FsvrtDeviceObject))
|
||||||
|
return STATUS_CANCELLED;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||||
|
FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
|
||||||
|
ASSERT(0 == Request->Hint);
|
||||||
|
|
||||||
|
/* associate the passed Request with our Irp; acquire ownership of the Request */
|
||||||
|
Request->Hint = (UINT_PTR)Irp;
|
||||||
|
Irp->Tail.Overlay.DriverContext[0] = Request;
|
||||||
|
|
||||||
|
if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp))
|
||||||
|
{
|
||||||
|
/* this can only happen if the Ioq was stopped */
|
||||||
|
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
||||||
|
|
||||||
|
/* disocciate the Request from our Irp; release ownership back to caller */
|
||||||
|
Request->Hint = 0;
|
||||||
|
Irp->Tail.Overlay.DriverContext[0] = 0;
|
||||||
|
|
||||||
|
Result = STATUS_CANCELLED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_PENDING;
|
||||||
|
|
||||||
|
exit:;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
FspDeviceRelease(FsvrtDeviceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFsvolInternalDeviceControlComplete(
|
||||||
|
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
|
{
|
||||||
|
FSP_ENTER_IOC(PAGED_CODE());
|
||||||
|
|
||||||
|
FSP_LEAVE_IOC("%s", IoctlCodeSym(IrpSp->Parameters.DeviceIoControl.IoControlCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspInternalDeviceControl(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
FSP_ENTER_MJ(PAGED_CODE());
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_INTERNAL_DEVICE_CONTROL == IrpSp->MajorFunction);
|
||||||
|
|
||||||
|
switch (FspDeviceExtension(DeviceObject)->Kind)
|
||||||
|
{
|
||||||
|
case FspFsvolDeviceExtensionKind:
|
||||||
|
FSP_RETURN(Result = FspFsvolInternalDeviceControl(DeviceObject, Irp, IrpSp));
|
||||||
|
default:
|
||||||
|
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_LEAVE_MJ("%s", IoctlCodeSym(IrpSp->Parameters.DeviceIoControl.IoControlCode));
|
||||||
|
}
|
@ -8,11 +8,14 @@
|
|||||||
|
|
||||||
NTSTATUS FspIopCreateRequest(
|
NTSTATUS FspIopCreateRequest(
|
||||||
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest);
|
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest);
|
||||||
|
NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
|
static IO_COMPLETION_ROUTINE FspIopPostWorkRequestCompletion;
|
||||||
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspIopCreateRequest)
|
#pragma alloc_text(PAGE, FspIopCreateRequest)
|
||||||
|
#pragma alloc_text(PAGE, FspIopPostWorkRequest)
|
||||||
#pragma alloc_text(PAGE, FspIopDispatchPrepare)
|
#pragma alloc_text(PAGE, FspIopDispatchPrepare)
|
||||||
#pragma alloc_text(PAGE, FspIopDispatchComplete)
|
#pragma alloc_text(PAGE, FspIopDispatchComplete)
|
||||||
#endif
|
#endif
|
||||||
@ -54,12 +57,67 @@ NTSTATUS FspIopCreateRequest(
|
|||||||
Request->FileName.Size = 0;
|
Request->FileName.Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 != Irp)
|
||||||
Irp->Tail.Overlay.DriverContext[0] = Request;
|
Irp->Tail.Overlay.DriverContext[0] = Request;
|
||||||
*PRequest = Request;
|
*PRequest = Request;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Request, FSP_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(0 == Request->Hint);
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
PIRP Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (0 == Irp)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||||
|
IrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.IoControlCode = FSP_FSCTL_WORK;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.InputBufferLength = Request->Size;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = Request;
|
||||||
|
|
||||||
|
ASSERT(METHOD_NEITHER == (IrpSp->Parameters.DeviceIoControl.IoControlCode & 3));
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp, FspIopPostWorkRequestCompletion, 0, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
Result = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (STATUS_PENDING == Result)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we did not receive STATUS_PENDING, we still own the Request and must delete it!
|
||||||
|
*/
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FspIopDeleteRequest(Request);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspIopPostWorkRequestCompletion(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
|
||||||
|
{
|
||||||
|
// !PAGED_CODE();
|
||||||
|
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
|
VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
@ -69,7 +127,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
|
|||||||
|
|
||||||
if (0 != Irp->Tail.Overlay.DriverContext[0])
|
if (0 != Irp->Tail.Overlay.DriverContext[0])
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(Irp->Tail.Overlay.DriverContext[0], FSP_TAG);
|
FspIopDeleteRequest(Irp->Tail.Overlay.DriverContext[0]);
|
||||||
Irp->Tail.Overlay.DriverContext[0] = 0;
|
Irp->Tail.Overlay.DriverContext[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user