?
Solved

SetWindowsHookEx - Why not working

Posted on 2005-03-02
9
Medium Priority
?
592 Views
Last Modified: 2012-05-05
This DLL gets injected in to a simple form application using a 'starter app' which uses CreateProccessEXA from Madshi's library (www.madshi.net).  For testing purposes I've set it up to hook the keyboard up and down arrows.  Because of this, I'm not sure if I'm setting the hook correctly or not.  

Can someone explain to me why this does not work?  I thought I had read somewhere that maybe the hook has to be in a loop or something...  I don't, the only example I find are very basic and they only seem to be in EXEs, not DLLs.  Does that make a difference?

I know that the DLL is getting injected and started because I get the "Attaching" messagebox when my starter app is used and "Detaching" messagebox when I close my form.  So the DLL is running in the simple form app  Ultimately what I would like to do is hook messages sent to controls with in the form.

Anyways, here's the code.  If more explanation is needed, just let me know.


/////////////// THE DLL ///////////////////

#include "stdafx.h"
#include "windows.h"
#include <stdlib.h>
#include "NSR_SM.h"

HHOOK hH;

LRESULT CALLBACK KeyboardProc(int hCode,WPARAM ww,LPARAM ll)
{
      if (hCode < 0)
            return CallNextHookEx(hH,hCode,ww,ll);
      else
      {
            switch(hCode)
            {
                  case VK_UP:
                        // log here info , ww has its HWND
                        MessageBox(0,"Up", "Hook",0);
                        break;
                  case VK_DOWN:
                        // same
                        MessageBox(0,"Down", "Hook",0);
                        break;
            }
            return CallNextHookEx(hH,hCode,ww,ll);
      }
}

BOOL WINAPI DllMain( HANDLE hModule,
                       DWORD reason,
                       LPVOID lpReserved)
{
      if (reason == DLL_PROCESS_ATTACH)
      {
            MessageBox(0,"Attaching", "Debug", 0);

            HINSTANCE hDll = GetModuleHandle(NULL);
            hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hDll,NULL);
      }
      else if (reason == DLL_PROCESS_DETACH)
      {
            MessageBox(0,"Detaching", "Debug", 0);
            UnhookWindowsHookEx(hH);
      }
       return TRUE;
}



//////////// THE STARTER APP /////////////

#include "stdafx.h"
#include "windows.h"
#include "madCHook.h"


int _tmain(int argc, _TCHAR* argv[])

{
      STARTUPINFO si;
        PROCESS_INFORMATION pi;

      ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );

      InitializeMadCHook();

      CreateProcessExA((LPCSTR)"C:\\NSR_Form.exe",
                              NULL,
                               NULL,
                               NULL,
                               FALSE,
                               0,
                               NULL,
                               NULL,
                               &si,
                                         &pi,
                               (LPCSTR)"C:\\NSR_SM.dll");
      FinalizeMadCHook();

      return 0;
}
0
Comment
Question by:Crestline
[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
  • 4
  • 4
9 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 1000 total points
ID: 13442292
>>HINSTANCE hDll = GetModuleHandle(NULL);

This is the problem - you need to pass the DLL's instance handle, not the one of the process. Use

BOOL WINAPI DllMain( HANDLE hModule,
                       DWORD reason,
                       LPVOID lpReserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
         MessageBox(0,"Attaching", "Debug", 0);

         hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hModule,NULL);
    }
    else if (reason == DLL_PROCESS_DETACH)
    {
         MessageBox(0,"Detaching", "Debug", 0);
         UnhookWindowsHookEx(hH);
    }
      return TRUE;
}
0
 

Author Comment

by:Crestline
ID: 13442548
Wow, thanks for the quick reply!

This is going to sound elementary, but  hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hModule,NULL); errors out because it want's amd HINSTANCE, not a HANDLE.  

Should simply casting as HINSTANCE work?
hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,(HINTANCE)hModule,NULL);

0
 
LVL 86

Expert Comment

by:jkr
ID: 13442585
Actually, you should provide the correct signature for your 'DllMain()', which is

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
);
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 48

Expert Comment

by:AlexFM
ID: 13442650
switch(hCode)

should be

switch(wParam)
0
 
LVL 86

Expert Comment

by:jkr
ID: 13442692
Or, actually

switch(ww)

*duck* :o)
0
 

Author Comment

by:Crestline
ID: 13443166
hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hinstDLL,NULL);

I only want this hook to occur in the form that this DLL is attached to, is this the case or do I need the dwThreadID as well?  Or is the dwThreadID the thread of the DLL and not the Form?

Thanks.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13443507
>>I only want this hook to occur in the form that this DLL is attached to

Oh, in this case, use

 hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,0);
0
 

Author Comment

by:Crestline
ID: 13443778
Not sure what I'm doing wrong but when I use the old version the hook works, but it starts up in other windows.  Like when I bring another window to the forground and hit a key on the keyboard, my "Attaching" meesagebox comes up because my DLL is now in that process.
 hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hinstDLL,NULL);

When I use the new version, nothing seems to happen, nothing is triggered by the key strokes.
hH = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,0);

I'm going to start a new Question as I didn't specifically state that I wanted this to only run in my Form's process and not system wide.  As I said, in the end, I want to monitor messages sent to controls in this form, specifically messages sent to a listbox.



0

Featured Post

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.

Question has a verified solution.

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

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

770 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