Консультация № 161236
24.02.2009, 04:27
0.00 руб.
0 4 1
Доброго времени суток. Есть проблема с установкой хуков на событие WM_RBUTTONDOWN да и в прочем на другие тоже.
Хук вешается из динамически подгружаемой библиотеки.
После нажатия Button1 (сообщение Start получено) и выполнения события WM_RBUTTONDOWN (т.е нажатия правой кнопки мыши непосредственно на десктопе) происходит следующее:
1. Вылезает 2 окошка "ОК", которые правда сопроваждаются далеко не 2мя "биканиями" появления окошка;
2. Компилятор Delphi 2007 виснет, но это не мешает окошкам "ОК" исправно спаунится уже в единичном кол-ве по RMB;
3. Vista успешно отдаёт концы, убив сперва Explorer.

Без WM_RBUTTONDOWN хуки подгружаются и выгражаются стабильно.
Снабжение кода сотней эксепшонов проблему не решает и не выявляет.





Приложение:
//Библиотека:

Код:
library mydll;

uses
Windows,
Messages;

var
M_Hook: HWND;

function my_proc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
begin

if (code = HC_ACTION) and (wparam = WM_RBUTTONDOWN)
then MessageBox(0, 'OK', 'OK', 0);

Result:= CallNextHookEx(M_Hook, Code, wParam, lParam);
end;

procedure hook(flag: Boolean) export; stdcall;
begin
if flag
then
begin
M_Hook := SetWindowsHookEx(WH_Mouse, @my_proc, HInstance, 0);
if M_Hook <> 0
then MessageBox(0, 'Start', 'Start', 0)
else MessageBox(0, 'F*CK!!!', 'F*CK!!!', 0);
end
else
begin
if UnhookWindowsHookEx(M_Hook)
then MessageBox(0, 'Stop', 'Stop', 0)
else MessageBox(0, 'F*CK!!!', 'F*CK!!!', 0);
end;
end;



exports hook;

begin
end.


//Тело программы:

Код:

type
My_Proc = procedure (flag : Boolean); stdcall;

//-----//

var
Form2: TForm2;
Hwnd_dll : HWND;


implementation

{$R *.dfm}


procedure TForm2.Button1Click(Sender: TObject);
var
hook: My_Proc;
begin
@hook:= nil;
Hwnd_dll:= LoadLibrary(PChar('mydll.dll'));
@hook:=GetProcAddress(Hwnd_dll, 'hook');
hook(true);
end;

procedure TForm2.Button2Click(Sender: TObject);
var
hook: My_Proc;
begin
@hook:= nil;
@hook:=GetProcAddress(Hwnd_dll, 'hook');
hook(false);
end;


procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeLibrary(Hwnd_dll);
end;

Обсуждение

Неизвестный
24.02.2009, 06:59
общий
это ответ
Здравствуйте, Тишкин И.О!

Нету под рукой у меня дельфи. Да и не доверяю я борланду…

> 1. Вылезает 2 окошка "ОК", которые правда сопроваждаются далеко не 2мя "биканиями" появления окошка;
Для начала надо бы ещё делать вот это:

MSDN: If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
то есть проверку
if(nCode < 0) return CallNextHookEx(…);

Потом, надо бы посмотреть, в каких процессах или на каких окнах наш хук сдетанировал. То есть вместо Ок-Ок надо выводить MOUSEHOOKSTRUCT::hWnd и GetCurrentThreadId() или GetCurrentProcessId()

> 2. Компилятор Delphi 2007 виснет, но это не мешает окошкам "ОК" исправно спаунится уже в единичном кол-ве по RMB;
Дельфи прописывает dll-ку в очередь хуков. После этого, оно может виснут скоко хочет - dll-ка будет работать уже в _чужих_ процессах…

> 3. Vista успешно отдаёт концы, убив сперва Explorer.
Первое, что в голову приходит - експлорер дохнет при попытке обратиться к dll-ке хука(которой уже нету в памяти?). Убить хуком эксплорер - проще простого
достаточно послать внутри него сообщение, требующее каких нибудь данных по битому адресу.

Раз бибиканий много а окон мало - возможно, вызов хука зациклился.
А ещё можно после хуков посмотреть ProcessExplorer-ом на процессы, где ваша dll-ка засела.
Вобщем, информации маловато, надо бы ещё покопать.
Неизвестный
24.02.2009, 10:40
общий
Я бы "немного" не точен. Оказалось, что окошек там ровно 26 (всегда).
То что там появляется после выполнения события трудно описать... это похоже на убитую до нельзя менюшку, которая появляется после нажатия правой кнопки мыши на десктопе. Убитость заключается в том, что там нет текста, но есть кнопки и выпадающие списки (вид, сортировка, обновить и.т.д, но без текста).

Похоже что хук тут не причём. Проблема появляется из-за того, что происходит 26 нажатий правой кнопки мыши, а не одно. Отбросил мышку и эмулировал нажатие RMB, но это ни к чему не привело.

Манипуляции с nCode приводят только к отключению реакции системы на кнопки мыши. Не знаю как nCode у хук-процедуры может быть меньше 0, если все константы-параметры определены от 0 и до 5.

Все хук-процедуры сработали конечно же на процессе explorer.exe, одного и того же потока :)

Наверно нужно изыскать способ "нормальной" передачи управления после выполнения хука...
Неизвестный
24.02.2009, 10:53
общий
> Все хук-процедуры сработали конечно же на процессе explorer.exe, одного и того же потока :)
И откуда там "Все"? 26 штук откуда получаются?

Ну, кстати, можно для отладки вместо MessageBox-а воспользоваться логами (причём имя создавать в зависимости от потока, куда прицепились, чтоб не было одновременной попытки открыть один файл несколькими хуками… ну или какой другой приём уникальности)

И всё-таки что-то тут нечисто…Не должно быть там 26 отработок хука... Либо дело как раз в MessageBox-ах... Что показывает отладка по hWnd которым летело сообщение? Я в при отладке MessageBox не использую как раз по причине его передёргиваний окон.

Кстати, а если попробовать WH_MOUSE_LL тип хука?
Неизвестный
24.02.2009, 11:28
общий
Проблема действительно была в MessageBox! Добавил логи и получил согласно им всего 1 выполнение хук-процедуры.... спасибо! Будем обходить меседжбоксы стороной)
Форма ответа