PowerLauncher: fix disabling by adjusting OpenProcess params (#4577)

This commit is contained in:
Andrey Nekrasov 2020-07-01 12:36:26 +03:00 committed by GitHub
parent 17343210c0
commit 738b5f5707
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -10,8 +10,10 @@
extern "C" IMAGE_DOS_HEADER __ImageBase;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Trace::RegisterProvider();
break;
@ -25,13 +27,14 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
return TRUE;
}
// These are the properties shown in the Settings page.
struct ModuleSettings {
struct ModuleSettings
{
} g_settings;
// Implement the PowerToy Module Interface and all the required methods.
class Microsoft_Launcher : public PowertoyModuleIface {
class Microsoft_Launcher : public PowertoyModuleIface
{
private:
// The PowerToy state.
bool m_enabled = false;
@ -48,15 +51,16 @@ private:
// Time to wait for process to close after sending WM_CLOSE signal
static const int MAX_WAIT_MILLISEC = 10000;
public:
// Constructor
Microsoft_Launcher() {
Microsoft_Launcher()
{
app_name = GET_RESOURCE_STRING(IDS_LAUNCHER_NAME);
init_settings();
};
~Microsoft_Launcher() {
~Microsoft_Launcher()
{
if (m_enabled)
{
terminateProcess();
@ -65,19 +69,22 @@ public:
}
// Destroy the powertoy and free memory
virtual void destroy() override {
virtual void destroy() override
{
delete this;
}
// Return the display name of the powertoy, this will be cached by the runner
virtual const wchar_t* get_name() override {
virtual const wchar_t* get_name() override
{
return app_name.c_str();
}
// Return array of the names of all events that this powertoy listens for, with
// nullptr as the last element of the array. Nullptr can also be returned for empty
// list.
virtual const wchar_t** get_events() override {
virtual const wchar_t** get_events() override
{
static const wchar_t* events[] = { nullptr };
// Available events:
// - ll_keyboard
@ -91,7 +98,8 @@ public:
}
// Return JSON with the configuration options.
virtual bool get_config(wchar_t* buffer, int* buffer_size) override {
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
// Create a Settings object.
@ -104,21 +112,26 @@ public:
// Signal from the Settings editor to call a custom action.
// This can be used to spawn more complex editors.
virtual void call_custom_action(const wchar_t* action) override {
virtual void call_custom_action(const wchar_t* action) override
{
static UINT custom_action_num_calls = 0;
try {
try
{
// Parse the action values, including name.
PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action);
}
catch (std::exception ex) {
catch (std::exception ex)
{
// Improper JSON.
}
}
// Called by the runner to pass the updated settings values as a serialized JSON.
virtual void set_config(const wchar_t* config) override {
try {
virtual void set_config(const wchar_t* config) override
{
try
{
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config);
@ -129,7 +142,8 @@ public:
// Otherwise call a custom function to process the settings before saving them to disk:
// save_settings();
}
catch (std::exception ex) {
catch (std::exception ex)
{
// Improper JSON.
}
}
@ -187,7 +201,7 @@ public:
DWORD pid = *pidBuffer;
if (pid)
{
m_hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
m_hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, pid);
break;
}
}
@ -213,19 +227,23 @@ public:
}
// Returns if the powertoys is enabled
virtual bool is_enabled() override {
virtual bool is_enabled() override
{
return m_enabled;
}
// Handle incoming event, data is event-specific
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override {
if (wcscmp(name, ll_keyboard) == 0) {
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override
{
if (wcscmp(name, ll_keyboard) == 0)
{
auto& event = *(reinterpret_cast<LowlevelKeyboardEvent*>(data));
// Return 1 if the keypress is to be suppressed (not forwarded to Windows),
// otherwise return 0.
return 0;
}
else if (wcscmp(name, win_hook_event) == 0) {
else if (wcscmp(name, win_hook_event) == 0)
{
auto& event = *(reinterpret_cast<WinHookEvent*>(data));
// Return value is ignored
return 0;
@ -234,7 +252,8 @@ public:
}
// Callback to send WM_CLOSE signal to each top level window.
static BOOL CALLBACK requestMainWindowClose(HWND nextWindow, LPARAM closePid) {
static BOOL CALLBACK requestMainWindowClose(HWND nextWindow, LPARAM closePid)
{
DWORD windowPid;
GetWindowThreadProcessId(nextWindow, &windowPid);
@ -245,11 +264,12 @@ public:
}
// Terminate process by sending WM_CLOSE signal and if it fails, force terminate.
void terminateProcess() {
void terminateProcess()
{
DWORD processID = GetProcessId(m_hProcess);
EnumWindows(&requestMainWindowClose, processID);
const DWORD result = WaitForSingleObject(m_hProcess, MAX_WAIT_MILLISEC);
if (result == WAIT_TIMEOUT)
if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
{
TerminateProcess(m_hProcess, 1);
}
@ -262,19 +282,21 @@ public:
};
// Load the settings file.
void Microsoft_Launcher::init_settings() {
try {
void Microsoft_Launcher::init_settings()
{
try
{
// Load and parse the settings file for this PowerToy.
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(get_name());
}
catch (std::exception ex) {
catch (std::exception ex)
{
// Error while loading from the settings file. Let default values stay as they are.
}
}
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() {
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new Microsoft_Launcher();
}