FilterGetMessage is error?

和自甴很熟 提交于 2019-12-23 02:34:32

问题


I am writing windows service to communication with minifilter (kernel).

  1. Using FltSendMessage in minifilter

  2. Using FilterGetMessage in service

The status of FilterGetMessage is success (status = 0). But the buffer is always null. What is not correct?

This is my code in minifilter: C++ code

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

p/s: above code is put PreCreate callback

This is my code in service: C# code

// 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);

UPDATE: Although, status is success, the value of message header is 0

 1. dataReceive.messageHeader.messageId = 0

 2. dataReceive.messageHeader.replyLength = 0

UPDATE ANSWER:

 1. Update old code:

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

And:

// Get data size
int dataSize = Marshal.SizeOf(dataReceive);
  1. Add new code: After use FilterGetMessage function

    // Check status and get content message

    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);
    }
    

回答1:


I can see one problem right away with this code:

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

This does not create a continuous struct. This will create a struct with one FILTER_MESSAGE_HEADER and one reference to an array (which is not what the function expects). A byte[] is a reference, so the array data is not in the struct. If you try Marshal.SizeOf on the struct, you'll get 16 or 20 bytes, not sizeof( FILTER_MESSAGE_HEADER ) + the length of the buffer. What you need here is to use unsafe code with a fixed buffer:

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

That will create a continuous struct, with the array data in the struct itself instead of somewhere else. Try this and verify the final size with Marshal.SizeOf.



来源:https://stackoverflow.com/questions/27860735/filtergetmessage-is-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!