EX_CALLBACK_FUNCTION回呼函式 (wdm.h)
篩選驅動程式的 RegistryCallback 例程可以監視、封鎖或修改登錄作業。
語法
EX_CALLBACK_FUNCTION ExCallbackFunction;
NTSTATUS ExCallbackFunction(
[in] PVOID CallbackContext,
[in, optional] PVOID Argument1,
[in, optional] PVOID Argument2
)
{...}
參數
[in] CallbackContext
驅動程式當做 Context 參數傳遞至 CmRegisterCallback 或 CmRegisterCallbackEx 時,在登錄此 RegistryCallback 例程時傳遞的值。
[in, optional] Argument1
REG_NOTIFY_CLASS型別值,識別正在執行的登錄作業類型,以及在執行登錄作業之前或之後,是否呼叫 RegistryCallback 例程。
[in, optional] Argument2
結構的指標,其中包含登錄作業類型特有的資訊。 結構類型取決於 Argument1REG_NOTIFY_CLASS型別值,如下表所示。 如需哪些REG_NOTIFY_CLASS型別值可供哪些作系統版本使用的詳細資訊,請參閱 REG_NOTIFY_CLASS。
從 Windows 7 開始,當 notify 類別為 RegNtPreCreateKeyEx 或 RegNtPreOpenKeyEx 時傳入的實際數據結構,分別是此結構的 V1 版本,REG_CREATE_KEY_INFORMATION_V1 或 REG_OPEN_KEY_INFORMATION_V1。 檢查保留成員以判斷結構的版本。
版本號碼 | 結構名稱 |
---|---|
0 | REG_CREATE_KEY_INFORMATION和REG_OPEN_KEY_INFORMATION |
1 | REG_CREATE_KEY_INFORMATION_V1和REG_OPEN_KEY_INFORMATION_V1 |
傳回值
如需當 RegistryCallback 例程傳回這些狀態值時的詳細資訊,請參閱 篩選登錄呼叫。
言論
若要收到登錄作業的通知,內核模式元件(例如防病毒軟體套件的驅動程式元件)可以呼叫 CmRegisterCallback 或 CmRegisterCallbackEx 來註冊 RegistryCallback 例程。
RegistryCallback 例程可以檢查登錄作業所提供輸入和輸出緩衝區的內容。 登錄作業可由呼叫使用者模式登錄例程的使用者模式應用程式起始(例如 RegCreateKeyEx 或 RegOpenKeyEx),或由呼叫內核模式登錄例程的驅動程式起始(例如 ZwCreateKey 或 ZwOpenKey)。 輸入緩衝區 是由登錄讀取作業輸入數據的啟動器提供的記憶體緩衝區。 輸出緩衝區 是由啟動器提供的緩衝區,登錄會將啟動器所要求的輸出數據寫入其中。
在呼叫 RegistryCallback 例程之前,核心探查(以確認對齊和輔助功能)Argument2 的所有成員 結構中指向使用者模式記憶體中的輸出緩衝區,但不會擷取系統記憶體中的使用者模式輸出緩衝區。 回呼例程必須將輸出緩衝區的任何存取封入 嘗試/,但 區塊除外。 如果回呼例程需要將輸出緩衝區指標傳遞至系統例程(例如,ZwOpenKey),且緩衝區處於使用者模式記憶體中,則回呼例程必須先擷取緩衝區。
輸入緩衝區的處理取決於 Windows 版本。 從 Windows 8 開始,核心會擷取系統記憶體中 Argument2 結構成員指向的所有輸入緩衝區,然後再呼叫 RegistryCallback 例程。 在 Windows 8 之前的 Windows 版本中,核心會探查指向使用者模式記憶體中輸入緩衝區的 Argument 2 的所有成員,但只會擷取系統記憶體中的部分緩衝區。 在這些舊版 Windows 中,回呼例程必須將輸入緩衝區的任何存取封入 嘗試/,但 區塊除外。 此外,如果回呼例程需要將輸入緩衝區指標傳遞至系統例程(例如,ZwOpenKey),而且緩衝區處於使用者模式記憶體中,則回呼例程必須先擷取緩衝區。
下表摘要說明 RegistryCallback 例程對緩衝區存取的需求。
緩衝區類型 | Windows 版本 | 傳遞至回呼例程的緩衝區指標 | 安全回呼例程直接存取? | 安全傳遞至系統例程 (例如 ZwOpenKey)? |
---|---|---|---|---|
使用者模式輸入 | Windows 8 和更新版本 | 指向擷取的數據。 | 是的 | 是的 |
使用者模式輸入 | Windows 7 和更早版本 | 指向擷取的數據或原始使用者模式緩衝區。 | 不。 必須在 try/except 底下讀取。 | 不。 必須配置核心記憶體、從 try/except 底下的原始緩衝區複製數據,並將複製的數據傳遞至系統例程。 |
使用者模式輸出 | 都 | 指向原始使用者模式緩衝區。 | 不。 必須在 try/except 底下寫入。 | 不。 必須配置核心記憶體、將核心記憶體傳遞至系統例程,並將結果複製到 try/except 底下的原始緩衝區。 |
內核模式輸入和輸出 | 都 | 指向原始內核模式緩衝區。 | 是的 | 是的 |
如需 RegistryCallback 例程和登錄篩選驅動程式的詳細資訊,請參閱 篩選登錄呼叫。
RegistryCallback 會在 IRQL = PASSIVE_LEVEL 以及執行登錄作業的線程內容中執行。
例子
若要定義 RegistryCallback 回呼例程,您必須先提供函式宣告,以識別您要定義的回呼例程類型。 Windows 提供一組驅動程式的回呼函式類型。 使用回呼函式類型宣告函式有助於 驅動程式的程式代碼分析、靜態驅動程式驗證器 (SDV)和其他驗證工具尋找錯誤,而且是撰寫 Windows作系統驅動程式的需求。
例如,若要定義名為 MyRegistryCallback
的 RegistryCallback 回呼例程,請使用 EX_CALLBACK_FUNCTION 類型,如下列程式代碼範例所示:
EX_CALLBACK_FUNCTION MyRegistryCallback;
然後,實作回呼例程,如下所示:
_Use_decl_annotations_
NTSTATUS
MyRegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
)
{
// Function body
}
EX_CALLBACK_FUNCTION函式類型定義於 Wdm.h 頭檔中。 若要在執行程式代碼分析工具時更準確地識別錯誤,請務必將 Use_decl_annotations 批註新增至函式定義。 Use_decl_annotations 批注可確保會使用套用至頭檔中EX_CALLBACK_FUNCTION函式類型的批注。 如需函式宣告需求的詳細資訊,請參閱 使用 WDM 驅動程式的函式角色類型來宣告函式。 如需 Use_decl_annotations的相關信息,請參閱 批注函式行為。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | 從 Windows XP 開始支援 (請參閱傳回值一節)。 |
目標平臺 | 桌面 |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
IRQL | 在 PASSIVE_LEVEL 呼叫 (請參閱一節)。 |