valkyrie
valkyrie

Reputation: 61

CreateThread in DLL Terminating Prematurely

I am trying to load a DLL from Console Application. The simple console application is shown below:

#include <iostream>
#include <windows.h>

int main(){
    HMODULE handleDll = LoadLibraryA("C:\\Tools\\TestDLL.dll");
    if (handleDll)
    {
        std::cout << "DLL Loaded at Address: " << handleDll << std::endl;
    }

    FreeLibrary(handleDll);
}

The DLL is supposed to a POP a MessageBox which it does but just flashes on the screen instead of waiting for user input. The DLL code is below:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>

DWORD WINAPI ThreadProc( __in  LPVOID lpParameter )
{
    MessageBox(NULL, L"Hi From The Thread!", L"Pop a Box!", MB_OK);
    return 0;
}

extern "C" __declspec(dllexport) 
VOID PopMessageBox()
{
    DWORD ThreadID;
    HANDLE handleThread; 

    handleThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadID);
    CloseHandle(handleThread);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        PopMessageBox();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

My question is..how do I make the code in the thread function fully execute without prematurely terminating or causing painful deadlocks? Apologies for my imperfect English and inexperience.

Upvotes: 2

Views: 527

Answers (1)

Nik Bougalis
Nik Bougalis

Reputation: 10613

The reason is that you are doing something unsafe in your DllMain: you are calling CreateThread.

You are very limited in what you can do from within DllMain in response to a process attach, a fact that the documentation calls out:

There are significant limits on what you can safely do in a DLL entry point. See General Best Practices for specific Windows APIs that are unsafe to call in DllMain. If you need anything but the simplest initialization then do that in an initialization function for the DLL. You can require applications to call the initialization function after DllMain has run and before they call any other functions in the DLL.

The warning links you to "General Best Pratices" which, among other things, says to "[c]all CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky."

Even without the risks associated with synchronizing with other threads, this code is flakey in other ways: for example, your main simply calls FreeLibrary and exits. The thread you had spawned in the DLL, which may literally be mid-execution, will have the code it's supposed to run unmapped. You're literally pulling the rug out from under it!

Upvotes: 0

Related Questions