ExAllocatePoolWithTag

功能描述
ExAllocatePoolWithTag函數:根據指定存儲區類型參數分配一段空間,並把該空間的首地址作爲返回值發送給調用者。


參數說明
PoolType
該參數用來指定想要申請的內存的類型(內核空間中的內存主要分成兩類;分頁內存區,和未分頁內存區)。查詢可選的內存區類型可以到MSDN查詢POOL_TYPE結構。

您也可以修改該參數,將當前的值和標誌POOL_RAISE_IF_ALLOCATION_FAILURE進行或運算(使用運算符:||)。標誌POOL_RAISE_IF_ALLOCATION_FAILURE的作用是在申請空間的請求無法被實現的時候(空間不足?權限不足?)報出異常。但是我們不建議您過多使用這個標誌位,因爲它對程序的性能影響太大~

同樣,您也可以把當前的PoolType和另一個標誌POOL_COLD_ALLOCATION進行或運算(使用運算符:||)。這個標誌的功能是提示系統從那些快要頁面溢出(Paged-out)的頁中分配空間(反正這個頁面中數據基本壞了,直接分配給其他人用,是這意思嗎?)。爲了儘可能的減少常駐存儲器池的數量,您還是少用這個標誌。同時POOL_COLD_ALLOCATION 標誌位只建議您在XP和之後的windows版本中使用(看來其中有不可告人的祕密)。

 

NumberOfBytes
通過該參數指定想要分配的內存的字節數。

 

Tag
爲將要被分配的空間指定標誌(就是給你得到的空間取個獨一無二的名字)。進一步解釋:賦給該參數的內容是一個字符串常量,最多可以包含四個字母,該字符串應該放到單引號當中(比如:‘tag1’‘tag2’)。另外,這個字符串常常是逆序的,如,‘1gaT’(所以大家會發現輸入這個參數的串確實都是倒過來的。。。)。輸入到這個參數中的每一個字符的ASCII值都必須在0-127之間。每次的申請空間的時候都最好應該使用一個獨一無二的標識,這樣可以幫助調試器和檢查器辨認和分析。

 

返回值
如果該函數發現目前系統的自由空間不足,就會返回NULL。否則,將返回指向被分配出來的空間的首地址。

 

附加說明
這個函數用於普通的申請內存空間。
如果參數NumberOfBytes 的值大於等於PAGE_SIZE ,那麼函數就會按照頁對齊(以頁爲單位)分配空間。當分配小於等於一個頁大小的空間時,函數會在一個單獨的頁中進行分配,也就是說該情況下分配的空間不會誇頁。同時,分配少於一個頁大小的空間時,分配是以字節爲對齊單位,在32位系統中以8字節對齊,在64位系統中以16字節對齊。
要成功的用該函數申請空間,需要在申請非分頁內存區的時候,參數NumberOfBytes 小於PAGE_SIZE,並且要給出想要申請的準確字節數。如果成功的申請到了大於一個頁的空間,並且參數NumberOfBytes不是頁大小的倍數,那麼最後一頁會含有不屬於該函數調用者的空間。如果可能的話,內存分配管理器會佔用這些空間。爲了防止發生數據訪問衝突,驅動程序只能操作已經顯式申請過的存儲空間。

系統將空間標識(第三個參數)和空間綁定起來。調試器,如WinDbg,可以顯式這些和內存空間綁定在一起的標識符。Gflag(一個windows自帶的調試工具),可以開啓一個系統功能——請求爲一個特定的標示符申請專有的空間。Poolmon,該工具包含在WDK中,可以通過給定的標示符追蹤內存區域。

Tag參數的值有時候會被以逆序的方式存儲或者顯示。如一個調用函數傳進來參數‘Fred’。而這個參數在其他地方或者被其他調試器顯示出來時則是‘derF’。而在寄存器和某些工具中顯示爲‘0x64657246’

該函數申請到的空間在釋放的時候可以使用ExFreePool或者ExFreePoolWithTag。

函數ExAllocatePoolWithTag的調用者的內核中斷級必須小於等於DISPATCH_LEVEL。如果調用者在DISPATCH_LEVEL級上執行,必須使用NonPagedXxx給PoolType複製,如果調用者的工作中斷級小於等於APC_LEVEL,那麼它在類型參數上也可以使用POOL_TYPE。但是中斷級和其他環境參數必須充分考慮分頁類型的空間。

注意:不要把NumberOfBytes設置成0,這會造成空間浪費,因爲系統會給每一次分配的空間加一個頭,哪怕分配的空間大小是0,同時還會在函數的調用者代碼中產生一些潛在的問題。
注意:被ExAllocatePoolWithTag分配出來的空間是沒有經過初始化的。一個內核驅動如果打算申請一段空間,並且讓應用層的程序可以訪問這個空間,必須先對它進行清零的初始化。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章