internal void MiniFilterReplyAndGetNext(SafeFileHandle hDataPort, SafeFileHandle hControlPort) { if (State != IrpState.CallbackReturned) { throw new ApplicationException("MiniFilterReplyMessage() Flags!=ContainsIRP"); } ioFlowHeader.Flags |= (IsDataModified ? (uint)HeaderFlags.HeaderFlagIsDataModified : 0); // // Always restore the copy IOFLOW_HEADER, including FILTER_REPLY_HEADER.Status field. // Buffer.BlockCopy(BackupHeaderBuffer, 0, Data, 0, (int)IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER); // // FltMgr reply message handler copies user reply buffer into a kernel-mode buffer. // The IoFlow driver needs to see the IOFLOW_HEADER, but only cause a buffer copy // of the data if the user modified the data. // uint replyDataLength = IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER; if (IsDataModified) { replyDataLength += DataLength; } // // The call to CompleteMiniFilterGetMessage() is async and its completion handler // CompleteMiniFilterGetMessage() can get entered on another IOCP thread before // the call to FilterReplyAndGetNext() has returned on this thread. Therefore // set the IRP state to a post FilterReplyAndGetNext() state *before* the call. // State = IrpState.GetMessageK2U; uint HResult = FilterReplyAndGetNext(hDataPort, lpMessageBuffer, // PFILTER_REPLY_HEADER lpReplyBuffer replyDataLength, // valid data is at start of static buffer. lpMessageBuffer, // PFILTER_MESSAGE_HEADER lpMessageBuffer (uint)Data.Length, // DWORD dwMessageBufferSize addrOverlapped); // LPOVERLAPPED lpOverlapped if (HResult != HRESULT_ERROR_IO_PENDING) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("FilterReplyAndGetNext != ERROR_IO_PENDING {0} HRESULT {1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); if (HResult == 0x80070057) { Console.WriteLine("Check that FltLibIoFlow.dll and ioflow.sys ioctl same build."); } Marshal.ThrowExceptionForHR((int)HResult); } }
internal void CompleteMiniFilterGetMessage() { if (State != IrpState.GetMessageK2U) { string msg = string.Format("CompleteGetMsg() err Flags {0} expected RxRunning", State.ToString()); throw new ApplicationException(msg); } // // Expose *copy* IOFLOW_HEADER to caller. This limits confusion when user // has damaged the header by writing below DataBuffer[SIZEOF_IOFLOW_HEADER]. // Buffer.BlockCopy(Data, 0, BackupHeaderBuffer, 0, (int)IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER); State = IrpState.CallbackRunning; IsDataModified = false; }
/// <summary> /// /// </summary> /// <param name="hDataPort"></param> internal void MiniFilterReplyMessage(SafeFileHandle hDataPort, SafeFileHandle hControlPort) { if (State != IrpState.CallbackReturned) { throw new ApplicationException("MiniFilterReplyMessage() Flags!=ContainsIRP"); } State = IrpState.ReplyMessageU2K; ioFlowHeader.Flags |= (IsDataModified ? (uint)HeaderFlags.HeaderFlagIsDataModified : 0); // // Always restore the copy IOFLOW_HEADER, including FILTER_REPLY_HEADER.Status field. // Buffer.BlockCopy(BackupHeaderBuffer, 0, Data, 0, (int)IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER); // // FltMgr reply message handler copies user reply buffer into a kernel-mode buffer. // The IoFlow driver needs to see the IOFLOW_HEADER, but only cause a buffer copy // of the data if the user modified the data. // uint replyDataLength = IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER; if (IsDataModified) { replyDataLength += DataLength; } uint HResult = FilterReplyMessage(hDataPort, // HANDLE hPort - opened with lpMessageBuffer, // PFILTER_REPLY_HEADER lpReplyBuffer replyDataLength); // valid data is at start of static buffer. if (HResult != S_OK) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("MiniFilterReplyMessage != S_OK {0} hr 0x{1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); Marshal.ThrowExceptionForHR((int)HResult); } State = IrpState.Free; }
internal void StartMiniFilterGetMessage() { if (State != IrpState.Free) { throw new ApplicationException("StartMiniFilterGetMessage() Flags!=Free"); } State = IrpState.GetMessageK2U; uint HResult = FilterGetMessage(hPort, // HANDLE hPort lpMessageBuffer, // PFILTER_MESSAGE_HEADER lpMessageBuffer (uint)Data.Length, // DWORD dwMessageBufferSize addrOverlapped); // LPOVERLAPPED lpOverlapped if (HResult != HRESULT_ERROR_IO_PENDING) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("StartMiniFilterGetMessage != ERROR_IO_PENDING {0} HRESULT {1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); Marshal.ThrowExceptionForHR((int)HResult); } }
internal void StartMiniFilterGetMessage() { if (State != IrpState.Free) throw new ApplicationException("StartMiniFilterGetMessage() Flags!=Free"); State = IrpState.GetMessageK2U; uint HResult = FilterGetMessage(hPort, // HANDLE hPort lpMessageBuffer, // PFILTER_MESSAGE_HEADER lpMessageBuffer (uint)Data.Length, // DWORD dwMessageBufferSize addrOverlapped); // LPOVERLAPPED lpOverlapped if (HResult != HRESULT_ERROR_IO_PENDING) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("StartMiniFilterGetMessage != ERROR_IO_PENDING {0} HRESULT {1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); Marshal.ThrowExceptionForHR((int)HResult); } }
internal void SetStateCallbackReturned() { State = IrpState.CallbackReturned; }
/// <summary> /// /// </summary> /// <param name="hDataPort"></param> internal void MiniFilterReplyMessage(SafeFileHandle hDataPort, SafeFileHandle hControlPort) { if (State != IrpState.CallbackReturned) throw new ApplicationException("MiniFilterReplyMessage() Flags!=ContainsIRP"); State = IrpState.ReplyMessageU2K; ioFlowHeader.Flags |= (IsDataModified ? (uint)HeaderFlags.HeaderFlagIsDataModified : 0); // // Always restore the copy IOFLOW_HEADER, including FILTER_REPLY_HEADER.Status field. // Buffer.BlockCopy(BackupHeaderBuffer, 0, Data, 0, (int)IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER); // // FltMgr reply message handler copies user reply buffer into a kernel-mode buffer. // The IoFlow driver needs to see the IOFLOW_HEADER, but only cause a buffer copy // of the data if the user modified the data. // uint replyDataLength = IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER; if (IsDataModified) replyDataLength += DataLength; uint HResult = FilterReplyMessage(hDataPort, // HANDLE hPort - opened with lpMessageBuffer, // PFILTER_REPLY_HEADER lpReplyBuffer replyDataLength); // valid data is at start of static buffer. if (HResult != S_OK) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("MiniFilterReplyMessage != S_OK {0} hr 0x{1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); Marshal.ThrowExceptionForHR((int)HResult); } State = IrpState.Free; }
internal void MiniFilterReplyAndGetNext(SafeFileHandle hDataPort, SafeFileHandle hControlPort) { if (State != IrpState.CallbackReturned) throw new ApplicationException("MiniFilterReplyMessage() Flags!=ContainsIRP"); ioFlowHeader.Flags |= (IsDataModified ? (uint)HeaderFlags.HeaderFlagIsDataModified : 0); // // Always restore the copy IOFLOW_HEADER, including FILTER_REPLY_HEADER.Status field. // Buffer.BlockCopy(BackupHeaderBuffer, 0, Data, 0, (int)IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER); // // FltMgr reply message handler copies user reply buffer into a kernel-mode buffer. // The IoFlow driver needs to see the IOFLOW_HEADER, but only cause a buffer copy // of the data if the user modified the data. // uint replyDataLength = IOFLOW_HEADER.SIZEOF_IOFLOW_HEADER; if (IsDataModified) replyDataLength += DataLength; // // The call to CompleteMiniFilterGetMessage() is async and its completion handler // CompleteMiniFilterGetMessage() can get entered on another IOCP thread before // the call to FilterReplyAndGetNext() has returned on this thread. Therefore // set the IRP state to a post FilterReplyAndGetNext() state *before* the call. // State = IrpState.GetMessageK2U; uint HResult = FilterReplyAndGetNext(hDataPort, lpMessageBuffer, // PFILTER_REPLY_HEADER lpReplyBuffer replyDataLength, // valid data is at start of static buffer. lpMessageBuffer, // PFILTER_MESSAGE_HEADER lpMessageBuffer (uint)Data.Length, // DWORD dwMessageBufferSize addrOverlapped); // LPOVERLAPPED lpOverlapped if (HResult != HRESULT_ERROR_IO_PENDING) { int rc = Marshal.GetLastWin32Error(); string msg = string.Format("FilterReplyAndGetNext != ERROR_IO_PENDING {0} HRESULT {1:X8}", rc.ToString(), HResult); Console.WriteLine(msg); if (HResult == 0x80070057) Console.WriteLine("Check that FltLibIoFlow.dll and ioflow.sys ioctl same build."); Marshal.ThrowExceptionForHR((int)HResult); } }