Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Доступ к 3-му параметру DllEntryPoint() [D5, D6, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2

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, к сожалению проверить не могу.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо