Convenzioni di chiamata, parametri e tipo restituito
Il prototipo della routine di supporto è:
FARPROC WINAPI __delayLoadHelper2(
PCImgDelayDescr pidd,
FARPROC * ppfnIATEntry
);
dove:
pidd
Puntatore const a un ImgDelayDescr (vedere delayimp.h) che contiene gli offset di vari dati relativi alle importazioni, un timestamp per le informazioni di associazione e un set di attributi che forniscono ulteriori informazioni sul contenuto del descrittore. Attualmente è presente un unico attributo, dlattrRva, che indica che gli indirizzi del descrittore sono indirizzi virtuali relativi e non indirizzi virtuali.Per la definizione della struttura PCImgDelayDescr, vedere Struttura e definizioni di costanti.
ppfnIATEntry
Puntatore allo slot della tabella degli indirizzi di importazione (IAT) a caricamento ritardato da aggiornare con l'indirizzo della funzione importata. Nella routine di supporto deve essere memorizzato lo stesso valore che verrà restituito in questa posizione.
Valori restituiti previsti
Se la funzione viene completata correttamente, viene restituito l'indirizzo della funzione importata.
Se la funzione non viene completata, viene generata un'eccezione e viene restituito 0. Possono essere generati tre tipi di eccezioni:
Parametro non valido, quando gli attributi in pidd non sono specificati correttamente.
Errore di LoadLibrary per la DLL specificata.
Errore di GetProcAddress.
È responsabilità del programmatore gestire queste eccezioni.
Osservazioni
La convenzione di chiamata per la funzione di supporto è __stdcall. Il tipo di valore restituito non è rilevante, pertanto viene utilizzato FARPROC. La funzione presenta un collegamento C.
Il valore restituito dal supporto per il caricamento ritardato deve essere memorizzato nella posizione del puntatore a funzione passato, a meno che non si desideri che la routine di supporto venga utilizzata come hook di notifica. In questo caso, il puntatore a funzione appropriato da restituire verrà individuato dal codice. Il valore restituito verrà quindi considerato come la destinazione effettiva dell'importazione dal codice di thunk generato dal linker, che verrà passato direttamente a tale destinazione.
Esempio
Nel codice riportato di seguito è illustrata la modalità di implementazione di una semplice funzione hook.
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;
*/