Udostępnij przez


Wywoływanie biblioteki DbgHelp

Mimo że DbgHelp.dll jest dostarczane ze wszystkimi wersjami systemu Windows, użytkownicy powinni rozważyć użycie jednej z nowszych wersji tej biblioteki DLL, które można znaleźć w pakiecie Narzędzia Debugowania Dla Systemu Windows. Aby uzyskać szczegółowe informacje na temat dystrybucji dbgHelp, zobacz DbgHelp Versions (Wersje dbgHelp).

W przypadku korzystania z narzędzia DbgHelp najlepszą strategią jest zainstalowanie kopii biblioteki z pakietu Debugowanie narzędzi dla systemu Windows w katalogu aplikacji logicznie sąsiadującego z oprogramowaniem, które go wywołuje. Jeśli serwer symboli i serwer źródłowy są również potrzebne, zarówno SymSrv.dll, jak i SrcSrv.dll muszą być zainstalowane w tym samym katalogu co DbgHelp.dll, ponieważ dbgHelp wywoła te biblioteki DLL tylko wtedy, gdy współużytkują z nim ten sam katalog. (Pamiętaj, że dbgHelp nie wywoła tych dwóch bibliotek DLL ze standardowej ścieżki wyszukiwania). Pomaga to zapobiec użyciu niezgodnych bibliotek DLL; podobnie zwiększa ona również ogólne bezpieczeństwo.

Poniższy kod jest wyodrębniany ze źródła DbgHelp. Pokazuje on, w jaki sposób dbgHelp ładuje tylko wersje SymSrv.dll i SrcSrv.dll z tego samego katalogu, w którym znajduje się 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;
}

Po załadowaniu tych dwóch bibliotek DLL dbgHelp wywołuje metodę GetProcAddress w celu uzyskania potrzebnych funkcji.

Zwykle kod wywołujący DbgHelp.dll gwarantuje, że poprawna wersja jest ładowana przez zainstalowanie DbgHelp.dll w tym samym katalogu co aplikacja, która zainicjowała bieżący proces. Jeśli kod wywołujący znajduje się w bibliotece DLL i nie ma dostępu do lokalizacji początkowego procesu ani informacji o nim, należy zainstalować DbgHelp.dll obok wywołującej biblioteki DLL i użyć kodu podobnego do funkcji LoadDLL z DbgHelp.

DbgHelp Versions

LoadLibrary

GetProcAddress

GetModuleFileName