Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];

Вниз

Странная проблема с Хуком   Найти похожие ветки 

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.045 c
1-1155530573
karton
2006-08-14 08:42
2006.09.24
Компоненты для экспорта из FastReport


2-1157350865
vegarulez
2006-09-04 10:21
2006.09.24
По поводу фискальных регистраторов.


15-1157020136
Layner
2006-08-31 14:28
2006.09.24
Посоветуйте рыбок для аквариума на работе


2-1157169755
Viktop
2006-09-02 08:02
2006.09.24
Отправка SMS на Биллайн


2-1157272621
Начинающие БД-шник
2006-09-03 12:37
2006.09.24
Помогите!!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский