问题
I am writing windows service to communication with minifilter (kernel).
Using FltSendMessage in minifilter
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);
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