views:

184

answers:

1

I'm getting a crash when loading dsound.dll from another DLL in Windows 7. The following code crashes:

#include <Windows.h>
#include <mmreg.h>
#include <dsound.h>
#include <assert.h>

HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
HMODULE hDsound;
BOOL CALLBACK DSEnum(LPGUID a, LPCSTR b, LPCSTR c, LPVOID d)
{
    return TRUE;
}
void CrashTest()
{
    HRESULT hr;
    hDsound = LoadLibraryA("dsound.dll");
    assert(hDsound);
    *(void**)&pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound, "DirectSoundEnumerateA");
    assert(pDirectSoundEnumerateA);
    hr = pDirectSoundEnumerateA(DSEnum, NULL);
    assert(!FAILED(hr));
}
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);
        CrashTest();
    }
}

with this error code:

Unhandled exception at ... in ...: 0xC0000005: Access violation reading location 0x00000044.

(it's always 0x44 for some reason). It works on Windows XP or when loading directly from the .exe (not from a separate DLL). Help!?! :)

+2  A: 

You should never call LoadLibrary from DllMain. From the documentation:

The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.

Instead, you can create and export an initialization function and call it after loading the DLL.

interjay
Thanks a bunch! ;)
Jonas Byström