diff --git a/HotkeyEngine.cpp b/HotkeyEngine.cpp index e4bbbe4..c5909b7 100644 --- a/HotkeyEngine.cpp +++ b/HotkeyEngine.cpp @@ -14,14 +14,14 @@ HotkeyEngine::KeyPressFn HotkeyEngine::OnKeyPress=NULL; // 1 - indicates that thread exited due to error // 2 - indicates that thread was forcefully terminated because it failed to respond in specified time -HotkeyEngine* HotkeyEngine::MakeInstance(HINSTANCE hInstance) +HotkeyEngine* HotkeyEngine::MakeInstance() { - instance.reset(new HotkeyEngine(hInstance)); + instance.reset(new HotkeyEngine()); return instance.get(); } -HotkeyEngine::HotkeyEngine(HINSTANCE hInstance): - running(false), hook_thread_handle(NULL), hook_thread_id(0), app_instance(hInstance), stack_commit(0) +HotkeyEngine::HotkeyEngine(): + running(false), hook_thread_handle(NULL), hook_thread_id(0), stack_commit(0) {} HotkeyEngine::~HotkeyEngine() @@ -103,7 +103,7 @@ DWORD WINAPI HotkeyEngine::ThreadProc(LPVOID lpParameter) { HHOOK kb_hook; - if ((kb_hook=SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, instance->app_instance, 0))) { + if ((kb_hook=SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0))) { SetEvent((HANDLE)lpParameter); //Signal success event and continue } else { return 1; //Exit (exit code = 1) diff --git a/HotkeyEngine.h b/HotkeyEngine.h index d3b72e9..0e51042 100644 --- a/HotkeyEngine.h +++ b/HotkeyEngine.h @@ -26,12 +26,11 @@ class HotkeyEngine { bool running; HANDLE hook_thread_handle; DWORD hook_thread_id; - HINSTANCE app_instance; size_t stack_commit; - HotkeyEngine(HINSTANCE hInstance); + HotkeyEngine(); public: - static HotkeyEngine* MakeInstance(HINSTANCE hInstance); + static HotkeyEngine* MakeInstance(); bool IsRunning(); bool Stop(); bool Start(); diff --git a/Suite.cpp b/Suite.cpp index 1326685..b58e965 100644 --- a/Suite.cpp +++ b/Suite.cpp @@ -12,6 +12,12 @@ #endif enum class CmdRes:char {DEFAULT, SETTINGS_SET, EXTERNAL_CALLED, ERR_MANY_ARGS, ERR_FEW_ARGS, ERR_UNKNOWN, ERR_NOT_IMPLEMENTED}; +enum class FstCmd:char {DEFAULT, LONG_PRESS, SHORT_PRESS}; + +CmdRes ProcessSettingsOptions(std::unique_ptr &Settings, int cmd_argc, wchar_t** cmd_argv, int cmd_shift); + +#define ARG_ALL L"machine" +#define ARG_CUR L"user" #ifdef OBSOLETE_WWINMAIN int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, int nCmdShow) @@ -54,9 +60,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi // /l ... - immidiately run long press event and exit (used with /i and /a options or w/o arguments) CmdRes cmd_res=CmdRes::DEFAULT; + FstCmd fst_cmd=FstCmd::DEFAULT; int ext_res; - const wchar_t ARG_ALL[]=L"machine"; - const wchar_t ARG_CUR[]=L"user"; if (wcslen(lpCmdLine)) { wchar_t** cmd_argv; int cmd_argc; @@ -70,146 +75,113 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi std::wcerr<4) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::Schedule(true, cmd_argv+2, cmd_argc-2); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::Schedule(false, cmd_argv+2, cmd_argc-2); - cmd_res=CmdRes::EXTERNAL_CALLED; + if (!wcscmp(cmd_argv[0], L"/s")) + fst_cmd=FstCmd::SHORT_PRESS; + else if (!wcscmp(cmd_argv[0], L"/l")) + fst_cmd=FstCmd::LONG_PRESS; + + if (fst_cmd!=FstCmd::DEFAULT) { + if (cmd_argc>1) cmd_res=ProcessSettingsOptions(Settings, cmd_argc, cmd_argv, 1); + } else { + if (!wcscmp(cmd_argv[0], L"/S")) { + if (cmd_argc>4) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::Schedule(true, cmd_argv+2, cmd_argc-2); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::Schedule(false, cmd_argv+2, cmd_argc-2); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/A")) { - if (cmd_argc>4) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::AddToAutorun(true, cmd_argv+2, cmd_argc-2); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::AddToAutorun(false, cmd_argv+2, cmd_argc-2); - cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcscmp(cmd_argv[0], L"/A")) { + if (cmd_argc>4) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::AddToAutorun(true, cmd_argv+2, cmd_argc-2); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::AddToAutorun(false, cmd_argv+2, cmd_argc-2); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/U")) { - if (cmd_argc>2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::Unschedule(true); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::Unschedule(false); - cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcscmp(cmd_argv[0], L"/U")) { + if (cmd_argc>2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::Unschedule(true); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::Unschedule(false); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/R")) { - if (cmd_argc>2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::RemoveFromAutorun(true); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::RemoveFromAutorun(false); - cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcscmp(cmd_argv[0], L"/R")) { + if (cmd_argc>2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::RemoveFromAutorun(true); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::RemoveFromAutorun(false); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/P")) { - if (cmd_argc>2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::AddToPath(true); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::AddToPath(false); - cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcscmp(cmd_argv[0], L"/P")) { + if (cmd_argc>2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::AddToPath(true); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::AddToPath(false); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/C")) { - if (cmd_argc>2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::RemoveFromPath(true); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { - ext_res=SuiteExtRel::RemoveFromPath(false); - cmd_res=CmdRes::EXTERNAL_CALLED; - } else { - cmd_res=CmdRes::ERR_UNKNOWN; - } - } else { - cmd_res=CmdRes::ERR_FEW_ARGS; - } - } else if (!wcscmp(cmd_argv[0], L"/i")) { - if (cmd_argc>2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - Settings.reset(new SuiteSettingsIni(cmd_argv[1])); - cmd_res=CmdRes::SETTINGS_SET; -#ifdef DEBUG - std::wcerr<2) { - cmd_res=CmdRes::ERR_MANY_ARGS; - } else if (cmd_argc>1) { - if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { - Settings.reset(new SuiteSettingsAppData(true)); - cmd_res=CmdRes::SETTINGS_SET; -#ifdef DEBUG - std::wcerr<2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>1) { + if (!wcsncmp(cmd_argv[1], ARG_CUR, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::RemoveFromPath(true); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else if (!wcsncmp(cmd_argv[1], ARG_ALL, wcslen(cmd_argv[1]))) { + ext_res=SuiteExtRel::RemoveFromPath(false); + cmd_res=CmdRes::EXTERNAL_CALLED; + } else { + cmd_res=CmdRes::ERR_UNKNOWN; + } } else { - cmd_res=CmdRes::ERR_UNKNOWN; + cmd_res=CmdRes::ERR_FEW_ARGS; } } else { - Settings.reset(new SuiteSettingsAppData()); - cmd_res=CmdRes::SETTINGS_SET; -#ifdef DEBUG - std::wcerr< &Settings, int cmd_argc, wchar_t** cmd_argv, int cmd_shift) +{ + CmdRes cmd_res=CmdRes::DEFAULT; + + if (!wcscmp(cmd_argv[cmd_shift], L"/i")) { + if (cmd_argc>cmd_shift+2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>cmd_shift+1) { + Settings.reset(new SuiteSettingsIni(cmd_argv[cmd_shift+1])); + cmd_res=CmdRes::SETTINGS_SET; +#ifdef DEBUG + std::wcerr<cmd_shift+2) { + cmd_res=CmdRes::ERR_MANY_ARGS; + } else if (cmd_argc>cmd_shift+1) { + if (!wcsncmp(cmd_argv[cmd_shift+1], ARG_CUR, wcslen(cmd_argv[cmd_shift+1]))) { + Settings.reset(new SuiteSettingsAppData(true)); + cmd_res=CmdRes::SETTINGS_SET; +#ifdef DEBUG + std::wcerr<GetSnkPath(); + DWORD dwAttrib=GetFileAttributes(snk_path.c_str()); + if (dwAttrib==INVALID_FILE_ATTRIBUTES||(dwAttrib&FILE_ATTRIBUTE_DIRECTORY)) { + ErrorMessage(L"Path to SnK is not valid!"); + return ERR_SUITEEXTREL+9; + } + + std::wstring snk_cmdline=QuoteArgument(snk_path.c_str()); + snk_cmdline.append(L" /sec /bpp +p /cmd="); + if (long_press) + snk_cmdline.append(QuoteArgument(settings->GetLhkCfgPath().c_str())); + else + snk_cmdline.append(QuoteArgument(settings->GetShkCfgPath().c_str())); + + PROCESS_INFORMATION pi={}; + STARTUPINFO si={sizeof(STARTUPINFO), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_USESHOWWINDOW, SW_SHOWNORMAL}; + if (CreateProcess(NULL, const_cast(snk_cmdline.c_str()), NULL, NULL, FALSE, HIGH_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return 0; + } + + ErrorMessage(L"Failed to launch SnK!"); + return ERR_SUITEEXTREL+10; +} diff --git a/SuiteExternalRelations.h b/SuiteExternalRelations.h index 50c3e58..02bc7c4 100644 --- a/SuiteExternalRelations.h +++ b/SuiteExternalRelations.h @@ -1,6 +1,7 @@ #ifndef SUITEEXTERNALRELATIONS_H #define SUITEEXTERNALRELATIONS_H +#include "SuiteSettings.h" #include #include @@ -14,6 +15,7 @@ namespace SuiteExtRel { bool LaunchSnkOpenDialog(std::wstring &fpath); void RestartApplication(const wchar_t* cmdline, bool elevate); void LaunchCommandPrompt(const wchar_t* dir); + int FireEvent(bool long_press, SuiteSettings *settings); } #endif //SUITEEXTERNALRELATIONS_H diff --git a/SuiteMain.cpp b/SuiteMain.cpp index 765067b..a8a1972 100644 --- a/SuiteMain.cpp +++ b/SuiteMain.cpp @@ -33,7 +33,7 @@ HBITMAP GetUacShieldBitmap(); extern template std::wstring std::operator+(wchar_t const*, std::wstring const&); //caused by use of std::operator+(wchar_t const*, std::wstring const&) #endif -int SuiteMain(HINSTANCE hInstance, SuiteSettings *settings) +int SuiteMain(SuiteSettings *settings) { TskbrNtfAreaIcon* SnkIcon=NULL; HotkeyEngine* SnkHotkey=NULL; @@ -78,7 +78,7 @@ int SuiteMain(HINSTANCE hInstance, SuiteSettings *settings) //It's ok to pass reference to NULL HotkeyEngine to OnWmCommand - see IconMenuProc comments //std::bind differs from lamda captures in that you can't pass references by normal means - object will be copied anyway //To pass a reference you should wrap referenced object in std::ref - SnkIcon=TskbrNtfAreaIcon::MakeInstance(hInstance, WM_HSTNAICO, SNK_HS_TITLE L": Running", elev_req?IDI_HSLTNAICO:IDI_HSTNAICO, L"SnK_HotkeySuite_IconClass", IDR_ICONMENU, IDM_STOP_START, + SnkIcon=TskbrNtfAreaIcon::MakeInstance(GetModuleHandle(NULL), WM_HSTNAICO, SNK_HS_TITLE L": Running", elev_req?IDI_HSLTNAICO:IDI_HSTNAICO, L"SnK_HotkeySuite_IconClass", IDR_ICONMENU, IDM_STOP_START, std::bind(IconMenuProc, std::ref(SnkHotkey), settings, &OnKeyTriplet, elev_req, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(CloseEventHandler, settings, std::placeholders::_1), std::bind(EndsessionTrueEventHandler, settings, std::placeholders::_1, std::placeholders::_2)); @@ -89,7 +89,7 @@ int SuiteMain(HINSTANCE hInstance, SuiteSettings *settings) //At this point taskbar icon is already visible but unusable - it doesn't respond to any clicks and can't show popup menu //So it's ok to customize menu here and initialize everything else - SnkHotkey=HotkeyEngine::MakeInstance(hInstance); + SnkHotkey=HotkeyEngine::MakeInstance(); //By default IDM_EDIT_LHK menu item is enabled and IDM_SET_EN_LHK is unchecked (see Res.rc) if (settings->GetLongPress()) { SnkIcon->CheckIconMenuItem(IDM_SET_EN_LHK, MF_BYCOMMAND|MF_CHECKED); diff --git a/SuiteMain.h b/SuiteMain.h index c0b60c1..980fad1 100644 --- a/SuiteMain.h +++ b/SuiteMain.h @@ -4,6 +4,6 @@ #include "SuiteSettings.h" #include -int SuiteMain(HINSTANCE hInstance, SuiteSettings *settings); +int SuiteMain(SuiteSettings *settings); #endif //SUITEMAIN_H