Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.045 c
1-1155092687
Avgust
2006-08-09 07:04
2006.09.24
Алгоритм запуска программы под админом


15-1157317488
ramzes2
2006-09-04 01:04
2006.09.24
как назначить родителя диалогу


11-1132361931
gdaujk
2005-11-19 03:58
2006.09.24
KOL зеркальный аналог TChart.


2-1157308104
Koka
2006-09-03 22:28
2006.09.24
HELP!


15-1157651419
Real
2006-09-07 21:50
2006.09.24
MIRANDA - погодный плагин