Share via


Fehlerbehandlung und Benachrichtigung

Wenn Ihr Programm verzögert geladene DLLs verwendet, muss es Fehler robust behandeln, da Fehler, die auftreten, während das Programm ausgeführt wird, zu unbehandelten Ausnahmen führen. Die Fehlerbehandlung besteht aus zwei Teilen: Wiederherstellung über einen Hook und Berichterstellung über eine Ausnahme.

Weitere Informationen zur DLL-Verzögerung beim Laden von Fehlern und Benachrichtigungen finden Sie unter Grundlegendes zur Hilfsfunktion.

Weitere Informationen zu Hook-Funktionen finden Sie unter Struktur- und Konstantendefinitionen.

Wiederherstellung über einen Hook

Möglicherweise muss Ihr Code bei einem Fehler wiederhergestellt werden oder eine alternative Bibliothek oder Routine bereitstellen. Sie können einen Hook für die Hilfsfunktion bereitstellen, die den alternativen Code bereitstellen oder die Situation beheben kann. Die Hook-Routine muss einen geeigneten Wert zurückgeben, damit die Verarbeitung fortgesetzt werden kann (ein HINSTANCE oder FARPROC). Alternativ kann 0 zurückgegeben werden, um anzugeben, dass eine Ausnahme ausgelöst werden soll. Es könnte auch eine eigene Ausnahme oder longjmp aus dem Haken werfen. Es gibt Benachrichtigungs-Hooks und Fehler-Hooks. Die gleiche Routine kann für beide verwendet werden.

Benachrichtigungshooks

Die Benachrichtigungshaken zum Verzögern des Ladevorgangs werden aufgerufen, bevor die folgenden Aktionen in der Hilfsroutine ausgeführt werden:

  • Das gespeicherte Handle für die Bibliothek wird überprüft, um festzustellen, ob es bereits geladen wurde.

  • LoadLibrary wird aufgerufen, um das Laden der DLL zu versuchen.

  • GetProcAddress wird aufgerufen, um zu versuchen, die Adresse der Prozedur abzurufen.

  • Kehren Sie zur Verzögerung import load thunk zurück.

Der Benachrichtigungshaken ist aktiviert:

  • Durch Bereitstellen einer neuen Definition des Zeigers __pfnDliNotifyHook2 , der initialisiert wird, um auf Ihre eigene Funktion zu verweisen, die die Benachrichtigungen empfängt.

    Oder

  • Indem Sie den Zeiger __pfnDliNotifyHook2 auf Ihre Hook-Funktion festlegen, bevor Aufrufe der DLL ausgeführt werden, die das Programm das Laden verzögert.

Wenn die Benachrichtigung lautet dliStartProcessing, kann die Hook-Funktion Folgendes zurückgeben:

  • NULL

    Der Standardhilfsprogramm behandelt das Laden der DLL. Es ist nützlich, nur zu Informationszwecken aufzurufen.

  • Ein Funktionszeiger

    Umgehen Sie die standardmäßige Verzögerungsladebehandlung. Damit können Sie Ihren eigenen Ladehandler bereitstellen.

Wenn die Benachrichtigung lautet dliNotePreLoadLibrary, kann die Hook-Funktion Folgendes zurückgeben:

  • 0, wenn nur Informationsbenachrichtigungen angezeigt werden sollen.

  • Die HMODULE für die geladene DLL, wenn sie die DLL selbst geladen hat.

Wenn die Benachrichtigung lautet dliNotePreGetProcAddress, kann die Hook-Funktion Folgendes zurückgeben:

  • 0, wenn nur Informationsbenachrichtigungen angezeigt werden sollen.

  • Die Adresse der importierten Funktion, wenn die Hook-Funktion die Adresse selbst abruft.

Wenn die Benachrichtigung lautet dliNoteEndProcessing, wird der Rückgabewert der Hook-Funktion ignoriert.

Wenn dieser Zeiger initialisiert ist (nonzero), ruft das Verzögerungsladehilfsprogramm die Funktion während der gesamten Ausführung an bestimmten Benachrichtigungspunkten auf. Der Funktionszeiger weist die folgende Definition auf:

// The "notify hook" gets called for every call to the
// delay load helper.  This allows a user to hook every call and
// skip the delay load helper entirely.
//
// dliNotify == {
//  dliStartProcessing |
//  dliNotePreLoadLibrary  |
//  dliNotePreGetProc |
//  dliNoteEndProcessing}
//  on this call.
//
ExternC
PfnDliHook   __pfnDliNotifyHook2;

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook   __pfnDliFailureHook2;

Die Benachrichtigungen übergeben eine DelayLoadInfo Struktur an die Hook-Funktion zusammen mit dem Benachrichtigungswert. Diese Daten sind identisch mit den Daten, die von der Verzögerungsladehilfsroutine verwendet werden. Der Benachrichtigungswert ist einer der werte, die in Struktur- und Konstantendefinitionen definiert sind.

Fehlerhooks

Der Fehlerhaken ist auf die gleiche Weise wie der Benachrichtigungshaken aktiviert. Die Hook-Routine muss einen geeigneten Wert zurückgeben, damit die Verarbeitung fortgesetzt werden kann (ein HINSTANCE oder FARPROC), oder 0, um anzugeben, dass eine Ausnahme ausgelöst werden soll.

Die Zeigervariable, die auf die benutzerdefinierte Funktion verweist, lautet:

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook   __pfnDliFailureHook2;

Die DelayLoadInfo Struktur enthält alle relevanten Daten, die für eine detaillierte Berichterstellung des Fehlers erforderlich sind, einschließlich des Werts von GetLastError.

Wenn die Benachrichtigung lautet dliFailLoadLib, kann die Hook-Funktion Folgendes zurückgeben:

  • 0, wenn der Fehler nicht behandelt werden kann.

  • Ein HMODULE, wenn der Fehler-Hook das Problem behoben und die Bibliothek selbst geladen hat.

Wenn die Benachrichtigung lautet dliFailGetProc, kann die Hook-Funktion Folgendes zurückgeben:

  • 0, wenn der Fehler nicht behandelt werden kann.

  • Eine gültige Proc-Adresse (Importfunktionsadresse), wenn der Fehlerhaken erfolgreich war, die Adresse selbst zu erhalten.

Melden mithilfe einer Ausnahme

Wenn alles, was zum Behandeln des Fehlers erforderlich ist, die Prozedur abzubrechen, ist kein Hook erforderlich, solange der Benutzercode die Ausnahme behandeln kann.

Verzögertes Laden von Ausnahmecodes

Strukturierte Ausnahmecodes können ausgelöst werden, wenn Fehler während einer verzögerten Auslastung auftreten. Die Ausnahmewerte werden mithilfe eines VcppException Makros angegeben:

//
// Exception information
//
#define FACILITY_VISUALCPP  ((LONG)0x6d)
#define VcppException(sev,err)  ((sev) | (FACILITY_VISUALCPP<<16) | err)

Bei einem LoadLibrary Fehler wird der Standard VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ausgelöst. Bei einem GetProcAddress Fehler wird VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)der ausgelöste Fehler zurückgegeben. Die Ausnahme übergibt einen Zeiger an eine DelayLoadInfo Struktur. Er befindet sich im LPDWORD Wert, der aus der EXCEPTION_RECORD Struktur abgerufen GetExceptionInformation wird, im ExceptionInformation[0] Feld.

Wenn die falschen Bits im grAttrs Feld festgelegt sind, wird die Ausnahme ERROR_INVALID_PARAMETER ausgelöst. Diese Ausnahme ist für alle Absichten und Zwecke tödlich.

Weitere Informationen finden Sie unter Struktur- und Konstantendefinitionen.

Siehe auch

Linker-Unterstützung für verzögert geladene DLLs