ホーム
Top.Mail.Ru Yandeks.Metrika
フォーラム: "WinAPI";
現在のアーカイブ:2003.07.28;
ダウンロード:[xml.tar.bz2];

ダウン

グローバルラットフックはバグがあります.... PAMAGITE! 似ている枝を探す


Дремучий   (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 помещает их в разделяемый сегмент данных.
Иными словами - как взаимодействет хук с установившей его программой? Как передаются данные?

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




Игорь Шевченко   (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];

2階





メモリ:0.62 MB
時間:0.026 c
6-91806
アライブ
2003-05-22 07:29
2003.07.28
プログラムでIEのサーバープロキシを変更する


14-91873
パクサー
2003-07-11 17:09
2003.07.28
ばかげた質問を手伝ってください。


7-91919
フリーズ
2003-05-16 12:58
2003.07.28
Win2kでパラメーターを指定してコマンドラインを実行する方法


1-91765
tovSuhov
2003-07-14 17:26
2003.07.28
ListItemのレンダリング


9-91615
7K
2003-01-23 19:10
2003.07.28
透明なテクスチャ-まったく透明ではありません。





アフリカーンス語 アルバニア語 アラビア語 アルメニア語 アゼルバイジャン語 バスク ベラルーシ ブルガリア語 カタルーニャ語 中国語(簡体字) 中国語(繁体字) クロアチア語 チェコ語 デンマーク語 オランダ語 英語 エストニア語 フィリピン語 フィンランド語 フランス語
ガリシア語 ジョージアン ドイツ語 ギリシャ語 ハイチ語 ヘブライ語 ヒンディー語 ハンガリー語 アイスランド語 インドネシア語 アイリッシュ イタリア語 日本語 韓国語 ラトビア語 リトアニア マケドニア語 マレー語 マルタ語 ノルウェー語
ペルシア語 ポーランド語 ポルトガル語 ルーマニア語 ロシア語 セルビア スロバキア語 スロベニア語 スペイン語 スワヒリ語 スウェーデン語 タイ語 トルコ語 ウクライナ語 ウルドゥー語 ベトナム語 ウェールズ語 イディッシュ語 ベンガル語 ボスニア語
セブアノ語 エスペラント グジャラート語 ハウサ語 モン族 イボ ジャワ語 カンナダ語 クメール語 ラオ語 ラテン マオリ語 マラーティー語 モンゴル語 ネパール語 パンジャブ語 ソマリ タミル語 テルグ語 ヨルバ語
ズールー語
Английский Французский Немецкий Итальянский ポルトガル語 Русский Испанский