mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: FspIopCompleteIrpEx: handle SRV2 query directory completion
This commit is contained in:
parent
096e5b7eb1
commit
9bcd8dcb8e
@ -17,6 +17,15 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* FspIopCompleteIrpEx does some special processing for IRP_MJ_DIRECTORY_CONTROL /
|
||||||
|
* IRP_MN_QUERY_DIRECTORY IRP's that come from SRV2. If the processing of this IRP
|
||||||
|
* changes substantially (in particular if we eliminate our use of
|
||||||
|
* Irp->AssociatedIrp.SystemBuffer) we should also revisit FspIopCompleteIrpEx.
|
||||||
|
*/
|
||||||
|
|
||||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||||
UINT64 DirectoryOffset, PUINT64 PDirectoryOffset,
|
UINT64 DirectoryOffset, PUINT64 PDirectoryOffset,
|
||||||
|
@ -225,7 +225,49 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the device object out of the IRP before completion */
|
/* get the device object out of the IRP before completion */
|
||||||
PDEVICE_OBJECT DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HACK:
|
||||||
|
*
|
||||||
|
* Turns out that SRV2 sends an undocumented flavor of IRP_MJ_DIRECTORY_CONTROL /
|
||||||
|
* IRP_MN_QUERY_DIRECTORY. These IRP's have a non-NULL Irp->MdlAddress. They expect
|
||||||
|
* the FSD to fill the buffer pointed by Irp->MdlAddress and they cannot handle
|
||||||
|
* completed IRP's with a non-NULL Irp->AssociatedIrp.SystemBuffer. So we have to
|
||||||
|
* provide special support for these IRPs.
|
||||||
|
*
|
||||||
|
* While this processing is IRP_MJ_DIRECTORY_CONTROL specific, we do this here for
|
||||||
|
* these reasons:
|
||||||
|
*
|
||||||
|
* 1. There may be other IRP's that have similar completion requirements under SRV2.
|
||||||
|
* If/when such IRP's are discovered the completion processing can be centralized
|
||||||
|
* here.
|
||||||
|
* 2. IRP_MJ_DIRECTORY_CONTROL has a few different ways that it can complete IRP's.
|
||||||
|
* It is far simpler to do this processing here, even if not academically correct.
|
||||||
|
*
|
||||||
|
* This will have to be revisited if IRP_MJ_DIRECTORY_CONTROL processing changes
|
||||||
|
* substantially (e.g. to no longer use Irp->AssociatedIrp.SystemBuffer).
|
||||||
|
*/
|
||||||
|
if (IRP_MJ_DIRECTORY_CONTROL == IrpSp->MajorFunction &&
|
||||||
|
IRP_MN_QUERY_DIRECTORY == IrpSp->MinorFunction &&
|
||||||
|
0 != Irp->MdlAddress && /* SRV2 queries have this set */
|
||||||
|
0 != Irp->AssociatedIrp.SystemBuffer &&
|
||||||
|
FlagOn(Irp->Flags, IRP_BUFFERED_IO))
|
||||||
|
{
|
||||||
|
if (STATUS_SUCCESS == Result)
|
||||||
|
{
|
||||||
|
PVOID Address = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||||
|
if (0 != Address)
|
||||||
|
RtlCopyMemory(Address, Irp->AssociatedIrp.SystemBuffer, Irp->IoStatus.Information);
|
||||||
|
else
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFreeExternal(Irp->AssociatedIrp.SystemBuffer);
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = 0;
|
||||||
|
ClearFlag(Irp->Flags, IRP_INPUT_OPERATION | IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
if (STATUS_SUCCESS != Result && STATUS_REPARSE != Result && STATUS_BUFFER_OVERFLOW != Result)
|
if (STATUS_SUCCESS != Result && STATUS_REPARSE != Result && STATUS_BUFFER_OVERFLOW != Result)
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user