呼叫慣例、參數和傳回型別
Helper 常式的原型 (Prototype) 為:
FARPROC WINAPI __delayLoadHelper2(
PCImgDelayDescr pidd,
FARPROC * ppfnIATEntry
);
其中:
pidd
指向 ImgDelayDescr (請參閱 delayimp.h) 的 const 指標,包含各種與匯入相關之資料的位移 (Offset)、繫結資訊的時間戳記,以及一組提供有關描述項內容的詳細資訊屬性。 目前只有一個屬性 dlattrRva,表示描述項內的位址為相對虛擬位址 (相對於虛擬位址)。如需 PCImgDelayDescr 結構的定義,請參閱結構和常數定義。
ppfnIATEntry
指向匯入位址表 (IAT) 中某位置的指標,該位置將被匯入函式的位址更新。 Helper 常式需要儲存將會傳回此位置的同一個值。
預期的傳回值
如果函式執行成功,將傳回匯入函式的位址。
如果函式執行失敗,將引發例外狀況並傳回 0。 可能引發的例外狀況有三種:
無效的參數,未正確定指定 pidd 中的屬性時將發生此例外狀況
LoadLibrary 在指定的 DLL 發生錯誤
GetProcAddress 失敗
您必須負責處理這些例外狀況。
備註
Helper 函式的呼叫慣例是 __stdcall。 傳回值型別不符,因此使用 FARPROC。 這個函式具有 C 連結。
延遲載入之 Helper 的傳回值必須儲存於傳入的函式指標位置,除非您希望將 Helper 常式當做告知攔截使用。 在這種情況下,您的程式碼將負責找出適當的函式指標來傳回。 然後連結器產生的 Thunk 程式碼將取得該傳回值,做為匯入的真正目標並直接跳至此位置。
範例
下列程式碼顯示如何實作一個簡單的攔截函式。
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
switch (dliNotify) {
case dliStartProcessing :
// If you want to return control to the helper, return 0.
// Otherwise, return a pointer to a FARPROC helper function
// that will be used instead, thereby bypassing the rest
// of the helper.
break;
case dliNotePreLoadLibrary :
// If you want to return control to the helper, return 0.
// Otherwise, return your own HMODULE to be used by the
// helper instead of having it call LoadLibrary itself.
break;
case dliNotePreGetProcAddress :
// If you want to return control to the helper, return 0.
// If you choose you may supply your own FARPROC function
// address and bypass the helper's call to GetProcAddress.
break;
case dliFailLoadLib :
// LoadLibrary failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_MOD_NOT_FOUND) and exit.
// If you want to handle the failure by loading an alternate
// DLL (for example), then return the HMODULE for
// the alternate DLL. The helper will continue execution with
// this alternate DLL and attempt to find the
// requested entrypoint via GetProcAddress.
break;
case dliFailGetProc :
// GetProcAddress failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_PROC_NOT_FOUND) and exit.
// If you choose you may handle the failure by returning
// an alternate FARPROC function address.
break;
case dliNoteEndProcessing :
// This notification is called after all processing is done.
// There is no opportunity for modifying the helper's behavior
// at this point except by longjmp()/throw()/RaiseException.
// No return value is processed.
break;
default :
return NULL;
}
return NULL;
}
/*
and then at global scope somewhere
PfnDliHook __pfnDliNotifyHook2 = delayHook;
*/