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

Вниз

Помогите с hook ом клавиатуры.   Найти похожие ветки 

 
axx   (2005-04-14 11:51) [0]

Проблема в следующем цепляю библиотеку (см. ниже) к своей программе стоит минуту а потом вылетает (Память не может быть рид. и тд и тп). Отцепляю библиотеку все нормально работает.
Не вижу я тут ошибки - может плохо смотрю ????
Если кто видит ткните плиз пальцем :-) а то уже второй день сижу над этим.
--------------------------------
library KeyLHook;
uses Windows,Messages;
{$R *.res}
const MMFName:PChar="KeyMMF";
type
 PGlobalDLLData=^TGlobalDLLData;
 TGlobalDLLData=packed record
   SysHook:HWND;
   MyAppWnd:HWND;
 end;

var
 GlobalData:PGlobalDLLData;
 MMFHandle:THandle;

function KeyboardProc(code:integer; wParam:word; lParam:longint):longint;stdcall;
var
CtrlDown:Boolean;
State:TKeyboardState;
begin
if (Code<0) or (wParam=PM_NOREMOVE) then
 begin
   Result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,дParam);
   exit;
 end;
GetKeyboardState(State);
CtrlDown:=((State[vk_Control] and 128)<>0);
if (TMsg(Pointer(lParam)^).hwnd=VK_LWIN) or
  (TMsg(Pointer(lParam)^).hwnd=VK_RWIN) or
  (TMsg(Pointer(lParam)^).hwnd=VK_MENU) or
  ((TMsg(Pointer(lParam)^).hwnd=VK_ESCAPE) and (CtrlDown)) or
  ((TMsg(Pointer(lParam)^).hwnd=VK_ESCAPE) and ((KF_ALTDOWN and TMsg(Pointer(lParam)^).wParam)=0)) or
  ((TMsg(Pointer(lParam)^).hwnd=VK_TAB) and ((KF_ALTDOWN and TMsg(Pointer(lParam)^).wParam)=0) )
     then
       begin
         if (wParam=WM_SYSKEYDOWN) or (wParam=WM_KEYDOWN) then
           begin
             MessageBeep(0);
             Result:=1;
lParam);
           end else result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,lParam);
       end else result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,lParam);
end;
procedure hook(switch:Boolean; hMainProg:HWND)export;stdcall;
begin
if switch=true then
 begin
   GlobalData^.SysHook:=SetWindowsHookEx(13,@KeyboardProc,HInstance,0);
   GlobalData^.MyAppWnd:=hMainProg;
 end else UnhookWindowsHookEx(GlobalData^.SysHook);
end;

procedure OpenGlobalData();
begin
MMFHandle:=CreateFileMapping(INVALID_HANDLE_VALUE,nil,PAGE_READWRITE,0,SizeOf(TGlobalDLLData),MMFName);
if MMFHandle=0 then Exit;
GlobalData:=MapViewOfFile(MMFHandle,FILE_MAP_ALL_ACCESS,0,0,SizeOf(TGlobalDLLData));
if GlobalData = nil then CloseHandle(MMFHandle);
end;

procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;

procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
case dwReason of
 DLL_PROCESS_ATTACH:OpenGlobalData;
 DLL_PROCESS_DETACH:CloseGlobalData;
end;
end;

exports hook;

begin
DLLProc:=@DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


 
Rouse_ ©   (2005-04-14 12:05) [1]

За такой код удавил бы сразу. Даже не спрашивай о причине - ошибка на ошибке...


 
axx   (2005-04-14 12:07) [2]

Понял :-)


 
VMcL ©   (2005-04-14 12:07) [3]

Ошибки, которые сразу бросаются в глаза:

1. function KeyboardProc(code:integer; wParam:word; lParam:longint):longint;stdcall; - неверная сигнатура

2. procedure DLLEntryPoint(dwReason: DWord); stdcall; - неверный тип соглашения о вызовах


 
axx   (2005-04-14 12:11) [4]

Ладно буду дальше возиться. Просто на основу был взять эксемпл вот от сюда http://www.delphimaster.ru/articles/hooks/index.html


 
Digitman ©   (2005-04-14 12:15) [5]


> Память не может быть рид. и тд и тп


не "и тд и тп", а приводи ПОЛНУЮ и ТОЧНУЮ диагностику отказа

и, хоть в дан.случае это и не принципиально, поменяй местами строчки

  GlobalData^.SysHook:=SetWindowsHookEх(13,@KeyboardProc,HInstance,0);
  GlobalData^.MyAppWnd:=hMainProg;


> SetWindowsHookEx(13


system-wide-хук типа WH_LL_KEYBOARD не требует размещения в отдельном ДЛЛ-модуле


 
Digitman ©   (2005-04-14 12:19) [6]


> на основу был взять эксемпл вот от сюда


вранья в этой статье предостаточно


 
axx   (2005-04-14 13:47) [7]

То Digitman
По поводу статьи :-(((

То All
Всем спасибо. Справился. :-)


 
Digitman ©   (2005-04-14 13:48) [8]


> Справился


поделился бы ... "узкими местами" ..


 
axx   (2005-04-14 14:13) [9]

1. function KeyboardProc(Code:Integer;wParam:wParam;
    lParam:lParam):lParam;stdcall;
Дальше все "практически" также
--------
2. DllEntryPoint - убил
--------
3. Open/Close GlobalData - на initialization\finalization

ну и по мелочам.
Вроде работает - ошибки не вылетают во всяком случае...


 
Lin7   (2005-04-14 14:30) [10]


> Digitman ©   (14.04.05 12:19) [6]
>
> вранья в этой статье предостаточно


Вранья или мелких опечяток?
Я начинал изучать хуки по этой статье и они работали. Можно для общего развития узнать, что в этой статье не так?


 
GuAV ©   (2005-04-14 14:43) [11]

Digitman ©   (14.04.05 12:19) [6]
вранья в этой статье предостаточно


Код к статье не очень хороший - это правда, а вот где враньё в самой статье ?


 
Digitman ©   (2005-04-14 15:05) [12]


> Lin7   (14.04.05 14:30) [10]


> что в этой статье не так?


хотя бы вот это :

Подчеркну это обстоятельство ещё раз: глобальные ловушки могут располагаться только в DLL, но никак не в EXE файлах !

это - вранье, снабженное самоуверенным воскл.знаком.

system-wide-хук  system-wide-хуку - рознь.
автор не удосужился изучить и опробовать в реальном коде материал, касающийся system-wide-хуков как таковых, а уже делает безапелляционные рекомендации.


> GuAV ©   (14.04.05 14:43) [11]


>  где враньё в самой статье ?


см.выше.


 
GuAV ©   (2005-04-14 15:22) [13]

Digitman ©   (14.04.05 15:05) [13]

нашёл:
Systemwide filter functions must reside in a DLL. ... The journal hooks, WH_JOURNALRECORD and WH_JOURNALPLAYBACK, are exceptions to this rule. ...

спасибо, а ещё ?


 
Digitman ©   (2005-04-14 15:25) [14]


> спасибо, а ещё ?


тот же самый - текущий - сабж...
т.е. WH_KEYBOARD_LL ..
сюда же смело можешь добавить WH_MOUSE_LL


 
GuAV ©   (2005-04-14 15:40) [15]

Я спрашиваю про другие неточности.

В том какой хук требует расположения в DLL разобратся сложно. В MSDN не нашел списка, более того в справке по SetWindowsHookEx (msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindow shookex.asp) написано:
...
HHOOK SetWindowsHookEx(          int idHook,
   HOOKPROC lpfn,
   HINSTANCE hMod,
   DWORD dwThreadId
);
...
lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.


 
Digitman ©   (2005-04-14 15:49) [16]


> GuAV ©   (14.04.05 15:40) [15]



> В MSDN не нашел списка


ЩАС тебе мелкомягкие список выложат !) ... вот ты раскатал) ..


> В том какой хук требует расположения в DLL разобратся сложно


сложно, но можно.

берешь конкретный тип хука и изучаешь ВСЮ доступную док-цию, прежде чем делать какие-то умозаключения ... уж не говоря о бездумном сдирании сомнительного рода "примеров"


 
ANB ©   (2005-04-14 16:15) [17]

В RSDN ищешь по WH_JOURNALRECORD - и самой первой вылезает статья про хуки. Там четко расписано, какие в DLL, какие можно в приложении.


 
ANB ©   (2005-04-14 16:16) [18]


> Digitman ©   (14.04.05 15:05) [12]
а я ведь тоже с этой статьи пример брал и нарвался на такую же ошибку.
Модераторы - уберите ее.


 
Eraser ©   (2005-04-14 16:19) [19]

Eraser

A global hook monitors messages for all threads in the same desktop as the calling thread. A thread-specific hook monitors messages for only an individual thread. A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate dynamic-link library (DLL) module. A thread-specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application"s code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL.

А в описании процедуры хука смотришь это global hook или thread-specific hook.


 
Eraser ©   (2005-04-14 16:20) [20]

Блин... сам себе сообщение отправил...

[19] ->> axx


 
mgcr ©   (2005-04-14 16:36) [21]

GuAV ©   (14.04.05 15:22) [13]
Digitman ©   (14.04.05 15:25) [14]

Все очень просто - WH_JOURNAL и _LL хуки не являются глобальными хуками. Они все работают с RawInputThread, поэтому им нет необходимости быть в контексте разных процессов.


 
Eraser ©   (2005-04-14 16:42) [22]

mgcr ©

This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.

Иными словами внедрение по Рихтеру, такими хуками не сделаешь?


 
mgcr ©   (2005-04-14 16:46) [23]

Eraser ©   (14.04.05 16:42) [22]


>
> Иными словами внедрение по Рихтеру, такими хуками не сделаешь?


Нет конечно. Куда ты внедряться собрался при помощи этих хуков, в Win32k.sys ? Ну, удачи тебе.


 
Digitman ©   (2005-04-14 16:47) [24]


> mgcr ©   (14.04.05 16:36) [21]


вполне логично.
И., ты бы не мне - ты бы это автору втолковал, ибо у него проблемы ... ч.н., "на огурцах") ..


 
Eraser ©   (2005-04-14 16:49) [25]

mgcr ©
Куда ты внедряться собрался при помощи этих хуков, в Win32k.sys ?


Не! Вндряться я никуда не собираюсь, времени нету ))


 
Digitman ©   (2005-04-14 16:52) [26]


> не являются глобальными хуками


и действительно - хотя бы в станд.справке от Борланда нет никаких "глобальных" хуков ... есть system-scope, есть thread-scope, есть system-or-thread-scope хуки .. а "глобальных" нет и в помине.


 
mgcr ©   (2005-04-14 16:58) [27]

Digitman ©   (14.04.05 16:52) [26]

Термин "Глобальный хук" используется в MSDN, для противопоставления его Thread-scope хуку. На самом деле, хуков, как мы с тобой знаем, всего два типа - активных в рамках потока (на что есть соответствующая структура у потока) и у рабочего стола (на что тоже есть соответствующая структура).

То есть, с точки зрения доступа из сервисов, например, глобальность тут же пропадает, так как десктоп у них совсем другой.

Это я не тебе, конечно, рассказываю, а народу, который еще не знает.

Впрочем, о чем тут, собственно, говорить, если есть не совсем грамотный код в нулевом посте и ссылки на не совсем грамотную статью :)


 
alpet ©   (2005-04-14 18:31) [28]

2 mgcr

У функции CreateDesktop есть параметр dwFlags, передавая в который DF_ALLOWOTHERACCOUNTHOOK можно получить:

"Enables processes running in other accounts on the desktop to set hooks in this process."

Я не совсем понимаю - для какого процесса можно будет устанавливать ловушки - создавшего десктоп или все запускаемые в этом десктопе.


 
mgcr ©   (2005-04-14 18:37) [29]

alpet ©   (14.04.05 18:31) [28]

Хук - это принадлежность Desktop"а. Если такого флага не установлено, то глобальные хуки могут создавать только процессы с той же учетной записью, что и процесс, создавший Desktop.
Если флаг установлен, то хуки могут создавать процессы, у которых тот же десктоп, но учетная запись отлична от учетной записи создателя десктопа. Например, десктоп Default с таким флагом создает Winlogon, чтобы пользовательские процессы моги устанавливать хуки.



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

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

Наверх





Память: 0.53 MB
Время: 0.02 c
11-1098883491
mii
2004-10-27 17:24
2005.06.06
RichEdit


3-1114954156
Fedor
2005-05-01 17:29
2005.06.06
Переменые для параметрического запроса в IBDataSet


14-1116617554
Sergey Masloff
2005-05-20 23:32
2005.06.06
Я в отпуске. Даже не верится... Отгуливаю за 2002 г. ;-)


6-1111330702
Евгений2
2005-03-20 17:58
2005.06.06
С помощью чего в Delphi это можно реализовать?


14-1116368859
ALL
2005-05-18 02:27
2005.06.06
Момогите найти





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