Search code examples
c++windowswinapisetwindowshookex

SetWindowsHookEx failing with google chrome. Error code 87 invalid parameter


I am making a tutorial based program and want to be able to hook my code into certain apps to get the tutorial interacting with the app.

My hook code works for most apps except google chrome. I have stripped my code down to the following so you can see it going wrong.

Main.cpp

#include <Windows.h>
#include <iostream>
#include <psapi.h>
#include <Tlhelp32.h>

unsigned long GetProcId( const std::string& name )
{
    unsigned long res = 0 ;

    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32 processInfo ;
    processInfo.dwSize=sizeof(PROCESSENTRY32W);

    if( !Process32First( hSnapShot, &processInfo ) )
    {
        CloseHandle( hSnapShot ); 
        return res ;
    }

    do 
    {
        if( NULL != ( strstr ( strlwr ( processInfo.szExeFile ), name.c_str() ) ) )
        {               
            res = processInfo.th32ProcessID ;
            break ;
        }
    } while(Process32Next( hSnapShot,&processInfo ));

    CloseHandle( hSnapShot ) ;
    return res ;
}

typedef LRESULT (CALLBACK *DllHookProc)(int nCode, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
               LPSTR lpCmdLine, int nCmdShow)
{
    unsigned int processid = GetProcId( "chrome.exe" ) ;

    if (processid == 0)
    {
        return 0 ;
    }

    HINSTANCE dllInstance = LoadLibrary("mydll.dll") ;

    if (dllInstance == NULL)
    {
        return 0 ;
    }

    DllHookProc hookProc = (DllHookProc)::GetProcAddress(dllInstance, "HookProc");

    if ( hookProc == NULL) 
    {
        FreeLibrary(dllInstance);
        return 0 ;
    }

    HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)hookProc,
        dllInstance, processid );

    if (hook == NULL)
    {
        FreeLibrary(dllInstance);
        return 0 ;
    }

    return 0 ;
}

Test Dll (mydll.dll)

LRESULT CALLBACK HookProc (int nCode, WPARAM wParam, LPARAM lParam )
{
    //Pass to the next chain in the process list
    return CallNextHookEx( 0, nCode, wParam, lParam);
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
    return TRUE;
}

Definition file

LIBRARY "MYDLL"
EXPORTS
HookProc @1

Everything works fine (including getting processId and loading library and getprocaddress) up to the SetWindowsHookEx which returns NULL with error code 87 (invalid parameter).

Both chrome.exe and my code are 32 bit.

Does this work for anyone else or does anyone know what it doesnt work?

Thanks


Solution

  • One possible problem would be if you're building 64bit code, but chrome.exe is 32bit (or the other way around). [See comment & update, this is not the case.]


    One suspicious thing in your code is that you're not calling Process32First, and that seems to be required. See for ex: Taking a Snapshot and Viewing Processes.


    Last suggestion: you're passing in a process id to SetWindowsHookEx, but that expects a thread id.