Skip to content

Commit

Permalink
Various
Browse files Browse the repository at this point in the history
* build*.bash: Check *.o timestamps vs *.c
* send_input/config.c: Restrict virtual key code to: 0x01 to 0xFE
* send_input/main.c
** Add Ctrl+C etc handler
** Improve SendInput() -- only one keyboard input each call
  • Loading branch information
kevinarpe committed Mar 7, 2022
1 parent 59921ce commit b5ce4b1
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

# Projects not for Git
hello-world/
task_switcher/

send_input/release/send_input-*

38 changes: 28 additions & 10 deletions send_input/build.bash
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ main()
echo_and_run_cmd \
cd "$this_script_abs_dir_path"

echo_and_run_gcc_cmd \
-c -o error_exit.o error_exit.c
echo_and_run_gcc_cmd_if_necessary \
error_exit.c error_exit.o

echo_and_run_gcc_cmd \
-c -o win32_xmalloc.o win32_xmalloc.c
echo_and_run_gcc_cmd_if_necessary \
win32_xmalloc.c win32_xmalloc.o

echo_and_run_gcc_cmd \
-c -o wstr.o wstr.c
echo_and_run_gcc_cmd_if_necessary \
wstr.c wstr.o

echo_and_run_gcc_cmd \
-c -o config.o config.c
echo_and_run_gcc_cmd_if_necessary \
config.c config.o

echo_and_run_gcc_cmd \
-c -o main.o main.c
echo_and_run_gcc_cmd_if_necessary \
main.c main.o

echo_and_run_gcc_cmd \
-o send_input.exe error_exit.o win32_xmalloc.o wstr.o config.o main.o -lgdi32
Expand Down Expand Up @@ -73,5 +73,23 @@ echo_and_run_gcc_cmd()
"$@"
}

echo_and_run_gcc_cmd_if_necessary()
{
# Ex: 'error_exit.c'
local input_file_path="$1"; shift
# Ex: 'error_exit.o'
local output_file_path="$1"; shift
# Remaining args stored in "$@"

if [ "$input_file_path" -nt "$output_file_path" ]
then
echo_and_run_gcc_cmd \
-c -o "$output_file_path" "$input_file_path" "$@"
# Remaining args stored in "$@"
else
printf -- '\n%s: Not updated\n' "$input_file_path"
fi
}

main "$@"

13 changes: 12 additions & 1 deletion send_input/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,18 @@ void ConfigParseShortcutKey(_In_ const struct WStr *lpShortcutKeyWStr, // Ex:
{
// Ref: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-s-snprintf-s-l-snwprintf-s-snwprintf-s-l
_snwprintf_s(g_lpErrorMsgBuffer, g_ulErrorMsgBufferSize, g_ulErrorMsgBufferSize,
L"Config file: Line #%zd: Failed to parse virtual key code [%ls]%d\r\n"
L"Config file: Line #%zd: Failed to parse virtual key code [%ls]\r\n"
L"Line: %ls\r\n",
(1 + ulLineIndex), lpVkCodeWStr->lpWCharArr, lpLineWStr->lpWCharArr);

ErrorExit(g_lpErrorMsgBuffer);
}

// Ref: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
if (dwVkCode < 0x01 || dwVkCode > 0xFE)
{
_snwprintf_s(g_lpErrorMsgBuffer, g_ulErrorMsgBufferSize, g_ulErrorMsgBufferSize,
L"Config file: Line #%zd: Invalid virtual key code [%ls]->%d: Min: 0x01 (1), Max: 0xFE (254)\r\n"
L"Line: %ls\r\n",
(1 + ulLineIndex), lpVkCodeWStr->lpWCharArr, dwVkCode, lpLineWStr->lpWCharArr);

Expand Down
26 changes: 22 additions & 4 deletions send_input/experimental/build_kb_test.bash
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ main()
echo_and_run_cmd \
cd "$this_script_abs_dir_path"

echo_and_run_gcc_cmd \
-c -I .. -o ../error_exit.o ../error_exit.c
echo_and_run_gcc_cmd_if_necessary \
../error_exit.c ../error_exit.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o kb_test.o kb_test.c
echo_and_run_gcc_cmd_if_necessary \
../kb_test.c ../kb_test.o -I ..

echo_and_run_gcc_cmd \
-o kb_test.exe ../error_exit.o kb_test.o -lgdi32
Expand Down Expand Up @@ -62,5 +62,23 @@ echo_and_run_gcc_cmd()
"$@"
}

echo_and_run_gcc_cmd_if_necessary()
{
# Ex: 'error_exit.c'
local input_file_path="$1"; shift
# Ex: 'error_exit.o'
local output_file_path="$1"; shift
# Remaining args stored in "$@"

if [ "$input_file_path" -nt "$output_file_path" ]
then
echo_and_run_gcc_cmd \
-c -o "$output_file_path" "$input_file_path" "$@"
# Remaining args stored in "$@"
else
printf -- '\n%s: Not updated\n' "$input_file_path"
fi
}

main "$@"

11 changes: 8 additions & 3 deletions send_input/experimental/kb_test.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "win32_winver.h"
#include "error_exit.h"
#include <windows.h>
#include <strsafe.h>
#include <assert.h>
#include <wchar.h>
#include <stdio.h>
Expand Down Expand Up @@ -171,8 +170,10 @@ LRESULT CALLBACK LowLevelKeyboardProc(_In_ int nCode,
const SHORT sRAltKeyState = GetAsyncKeyState(VK_RMENU);
const BOOL bIsRAltKeyDown = (sRAltKeyState & SHORT_MOST_SIGNIFICANT_BIT) ? TRUE : FALSE;

printf("eKeyModifiers: %d, wParam: %s, vkCode: 0x%X, IsExtended? %d, IsAltDown? %d, IsKeyUp? %d, Shift? %d, LShift? %d, RShift? %d, Ctrl? %d, LCtrl? %d, RCtrl? %d, Alt? %d, LAlt? %d, RAlt? %d\r\n",
eKeyModifiers, lpWParamDesc, info->vkCode, bIsExtended, bIsAltDown, bIsKeyUp,
const DWORD dwThreadId = GetCurrentThreadId();

printf("dwThreadId: %d, eKeyModifiers: %d, wParam: %s, vkCode: 0x%X, IsExtended? %d, IsAltDown? %d, IsKeyUp? %d, Shift? %d, LShift? %d, RShift? %d, Ctrl? %d, LCtrl? %d, RCtrl? %d, Alt? %d, LAlt? %d, RAlt? %d\r\n",
dwThreadId, eKeyModifiers, lpWParamDesc, info->vkCode, bIsExtended, bIsAltDown, bIsKeyUp,
bIsShiftKeyDown, bIsLShiftKeyDown, bIsRShiftKeyDown,
bIsCtrlKeyDown, bIsLCtrlKeyDown, bIsRCtrlKeyDown,
bIsAltKeyDown, bIsLAltKeyDown, bIsRAltKeyDown);
Expand Down Expand Up @@ -230,8 +231,12 @@ int WINAPI wWinMain(HINSTANCE hInstance, // The operating system uses this
ErrorExit(L"SetWindowsHookEx(WH_KEYBOARD_LL, ...)");
}

const DWORD dwThreadId = GetCurrentThreadId();
const DWORD z = HSHELL_WINDOWREPLACED;

printf("Press any key combination to watch low level keyboard events\r\n");
printf("Press Ctrl+C in this terminal to exit\r\n");
printf("dwThreadId: %d\r\n", dwThreadId);
printf("\r\n");

MSG msg = {};
Expand Down
39 changes: 29 additions & 10 deletions send_input/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ struct ConfigEntryDynArr g_configEntryDynArr = {};

enum EKeyModifier g_eKeyModifiers = 0;

// Ref: https://docs.microsoft.com/en-us/windows/console/registering-a-control-handler-function
// Ref: https://docs.microsoft.com/en-us/windows/console/handlerroutine
static BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType)
{
printf("Handled event: CTRL_C_EVENT, CTRL_BREAK_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT\r\n");
// Ref: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitprocess
ExitProcess(1);
}

static void UpdateEKeyModifiers(_In_ const BOOL bIsKeyUp,
_In_ const enum EKeyModifier eKeyModifier)
{
Expand Down Expand Up @@ -40,18 +49,23 @@ static void HandleKeyUp(_In_ const DWORD dwVkCode)
printf("SendKeys(%ls)\r\n", lpConfigEntry->sendKeysWStr.lpWCharArr);
// Ref: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
// Ref: https://stackoverflow.com/questions/32149644/keyboard-input-via-sendinput-win32-api-doesnt-work-hardware-one-does
const UINT uSent = SendInput(lpConfigEntry->inputKeyArr.ulSize,
lpConfigEntry->inputKeyArr.lpInputKeyArr,
sizeof(INPUT));

if (uSent != lpConfigEntry->inputKeyArr.ulSize)
// Ref: https://stackoverflow.com/a/71384213/257299
// Ref: https://batchloaf.wordpress.com/2014/10/02/using-sendinput-to-type-unicode-characters/
for (size_t j = 0; j < lpConfigEntry->inputKeyArr.ulSize; ++j)
{
_snwprintf_s(g_lpErrorMsgBuffer, g_ulErrorMsgBufferSize, g_ulErrorMsgBufferSize,
L"SendInput([%zd]%ls): Sent %zd events, but expected %zd\r\n",
lpConfigEntry->sendKeysWStr.ulSize, lpConfigEntry->sendKeysWStr.lpWCharArr,
uSent, lpConfigEntry->inputKeyArr.ulSize);
const UINT cInputs = 1;
const UINT uSent = SendInput(cInputs, // [in] UINT cInputs
lpConfigEntry->inputKeyArr.lpInputKeyArr + j, // [in] LPINPUT pInputs
sizeof(INPUT)); // [in] int cbSize
if (uSent != cInputs)
{
_snwprintf_s(g_lpErrorMsgBuffer, g_ulErrorMsgBufferSize, g_ulErrorMsgBufferSize,
L"SendInput([%zd]%ls[index:%zd]): Sent %zd events, but expected %zd\r\n",
lpConfigEntry->sendKeysWStr.ulSize, lpConfigEntry->sendKeysWStr.lpWCharArr, j,
uSent, lpConfigEntry->inputKeyArr.ulSize);

ErrorExit(g_lpErrorMsgBuffer);
ErrorExit(g_lpErrorMsgBuffer);
}
}
break;
}
Expand Down Expand Up @@ -228,6 +242,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, // The operating system uses this
PWSTR lpCmdLine, // ... contains the command-line arguments as a Unicode string.
int nCmdShow) // ... is a flag that says whether the main application window will be minimized, maximized, or shown normally.
{
const BOOL bIsAdd = TRUE;
if (!SetConsoleCtrlHandler(HandlerRoutine, bIsAdd))
{
ErrorExit(L"SetConsoleCtrlHandler()");
}
wchar_t *lpConfigFilePath = NULL;
CheckCommandLineArgs(&lpConfigFilePath);

Expand Down
38 changes: 28 additions & 10 deletions send_input/test/build_config_test.bash
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ main()
echo_and_run_cmd \
cd "$this_script_abs_dir_path"

echo_and_run_gcc_cmd \
-c -I .. -o ../error_exit.o ../error_exit.c
echo_and_run_gcc_cmd_if_necessary \
../error_exit.c ../error_exit.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o ../win32_xmalloc.o ../win32_xmalloc.c
echo_and_run_gcc_cmd_if_necessary \
../win32_xmalloc.c ../win32_xmalloc.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o ../wstr.o ../wstr.c
echo_and_run_gcc_cmd_if_necessary \
../wstr.c ../wstr.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o ../config.o ../config.c
echo_and_run_gcc_cmd_if_necessary \
../config.c ../config.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o config_test.o config_test.c
echo_and_run_gcc_cmd_if_necessary \
../config_test.c ../config_test.o -I ..

echo_and_run_gcc_cmd \
-o config_test.exe ../error_exit.o ../win32_xmalloc.o ../wstr.o ../config.o config_test.o -lgdi32
Expand Down Expand Up @@ -71,5 +71,23 @@ echo_and_run_gcc_cmd()
"$@"
}

echo_and_run_gcc_cmd_if_necessary()
{
# Ex: 'error_exit.c'
local input_file_path="$1"; shift
# Ex: 'error_exit.o'
local output_file_path="$1"; shift
# Remaining args stored in "$@"

if [ "$input_file_path" -nt "$output_file_path" ]
then
echo_and_run_gcc_cmd \
-c -o "$output_file_path" "$input_file_path" "$@"
# Remaining args stored in "$@"
else
printf -- '\n%s: Not updated\n' "$input_file_path"
fi
}

main "$@"

34 changes: 26 additions & 8 deletions send_input/test/build_wstr_test.bash
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ main()
echo_and_run_cmd \
cd "$this_script_abs_dir_path"

echo_and_run_gcc_cmd \
-c -I .. -o ../error_exit.o ../error_exit.c
echo_and_run_gcc_cmd_if_necessary \
../error_exit.c ../error_exit.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o ../win32_xmalloc.o ../win32_xmalloc.c
echo_and_run_gcc_cmd_if_necessary \
../win32_xmalloc.c ../win32_xmalloc.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o ../wstr.o ../wstr.c
echo_and_run_gcc_cmd_if_necessary \
../wstr.c ../wstr.o -I ..

echo_and_run_gcc_cmd \
-c -I .. -o wstr_test.o wstr_test.c
echo_and_run_gcc_cmd_if_necessary \
../wstr_test.c ../wstr_test.o -I ..

echo_and_run_gcc_cmd \
-o wstr_test.exe ../error_exit.o ../win32_xmalloc.o ../wstr.o wstr_test.o -lgdi32
Expand Down Expand Up @@ -68,5 +68,23 @@ echo_and_run_gcc_cmd()
"$@"
}

echo_and_run_gcc_cmd_if_necessary()
{
# Ex: 'error_exit.c'
local input_file_path="$1"; shift
# Ex: 'error_exit.o'
local output_file_path="$1"; shift
# Remaining args stored in "$@"

if [ "$input_file_path" -nt "$output_file_path" ]
then
echo_and_run_gcc_cmd \
-c -o "$output_file_path" "$input_file_path" "$@"
# Remaining args stored in "$@"
else
printf -- '\n%s: Not updated\n' "$input_file_path"
fi
}

main "$@"

0 comments on commit b5ce4b1

Please sign in to comment.