#include "pch.h" #include #include #include #include "trace.h" #include "resource.h" #include "AwakeConstants.h" #include #include #include #include #include #include #include #include BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: Trace::RegisterProvider(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: Trace::UnregisterProvider(); break; } return TRUE; } // The PowerToy name that will be shown in the settings. const static wchar_t* MODULE_NAME = L"Awake"; // Add a description that will we shown in the module settings page. const static wchar_t* MODULE_DESC = L"A module that keeps your computer awake on-demand."; // Implement the PowerToy Module Interface and all the required methods. class Awake : public PowertoyModuleIface { std::wstring app_name; // Contains the non localized key of the powertoy std::wstring app_key; private: // The PowerToy state. bool m_enabled = false; HANDLE m_hProcess; HANDLE send_telemetry_event; // Handle to event used to invoke PowerToys Awake HANDLE m_hInvokeEvent; bool is_process_running() { return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; } void launch_process() { Logger::trace(L"Launching PowerToys Awake process"); unsigned long powertoys_pid = GetCurrentProcessId(); std::wstring executable_args = L"--use-pt-config --pid " + std::to_wstring(powertoys_pid); Logger::trace(L"PowerToys Awake launching with parameters: " + executable_args); SHELLEXECUTEINFOW sei{ sizeof(sei) }; sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; sei.lpFile = L"modules\\Awake\\PowerToys.Awake.exe"; sei.nShow = SW_SHOWNORMAL; sei.lpParameters = executable_args.data(); if (!ShellExecuteExW(&sei)) { DWORD error = GetLastError(); std::wstring message = L"PowerToys Awake failed to start with error = "; message += std::to_wstring(error); Logger::error(message); } m_hProcess = sei.hProcess; } public: // Constructor Awake() { app_name = GET_RESOURCE_STRING(IDS_AWAKE_NAME); app_key = AwakeConstants::ModuleKey; std::filesystem::path logFilePath(PTSettingsHelper::get_module_save_folder_location(this->app_key)); logFilePath.append(LogSettings::awakeLogPath); Logger::init(LogSettings::launcherLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location()); Logger::info("Launcher object is constructing"); }; // Destroy the powertoy and free memory 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 { return MODULE_NAME; } // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); // Create a Settings object. PowerToysSettings::Settings settings(hinstance, get_name()); settings.set_description(MODULE_DESC); return settings.serialize_to_buffer(buffer, buffer_size); } // Return the non localized key of the powertoy, this will be cached by the runner virtual const wchar_t* get_key() override { return app_key.c_str(); } // Called by the runner to pass the updated settings values as a serialized JSON. virtual void set_config(const wchar_t* config) override { try { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); // If you don't need to do any custom processing of the settings, proceed // to persists the values calling: values.save_to_settings_file(); } catch (std::exception&) { // Improper JSON. } } virtual void enable() { ResetEvent(send_telemetry_event); ResetEvent(m_hInvokeEvent); launch_process(); m_enabled = true; }; virtual void disable() { if (m_enabled) { ResetEvent(send_telemetry_event); ResetEvent(m_hInvokeEvent); TerminateProcess(m_hProcess, 1); } m_enabled = false; } // Returns if the powertoys is enabled virtual bool is_enabled() override { return m_enabled; } }; extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() { return new Awake(); }