Hello,
I’m facing a problem that I don’t know how to overcome.
I have this code snippet, it just lock some part of a file (c:\lock_test.txt) and then tries to write on some bytes of this part. It runs well, no problems.
h_file=CreateFileA(p_file_name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL); LockFile(h_file, 0, 0, 1, 0); WriteFile(h_file, buff, 10, &ucb_written, NULL);
Then, I have a minifilter, that intercepts this WRITE request and posts it to a worker thread. The worker thread tries to perform some WRITE on this file using FltWriteFileEx(). In the sample I just issue the same WRITE request I received and then complete the I/O.
/*------------------------------------------------------------------------------ IRPFlagsToIoOperationFlags ------------------------------------------------------------------------------*/ FLT_IO_OPERATION_FLAGS IRPFlagsToIoOperationFlags(ULONG uIRPFlags) { FLT_IO_OPERATION_FLAGS ioFlags=0; if (uIRPFlags&IRP_NOCACHE) { ioFlags=FLTFL_IO_OPERATION_NON_CACHED; } if (uIRPFlags&IRP_PAGING_IO) { ioFlags=FLTFL_IO_OPERATION_PAGING; } if (uIRPFlags&IRP_SYNCHRONOUS_PAGING_IO) { ioFlags=FLTFL_IO_OPERATION_SYNCHRONOUS_PAGING; } return ioFlags; } /*------------------------------------------------------------------------------ pWriteCB ------------------------------------------------------------------------------*/ void pWriteCB(PFLT_DEFERRED_IO_WORKITEM pDW, PFLT_CALLBACK_DATA pCBData, void *pCtx) { NTSTATUS rc; ULONG ucbWritten=0; rc=FltWriteFileEx( pCBData->Iopb->TargetInstance, pCBData->Iopb->TargetFileObject, &pCBData->Iopb->Parameters.Write.ByteOffset, pCBData->Iopb->Parameters.Write.Length, NULL, IRPFlagsToIoOperationFlags(pCBData->Iopb->IrpFlags), &ucbWritten, NULL, NULL, &pCBData->Iopb->Parameters.Write.Key, pCBData->Iopb->Parameters.Write.MdlAddress); __DBG_ERR("Write request ended with 0x%x, bytes written %u.\n", rc, ucbWritten); pCBData->IoStatus.Status=rc; pCBData->IoStatus.Information=ucbWritten; FltCompletePendedPreOperation(pCBData, FLT_PREOP_COMPLETE, NULL); FltFreeDeferredIoWorkItem(pDW); } DECLARE_CONST_UNICODE_STRING(usLockTest, L"\\device\\harddiskvolume3\\lock_test.txt"); /*------------------------------------------------------------------------------ WritePreOp ------------------------------------------------------------------------------*/ FLT_PREOP_CALLBACK_STATUS WritePreOp( _Inout_ PFLT_CALLBACK_DATA pCBData, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext) { NTSTATUS rc, ret; PFLT_FILE_NAME_INFORMATION nameInfo = NULL; PFLT_DEFERRED_IO_WORKITEM pDW; rc=FltGetFileNameInformation(pCBData, FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo); if (rc!=STATUS_SUCCESS) { ret=FLT_PREOP_SUCCESS_NO_CALLBACK; goto end; } if (RtlEqualUnicodeString(&nameInfo->Name, &usLockTest, TRUE)==FALSE) { ret=FLT_PREOP_SUCCESS_NO_CALLBACK; goto end; } __DBG("Got a WRITE on %wZ.\n", nameInfo->Name); rc=FltLockUserBuffer(pCBData); if (rc!=STATUS_SUCCESS) { __DBG_ERR("Failed to lock UserBuffer %p.\n", pCBData->Iopb->Parameters.Write.WriteBuffer); ret=FLT_PREOP_SUCCESS_NO_CALLBACK; goto end; } pDW=FltAllocateDeferredIoWorkItem(); if (pDW==NULL) { __DBG_ERR("Failed allocating a WORKITEM.\n"); ret=FLT_PREOP_SUCCESS_NO_CALLBACK; goto end; } rc=FltQueueDeferredIoWorkItem(pDW, pCBData, pWriteCB, DelayedWorkQueue, NULL); if (rc!=STATUS_SUCCESS) { __DBG_ERR("Failed posting WORKITEM.\n"); FltFreeDeferredIoWorkItem(pDW); ret=FLT_PREOP_SUCCESS_NO_CALLBACK; goto end; } __DBG("THREAD IS %p.\n", pCBData->Thread); ret=FLT_PREOP_PENDING; end: if (nameInfo!=NULL) { FltReleaseFileNameInformation( nameInfo ); } return ret; }
But the FltWriteFileEx() ends with a FILE_LOCK_CONFLICT. I imagine it happends because I switch thread context.
I also tried to do FltAllocateCallbackDataEx() & FltPerformSynchronousIo() but it just ends the same way.
If I forward the posted request, it works well :
/*------------------------------------------------------------------------------ pWriteCB3 ------------------------------------------------------------------------------*/ void pWriteCB3(PFLT_DEFERRED_IO_WORKITEM pDW, PFLT_CALLBACK_DATA pCBData, void *pCtx) { UNREFERENCED_PARAMETER(pCtx); __DBG("Write request TRANSMITTED."); FltCompletePendedPreOperation(pCBData, FLT_PREOP_SUCCESS_NO_CALLBACK, NULL); FltFreeDeferredIoWorkItem(pDW); }
What can I do to no have this FILE_LOCK_CONFLICT ? Because I really need to post this request and then perform some other requests …
Thank you !