Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Keyb Hooks LIST

Posted on 2002-04-23
15
Medium Priority
?
472 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
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses

782 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