![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Доступ к 3-му параметру DllEntryPoint() [D5, D6, Win95/98, WinME, NT4, Win2k, WinXP]
Digitman © (2002-09-12 08:21:00)BOOL WINAPI DllEntryPoint(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
);
lpvReserved
Specifies further aspects of DLL initialization and cleanup.
If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads.
If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllEntryPoint has been called by using FreeLibrary and non-NULL if DllEntryPoint has been called during process termination.
Оч простой вопрос :
Каким образом, не меняя контекст system.pas и sysinit.pas, получить доступ по чтению к параметру lpvReserved в момент, когда код инициализации/деинициализации DLL (генерируемой средствами Делфи) получает управление ?
Интересны простые и изящные идеи, обеспечивающие надежное решение задачи для указанных ОС и версий Делфи.
Digitman (2002-09-12 11:31:00) [21]быть бы уверенным, что и в полсед.версиях смещение будет равно +16 - нет проблем, конечно, достать из стека ...
Ученик (2002-09-12 11:17:00) [22]>Digitman ©
Из стэка уже достали ?
Игорь Шевченко (2002-09-12 11:14:00) [23]Digitman © (12.09.02 11:11)
Извиняюсь, не углядел, что вызываемая по DLLProc процедура имеет fastcall calling convention.
Спасибо за науку :-)
С уважением,
Digitman (2002-09-12 11:11:00) [24]>Игорь Шевченко
да вот не получается, Игорь, как ты имеешь честь скромно предполагать)
Вот смотри - явно же видна разница :
D5:
@@noTLSproc:
{ Call any DllProc }
MOV EDX,[ESP+4]
TEST EDX,EDX
JE @@noDllProc
MOV EAX,[EBP+12] //Reason - как положено : 1-м параметром в EAX
CALL EDX // 2-й параметр д.б. в EDX, а этот РОН использован для иной цели - как CALL-диспетчер
D6:
{ Call any DllProc }
PUSH ECX
MOV ECX,[ESP+8]
TEST ECX,ECX
JE @@noDllProc
MOV EAX,[EBP+12] //Reason - 1-м параметром в EAX
MOV EDX,[EBP+16] //Reserved - 2-м параметром в EDX
CALL ECX //порядок ! оба параметра доступны в теле DLLProc
Игорь Шевченко (2002-09-12 10:20:00) [25]IMHO, анализируя код, похоже, что переданные параметры передаются в DLLProc без изменения, как в D5, так и в D6
Ученик (2002-09-12 09:24:00) [26]procedure _InitLib;
asm
{ -> EAX Inittable }
{ [EBP+8] Hinst }
{ [EBP+12] Reason }
{ [EBP+16] Resvd }
MOV EDX,offset Module
CMP dword ptr [EBP+12],DLL_PROCESS_ATTACH
JNE @@notInit
PUSH EAX
PUSH EDX
MOV ModuleIsLib,1
MOV ECX,[EBP+8]
MOV HInstance,ECX
MOV [EDX].TLibModule.Instance,ECX
MOV [EDX].TLibModule.CodeInstance,0
MOV [EDX].TLibModule.DataInstance,0
CALL InitializeModule
POP EDX
POP EAX
@@notInit:
PUSH DllProc
MOV ECX,offset TlsProc
CALL _StartLib
end;
procedure _StartLib;
asm
{ -> EAX InitTable }
{ EDX Module }
{ ECX InitTLS }
{ [ESP+4] DllProc }
{ [EBP+8] HInst }
{ [EBP+12] Reason }
{ Push some desperately needed registers }
PUSH ECX
PUSH ESI
PUSH EDI
{ Save the current init context into the stackframe of our caller }
MOV ESI,offset InitContext
LEA EDI,[EBP- (type TExcFrame) - (type TInitContext)]
MOV ECX,(type TInitContext)/4
REP MOVSD
{ Setup the current InitContext }
POP InitContext.DLLSaveEDI
POP InitContext.DLLSaveESI
MOV InitContext.DLLSaveEBP,EBP
MOV InitContext.DLLSaveEBX,EBX
MOV InitContext.InitTable,EAX
MOV InitContext.Module,EDX
LEA ECX,[EBP- (type TExcFrame) - (type TInitContext)]
MOV InitContext.OuterContext,ECX
XOR ECX,ECX
CMP dword ptr [EBP+12],0
JNE @@notShutDown
MOV ECX,[EAX].PackageInfoTable.UnitCount
@@notShutDown:
MOV InitContext.InitCount,ECX
MOV EAX, offset RaiseException
MOV RaiseExceptionProc, EAX
MOV EAX, offset RTLUnwind
MOV RTLUnwindProc, EAX
CALL SetExceptionHandler
MOV EAX,[EBP+12]
INC EAX
MOV InitContext.DLLInitState,AL
DEC EAX
{ Init any needed TLS }
POP ECX
MOV EDX,[ECX]
MOV InitContext.ExitProcessTLS,EDX
JE @@skipTLSproc
CMP AL,3 // DLL_THREAD_DETACH
JGE @@skipTLSproc // call ExitThreadTLS proc after DLLProc
CALL dword ptr [ECX+EAX*4]
@@skipTLSproc:
{ Call any DllProc }
PUSH ECX
MOV ECX,[ESP+8]
TEST ECX,ECX
JE @@noDllProc
MOV EAX,[EBP+12]
MOV EDX,[EBP+16]
CALL ECX
@@noDllProc:
POP ECX
MOV EAX, [EBP+12]
CMP AL,3 // DLL_THREAD_DETACH
JL @@afterDLLproc // don"t free TLS on process shutdown
CALL dword ptr [ECX+EAX*4]
@@afterDLLProc:
{ Set IsLibrary if there was no exe yet }
CMP MainInstance,0
JNE @@haveExe
MOV IsLibrary,1
FNSTCW Default8087CW // save host exe"s FPU preferences
@@haveExe:
MOV EAX,[EBP+12]
DEC EAX
JNE _Halt0
CALL InitUnits
RET 4
end;
Digitman (2002-09-12 09:19:00) [27]>Ученик
Не будет это работать в D5.
@@noTLSproc:
{ Call any DllProc }
MOV EDX,[ESP+4]
TEST EDX,EDX
JE @@noDllProc
MOV EAX,[EBP+12]
CALL EDX
А как это реализовано в D6 ?
Приведи, пожалуйста, полный код _StartLib, у меня нет под руеой Д6
Ученик (2002-09-12 08:55:00) [28]Есть подозрение, что DllProc нужно присвоить адрес процедуры
procedure MyDLLProcEx(Reason: Integer; Reserved: Integer);
begin
end;
В Delphi 6 переменная называется
{ DllProcEx passes the Reserved param provided by WinNT on DLL load & exit }
DllProcEx: TDLLProcEx absolute DllProc;
Для Delphi 5 переменной нет, но возможно будет работать для DllProc, к сожалению проверить не могу.