WDK中出現的特殊代碼

WDK中出現的特殊代碼程序員


    咱們用本章的最後一個小節來介紹一些在WDK示例代碼中見到的特殊形式編碼。這些代碼在Win32應用程序的編程中不多見到,讀者須要首先熟悉一下。
    首先是參數說明宏。參數說明宏通常都是空宏,最多見的是IN和OUT。其實定義很簡單,以下所示:
#define IN
#define OUT
    這樣一來,IN和OUT就被定義成了空。不管出如今代碼中的任何地方,對代碼都不會有什麼實質的影響。在WDK的代碼中,用來做爲函數的說明。IN表示這個參數用於輸入;OUT表示這個參數用來返回結果。好比下面的例子:
NTSTATUS
  ZwQueryInformationFile(
    IN HANDLE  FileHandle,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass
    );
IN和OUT是比較傳統的參數說明宏。在WDK中處處可見更復雜的參數說明宏,好比下面的例子:
VOID
NdisProtStatus(
    IN NDIS_HANDLE                          ProtocolBindingContext,
    IN NDIS_STATUS                          GeneralStatus,
    __in_bcount(StatusBufferSize) IN PVOID  StatusBuffer,
    IN UINT                                 StatusBufferSize
    )
    其中的__in_bcount不但說明參數StatusBuffer是一個輸入參數,並且說明了StatusBuffer做爲一個緩衝區,它的字節長度被另外一個參數StatusBufferSize所指定。讀者再見到相似的說明宏,就以字面意思理解便可。
而後是指定函數位置的預編譯指令。好比下面的例子:
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, NdisProtUnload)
#pragma alloc_text(PAGE, NdisProtOpen)
#pragma alloc_text(PAGE, NdisProtClose)
    #pragma alloc_text這個宏僅僅用來指定某個函數的可執行代碼在編譯出來後在sys文件中的位置。內核模塊編譯出來以後是一個PE格式的sys文件,這個 文件的代碼段(text段)中有不一樣的節(Section),不一樣的節被加載到內存中以後處理狀況不一樣。讀者須要關心的主要是3種節:INIT節的特色是 在初始化完畢以後就被釋放。也就是說,就再也不佔用內存空間了。PAGE節的特色是位於能夠進行分頁交換的內存空間,這些空間在內存緊張時能夠被交換到硬盤 上以節省內存。若是未用上述的預編譯指令處理,則代碼默認位於PAGELK節,加載後位於不可分頁交換的內存空間中。
    函數DriverEntry顯然只須要在初始化階段執行一次,所以這個函數通常都用#pragma alloc_text(INIT, DriverEntry)使之位於初始化後馬上釋放的空間內。爲了節約內存,能夠把不少函數放在PAGE節中。可是要注意:放在PAGE節中的函數不能夠 在Dispatch級調用,由於這種函數的調用可能誘發缺頁中斷。可是缺頁中斷處理不能在Dispatch級完成。爲此,通常都用一個宏 PAGED_CODE()進行測試。若是發現當前中斷級爲Dispatch級,則程序直接報異常,讓程序員及早發現。示例以下:
#pragma alloc_text(PAGE, SfAttachToMountedDevice)
……
NTSTATUS
SfAttachToMountedDevice (
    IN PDEVICE_OBJECT DeviceObject,
    IN PDEVICE_OBJECT SFilterDeviceObject
    )
{       
    PSFILTER_DEVICE_EXTENSION newDevExt =
         SFilterDeviceObject->DeviceExtension;
    NTSTATUS status;
    ULONG i;

    PAGED_CODE();
    …編程

相關文章
相關標籤/搜索