Текущий архив: 2006.09.24;
Скачать: CL | DM;
ВнизСтранная проблема с Хуком Найти похожие ветки
← →
Nostradamus (2006-05-18 17:37) [0]Я использую в своей программе хук WH_CALLWNDPROCRET.
Заметил странный побочный эффект: если запустить определённую программу (на пример IE), потом мою и потом закрыть IE, то он (IE) крэшится.
Вот хук:
library hookshell;
uses
Windows, Messages;
const
MapID = "CALLWND_Hook";
type
PData = ^TData;
TData = record
AppWnd: HWND;
OldHook: HHOOK;
end;
var
HMap: THandle = 0;
Data: PData = nil;
procedure DLLEntryPoint(dwReason: Integer);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
HMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TData), MapID);
Data := MapViewOfFile(HMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TData));
end;
DLL_PROCESS_DETACH:
begin
UnMapViewOfFile(Data);
CloseHandle(HMap);
end;
end;
end;
function ShellHook(Code: Integer; ParamW: WPARAM; ParamL: LPARAM): LRESULT; stdcall;
var
WS : CWPRETSTRUCT;
begin
if Code < 0 then
Result := CallNextHookEx(Data^.OldHook, Code, ParamW, ParamL)
else begin
if Code = HC_ACTION then begin
WS := CWPRETSTRUCT(Pointer(ParamL)^);
if (WS.message = WM_ACTIVATE) OR (WS.message = WM_SETFOCUS) OR (WS.message = WM_SHOWWINDOW) then
SendMessage(Data^.AppWnd, WM_USER, WS.message, ParamL);
end;
Result := CallNextHookEx(Data^.OldHook, Code, ParamW, ParamL) //если сдесь сделать Result := 0, то побочный эффект не происходит
end;
end;
function SetShellHook(Wnd: HWND): BOOL; stdcall;
begin
if Data <> nil then
begin
Data^.AppWnd := Wnd;
Data^.OldHook := SetWindowsHookEx(WH_CALLWNDPROCRET, @ShellHook, HInstance, 0);
Result := Data^.OldHook <> 0
end
else Result := False;
end;
function RemoveShellHook: BOOL; stdcall;
begin
Result := UnhookWindowsHookEx(Data^.OldHook);
end;
exports
SetShellHook,
RemoveShellHook;
begin
DllProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Что интересно, если не возвращать результат CallNextHookEx, то этот феномен не наблюдается.
Подскажите, пожалуйста, в чём может быть проблема.
← →
Сергей М. © (2006-05-19 13:19) [1]А нафига ты допускаешь 2 раза вызов CallNextHookEx() ?
Первый раз - при условии Code < 0, второй - вообще безусловно ..
Для начала убери безусловный вызов !
← →
Сергей М. © (2006-05-19 13:23) [2]Извиняюсь, я не прав.
Но тем не менее MSDN рекомендует вызывать CallNextHookEx() только при условии Code < 0
← →
Игорь Шевченко © (2006-05-19 13:39) [3]
> Но тем не менее MSDN рекомендует вызывать CallNextHookEx()
> только при условии Code < 0
Вообще-то во всех случаях рекомендует вызывать
"Calling CallNextHookEx is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications"
← →
Nostradamus (2006-05-19 16:16) [4]В том то и дело, что делаю всё, так сказать, по учебнику...
Конечно может быть, что программы у которых наблюдается такой эффект криво написаны, но странно что их есть N и от разных производителей.
Этот эффект наблюдается с: MS IE 6, MS Outlook, Skype 2, Babylon
Одним словом, пока установил Result := 0, чтоб заказчик не морочил голову, но мне это решение очень не нравится :(
← →
Leonid Troyanovsky © (2006-05-19 18:09) [5]
> Nostradamus (18.05.06 17:37)
Проблемы, видимо, с теми (многопоточными?) приложениями,
которые сами используют хуки, т.е., во взаимодействии с оными.
По всей видимости, порядок имеет значение, и стоит, IMHO,
попробывать включить вызов RemoveShellHook в обработчик
DLL_PROCESS_DETACH.
Ну, а для избежания повторного UnHook после Remove
обнулять OldHook (с проверкой в хуковой процедуре).
--
Regards, LVT.
← →
Nostradamus © (2006-05-20 03:41) [6]Спасибо за советы, обязательно ими воспользуюсь
← →
Nostradamus © (2006-05-23 21:49) [7]Я использовал совет Leonid Troyanovsky © (19.05.06 18:09) [5] и добавил UnhookWindowsHookEx(Data^.OldHook); в DLL_PROCESS_DETACH и после того как я запускал какое-то приложение паралельно моему и закрывал его, то код в DLL_PROCESS_DETACH выполнялся (не смотря на то, что я не вызывал DLLEntryPoint и моя программа работала дальше). У меня такое ощущение, что моя DLL подгружается другими приложениями...
Единственное объяснение, которое мне приходит в голову, это тот факт, что у меня в самой программе вызывается AttachThreadInput. Я предполагаю, что именно те программы к которым атачится мой процесс и подгружают ДЛЛ.
Вопрос теперь в том как это предотвратить???
← →
Leonid Troyanovsky © (2006-05-24 18:20) [8]
> Nostradamus © (23.05.06 21:49) [7]
> DLL_PROCESS_DETACH и после того как я запускал какое-то
> приложение паралельно моему и закрывал его, то код в DLL_PROCESS_DETACH
> выполнялся (не смотря на то, что я не вызывал DLLEntryPoint
> и моя программа работала дальше). У меня такое ощущение,
> что моя DLL подгружается другими приложениями...
Что-то не очень понятно.
Сначала ты устанавливаешь глобальный хук (на все потоки,
последний параметр 0), а после удивляешься тому,
что твоя бибиотека загружается другими процессами.
Если тебя интересует конкретный поток, задай его threadId,
получить который можно, например, GetWindowThreadProcessId.
--
Regards, LVT.
Страницы: 1 вся ветка
Текущий архив: 2006.09.24;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.045 c