How can my DLL detect whether it was loaded implicitly or explicitly?
Example MyTestDll.dll
library MyTestDll;
uses SimpleShareMem, Windows, Dialogs;
procedure DetectMethodDllLoad: bool;
begin
// ?????
// need to detect loading method - implicit or explicit
end;
procedure MyTest; stdcall;
begin
if DetectMethodDllLoad then
ShowMessage('Working Program1 (implicit dll load)')
else
ShowMessage('Working Program2 (explicit dll load)');
end;
exports MyTest;
begin
end.
Program1.exe (implicit dll load)
procedure MyTest; stdcall; external 'MyTestDll.dll' Name 'MyTest';
procedure TForm1.Button1Click(Sender: TObject);
begin
MyTest;
end;
Program2.exe (explicit dll load)
type
TMyTest = procedure; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
MyTest: TMyTest;
H: HModule;
begin
H := LoadLibrary('MyTestDll.dll');
if H = 0 then
exit;
@MyTest := GetProcAddress(H, 'MyTest');
if Assigned(MyTest) then
MyTest;
FreeLibrary(H);
end;
How can I implement DetectMethodDllLoad
?
If you can create a DllMain procedure, the lpReserved parameter for the DLL_PROCESS_ATTACH call will tell you whether the load is static or dynamic.
http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx
You could certainly do this in C. I don't know whether it is possible in Delphi.
Here is a very good tutorial with the 2 methods, static and dynamic:
Static vs. Dynamic Dynamic Link Library Loading - A Comparison
Thanks Harry Johnston!!! :)
library MyTestDll;
uses SimpleShareMem, Windows, Dialogs;
type
PDllEntryPointFrame = ^TDllEntryPointFrame;
TDllEntryPointFrame = packed record
hModule: THandle; // DLL module handle
dwReason: DWord; // reason for calling DLLEntryPoint function of DLL
bStatic: LongBool; // TRUE if DLL is loading/unloading satically, FALSE - dinamically
end;
function DetectMethodDllLoad: bool;
asm
mov edx, [hInstance]
mov eax, ebp
@@nextframe:
cmp [eax + $08].TDllEntryPointFrame.hModule, edx
je @@found
mov eax, [eax]
jmp @@nextframe
@@found:
mov eax, [eax + $08].TDllEntryPointFrame.bStatic
end;
procedure MyTest; stdcall;
begin
...
end;
exports MyTest;
begin
if DetectMethodDllLoad then
ShowMessage('Working Program1 (implicit dll load)')
else
ShowMessage('Working Program2 (explicit dll load)');
end.
P.s. System.TDLLProcEx not working in Delphi XE!
library MyTestDll;
....
procedure MyDLLProcEx(Reason:integer;x:pointer);
begin
if x=nil then showmessage('dyn') else showmessage('stat');
end;
begin
DLLProcEx:=@MyDLLProcEx;
end;
x = nil always :(