1
votes

I am trying to send user registered message to window procedure, procedure receives a message but it fails to see that its specific registered message i am sending.

So from start... I make sure that all dll instances share the meessage.

#pragma data_seg (".shared")
...
...
UINT    WM_HOOKEX = 0;
...
#pragma data_seg ()
#pragma comment(linker,"/SECTION:.shared,RWS")

In dllmain i make sure its only registered once

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    if( ul_reason_for_call == DLL_PROCESS_ATTACH ) 
    {
        hDll = (HINSTANCE) hModule; 
        //DisableThreadLibraryCalls( hDll );

        if( WM_HOOKEX==NULL )
            WM_HOOKEX = ::RegisterWindowMessage( _T("WM_HOOKEX_RK") );          
    }

    return TRUE;
}

Later with exported dll function(that shares dll and the message) that i use in my app i hook to the procedure of the desired window and send it this message with

SendMessage( plist,WM_HOOKEX,0,1 );

The hooked procedure receives the message(as i am inspecting it with dll debugging) but it fails to see what message it is. Dll debugging shows that the thread has the message registered in its memory though but procedure doesnt recieve correct message parameters.

Also i am sure it is receiving this message and not some other one because this is the only message directed to the procedure that i invoke, so i leave out the possibility that my custom mssg might still be in queue, then why i wonder why for several days now, why is it not receiving message as it should even debugging shows that it holds the custom message in its memory!

This is the procedure that recieves it(or actually doesnt)

#define pCW ((CWPSTRUCT*)lParam)

LRESULT HookProc (
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
)
{
    if( (pCW->message == WM_HOOKEX) && pCW->lParam ) 
    {
        ::UnhookWindowsHookEx( g_hHook );

        if( g_bSubclassed ) 
            goto END;       // already subclassed?

        // Let's increase the reference count of the DLL (via LoadLibrary),
        // so it's NOT unmapped once the hook is removed;
        TCHAR lib_name[MAX_PATH]; 
        ::GetModuleFileName( hDll, lib_name, MAX_PATH );

        if( !::LoadLibrary( lib_name ) )
            goto END;       

        // Subclass START button
        OldProc = (WNDPROC) 
            ::SetWindowLong( g_hWnd, GWL_WNDPROC, (long)NewProc );
        if( OldProc==NULL )         // failed?
            ::FreeLibrary( hDll );
        else {                      // success -> leave "HookInjEx.dll"
            ::MessageBeep(MB_OK);   // mapped into "explorer.exe"
            g_bSubclassed = true;
        }       
    }
    else if( pCW->message == WM_HOOKEX ) 
    {
        ::UnhookWindowsHookEx( g_hHook );

        // Failed to restore old window procedure? => Don't unmap the
        // DLL either. Why? Because then "explorer.exe" would call our
        // "unmapped" NewProc and  crash!!
        if( !SetWindowLong( g_hWnd, GWL_WNDPROC, (long)OldProc ) )
            goto END;

        ::FreeLibrary( hDll );

        ::MessageBeep(MB_OK);
        g_bSubclassed = false;  
    }

END:
    return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}

I suspect all of this has to do with the fact that i am sending the message with exported function which i call from my app. If i do this with function from the example app that came with original project, it uses imported function i think so perhaps exported function might be the cause.

Also i am unable to test imported function as its from another language.

edit:

So i also tried to register mssg everytime as someone here suggested but it made no differene, the weird thing here is that everything works fine if i call the function which hooks and sends the mssg internally, this is the header of the function that the gui app uses(in this case all works fine)

#if !defined INJECT_EX__H
#define INJECT_EX__H


#ifdef INJECT_EX_EXPORTS
#define HOOKDLL_API __declspec(dllexport)
#else
#define HOOKDLL_API __declspec(dllimport)
#endif


extern int HOOKDLL_API g_bSubclassed;
HOOKDLL_API int InjectDll();
HOOKDLL_API int UnmapDll();

#endif // !defined(INJECT_EX__H)


#define DIPSLIBAPI extern "C" __declspec(dllexport)

// External function prototypes
DIPSLIBAPI BOOL WINAPI SetDIPSHook(BOOL hook_it, BOOL just_save_list, int lobby, int type);

So this is the header that i believe gui app uses injectdll function as imported function and maybe thats why it works? If i use the function as exported without this header then mssg is not seen right.

edit2:

Here are the preprocessor directives from dll project: _DEBUG WIN32 _WINDOWS _USRDLL INJECT_EX_EXPORTS

2

2 Answers

1
votes

I'm not entirely clear on what you describe the problem to be. I'm guessing it would correspond to the behavior you'd get if WM_HOOKEX was still 0 in the injected dll. Assuming this is the problem, you need to do the following:

volatile UINT WM_HOOKEX = 0;

This ensures that the compiler will not optimize references to WM_HOOKEX but rather read it from memory every time you use it.

0
votes

One particular issue is that you should call ::RegisterWindowMessage( _T("WM_HOOKEX_RK") ); in every process you wish to receive it on. The system will return you the same message number across any process, the message is registered system wide.