mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-24 01:13:04 -05:00
sys: IRP_MJ_FLUSH_BUFFERS: flush volume implementation
This commit is contained in:
parent
71c1469b46
commit
83c59a6f37
@ -40,6 +40,9 @@ VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
|||||||
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareContext;
|
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareContext;
|
||||||
static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateContext;
|
static RTL_AVL_ALLOCATE_ROUTINE FspFsvolDeviceAllocateContext;
|
||||||
static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeContext;
|
static RTL_AVL_FREE_ROUTINE FspFsvolDeviceFreeContext;
|
||||||
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PVOID **PContexts, PULONG PContextCount);
|
||||||
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount);
|
||||||
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
BOOLEAN SubpathOnly, PVOID *PRestartKey);
|
BOOLEAN SubpathOnly, PVOID *PRestartKey);
|
||||||
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
||||||
@ -79,6 +82,8 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContext)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContext)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContext)
|
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContext)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContext)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContext)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextByNameList)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextByNameList)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceInsertContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceInsertContextByName)
|
||||||
@ -653,6 +658,45 @@ static VOID NTAPI FspFsvolDeviceFreeContext(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PVOID **PContexts, PULONG PContextCount)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT_DATA *Data;
|
||||||
|
PVOID *Contexts;
|
||||||
|
ULONG ContextCount, Index;
|
||||||
|
|
||||||
|
*PContexts = 0;
|
||||||
|
*PContextCount = 0;
|
||||||
|
|
||||||
|
ContextCount = RtlNumberGenericTableElementsAvl(&FsvolDeviceExtension->ContextByNameTable);
|
||||||
|
Contexts = FspAlloc(sizeof(PVOID) * ContextCount);
|
||||||
|
if (0 == Contexts)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
Data = RtlEnumerateGenericTableAvl(&FsvolDeviceExtension->ContextByNameTable, TRUE);
|
||||||
|
while (Index < ContextCount && 0 != Data)
|
||||||
|
{
|
||||||
|
Contexts[Index++] = Data->Context;
|
||||||
|
Data = RtlEnumerateGenericTableAvl(&FsvolDeviceExtension->ContextByNameTable, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
*PContexts = Contexts;
|
||||||
|
*PContextCount = Index;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FspFree(Contexts);
|
||||||
|
}
|
||||||
|
|
||||||
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
BOOLEAN SubpathOnly, PVOID *PRestartKey)
|
BOOLEAN SubpathOnly, PVOID *PRestartKey)
|
||||||
{
|
{
|
||||||
@ -668,7 +712,7 @@ PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE
|
|||||||
|
|
||||||
Result = RtlEnumerateGenericTableLikeADirectory(&FsvolDeviceExtension->ContextByNameTable,
|
Result = RtlEnumerateGenericTableLikeADirectory(&FsvolDeviceExtension->ContextByNameTable,
|
||||||
0, 0, SubpathOnly, PRestartKey, &DeleteCount, &FileName);
|
0, 0, SubpathOnly, PRestartKey, &DeleteCount, &FileName);
|
||||||
|
|
||||||
if (0 != Result &&
|
if (0 != Result &&
|
||||||
RtlPrefixUnicodeString(FileName, Result->FileName, CaseInsensitive) &&
|
RtlPrefixUnicodeString(FileName, Result->FileName, CaseInsensitive) &&
|
||||||
FileName->Length < Result->FileName->Length &&
|
FileName->Length < Result->FileName->Length &&
|
||||||
|
@ -764,6 +764,9 @@ PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier
|
|||||||
FSP_DEVICE_CONTEXT_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
FSP_DEVICE_CONTEXT_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
||||||
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
||||||
PBOOLEAN PDeleted);
|
PBOOLEAN PDeleted);
|
||||||
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
PVOID **PContexts, PULONG PContextCount);
|
||||||
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount);
|
||||||
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
BOOLEAN SubpathOnly, PVOID *PRestartKey);
|
BOOLEAN SubpathOnly, PVOID *PRestartKey);
|
||||||
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
||||||
@ -881,6 +884,9 @@ typedef struct
|
|||||||
UINT64 DirInfo;
|
UINT64 DirInfo;
|
||||||
ULONG DirInfoCacheHint;
|
ULONG DirInfoCacheHint;
|
||||||
} FSP_FILE_DESC;
|
} FSP_FILE_DESC;
|
||||||
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
||||||
|
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
||||||
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
||||||
|
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode);
|
||||||
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode);
|
||||||
@ -51,6 +54,8 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
|||||||
PUNICODE_STRING FileName, BOOLEAN Reset);
|
PUNICODE_STRING FileName, BOOLEAN Reset);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeCopyList)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeDeleteList)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCreate)
|
#pragma alloc_text(PAGE, FspFileNodeCreate)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeDelete)
|
#pragma alloc_text(PAGE, FspFileNodeDelete)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeAcquireSharedF)
|
#pragma alloc_text(PAGE, FspFileNodeAcquireSharedF)
|
||||||
@ -102,6 +107,38 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
|||||||
if (IrpValid) \
|
if (IrpValid) \
|
||||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3))
|
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3))
|
||||||
|
|
||||||
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(DeviceObject);
|
||||||
|
Result = FspFsvolDeviceCopyContextByNameList(DeviceObject, PFileNodes, PFileNodeCount);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
for (Index = 0; *PFileNodeCount > Index; Index++)
|
||||||
|
FspFileNodeReference((*PFileNodes)[Index]);
|
||||||
|
}
|
||||||
|
FspFsvolDeviceUnlockContextTable(DeviceObject);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
for (Index = 0; FileNodeCount > Index; Index++)
|
||||||
|
FspFileNodeDereference(FileNodes[Index]);
|
||||||
|
|
||||||
|
FspFsvolDeviceDeleteContextByNameList(FileNodes, FileNodeCount);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ULONG ExtraSize, FSP_FILE_NODE **PFileNode)
|
ULONG ExtraSize, FSP_FILE_NODE **PFileNode)
|
||||||
{
|
{
|
||||||
|
121
src/sys/flush.c
121
src/sys/flush.c
@ -7,7 +7,7 @@
|
|||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFlushBuffers(
|
static NTSTATUS FspFsvolFlushBuffers(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete;
|
||||||
static FSP_IOP_REQUEST_FINI FspFsvolFlushBuffersRequestFini;
|
static FSP_IOP_REQUEST_FINI FspFsvolFlushBuffersRequestFini;
|
||||||
FSP_DRIVER_DISPATCH FspFlushBuffers;
|
FSP_DRIVER_DISPATCH FspFlushBuffers;
|
||||||
@ -23,60 +23,98 @@ enum
|
|||||||
{
|
{
|
||||||
/* FlushBuffers */
|
/* FlushBuffers */
|
||||||
RequestFileNode = 0,
|
RequestFileNode = 0,
|
||||||
|
RequestFlushResult = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFlushBuffers(
|
static NTSTATUS FspFsvolFlushBuffers(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result, FlushResult;
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
|
FSP_FILE_NODE **FileNodes;
|
||||||
|
ULONG FileNodeCount, Index;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
/* is this a valid FileObject? */
|
/*
|
||||||
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
* A flush request on the volume (or the root directory according to FastFat)
|
||||||
|
* is a request to flush the whole volume.
|
||||||
|
*/
|
||||||
|
if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory)
|
||||||
{
|
{
|
||||||
/* indicate that we are flushing the whole volume! */
|
Result = FspFileNodeCopyList(FsvolDeviceObject, &FileNodes, &FileNodeCount);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerate in reverse order so that files are flushed before containing directories.
|
||||||
|
* This would be useful if we ever started flushing directories, but since we do not
|
||||||
|
* it is not as important now.
|
||||||
|
*/
|
||||||
|
FlushResult = STATUS_SUCCESS;
|
||||||
|
for (Index = FileNodeCount - 1; FileNodeCount > Index; Index--)
|
||||||
|
if (!FileNodes[Index]->IsDirectory)
|
||||||
|
{
|
||||||
|
Result = FspCcFlushCache(&FileNodes[Index]->NonPaged->SectionObjectPointers,
|
||||||
|
0, 0, &IoStatus);
|
||||||
|
if (!NT_SUCCESS(Result) && NT_SUCCESS(FlushResult))
|
||||||
|
FlushResult = Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFileNodeDeleteList(FileNodes, FileNodeCount);
|
||||||
|
|
||||||
Result = FspIopCreateRequest(Irp, 0, 0, &Request);
|
Result = FspIopCreateRequest(Irp, 0, 0, &Request);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
/* a NULL UserContext indicates to user-mode to flush the whole volume! */
|
||||||
Request->Kind = FspFsctlTransactFlushBuffersKind;
|
Request->Kind = FspFsctlTransactFlushBuffersKind;
|
||||||
|
//Request->Req.FlushBuffers.UserContext = 0;
|
||||||
|
//Request->Req.FlushBuffers.UserContext2 = 0;
|
||||||
|
|
||||||
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
|
FspIopRequestContext(Request, RequestFlushResult) = (PVOID)(UINT_PTR)FlushResult;
|
||||||
|
|
||||||
return FSP_STATUS_IOQ_POST;
|
return FSP_STATUS_IOQ_POST;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
|
||||||
IO_STATUS_BLOCK IoStatus;
|
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
|
||||||
|
|
||||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
|
||||||
|
|
||||||
Result = FspCcFlushCache(FileObject->SectionObjectPointer, 0, 0, &IoStatus);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
{
|
||||||
FspFileNodeRelease(FileNode, Full);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
return Result;
|
|
||||||
|
/* cannot really flush directories but we will say we did it! */
|
||||||
|
if (FileNode->IsDirectory)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||||
|
|
||||||
|
Result = FspCcFlushCache(FileObject->SectionObjectPointer, 0, 0, &IoStatus);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolFlushBuffersRequestFini, &Request);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request->Kind = FspFsctlTransactFlushBuffersKind;
|
||||||
|
Request->Req.FlushBuffers.UserContext = FileNode->UserContext;
|
||||||
|
Request->Req.FlushBuffers.UserContext2 = FileDesc->UserContext2;
|
||||||
|
|
||||||
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
|
FspIopRequestContext(Request, RequestFlushResult) = 0;
|
||||||
|
|
||||||
|
return FSP_STATUS_IOQ_POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolFlushBuffersRequestFini, &Request);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Request->Kind = FspFsctlTransactFlushBuffersKind;
|
|
||||||
Request->Req.FlushBuffers.UserContext = FileNode->UserContext;
|
|
||||||
Request->Req.FlushBuffers.UserContext2 = FileDesc->UserContext2;
|
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
|
||||||
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
|
||||||
|
|
||||||
return FSP_STATUS_IOQ_POST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolFlushBuffersComplete(
|
NTSTATUS FspFsvolFlushBuffersComplete(
|
||||||
@ -84,6 +122,17 @@ NTSTATUS FspFsvolFlushBuffersComplete(
|
|||||||
{
|
{
|
||||||
FSP_ENTER_IOC(PAGED_CODE());
|
FSP_ENTER_IOC(PAGED_CODE());
|
||||||
|
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
NTSTATUS FlushResult = (NTSTATUS)(UINT_PTR)FspIopRequestContext(Request, RequestFlushResult);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||||
|
Result = Response->IoStatus.Status;
|
||||||
|
else if (!NT_SUCCESS(FlushResult))
|
||||||
|
Result = FlushResult;
|
||||||
|
else
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
FSP_LEAVE_IOC("FileObject=%p",
|
FSP_LEAVE_IOC("FileObject=%p",
|
||||||
IrpSp->FileObject);
|
IrpSp->FileObject);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user