CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    [solved] SetWindowsHookEx stop receivings notifications after focus lost

    Good evening

    I've search a lot of forums but did not found any answer to my question. So here I post it.

    I'm trying to set hook to keyboard to receive all multimedia keys notification, for altering they default behavior or simply disable them. But I've run into some problem.

    In my .exe file I call functions from .dll which simply sets the hook with this code
    Code:
    SetWindowsHookEx( WH_SHELL, ShellProc, gModule, 0 );
    Then goes the handling like this
    Code:
    LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode >= 0 )
        {
            switch( wParam )
            {
                 // here I would like to handle WH_SHELL -> HSHELL_APPCOMMAND -> ie. APPCOMMAND_LAUNCH_APP2
            }
        } // if
        return CallNextHookEx (gHookProc, nCode, wParam, lParam);
    }
    Everything works correctly to the moment o losing the focus, after that my application simply stops receiving the notifications. When setting the focus back to my app it start working again.
    Do I need to set up sth more? Switch sth in the system? Disable sth?

    I use the m$ way to link the .exe with .dll with dllimport/dllexport. No dynamic load of .dll.
    My system is Vista64. I don't have any drivers for my keyboard I use the ones that comes with vista.

    Please help.
    J.



    //EDIT: syntax error fix
    Last edited by macabre13; January 29th, 2009 at 03:34 AM. Reason: solved

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Are you sure your code is correct? I can't see the closing brace for if statement.
    Best regards,
    Igor

  3. #3
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Quote Originally Posted by Igor Vartanov View Post
    Are you sure your code is correct? I can't see the closing brace for if statement.
    Are you sure that yours answer help me somehow?

    Maybe it is a mistake when ctrl+c/v but like I said it works when windows has the focus. So looks like I compiled my code before and simply paste it (with syntax error not logical) to show how am I implementing the code. And asking for solution.

    /m13

  4. #4
    Join Date
    Nov 2003
    Posts
    1,902

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Perhaps gModule is NULL - or you system is running a mixture of 32bit and 64bit apps. If your hook DLL is 64bit, it will only hook other 64bit apps.

    gg

  5. #5
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Quote Originally Posted by Codeplug View Post
    Perhaps gModule is NULL - or you system is running a mixture of 32bit and 64bit apps. If your hook DLL is 64bit, it will only hook other 64bit apps.

    gg
    Hi thanks for reply.
    Is there a way to hook both 32 and 64 bit? Should I implement and call SetWindowsHook from 32 and 64 bit build dll?

    gModule is taken from dllMain whe .dll is being loaded. And after I check it, look likes there is proper value.

    Or maybe where to look to get information how window do manage the input of multimedia keys?

    Thanks!
    /m13

  6. #6
    Join Date
    Nov 2003
    Posts
    1,902

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    >> Should I implement and call SetWindowsHook from 32 and 64 bit build dll?
    According to MSDN, yes. And give them different names.

    Don't know about MM keys...

    gg

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Quote Originally Posted by macabre13 View Post
    Are you sure that yours answer help me somehow?
    Now I doubt. Believe me, I never ask just for asking. Typically this kind of question makes people be more accurate in quoting and finally prevents from suffering from silly mistakes and misguiding answers. Definitely not your case.

    Maybe it is a mistake when ctrl+c/v but like I said it works when windows has the focus. So looks like I compiled my code before and simply paste it (with syntax error not logical) to show how am I implementing the code. And asking for solution.

    /m13
    Maybe. Sorry, really sorry for pointing this once again, but this only showed your code like hardly compilable, nothing more than that.

    Is there a way to hook both 32 and 64 bit? Should I implement and call SetWindowsHook from 32 and 64 bit build dll?
    Well, MSDN answers that unambiguously:

    SetWindowsHookEx Function
    Remarks

    SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.
    Last edited by Igor Vartanov; January 27th, 2009 at 04:01 PM.
    Best regards,
    Igor

  8. #8
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    So I did some test and:
    On win xp32 with 32bit .dll my application works in 50%:
    I'm able to set hook, get the message and prevent other application from receiving it. But after loosing focus my application also stops receiving the messages. So then nothing happens.

    Code:
    // shellhook.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdafx.h"
    #include "shellhook.h"
    #include <tchar.h>
    
    HINSTANCE gModule;
    HHOOK gHookProc = NULL;
    HWND gWindow;
    
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                          DWORD  ul_reason_for_call,
                          LPVOID lpReserved
                          )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            gModule = hModule;
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }
    
    
    SHELLHOOK_API DWORD registerWindow( HWND _inHwnd )
    {
        DWORD dwErrId = 0;
        gHookProc = SetWindowsHookEx( WH_SHELL, ShellProc, gModule, 0 );
        if( NULL == gHookProc )
        {
            dwErrId = GetLastError( );
            TCHAR errBuf[255];
            FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, dwErrId, 0, errBuf, 255, 0 );
            SetWindowText( _inHwnd, errBuf );
        }
        else
        {
            gWindow = _inHwnd;
        }
        return dwErrId;
    }
    
    SHELLHOOK_API DWORD unRegisterWindow( HWND _inHwnd )
    {
        if( NULL != gHookProc )
        {
            BOOL result = UnhookWindowsHookEx( gHookProc );
            DWORD dwErrId = GetLastError( );
            if( FALSE == result )
            {
                TCHAR errBuf[255];
                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, dwErrId, 0, errBuf, 255, 0 );
                SetWindowText( _inHwnd, errBuf );
            }
            else
            {
                gWindow = NULL;
                gHookProc = NULL;
            }
            return dwErrId;
        }
        return 0;
    }
    
    LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    
        if (HSHELL_APPCOMMAND == nCode )
        {
            switch( GET_APPCOMMAND_LPARAM(lParam) )
            {
            case APPCOMMAND_VOLUME_MUTE:
                SetWindowText( gWindow, _T("APPCOMMAND_VOLUME_MUTE"));
                break;
            // similar for other cases
            }
            return 1;
        }
        return CallNextHookEx (gHookProc, nCode, wParam, lParam);
    }
    Does the code looks ok? I mean the hooking.


    @Igor: no hard feelings

    Thanks!
    /m13

  9. #9
    Join Date
    Nov 2003
    Posts
    1,902

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    >> my application also stops receiving the messages
    Probably because gWindow is NULL. A global/system hook means that your DLL is loaded into the address space of other processes. You will have to use some sort of IPC for your DLL to communicate with the DLL instance in the process that called registerWindow().

    gg

  10. #10
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Try this:
    Code:
    #pragma comment(linker, "/section:HOOKDAT,RWS") 
    #pragma data_seg( "HOOKDAT" )
    HWND gWindow = NULL; // !! must be initialized !!
    #pragma data_seg()
    @Igor: no hard feelings
    Sure.
    Best regards,
    Igor

  11. #11
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Ok.
    Now it works with this #pragma's. I don't know how and why this works. But I will investigate this. Any way thanks a lot.

  12. #12
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    With these code lines your dll obtains a very special section HOOKDAT that is shared among all the dll instances in all processes that did load it. While loading dll a loader never allocates process-specific memory pages for shared sections but maps already existing ones (if any).

    Your hook runner loads dll and initializes the section variable. After installing hook the dll emerges in victim process - and has the gWindow variable already initialized with the valid window handle. Exactly this point was missed in your original design - when your dll got injected to victim, gWindow had just a garbage in it.
    Last edited by Igor Vartanov; January 29th, 2009 at 04:22 AM.
    Best regards,
    Igor

  13. #13
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    The problem was that I was unable to understand why some other loads my .dll.
    But I have think it over and now I do understand this way:

    *) I register my hookProc in system and let it run.
    *) someone pushes the MULTIMEDIA_BUTTON_X
    *) sytem handle it and send the message through the hooks chain
    *) my .dll is being loaded and hookProc called with proper MULTIMEDIA_BUTTON_X value
    *) calling/not calling CallNextHookEx(...)
    *) .dll is unloaded ?
    End of processing the message.

    Am I right?

    /m13

  14. #14
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    Afraid not (but I'm not sure).

    After installing a global hook a dll is loaded into every process that comply with hook specifics (immediately or at first event). And it will be unloaded only after unhook is called. BTW, Richter's Programming Applications... has (as far as I remember) a good chapter about dll injection you may refer to.

    And you easily can do some logging in DllMain and see the process flow.
    Best regards,
    Igor

  15. #15
    Join Date
    Sep 2007
    Location
    poland|wrocław
    Posts
    47

    Re: SetWindowsHookEx stop receivings notifications after focus lost

    OK. I will look for that book. Thanks!

    /m13

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured