Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi DllMain DLL_PROCESS_DETACH called before DLL_PROCESS_ATTACH

I'm having a lot of trouble dealing with a DLL I've written in Delphi. I've set up a DllMain function using the following code in the library:

begin
  DllProc := DllMain;
end.

My DllMain procedure looks like this:

procedure DllMain(reason: Integer);
begin
  if reason = DLL_PROCESS_DETACH then
    OutputDebugString('DLL PROCESS DETACH')
  else if reason = DLL_PROCESS_ATTACH then
    OutputDebugString('DLL PROCESS ATTACH')
  else if reason = DLL_THREAD_ATTACH then
    OutputDebugString('DLL THREAD ATTACH')
  else if reason = DLL_THREAD_DETACH then
    OutputDebugString('DLL THREAD DETACH')
  else
    OutputDebugString('DllMain');
end;

What I'm finding is that DETACH seems to be called (twice?!) by a caller (that I don't control) before ATTACH is ever called. Is that even possible, or am I misunderstanding how this is supposed to work? My expectation would be that every ATTACH call would be met with a matching DETACH call, but that doesn't appear to be the case.

What's goin' on here?!

like image 230
aardvarkk Avatar asked Apr 30 '12 00:04

aardvarkk


1 Answers

Unfortunately when begin is executed in your dll code, the OS has already called DllMain in your library. So when your DllProc := DllMain; statement executes it is already too late. The Delphi compiler does not allow user code to execute when the dll is attached to a process. The suggested workaround (if you can call that a workaround) is to call your own DllMain function yourself in a unit initalization section or in the library code:

begin
  DllProc := DllMain;
  DllMain(DLL_PROCESS_ATTACH);
end;

The relevant documentation:

Note: DLL_PROCESS_ATTACH is passed to the procedure only if the DLL's initialization code calls the procedure and specifies DLL_PROCESS_ATTACH as a parameter.

like image 122
Sertac Akyuz Avatar answered Nov 12 '22 21:11

Sertac Akyuz