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

Вниз

Глючит глобальный хук на крысу.... ПАМАГИТЕ!   Найти похожие ветки 

 
Дремучий   (2003-05-22 11:09) [0]

вот тут описание траблы и архив с кодом
http://deep.webm.ru/forum/reply.php?num=1.2&id=14960&from=6


 
Юрий Зотов   (2003-05-22 13:48) [1]

В статье, которой Вы пользовались, есть такие строки:
"Для того, чтобы сделать эти данные общими для всех экземпляров библиотеки, HOOKSDLL помещает их в разделяемый сегмент данных. Для этого HOOKSDLL предпринимает следующие шаги...".

И далее следует код. Вы этот код при переводе на Паскаль учли?

Иными словами - как взаимодействет хук с установившей его программой? Как передаются данные?

На 99% уверен, что ошибка именно в этом. Прочитайте статью Алексея Павлова здесь же.


 
Дремучий   (2003-05-22 14:21) [2]

вот код из длл (привожу упрощенный вариант нужных кусков, полный вариант см. в архиве)
---------------------

//хук на клаву
function hook_keyb(code, wParam, lParam : integer): Lresult; stdcall;
var msg: cardinal;
begin
if code < 0
then begin
result:= CallNextHookEx(H_keyb, code, wParam, lParam);
exit;
end;

//вот и все что должен делать хук
Idle.FTime:= 0;

result:= CallNextHookEx(H_keyb, code, wParam, lParam);
end;

//хук на крысу
function hook_mouse(code, wParam, lParam : integer): Lresult; stdcall;
var msg: cardinal;
begin
if code < 0
then begin
result:= CallNextHookEx(H_mouse, code, wParam, lParam);
exit;
end;

//обнуляем время бездействия
Idle.FTime:= 0;

result:= CallNextHookEx(H_mouse, code, wParam, lParam);
end;


function SetHook: integer;
begin
H_keyb:= SetWindowsHookEx(WH_KEYBOARD, @hook_keyb, hInstance, 0);
H_mouse:= SetWindowsHookEx(WH_MOUSE, @hook_mouse, hInstance, 0);
if (H_keyb = 0)or(H_mouse = 0)
then begin
//error - не удается установить hook!
result:= 1;
exit;
end;

//небольшой объект для понта
//там будем юзать таймер и счетчик
Idle:= TIdle.Create(nil);
//hook успешно установлен!!!
result:= 0;
end;

procedure RemoveHook;
var
P: TIdle;
begin
UnhookWindowsHookEx(H_keyb);
UnhookWindowsHookEx(H_mouse);
end;


function GetIdleTime: cardinal;
begin
if Assigned(Idle)
then result:= Idle.FTime
else result:= 0;
end;

exports
SetHook index 1 name "sethook",
RemoveHook index 2 name "removehook",
GetIdleTime index 3 name "getidletime";
end.


----------------------------------------
----------------------------------------



а вот код для использования хука
---------
var
function sethook:integer; external "idlehook.dll" name "sethook";
procedure removehook; external "idlehook.dll" name "removehook";
function getidletime:cardinal; external "idlehook.dll" name "getidletime";


procedure TForm1.Button1Click(Sender: TObject);
var
res: string;
begin
Case sethook of
0: res:= "Hook успешно установлен!";
1: res:= "Не удается установить Hook!";
2: res:= "Hook уже установлен!";
End;
memo1.lines.add("Set Hook... - " + res);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
removehook;
memo1.lines.add("Remove Hook..");
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
pnIdleTime.Caption:= IntToStr(getidletime);
end;





> Для того, чтобы сделать эти данные общими для всех экземпляров
> библиотеки, HOOKSDLL помещает их в разделяемый сегмент данных.
Иными словами - как взаимодействет хук с установившей его программой? Как передаются данные?

у меня время бездействия считается в самой длл(по таймеру инкримируется счетчик), при акмвности пользователя - обнуляется(в самой длл). Сделать эти данные общими для всех экземпляров библиотеки? Дак у меня уже для одного экземляра глючит. Но все равно, если данные находятся в самой длл, как сделать их общими для всех прог(экземпляров длл)?



 
Игорь Шевченко   (2003-05-22 14:30) [3]


> Но все равно, если данные находятся в самой длл, как сделать
> их общими для всех прог(экземпляров длл)?


MMF(Memory-Mapped-File) например, использовать


 
Дремучий   (2003-05-22 14:41) [4]


> Юрий Зотов © (22.05.03 13:48)

статью почитал, спасибо.
НО...
1)Memory Mapped File мне в данном случае не очень то и нужен, ибо результат который выдаст мне длл - впринципе меня удовлетворит не зависимо от копии длл. А на будущее пригодится.
2)В примерах используется другой механиз установки хуков, т.е. хук ставится из проги, а у меня хук ставится в длл(в мсдн описано как альтернативный вариант установки хуков).Хотелось бы использовать именно его - так больше кода переноситься в длл.
3)у меня хук на клаву работает, а на мышь нет, хотя они практически идентичные. Вот это и озадачивает.



 
Дремучий   (2003-05-23 14:48) [5]

вопрос все еще не снят!


 
Юрий Зотов   (2003-05-23 16:58) [6]

Ну, что ж, теперь 99% превратились в 100. Вы действительно не учли разделение данных.

> вопрос все еще не снят!

Как так? Неужели за целые сутки Вы так и не прочли статью Алексея Павлова?

А зря.


 
Дремучий   (2003-05-23 17:04) [7]


> Юрий Зотов © (23.05.03 16:58

прочел, это написано в одном из моих постов (Дремучий © (22.05.03 14:41), который вы наверное не прочитали...
возможно я чего-то не понял, но как вы в свете статьи Павлова и моих исходников(исходники в зипе) объясните мой п.3.

3)у меня хук на клаву работает, а на мышь нет, хотя они практически идентичные. Вот это и озадачивает


 
Юрий Зотов   (2003-05-23 17:13) [8]

> Дремучий © (22.05.03 14:41)

> Memory Mapped File мне в данном случае не очень то и нужен,
Это ОЧЕНЬ большое заблуждение. Из-за него и все глюки.

> В примерах используется другой механиз установки хуков,
Без разницы. При любом способе установки данные должны быть глобальными. У Вас этого нет.

> у меня хук на клаву работает, а на мышь нет
Хук на клаву у Вас тоже не работает, только это еще не проявилось.

В общем, сделайте, как написано в статье и все заработает.


 
Дремучий   (2003-05-23 21:22) [9]


> Юрий Зотов © (23.05.03 17:13)
> > Дремучий © (22.05.03 14:41)
>
> > Memory Mapped File мне в данном случае не очень то и нужен,
> Это ОЧЕНЬ большое заблуждение. Из-за него и все глюки.

верю, что это одна из самых распостраненных ошибок...


> > В примерах используется другой механиз установки хуков,
> Без разницы. При любом способе установки данные должны быть
> глобальными. У Вас этого нет.

у меня запускается ТОЛЬКО ОДНА КОПИЯ ПРОГИ(ДЛЛ). Зачем ей глобальные данные?


> > у меня хук на клаву работает, а на мышь нет
> Хук на клаву у Вас тоже не работает, только это еще не проявилось.

сорьки, но на эту фразу я добродушно улыбнулся....
за три дня юзания беты - глюка хука клавы не увидел...
хотя, понимаю, что от него не застрахован в будущем...
:)))



> В общем, сделайте, как написано в статье и все заработает.

Ок, переделываю... И оно работает. Собственно, в работоспособности способа описанно в статье я и не сомневался, однако интересно ж было, отчего оно в моем примере глючит...
Ладушки, работает и здорово. %)))

Большой сенкс за помощь.





 
Юрий Зотов   (2003-05-23 22:12) [10]

Ох-х-х, вот же Фома Неверующий...

> у меня запускается ТОЛЬКО ОДНА КОПИЯ ПРОГИ(ДЛЛ).

Вот в этом-то и есть заблуждение. И ошибка.

Прога действительно запускается одна. А вот DLL - столько, сколько в системе существует процессов, использующих клаву или мышь. И при запуске любого такого нового процесса Ваша DLL будет подгружаться и к нему тоже. Вы же хотели поставить ГЛОБАЛЬНЫЕ хуки? Вот и поставили.

Запустите вашу прогу, пусть она загрузит хуки и спокойно себе работает. А Вы в это время в Delphi сделайте новый проект, поставьте в нем в любом месте BreakPoint и после прихода на этот BreakPoint вызовите окно Events. И в нем Вы увидите, что Ваш проект, который ни о каких хукахи ни о каких DLL не имел ни малейшего понятия, тем не менее, загрузил Вашу же DLL с хуками. Впечатляет?

Точнее, эту DLL конечно, подгрузил не проект, а сама система. Теперь ясно, чем и как обеспечивается глобальность хука? Очень просто - его DLL подгружается ко всем процессам. Отсюда и вытекает требование - глобальный хук ОБЯЗАН быть ТОЛЬКО в DLL, а не в самой программе (а вот локальный - где угодно).

При этом "размножении" DLL в каждой ее "копии" существует свой собственный блок ее данных. То есть, Ваши переменные H_keyb, H_mouse и другие. А дальше вот что.

Итак, Ваша программа загрузила DLL и вызвала SetHook. При этом проинициализировались H_keyb и H_mouse - но какие? Только те, которые существуют в контексте ВАШЕГО процесса. А потом система подгружает эту же DLL к остальным процессам - но ведь они-то никаких SetHook не вызывали, и поэтому в ИХ контексте эти переменные так и остаются непроинициализированными. То есть, в них сидит любой мусор.

Теперь скажите - а как же в этих чужих процессах сможет работать CallNextHookEx, если у нее в первом параметре сидит полная лажа? Никак. Она и не работает, только этого незаметно (до поры до времени, пока Вы не посадите Ваш хук поверх чужого и тот окажется отключенным для всех программ, кроме Вашей).

Вот Вам и ошибка (и вот почему я писал, что Ваша ловушка на клаву тоже не работает, только этого еще не проявилось).

Обычно делают еще одну такую же ошибку, пытаясь послать из хука сообщение своему окну, причем хэндл этого окна передают в ту же SetHook и запоминают внутри DLL. Ясно, что в чужих процессах этот хэндл будет битым и никакого сообщения не придет. Но у Вас более простой код, там этого нет.

Вот по всем по этим причинам переменные DLL, используемые хуком тоже должны быть ГЛОБАЛЬНЫМИ. Для этого их и помещают в Memory Mapped File, после чего они инициализипуются по-прежнему один раз, но становятся доступны в ЛЮБОМ процессе.

Уффф. Заставили-таки лекцию прочитать, настырный Вы мой. А ведь в статье Алексея все это описано, как же Вы ее так невнимательно читали-то, а?


 
Дремучий   (2003-05-24 17:04) [11]

> Юрий Зотов © (23.05.03 22:12
Юрий, огромное вам спасибо. Вы мне прояснили моменты, в которых я заблуждался. Собственно, я не знал главного:

> Прога действительно запускается одна. А вот DLL - столько,
> сколько в системе существует процессов, использующих клаву
> или мышь. И при запуске любого такого нового процесса Ваша
> DLL будет подгружаться и к нему тоже.


Мой аргумент насчет одной копии моего приложения и длл - теперь мне кажется довольно забавным. :))) Еще раз сенкс.





Страницы: 1 вся ветка

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

Наверх





Память: 0.5 MB
Время: 0.005 c
3-91629
DBDev
2003-07-04 10:27
2003.07.28
Кто-нибудь юзал TADOQuery::OnFetchProgress??? Поделитесь ...


11-91701
/-\|e}{
2002-11-21 12:49
2003.07.28
KOLGIF


14-91907
reticon
2003-07-12 00:46
2003.07.28
Что в имени твоем...


14-91859
petr_v_a
2003-07-11 12:33
2003.07.28
«Общество аплодирует» наезду на Ходорковского


4-91942
mpe
2003-05-24 19:17
2003.07.28
Как получить Handle каталога (Win98SE)?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский