I am implementing a file transparent encryption based on minifitler, which requires adding some encrypted information at the end of the file. I want to write this information to the end of the file during PostCloseWhenSafe Routine.
Acquire lock before FltWriteFileEx and release the lock after completion:
CtxAcquireResourceExclusive(streamContext->Resource);
DbgPrint("before FltWriteFileEx.\n");
Status = FltWriteFileEx(
Instance,
FileObject,
&ByteOffset,
WriteLength,
WriteBuffer,
FLTFL_IO_OPERATION_NON_CACHED |
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
&BytesWritten,
NULL,
NULL,
NULL,
NULL);
if (!NT_SUCCESS(Status) || BytesWritten == 0) {
DbgPrint("tail FltWriteFile failed. status = %08x, bytesWritten = %ld.\n", Status, BytesWritten);
goto EXIT;
}
streamContext->something = xxx;
DbgPrint("after FltWriteFileEx.\n");
CtxReleaseResource(streamContext->Resource);
And, in the PostWrite, there is the following logic:
DbgPrint("PostWrite xxx.\n");
DbgPrint("before CtxAcquireResourceExclusive.\n");
CtxAcquireResourceExclusive(streamContext->Resource);
DbgPrint("set streamContext content.\n");
streamContext->something = xxx;
CtxReleaseResource(streamContext->Resource);
DbgPrint("after CtxAcquireResourceExclusive.\n");
Phenomenon: Sometimes it works, sometimes deadlocks occur during writing. Logs when it works:
...
before FltWriteFileEx.
PreWrite xxx.
PostWrite xxx.
before CtxAcquireResourceExclusive.
set streamContext content.
after CtxAcquireResourceExclusive.
after FltWriteFileEx.
...
Logs when dead lock:
...
before FltWriteFileEx.
PreWrite xxx.
PostWrite xxx.
before CtxAcquireResourceExclusive.
I also printed offset and writelen in PostWrite, although they are different from those in FltWriteFileEx, it is indeed waiting for PostWrite to complete and return.
However, According to the document:
FltWriteFileEx causes a write request to be sent to the minifilter driver instances attached below the initiating instance and to the file system. The specified instance and the instances attached above it do not receive the write request.
Anyone Can Help This issue? Thanks.
When deadlock occurs:
FltWriteFileEx indirectly triggers the Cache Manager to issue a PagingIO(in order to refresh some dirty caches). And FltWriteFileEx seems to be waiting for this operation.
Solution:
if it is pagingIO, do not acquire the resource.