I am looking at the File System Filter driver example in the WDK called minispy... specially how they are passing data between userspace and the kernel using the FilterSendMessage and related functions:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff541513%28v=vs.85%29.aspx
The code I am looking at and will be referring to should be located here if you install the WDK:
WinDDK Root Dir\\version\\src\\filesys\\miniFilter\\minispy
So basically the first thing I am looking at is the shared header file in inc\\minispy.h:
#pragma warning(push)
#pragma warning(disable:4200) // disable warnings for structures with zero length arrays.
typedef struct _LOG_RECORD {
ULONG Length; // Length of log record. This Does not include
ULONG SequenceNumber; // space used by other members of RECORD_LIST
ULONG RecordType; // The type of log record this is.
ULONG Reserved; // For alignment on IA64
RECORD_DATA Data;
WCHAR Name[]; // This is a null terminated string
} LOG_RECORD, *PLOG_RECORD;
Here we have Name which is not given an explicit size and it looks like they are using some options to disable warnings for this.
Now I am looking at where this is filled in, filter\\mspyLib.c:
(I only copied lines I thought were relevant...)
VOID SpySetRecordName (__inout PLOG_RECORD LogRecord, __in PUNICODE_STRING Name)
ULONG nameCopyLength;
PCHAR copyPointer = (PCHAR)LogRecord->Name;
...
// A bunch of code for getting nameCopyLength from UNICODE_STRING -- I understand this.
...
// comment about adding sizeof(PVOID) for IA64 alignment -- I understand this.
LogRecord->Length = ROUND_TO_SIZE( (LogRecord->Length + nameCopyLength + sizeof( UNICODE_NULL )), sizeof( PVOID ) );
RtlCopyMemory( copyPointer, Name->Buffer, nameCopyLength );
copyPointer += nameCopyLength;
*((PWCHAR) copyPointer) = UNICODE_NULL;
So my question is basically is this the best method for passing strings inside of a struct for user-kernel communication using FilterSendMessage? I'm having trouble picturing the layout of these structs and what happens if the name string turns out to be too big. Also, allocation for the struct happens in the userspace component on it's stack but the resize happens in kernel space component acting on a passed pointer to the struct. I think this is more a problem of me not understanding zero length arrays but how does the userspace component know how much space to reserve for the Name field before its resized?
This essentially seems to be a form of dynamically sized arrays which is discussed in several threads such as:
您需要先调用FilterConnectCommunicationPort ()才能打开新连接,然后调用FilterSendMessage ()。
First of all, yes, it appears to be a form of dynamically sized array. Basically, the Name
string is placed right after the end of structure. When passing data between user- and kernel-mode it is very often used trick. There are several advantages of this approach:
It is very useful approach. I personally use such trick to avoid multiples calls to memory functions (allocate, copy, move etc.) even in simple applications. When developing Windows drivers I see such structures everywhere (ie ZwQueryInformationFile, ZwQueryDirectoryFile etc.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.