FilterGetMessage 出错?
FilterGetMessage is error?
我正在编写 windows 服务来与 minifilter(内核)通信。
在 minifilter
中使用 FltSendMessage
在服务中使用 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);
添加新代码:使用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
.
验证最终大小
我正在编写 windows 服务来与 minifilter(内核)通信。
在 minifilter
中使用 FltSendMessage
在服务中使用 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);
添加新代码:使用
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
.