Thread: Problem with keyboard hook

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    Problem with keyboard hook

    Ok I thought the following would hook the keyboard input for only the one process but its getting it for all. Is there a way I can limit it to just one process?

    File: dll.h
    Code:
    #ifndef _DLL_H_
    #define _DLL_H_
    #include <windows.h>
    
    #define EXPORT __declspec (dllexport)
    
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    
    EXPORT LRESULT CALLBACK KbProc(int, WPARAM, LPARAM);
    EXPORT BOOL WINAPI InstallHook(HWND);
    EXPORT void WINAPI RemoveHook(void);
    #endif /* _DLL_H_ */
    File: dllmain.c
    Code:
    #include "dll.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    
    #pragma data_seg("shared_data")
    // Superglobals
    HHOOK hookdata = 0;
    #pragma data_seg()
    #pragma comment(linker, "/SECTION:shared_data,S")
    
    HMODULE hmodule = 0;
    HWND hwindow = 0;
    BOOL recycle = FALSE;
    BOOL running = FALSE;
    UINT timerid = 0;
    void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
    
    EXPORT LRESULT CALLBACK KbProc(int code, WPARAM w, LPARAM l)
    {
      if ( code < 0 || code != HC_ACTION )
        return CallNextHookEx(hookdata,code,w,l);
    
      char buff[100];
    
      sprintf(buff,"Values are: %d %u %u\n", code, w, l);
    
      MessageBox(0, buff, "ok", 0);
    
      switch(w)
      {
        default: return CallNextHookEx(hookdata,code,w,l);
      }
      return TRUE;
    }
    
    BOOL APIENTRY DllMain (HMODULE hmod,
                           DWORD reason,
                           LPVOID na)
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
               hmodule = hmod;
            break;
    
          case DLL_PROCESS_DETACH:
            break;
    
          case DLL_THREAD_ATTACH:
            break;
    
          case DLL_THREAD_DETACH:
            break;
        }
    
        /* Returns TRUE on success, FALSE on failure */
        return TRUE;
    }
    
    EXPORT BOOL WINAPI InstallHook(HWND hwnd)
    {
      if ( hookdata != 0 )
         return FALSE;
      hwindow = hwnd;
      hookdata = SetWindowsHookEx(WH_KEYBOARD, KbProc, hmodule, 0);
      if ( !hookdata )
         MessageBox(0, TEXT("Hook failed."), TEXT("Error"), MB_ICONEXCLAMATION); 
      return hookdata != 0;
    }
    
    EXPORT void WINAPI RemoveHook(void)
    {
      if ( hookdata != 0 )
      {
        UnhookWindowsHookEx(hookdata);
      }
    }
    
    void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
    {
    }
    File: main.c (its in one directory deeper then the other two)
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "..\dll.h"
    
    typedef BOOL (WINAPI *INST)(HWND);
    typedef void (WINAPI *UNINST)(void);
    
    int main(int argc, char *argv[])
    {
      HWND hwindow = FindWindow(NULL,"Untitled - Notepad");
      if ( !hwindow )
      {
         MessageBox(0, TEXT("Could not locate notepad"), TEXT("Error"), MB_ICONEXCLAMATION);
         system("pause");
         return EXIT_FAILURE;
      }
    
      HMODULE hmod = LoadLibrary(TEXT("..\\Hooks.dll")); 
      if ( hmod == 0 )
      {
         MessageBox(0, TEXT("Could not load library"), TEXT("Error"), MB_ICONEXCLAMATION);
         system("pause");
         return EXIT_FAILURE;
      }
    
      INST InHook = (void*)GetProcAddress(hmod, TEXT("InstallHook"));
      UNINST UnHook = (void*)GetProcAddress(hmod, TEXT("RemoveHook"));
      
      if ( InHook && UnHook )
      {
         InHook(hwindow);
         printf("Please press enter to terminate: ");
         fflush(stdout);
         getchar();
         UnHook();
      }
    
      FreeLibrary(hmod);
      
      system("pause");
      return 0;
    };
    References: http://cboard.cprogramming.com/showthread.php?t=60642
    http://cboard.cprogramming.com/showt...t=windows+hook

    As I said it is getting info from all processes which is ok if I can filter them out and send them on their way.

    Also is there a way to get the HWND using the process name and not the the window name?
    Last edited by Thantos; 01-15-2005 at 01:08 AM.

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Heh Ok I figured it out. The last parameter on SetWindowsHookEx is the thread id it should attach the hook onto. Since I had it 0 it attached to all. Replacing that with
    Code:
    GetWindowThreadProcessId(hwnd,NULL)
    Fixed the problem.

    Of course If anyone can answer the additional question I'd be grateful.

    Also if anyone knows a better way or any code suggestions I'd be happy to hear them. But please no comments on the driver program. I know its fugly. Its just a test app until I get the hook and DLL working.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Also is there a way to get the HWND using the process name and not the the window name?
    Hmm, well you could enumerate all top level windows with EnumWindows(). Then for each window, call GetWindowThreadProcessId() to see if that window's process is the one you are looking for. There isnt a direct API function for this since a process can have 0 windows, or several.

    As for your DLL code, it looks pretty clean at a glance

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    To retrieve a list of processes you can use CreateToolhelp32Snapshot with TH32CS_SNAPPROCESS. One of the entries in the PROCESSENTRY32 structure that is returned for every process is szExeFile. Once you have found a target process, you can either match up its process id with the one returned from GetWindowThreadProcessId, as suggested by bithub, or enumerate its threads with TH32CS_SNAPTHREAD.

    Shared segments are bad.
    Last edited by anonytmouse; 01-15-2005 at 08:08 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  2. Do I need to use Keyboard Hooks to solve my problem?
    By BenPage in forum C++ Programming
    Replies: 3
    Last Post: 07-16-2005, 10:10 AM
  3. Global hook only works on one window?
    By CornedBee in forum Windows Programming
    Replies: 5
    Last Post: 01-19-2004, 12:25 PM
  4. How to keep static data in a keyboard hook?
    By junbin in forum Windows Programming
    Replies: 1
    Last Post: 01-19-2003, 03:24 AM
  5. Game Design Topic #2 - Keyboard or Mouse?
    By TechWins in forum Game Programming
    Replies: 4
    Last Post: 10-08-2002, 03:34 PM