![]() |
| ||
|
|
Новости |
Поиск |
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 (генерируемой средствами Делфи) получает управление ?
Интересны простые и изящные идеи, обеспечивающие надежное решение задачи для указанных ОС и версий Делфи.
msts (2002-09-13 16:34:00) [1]У меня сообщение показывается
только без обработки ввода - прорисовывается и сразу закрывается
видимо процесс выгрузки независим от GUI и пока он незавершен
то сообщение видимо а как только достигнул определенной стадии
(например библиотека какая то выгружается) исчезает
заметно когда много BPL-ек используется (в данном случае штук 30)
paul_shmakov (2002-09-13 14:46:00) [2]лучше OutputDebugString для таких вещей использовать
Ученик (2002-09-12 19:09:00) [3]>Digitman © (12.09.02 18:58)
Здесь нет Dialogs, ShowMessage, и так далее :-), сообщения выводятся средствами Windows API,
только если указан MB_SERVICE_NOTIFICATION, оно показывается по другому, почему не показывается в первом случае так и не понятно.
Digitman (2002-09-12 18:58:00) [4]Отсюда - вывод : предположение неверно.
значит, что-то в Dialogs ...
Ученик (2002-09-12 18:39:00) [5]Попробовал MessageBox(0, "F Static", "Info", MB_OK + MB_SERVICE_NOTIFICATION); сообщение в этом случае показывается
Digitman (2002-09-12 17:41:00) [6]>Игорь Шевченко
Я тоже сомневаюсь. Но, тем не менее, факт остается фактом и , значит, причина в чем-то другом. Без трассировки это сложно сказать
Игорь Шевченко (2002-09-12 17:27:00) [7]Digitman © (12.09.02 16:57)
Ученик © (12.09.02 17:08)
Есть список InitializationOrderList в PEB^.LoaderData - там можно посмотреть, кто в какой последовательности инициализировался. Выгрузка происходит в обратном порядке (IMHO).
Но я сомневаюсь, что user32 деинициализируется раньше, чем клиентская DLL.
С уважением,
Digitman (2002-09-12 17:27:00) [8]> Ученик
Если не лень, оттрассируй пошагово неработающий MessageBox() в данной ситуации - мне тоже интересно...
Ученик (2002-09-12 17:08:00) [9]>Digitman © (12.09.02 16:57)
Здесь Windows.MessageBox, но скорее всего действительно вывод гасится, хотя почему бы не сообщать об Exception-ах, которые происходят при выгрузке
Digitman (2002-09-12 16:57:00) [10]>Ученик
ShowMessage() в модуле Dialogs требует как миниму наличия невыгруженного и не деинициализированного еще модуля USER32.DLL в АП хост-процесса. И вполне возможно, что при стат. деинициализации/выгрузке системой модулей, загруженных ранее статически, модуль USER32.DLL деинициализируется системой несколько раньше обращения к нему со стороны кода в Dialogs, поэтому окно не выводится, а потенциальнеые ошибки обращения к USER32 мягко "гасятся" системой : на кой черт, спрашивается, ей чего-то сообщать юзеру, если процесс завершен и приложение все равно выгружается вместе со всеми "потрохами" ?
Хотя ... предположение (о порядке деинициализации/выгрузке взаимозависимых модулей) проверить, конечно, следовало бы ...
Ученик (2002-09-12 16:10:00) [11]>Ученик © (12.09.02 15:56)
Диагноз верен, сообщения в файл выводятся, с MessageBox непонятки
Ученик (2002-09-12 15:56:00) [12]>Digitman © (12.09.02 15:29)
initialization
if IsLibrary then begin
if IsStaticDLLCall then
MessageBox(0, "I Static", "Info", MB_OK)
else
MessageBox(0, "I Dynamic", "Info", MB_OK)
end
finalization
if IsLibrary then begin
if IsStaticDLLCall then
MessageBox(0, "F Static", "Info", MB_OK)
else
MessageBox(0, "F Dynamic", "Info", MB_OK)
end
end
FreeLibrary(LoadLibrary("DllTest.dll"));
Два сообщения
function ExportString : PChar; stdcall; external "DllTest.dll";
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(ExportString)
end
Одно сообщение на загрузке,
Может конечно вызывается, но окно не показывается, интересно почему.
Digitman (2002-09-12 15:29:00) [13]>Ученик
>>При статической похоже final не вызывается
быть того не может)
ну да ладно, это уже не столь важно..
главное, что стековые манипуляции (в интересующем меня плане) оказываются идентичными в модулях system и sysinit начиная с D5 и вплоть до D7.
Благодарю за помощь и содействие !
Ученик (2002-09-12 15:22:00) [14]>Digitman © (12.09.02 15:14)
При динамической работает в секциях init/final
При статической похоже final не вызывается
Digitman (2002-09-12 15:14:00) [15]>Ученик
А в разделах init/final - тоже работает ? Или не пробовал ?
Ученик (2002-09-12 14:48:00) [16]Шутка
procedure Test(I1, I2, I3, I4 : Integer);
begin
if IsStaticDLLCall then
MessageBox(0, "Static", "Info", MB_OK)
else
MessageBox(0, "Dynamic", "Info", MB_OK)
end;
begin
Test(HInstance, HInstance, HInstance, HInstance)
end.
Ученик (2002-09-12 14:29:00) [17]Сорри, не туда вставил, все работает
Ученик (2002-09-12 14:25:00) [18]Delphi 7, Windows 2000, не работает (AV), статическая загрузка DLL
Digitman (2002-09-12 14:08:00) [19]Господа, будьте любезны, проверьте этот код у себя :
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 IsStaticDLLCall: Boolean;
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;
результат вызова ф-ции контекстом исполняемого внутри DLL кода показывает, как было осуществлено обращение к DLL из хост-процесса для загрузки/выгрузки - статически или динамически
код вроде бы устойчиво работает (в D5) и в dpr дельфийской библиотеки и в разделах initialization/finalization любого из ее модулей
хотелось бы проверить это в Д6/Д7
Ученик (2002-09-12 11:43:00) [20]В последних версиях $IFDEF VERXXX и DllProcEx