1

I'm trying to hook an external process(Cubase) in order to intercept keybord events(specifically "ctrl + shift + s" [Save As]) to SendInput(...) in order to fill the file name text area with the current date & time. After some time I realized that I do not understand C++ nearly well enough to achieve the desired result, so I tweaked this code a bit.

DLL:

#include <windows.h>
#include <stdio.h>

HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK g_hook = 0;
#pragma data_seg()

LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam) {
    printf_s("callback...\n");
    if (code < 0) {
        return CallNextHookEx(g_hook, code, wParam, lParam);
    }

    KBDLLHOOKSTRUCT kbd = *((KBDLLHOOKSTRUCT*) lParam);

    if (kbd.vkCode == 0x53 && GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) < 0) { // 0x53 -> 's'
        MessageBox(NULL, "ctrl + shift + s", "CALLBACK", MB_ICONINFORMATION);
    }

    return CallNextHookEx(g_hook, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install(DWORD threadID) {
    if (!(g_hook = SetWindowsHookEx(WH_KEYBOARD, HookProc, hinst, threadID))) {
        printf_s("failed installing hook...\n");
    }
    else {
        printf_s("hook installed...\n");
    }

}
extern "C" __declspec(dllexport) void uninstall() {
    UnhookWindowsHookEx(g_hook);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    hinst = hinstDLL;
    return TRUE;
}

main.cpp:

#include <tchar.h>
#include <Windows.h>

#define APP_PATH _T("C:\\Program Files (x86)\\Steinberg\\Cubase 5\\Cubase5.exe")

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

    HINSTANCE hinst = LoadLibrary(_T("CuBaseHook.dll")); 

    if (hinst) {
        typedef void (*Install)(DWORD);
        typedef void (*Uninstall)();

        Install install = (Install) GetProcAddress(hinst, "install");
        Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");

        STARTUPINFO         info{ sizeof(info) };
        PROCESS_INFORMATION pInfo;
        if (CreateProcess(APP_PATH, "", NULL, NULL, TRUE, 0, NULL, NULL, &info, &pInfo)) {
            install(pInfo.dwThreadId);

            MSG msg;
            while (GetMessage(&msg, NULL, 0, 0) != 0)
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }

            uninstall();
        }
    }

    return 0;
}

The above compiles, but fails on SetWindowsHookEx(WH_KEYBOARD, HookProc, hinst, threadID) in the DLL install(...) function.

Frankly I have no idea why. Can it be hinstDLL or threadID issue?

PS: If there is another way of achieving the desired result then please by all means let me know...

Community
  • 1
  • 1
Dima Maligin
  • 1,386
  • 2
  • 15
  • 30
  • What does `GetLastError()` say when `SetWindowsHookEx()` fails? Also, you should be exporting `HookProc()` function. Also, you are not closing the `hProcess` and `hThread` handles returned by `CreateProcess()`. In any case, your hook is calling `GetKeyState()`, so it will get state info from the thread that is calling `HookProc()`, which is not the thread that is being hooked. Read the documentation: "*This hook may be called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook.*" – Remy Lebeau Dec 13 '15 at 20:34
  • Based on what you are attempting to solve, intercepting keystrokes is not the right solution. What if the user invokes the "Save As" dialog via mouse instead of keyboard? You will probably have to inject code directly into the target process, such as with `CreateRemoteThread()`, and have that code monitor for the dialog and then manipulate it directly. Or, have your hooking app simply run a timer that watches for the "Save As" dialog onscreen and then uses UI Automation to manipulate it. No need to hook the other process at all in that situation. – Remy Lebeau Dec 13 '15 at 20:41
  • @RemyLebeau im not doing it for distribution... this is for personal use only... and the keystrokes are good enough since i only use the shortcuts... thank you for the info though.. got me moving somewhere... – Dima Maligin Dec 13 '15 at 21:10

0 Answers0