Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Keyb Hooks LIST

Posted on 2002-04-23
15
Medium Priority
?
464 Views
Last Modified: 2010-04-04
How can I retrieve a list of keyboard hooks
installed and the respective applications who
called them ?
0
Comment
Question by:bryan7
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
15 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6964433
create a system debug hook with SetWindowsHookEx with WH_DEBUG

in the DebugProc check if it's a keyboard hook
if wParam = WH_DEBUG then begin
...
check the DEBUGHOOKINFO for idThreadInstaller
that's the thread that installed the hook

getting the application of the thread that installed the hook is another thing
it could even be installed from within a thread created in a dll function which was called from some app :)
about getting the list .. simply add a hook each time you get notified of one
ofcourse check if it's in the list already
I'm assuming you know about system hooks so I won't code it for ya now
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6964435
if wParam = WH_DEBUG then begin

darn .. that should've been
if wParam = WH_KEYBOARD then begin
...
0
 
LVL 3

Author Comment

by:bryan7
ID: 6966760
Hello, thanks for the answer.. however I'm not
that good on hooks ;( I can make a system key hook
in a dll but that's all my knowledge about hooks =(

Can you make the code for me ? I need it to get the list
of all currently set keyboard hooks, I'll add more points
if you wish... I really need this app.

btw, if you know of an already made application that
does that (no need for source) I'll give you the points
too :)

Thanks.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6966981
don't know of such an app
I'll write the code as it's not that much work
when I wake up :)
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 1000 total points
ID: 6967468
here's the complete project code
haven't tested it, just compiled it successfully :)
it was a minor change to one of my other hooks so it should work
I'm not shure about the TList being stored in the mmf
if that doesn't work then simply make a static array of cardinal or some record
---------------------------------------------------------

library lnKbdDebugHook;

uses
  Windows, Classes;

{$R *.RES}


const
    WM_USER = $0400;
    WM_lnHOOK = WM_USER + 133;

    errSuccess  = 1;
    errHooked   = 0;
    errUnhooked = 0;
    errCantHook = -1;
    errCantUnHk = -1;

type
  PHookRec = ^THookRec;
  THookRec = packed record
    MainWindow: HWND;
    HookID: HHOOK;
    HookList: TList;
  end;


var
   HookRec: PHookRec = nil;
   hMapObject: THandle = 0;


// hook procedure
function hpWSH(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
var lpDHI: PDebugHookInfo;
    I: Integer;
    found: boolean;
begin
     try
        // check if it's a keybd hook and if we should process the message
        if (wParam = WH_KEYBOARD) and (nCode = HC_ACTION) then begin
           lpDHI:=PDebugHookInfo(lParam);
           found:=false;
           // check our list if the threadid exists
           with HookRec^.HookList do begin
             for I:=0 to Count-1 do
                 if Cardinal(Items[I]) = lpDHI^.idThreadInstaller then begin
                    found:=true;
                    break;
                 end;
             // if threadid not found add it to the list
             if not found then
                Add(Pointer(lpDHI^.idThreadInstaller));
           end;

           // notify our main window
           if HookRec^.MainWindow > 0 then
              PostMessage(HookRec^.MainWindow, WM_lnHOOK, wParam, lParam);
        end;
     finally
        Result:=CallNextHookEx(HookRec^.HookID, nCode, wParam, lParam);
     end;
end;

// set the notification window
function SetMainWindow(const hWin: hWND): hWND;stdcall;
begin
     HookRec^.MainWindow:=hWin;
     Result:=hWin;
end;

// start hook
function HookWindoze: Integer;stdcall;
begin
     if HookRec^.HookID = 0 then begin
        HookRec^.HookID:=SetWindowsHookEx(WH_DEBUG, hpWSH, hInstance, 0);
        if HookRec^.HookID = 0 then
           Result:=errCantHook
        else
           Result:=errSuccess;
     end else Result:=errHooked;
end;

// stop hook
function UnhookWindoze: Integer;stdcall;
begin
     if HookRec^.HookID <> 0 then begin
        if UnhookWindowsHookEx(HookRec^.HookID) then
           Result:=errSuccess
        else
           Result:=errCantUnHk;
        HookRec^.HookID:=0;
     end else Result:=errUnhooked;
end;

function GetHookCount: Integer; stdcall;
begin
     try
        Result:=HookRec.HookList.Count;
     except
        Result:=-2;
     end;
end;

function GetHookID(Index: Integer): Cardinal; stdcall;
begin
     try
        Result:=Cardinal(HookRec.HookList.Items[Index]);
     except
        Result:=0;
     end;
end;

procedure EntryPointProc(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin // reserve 4k for the list (cca 1000 entries)
        hMapObject:=CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THookRec) + 4069, 'ln_kbdList');
        HookRec:=MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
        // check if the list already created
        if not Assigned(HookRec^.HookList) then
           HookRec^.HookList:=TList.Create;
      end;

    DLL_PROCESS_DETACH:
      begin
        try
          // clear the list each time a process detaches
          // we could check the threads ids for their validity, but in order to do that
          // we'd need to have their handles but we only have their IDs
          // on win me/2000/xp there's a function called OpenThread
          // with it we could check if the thread id is still valid
          // no support for that function on win 9x systems
          // this should suffice coz with one key press we get all the installed keybd hooks
          // ofcourse if all of them call CallNextHookEx :)
          HookRec^.HookList.Clear;
        finally
          UnMapViewOfFile(HookRec);
          // close the handle to the map object
          // it will not close the handle while there's at least one open View
          CloseHandle(hMapObject);
        end;
      end;
  end;
end;

// ---------- export funkcije
exports
   SetMainWindow,
   HookWindoze,
   UnhookWindoze,
   GetHookCount,
   GetHookID;


begin
     DllProc := @EntryPointProc;
     EntryPointProc(DLL_PROCESS_ATTACH);
end.


hope it works for you :)
0
 
LVL 3

Author Comment

by:bryan7
ID: 6967621
Hello, thanks for the code, I've been
trying to implement the app to get the
list from the dll with no succes :(
would you mind making it for me ? I
can add more points as wished :)

(you'll get A graded)
0
 
LVL 3

Expert Comment

by:smurff
ID: 6967933
listening
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6968524
:)
in my spare time ... today/tomorrow
0
 
LVL 3

Author Comment

by:bryan7
ID: 6968526
:)
0
 
LVL 1

Expert Comment

by:quantum2
ID: 6981383
listening
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6990278
sorry I was away for a "few" days ...
have you got it working ? if not I'll make a sample app to show you how to use that dll
0
 
LVL 3

Author Comment

by:bryan7
ID: 7008349
haven't got it running yet,
would be nice if you could
make that app :)

thanks.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7008745
ok I will :)
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9004097
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from Lee_Nover

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 9097486
humz ..
if anybody needs a List that's shared between processes then check out my TGlobalList ;)
http://www.siwww.net/Delphi/GLTest.zip

just change the TGLItem to fit your needs
it must not contain any pointer type fields !
for strings use a fixed length array of char

it already includes locking mechanisms so it's completely thread/process safe ;)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question