Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.06;
Скачать: CL | DM;

Вниз

Помогите с 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 вся ветка

Текущий архив: 2005.06.06;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.031 c
1-1116676673
antol
2005-05-21 15:57
2005.06.06
как ввести логическое выражение


14-1116577335
_RusLAN
2005-05-20 12:22
2005.06.06
Delphi World 6.0 со всеми базами и сразу. Скачать


1-1116487474
dp200
2005-05-19 11:24
2005.06.06
Как програмно открыть файл в конкретном приложении


8-1108800982
Rustam
2005-02-19 11:16
2005.06.06
вставка теста в графику(image)


14-1116405822
_Pasha_
2005-05-18 12:43
2005.06.06
Вид из космоса