![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не вызывается DLLProc(DLL_PROCESS_DETACH) [D6, WinXP]
QymL © (2002-08-21 20:53:00)В DLL не могу обработать выгрузку библиотеки из процесса
Это глюк Delphi или неверный код:
library t1lib;
uses
Windows;
//uNet in "uNet.pas";
var hth:THandle;
id:CArdinal;
{$R *.res}
function go():DWord;stdcall;
var i:Cardinal;
begin
ExitThread(0);
end;
function DLLEntryPoint(dwReason: DWORD):BOOL; stdcall;
var i:Integer;
Begin
Case dwReason Of
DLL_PROCESS_ATTACH:
Begin
DisableThreadLibraryCalls(HInstance);
hth:=CreateThread(0,0,@go,0,0,id);
End;
DLL_PROCESS_DETACH:
Begin
WaitForSingleObjectEx(hth,INFINITE,true);
TerminateThread(hth,0);
CloseHandle(hth);
End
End;
Result:=true;
End;
begin
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH)
end.
QymL (2002-08-26 19:13:00) [1]Спасибо всем, кто принимал обсуждение данного вопроса.
Romkin (2002-08-26 18:16:00) [2]Мораль здесь - прежде чем переходить на новую версию ПО, дождитесь и установите сервис пак (лучше второй :-)))
или хотя бы смотрите bug report
paul_shmakov (2002-08-26 18:03:00) [3]да, только delphi 6, да и без второго сервис пака к тому же.
Digitman (2002-08-26 16:56:00) [4]Я так понял - речь идет искл-но о D6 ?
В D5 все работает вроде бы как положено
paul_shmakov (2002-08-26 16:53:00) [5]2 Romkin:
" Update Pack 2"
вот и мораль - ставьте последние service packs.
Romkin (2002-08-26 16:30:00) [6]{ Call any DllProc }
PUSH ECX
MOV ECX,[ESP+8]
TEST ECX,ECX
JE @@noDllProc
MOV EAX,[EBP+12]
MOV EDX,[EBP+16]
CALL ECX
Update Pack 2
paul_shmakov (2002-08-26 16:19:00) [7]> вот так, по счастливой случайности все работало и совсем не глючило :)
точнее: ничего не работало и совсем не глючило ;)
paul_shmakov (2002-08-26 16:15:00) [8]кстати, к вопросу о том, почему глюк раньше не обнаружили, или почему ничего не грохалось? все просто.
пока один из программистов borland не добавил команду PUSH ECX, стек выглядел следующем образом:
[ESP] - адрес возврата из процедуры _StartLib
[ESP+4] - значение переменной DllProc
потом добавили команду PUSH ECX. теперь [ECX+4] указавает туда, куда раньше указывал [ECX], т.е. на адрес возврата из процедуры _StartLib.
т.е. вызываться теперь из-за ошибки будет не наша DllProc, а процедура по "адресу возврата из _StartLib".
теперь посмотрим, а куда же указывает этот адрес возврата.
_StartLib вызывается из процедуры _InitLib (sysinit.pas).
procedure _InitLib;
asm
// ......
PUSH DllProc
MOV ECX,offset TlsProc
CALL _StartLib
end;
или на ассемблере:
// ......
PUSH DllProc
MOV ECX,offset TlsProc
CALL _StartLib
RET // !!!!!!!!!!!
строчка, отмеченная табуном восклицательных знаков - это как раз и есть тот самый адрес возврата из процедуры _StartLib.
т.е. вместо нашей DllProc вызываться будет процедура, состоящая из одной команды RET.
вот так, по счастливой случайности все работало и совсем не глючило :)
SEM (2002-08-26 15:58:00) [9]А насчет вылетания Project.exe, файл c:\aaa\bbb\test.txt создан?
Я писал это в письме.
SEM (2002-08-26 15:56:00) [10]Может быть. У меня Delphi5.
paul_shmakov (2002-08-26 15:51:00) [11]все дело в том, что QymL использует Delphi 6 Enterprise. я только что обнаружил баг в его system.pas (размер файла 491801), который и приводит к тому, что DllProc не вызывается.
procedure _StartLib
//...
{ Call any DllProc }
PUSH ECX
MOV ECX,[ESP+4] // Вот здесь должно быть [ESP+8]
TEST ECX,ECX
JE @@noDllProc
MOV EAX,[EBP+12]
MOV EDX,[EBP+16]
CALL ECX
@@noDllProc:
//...
похоже, что сохранение регистра ECX они добавили позже, но совсем забыли, что нужно поправить и смещение параметра DllProc, изначально лежащего в [ESP+4], на [ESP+8].
Так что, если у вас еще не исправлено (может какой service pack это дело исправляет), то правьте руками.
2 QymL: я послал по почте версию вашей dll, в которой эторт байт исправлен - все работает.
SEM (2002-08-26 15:49:00) [12]1.Вылетает сразу после нажатия Button1?
2.Какая ОС?
QymL (2002-08-26 15:03:00) [13]
> SEM © (26.08.02 14:18)
Project1.exe просто вылетает и все
SEM (2002-08-26 14:18:00) [14]Кинул.
QymL (2002-08-26 14:04:00) [15]
> SEM
Кинь мне на мыло или в форум
SEM (2002-08-26 14:00:00) [16]При желании, могу кинуть исходники твоего кода :)
Кстати, там я вывожу messagebox на DLL_PROCESS_DETACH.
SEM (2002-08-26 13:49:00) [17]Ну да.
QymL (2002-08-26 13:07:00) [18]
> SEM © (22.08.02 13:32)
> Первоначальный пример заработал при замене ExitThread на
> TerminateThread. Соответственно, на старом месте TerminateThread
> необходимо убрать.
Первоначальный - это мой ?
SEM (2002-08-26 11:27:00) [19]win2000Prof
QymL (2002-08-24 14:33:00) [20]Может кто уже сталкивался и есть решение этой проблемы?
> SEM
В какой ОС?