簡體   English   中英

Windows驅動程序 - 在用戶模式和內核模式之間傳遞字符串。 動態大小的結構

[英]Windows Driver - Passing strings between user mode and kernel mode. Dynamically sized struct

我正在查看WDK中名為minispy的文件系統過濾器驅動程序示例...特別是它們如何使用FilterSendMessage和相關函數在用戶空間和內核之間傳遞數據:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff541513%28v=vs.85%29.aspx

如果您安裝WDK,我正在查看並將引用的代碼應位於此處:

WinDDK Root Dir \\ version \\ src \\ filesys \\ miniFilter \\ minispy

所以我首先要看的是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;

這里我們有Name沒有明確的大小,看起來他們正在使用一些選項來禁用此警告。

現在我正在查看填充的位置,filter \\ mspyLib.c:

(我只復制了我認為相關的行......)

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;

所以我的問題基本上是使用FilterSendMessage在結構中傳遞字符串以進行用戶內核通信的最佳方法嗎? 我無法想象這些結構的布局,如果名稱字符串太大,會發生什么。 此外,struct的分配發生在它的堆棧上的userspace組件中,但resize發生在內核空間組件中,作用於傳遞給struct的指針。 我認為這不是我不理解零長度數組的問題,而是用戶空間組件如何知道在調整大小之前為Name字段保留多少空間?

這基本上似乎是動態大小的數組的形式,在幾個線程中討論,例如:

C:動態大小結構的推薦樣式

您需要先調用FilterConnectCommunicationPort ()才能打開新連接,然后調用FilterSendMessage ()。

首先,是的,它似乎是一種動態大小的數組。 基本上, Name字符串放在結構的結尾之后。 在用戶模式和內核模式之間傳遞數據時,經常使用技巧。 這種方法有幾個優點:

  • 它不需要多次內存分配。
  • 將數據從用戶模式傳遞到內核模式(反之亦然)時,您經常需要將內存從一個緩沖區復制到另一個緩沖區(我相信FilterSendMessage會這樣做)。 如果我們使用指向不同內存位置的指針來存儲字符串,我們將需要多次調用來復制(或鎖定)內存。 處理用戶提供的消息時,操作系統無法知道數據結構的布局。 解決這個問題的關鍵是使用如上所述的平面結構。

這是非常有用的方法。 我個人使用這樣的技巧來避免即使在簡單的應用程序中多次調用內存函數(分配,復制,移動等)。 在開發Windows驅動程序時,我到處都看到這樣的結構(即ZwQueryInformationFile,ZwQueryDirectoryFile等)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM