Partager via


Appel de la bibliothèque DbgHelp

Bien que DbgHelp.dll fourni avec toutes les versions de Windows, les appelants doivent envisager d’utiliser l’une des versions les plus récentes de cette DLL, comme indiqué dans le package Outils de débogage pour Windows . Pour plus d’informations sur la distribution de DbgHelp, consultez Versions dbgHelp.

Lors de l’utilisation de DbgHelp, la meilleure stratégie consiste à installer une copie de la bibliothèque à partir du package Outils de débogage pour Windows dans le répertoire de l’application qui se trouve logiquement à côté du logiciel qui l’appelle. Si le serveur de symboles et le serveur source sont également nécessaires, les deux SymSrv.dll et SrcSrv.dll doivent être installés dans le même répertoire que DbgHelp.dll, car DbgHelp appelle uniquement ces DLL s’ils partagent le même répertoire avec celui-ci. (Notez que DbgHelp n’appelle pas ces deux DLL à partir du chemin de recherche standard.) Cela permet d’éviter l’utilisation de DLL incompatibles ; de même, elle améliore également la sécurité globale.

Le code suivant est extrait de la source DbgHelp. Il montre comment DbgHelp charge uniquement les versions de SymSrv.dll et de SrcSrv.dll à partir du même répertoire dans lequel se trouve DbgHelp.dll.

HINSTANCE ghinst;

// For calculating the size of arrays for safe string functions.

#ifndef cch
 #define ccht(Array, EltType) (sizeof(Array) / sizeof(EltType))
 #define cch(Array) ccht(Array, (Array)[0])
#endif

//
// LoadLibrary() a DLL, using the same directory as dbghelp.dll.
//

HMODULE 
LoadDLL(
    __in PCWSTR filename
    )
{
    WCHAR drive[10] = L"";
    WCHAR dir[MAX_PATH + 1] = L"";
    WCHAR file[MAX_PATH + 1] = L"";
    WCHAR ext[MAX_PATH + 1] = L"";
    WCHAR path[MAX_PATH + 1] = L"";
    HMODULE hm;
    
    // Chop up 'filename' into its elements.
    
    _wsplitpath_s(filename, drive, cch(drive), dir, cch(dir), file, cch(file), ext, cch(ext));

    // If 'filename' contains no path information, then get the path to our module and 
    // use it to create a fully qualified path to the module we are loading.  Then load it.
    
    if (!*drive && !*dir) 
    {
        // ghinst is the HINSTANCE of this module, initialized in DllMain or WinMain
         
        if (GetModuleFileNameW(ghinst, path, MAX_PATH)) 
        {
            _wsplitpath_s(path, drive, cch(drive), dir, cch(dir), NULL, 0, NULL, 0);
            if (*drive || *dir) 
            {
                swprintf_s(path, cch(path), L"%s%s%s%s", drive, dir, file, ext);
                hm = LoadLibrary(path);
                if (hm)
                    return hm;
            }
        }
    }
    else
    {
        // If we wanted to, we could have LoadDLL also support directories being specified
        // in 'filename'.  We could pass the path here.  The result is if no path is specified,
        // the module path is used as above, otherwise the path in 'filename' is specified.
        // But the standard search logic of LoadLibrary is still avoided.
        
        /*
        hm = LoadLibrary(path);
        if (hm)
            return hm;
        */
    }
    
    return 0;
}

Après avoir chargé ces deux DLL, DbgHelp appelle GetProcAddress pour obtenir les fonctions dont elle a besoin.

Normalement, le code qui appelle DbgHelp.dll garantit que la version correcte est chargée en installant DbgHelp.dll dans le même répertoire que l’application qui a lancé le processus actuel. Si le code appelant se trouve dans une DLL et n’a pas accès à ou à la connaissance de l’emplacement du processus initial, DbgHelp.dll doit être installé en même temps que la DLL appelante et le code similaire à LoadDLL de DbgHelp doit être utilisé.

Versions de DbgHelp

LoadLibrary

GetProcAddress

GetModuleFileName