NO

Author Topic: Creating keyboard hook for 32-bit and 64-bit apps on x64  (Read 10363 times)

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Creating keyboard hook for 32-bit and 64-bit apps on x64
« on: September 05, 2007, 05:04:57 PM »
Hello,
I use a tool that maps the comma of the German keypad to a period.

On x64 I need one version for 32-bit apps and one version for 64-bit apps, but if both are running, only one will work.
It seems that one keyboard hook corrupts the other.

I would like to check if the window having focus is a 32-bit app (WOW64).
Is the correct way to use the following functions in the listed order?
  • GetWindowThreadID ... to get the process Id of the window
  • OpenProcess ... to get a handle to the owning process
  • IsWow64Process ... to check if the process is 32-bit
  • CloseHandle ... to clean up
---
Stefan

Proud member of the UltraDefrag Development Team

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
« Reply #1 on: September 05, 2007, 06:26:35 PM »
Not for hooking but if register based remapping is enought:
http://support.microsoft.com/kb/Q216893
May the source be with you

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
« Reply #2 on: September 06, 2007, 05:54:47 PM »
Remapping is not an option.

BTW, is there anything I have to set in addition to the standard DLL settings under the project properties, when I use this DLL to create a system wide hook?
---
Stefan

Proud member of the UltraDefrag Development Team

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
« Reply #3 on: February 18, 2008, 05:07:47 PM »
Using the latest release beta, I was able to create a working 32-bit and 64-bit version of this global hook dll.
I am still facing the problem that only the last started hook will take effect, if both, 32-bit and 64-bit, hooks are active.
If only one of the global hooks is active, all is working as expected.

Does anyone see what might be wrong ???

I can't post the whole projects, since I do not have the permission of the owner.
I hope I do not violate his ownership by posting the two pieces.

32-bit hook procedure
Code: [Select]
#define _WIN32_WINNT 0x0501

#include <windows.h>

HHOOK hPunktHook;

typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LRESULT __declspec(dllexport)
CALLBACK PunktHook(int nCode, WPARAM wParam, LPARAM lParam);
void __declspec(dllexport) DLLInit(HINSTANCE hDLL, BOOL install);

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
//...
}

/* Return success */
return TRUE;
}

LRESULT CALLBACK PunktHook(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT RetVal;
HWND hwnd;
LPARAM scancode;
DWORD ProcID;
HANDLE hProc;
BOOL bWOW64Proc = FALSE;
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");

if (nCode == HC_ACTION)
{
if (wParam == VK_DECIMAL)
{
// Map comma to point

hwnd = GetFocus();
if (hwnd == NULL)
hwnd = GetForegroundWindow();

/* on 32-bit Windows no 64-bit check needed */
if ( fnIsWow64Process==NULL )
{
bWOW64Proc = TRUE;
}
else
{
/* is process WOW64 */
GetWindowThreadProcessId(hwnd, &ProcID);
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);
fnIsWow64Process(hProc, &bWOW64Proc);
CloseHandle(hProc);
}

if (bWOW64Proc == TRUE)
{
// send period instead of comma

RetVal = 1;
return RetVal;
}
}
}

RetVal = CallNextHookEx(hPunktHook, nCode, wParam, lParam);
return RetVal;
}

64-bit hook procedure
Code: [Select]
#define _WIN32_WINNT 0x0501

#include <windows.h>

HHOOK hPunktHook;

LRESULT __declspec(dllexport)
CALLBACK PunktHookX(int nCode, WPARAM wParam, LPARAM lParam);
void __declspec(dllexport) DLLInitX(HINSTANCE hDLL, BOOL install);

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
//...
}

/* Return success */
return TRUE;
}

LRESULT CALLBACK PunktHookX(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT RetVal;
HWND hwnd;
LPARAM scancode;
DWORD ProcID;
HANDLE hProc;
BOOL bWOW64Proc = TRUE;

if (nCode == HC_ACTION)
{
if (wParam == VK_DECIMAL)
{
// Map comma to period

hwnd = GetFocus();
if (hwnd == NULL)
hwnd = GetForegroundWindow();

/* check if 64-bit process */
GetWindowThreadProcessId(hwnd, &ProcID);
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);
IsWow64Process(hProc, &bWOW64Proc);
CloseHandle(hProc);

if (bWOW64Proc == FALSE)
{
// send period instead of comma

RetVal = 1;
return RetVal;
}
}
}

RetVal = CallNextHookEx(hPunktHook, nCode, wParam, lParam);
return RetVal;
}
---
Stefan

Proud member of the UltraDefrag Development Team