FilterGetMessage 出错?

FilterGetMessage is error?

我正在编写 windows 服务来与 minifilter(内核)通信。

  1. 在 minifilter

  2. 中使用 FltSendMessage
  3. 在服务中使用 FilterGetMessage

FilterGetMessage 的状态为成功(状态 = 0)。但缓冲区始终为空。 哪里不对?

这是我在 minifilter 中的代码:C++ 代码

status = FltSendMessage(
                gFilterHandle,
                &gClientPort, 
                (PVOID)FltObjects->FileObject->FileName.Buffer,
                FltObjects->FileObject->FileName.MaximumLength,
                NULL,
                NULL,
                NULL);

p/s: 上面的代码是PreCreate回调

这是我的服务代码:C#代码

// Constant buffer size
public const int BUFFER_SIZE = 1024;

// message header struct
[StructLayout(LayoutKind.Sequential)]
public struct FILTER_MESSAGE_HEADER {
        public uint replyLength;
        public ulong messageId;
}

// message receive struct
public struct DATA_RECEIVE
{
        public FILTER_MESSAGE_HEADER messageHeader;
        public byte[] messageContent;
}

DATA_RECEIVE dataReceive = new DATA_RECEIVE();
dataReceive.messageContent = new byte[BUFFER_SIZE];

int headerSize = Marshal.SizeOf(dataReceive.messageHeader);
int dataSize = BUFFER_SIZE + headerSize;

status = FilterGetMessage(hPort, out dataReceive.messageHeader, dataSize, IntPtr.Zero);

更新:虽然状态是成功,但是消息头的值为0

 1. dataReceive.messageHeader.messageId = 0

 2. dataReceive.messageHeader.replyLength = 0

更新答案:

 1. Update old code:

// message receive struct
public struct DATA_RECEIVE
{
        public FILTER_MESSAGE_HEADER messageHeader;
        public fixed byte messageContent[BUFFER_SIZE];
}

并且:

// Get data size
int dataSize = Marshal.SizeOf(dataReceive);
  1. 添加新代码:使用FilterGetMessage函数后

    // 检查状态并获取消息内容

    int status = FilterGetMessage(hPort, out dataReceive.messageHeader, dataSize, IntPtr.Zero);
    
    if (status == 0)
    {
       int index = 0;
       unsafe
       {
          byte* ptr = dataReceive.messageContent;
          for (; *ptr != 0; ptr += 2)
          {
               messageContent[index++] = *ptr;
          }
       };
       filePath = Encoding.ASCII.GetString(messageContent);
    }
    

我可以通过这段代码立即看出一个问题:

public struct DATA_RECEIVE
{
    public FILTER_MESSAGE_HEADER messageHeader;
    public byte[] messageContent;
}

这不会创建连续结构。这将创建一个结构,其中包含一个 FILTER_MESSAGE_HEADER 和一个对数组的引用(这不是函数所期望的)。 A byte[] 是引用,因此数组数据不在结构中。如果你在结构上尝试 Marshal.SizeOf,你将得到 16 或 20 个字节,而不是 sizeof( FILTER_MESSAGE_HEADER ) + the length of the buffer。这里你需要的是使用固定缓冲区的不安全代码:

public unsafe struct DATA_RECEIVE
{
    public FILTER_MESSAGE_HEADER messageHeader;
    public fixed byte messageContent[BUFFER_SIZE];
}

这将创建一个连续的结构,数组数据位于结构本身而不是其他地方。试试这个并使用 Marshal.SizeOf.

验证最终大小