mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-05 04:39:08 +08:00
Removed get_res_string_wchar and used the get_resource_string() function instead which returns a wstring typecast into wchar*
This commit is contained in:
parent
bde0e0b86a
commit
df1c6b9b0b
@ -7,401 +7,467 @@
|
||||
#include <sddl.h>
|
||||
#include "version.h"
|
||||
|
||||
std::optional<RECT> get_button_pos(HWND hwnd) {
|
||||
RECT button;
|
||||
if (DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS, &button, sizeof(RECT)) == S_OK) {
|
||||
return button;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
std::optional<RECT> get_button_pos(HWND hwnd)
|
||||
{
|
||||
RECT button;
|
||||
if (DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS, &button, sizeof(RECT)) == S_OK)
|
||||
{
|
||||
return button;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<RECT> get_window_pos(HWND hwnd) {
|
||||
RECT window;
|
||||
if (DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &window, sizeof(window)) == S_OK) {
|
||||
return window;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
std::optional<RECT> get_window_pos(HWND hwnd)
|
||||
{
|
||||
RECT window;
|
||||
if (DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &window, sizeof(window)) == S_OK)
|
||||
{
|
||||
return window;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<POINT> get_mouse_pos() {
|
||||
POINT point;
|
||||
if (GetCursorPos(&point) == 0) {
|
||||
return {};
|
||||
} else {
|
||||
return point;
|
||||
}
|
||||
std::optional<POINT> get_mouse_pos()
|
||||
{
|
||||
POINT point;
|
||||
if (GetCursorPos(&point) == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return point;
|
||||
}
|
||||
}
|
||||
|
||||
WindowAndProcPath get_filtered_base_window_and_path(HWND window) {
|
||||
return hwnd_cache.get_window_and_path(window);
|
||||
WindowAndProcPath get_filtered_base_window_and_path(HWND window)
|
||||
{
|
||||
return hwnd_cache.get_window_and_path(window);
|
||||
}
|
||||
|
||||
HWND get_filtered_active_window() {
|
||||
return hwnd_cache.get_window(GetForegroundWindow());
|
||||
HWND get_filtered_active_window()
|
||||
{
|
||||
return hwnd_cache.get_window(GetForegroundWindow());
|
||||
}
|
||||
|
||||
int width(const RECT& rect) {
|
||||
return rect.right - rect.left;
|
||||
int width(const RECT& rect)
|
||||
{
|
||||
return rect.right - rect.left;
|
||||
}
|
||||
|
||||
int height(const RECT& rect) {
|
||||
return rect.bottom - rect.top;
|
||||
int height(const RECT& rect)
|
||||
{
|
||||
return rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
bool operator<(const RECT& lhs, const RECT& rhs) {
|
||||
auto lhs_tuple = std::make_tuple(lhs.left, lhs.right, lhs.top, lhs.bottom);
|
||||
auto rhs_tuple = std::make_tuple(rhs.left, rhs.right, rhs.top, rhs.bottom);
|
||||
return lhs_tuple < rhs_tuple;
|
||||
bool operator<(const RECT& lhs, const RECT& rhs)
|
||||
{
|
||||
auto lhs_tuple = std::make_tuple(lhs.left, lhs.right, lhs.top, lhs.bottom);
|
||||
auto rhs_tuple = std::make_tuple(rhs.left, rhs.right, rhs.top, rhs.bottom);
|
||||
return lhs_tuple < rhs_tuple;
|
||||
}
|
||||
|
||||
RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect) {
|
||||
RECT result = small_rect;
|
||||
if ((result.right - result.left) > (big_rect.right - big_rect.left)) {
|
||||
// small_rect is too big horizontally. resize it.
|
||||
result.right = big_rect.right;
|
||||
result.left = big_rect.left;
|
||||
} else {
|
||||
if (result.right > big_rect.right) {
|
||||
// move the rect left.
|
||||
result.left -= result.right-big_rect.right;
|
||||
result.right -= result.right-big_rect.right;
|
||||
RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect)
|
||||
{
|
||||
RECT result = small_rect;
|
||||
if ((result.right - result.left) > (big_rect.right - big_rect.left))
|
||||
{
|
||||
// small_rect is too big horizontally. resize it.
|
||||
result.right = big_rect.right;
|
||||
result.left = big_rect.left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.right > big_rect.right)
|
||||
{
|
||||
// move the rect left.
|
||||
result.left -= result.right - big_rect.right;
|
||||
result.right -= result.right - big_rect.right;
|
||||
}
|
||||
|
||||
if (result.left < big_rect.left)
|
||||
{
|
||||
// move the rect right.
|
||||
result.right += big_rect.left - result.left;
|
||||
result.left += big_rect.left - result.left;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.left < big_rect.left) {
|
||||
// move the rect right.
|
||||
result.right += big_rect.left-result.left;
|
||||
result.left += big_rect.left-result.left;
|
||||
if ((result.bottom - result.top) > (big_rect.bottom - big_rect.top))
|
||||
{
|
||||
// small_rect is too big vertically. resize it.
|
||||
result.bottom = big_rect.bottom;
|
||||
result.top = big_rect.top;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.bottom > big_rect.bottom)
|
||||
{
|
||||
// move the rect up.
|
||||
result.top -= result.bottom - big_rect.bottom;
|
||||
result.bottom -= result.bottom - big_rect.bottom;
|
||||
}
|
||||
|
||||
if ((result.bottom - result.top) > (big_rect.bottom - big_rect.top)) {
|
||||
// small_rect is too big vertically. resize it.
|
||||
result.bottom = big_rect.bottom;
|
||||
result.top = big_rect.top;
|
||||
} else {
|
||||
if (result.bottom > big_rect.bottom) {
|
||||
// move the rect up.
|
||||
result.top -= result.bottom-big_rect.bottom;
|
||||
result.bottom -= result.bottom-big_rect.bottom;
|
||||
if (result.top < big_rect.top)
|
||||
{
|
||||
// move the rect down.
|
||||
result.bottom += big_rect.top - result.top;
|
||||
result.top += big_rect.top - result.top;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.top < big_rect.top) {
|
||||
// move the rect down.
|
||||
result.bottom += big_rect.top-result.top;
|
||||
result.top += big_rect.top-result.top;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_message_loop() {
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
|
||||
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw) {
|
||||
// Retrieve the system error message for the error code
|
||||
LPWSTR lpMsgBuf = NULL;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
lpMsgBuf,
|
||||
0, NULL) > 0) {
|
||||
// Display the error message and exit the process
|
||||
LPWSTR lpDisplayBuf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, (lstrlenW(lpMsgBuf) + lstrlenW(lpszFunction) + 40) * sizeof(WCHAR));
|
||||
if (lpDisplayBuf != NULL) {
|
||||
StringCchPrintfW(lpDisplayBuf,
|
||||
LocalSize(lpDisplayBuf) / sizeof(WCHAR),
|
||||
L"%s failed with error %d: %s",
|
||||
lpszFunction, dw, lpMsgBuf);
|
||||
MessageBoxW(NULL, (LPCTSTR)lpDisplayBuf, L"Error", MB_OK);
|
||||
LocalFree(lpDisplayBuf);
|
||||
int run_message_loop()
|
||||
{
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
|
||||
WindowState get_window_state(HWND hwnd) {
|
||||
WINDOWPLACEMENT placement;
|
||||
placement.length = sizeof(WINDOWPLACEMENT);
|
||||
|
||||
if (GetWindowPlacement(hwnd, &placement) == 0) {
|
||||
return UNKNONW;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED || IsIconic(hwnd)) {
|
||||
return MINIMIZED;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MAXIMIZE || placement.showCmd == SW_SHOWMAXIMIZED) {
|
||||
return MAXIMIZED;
|
||||
}
|
||||
|
||||
auto rectp = get_window_pos(hwnd);
|
||||
if (!rectp) {
|
||||
return UNKNONW;
|
||||
}
|
||||
|
||||
auto rect = *rectp;
|
||||
MONITORINFO monitor;
|
||||
monitor.cbSize = sizeof(MONITORINFO);
|
||||
auto h_monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
GetMonitorInfo(h_monitor, &monitor);
|
||||
bool top_left = monitor.rcWork.top == rect.top && monitor.rcWork.left == rect.left;
|
||||
bool bottom_left = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.left == rect.left;
|
||||
bool top_right = monitor.rcWork.top == rect.top && monitor.rcWork.right == rect.right;
|
||||
bool bottom_right = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.right == rect.right;
|
||||
|
||||
if (top_left && bottom_left) return SNAPED_LEFT;
|
||||
if (top_left) return SNAPED_TOP_LEFT;
|
||||
if (bottom_left) return SNAPED_BOTTOM_LEFT;
|
||||
if (top_right && bottom_right) return SNAPED_RIGHT;
|
||||
if (top_right) return SNAPED_TOP_RIGHT;
|
||||
if (bottom_right) return SNAPED_BOTTOM_RIGHT;
|
||||
|
||||
return RESTORED;
|
||||
}
|
||||
|
||||
bool is_process_elevated() {
|
||||
HANDLE token = nullptr;
|
||||
bool elevated = false;
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
||||
TOKEN_ELEVATION elevation;
|
||||
DWORD size;
|
||||
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {
|
||||
elevated = (elevation.TokenIsElevated != 0);
|
||||
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw)
|
||||
{
|
||||
// Retrieve the system error message for the error code
|
||||
LPWSTR lpMsgBuf = NULL;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
lpMsgBuf,
|
||||
0,
|
||||
NULL) > 0)
|
||||
{
|
||||
// Display the error message and exit the process
|
||||
LPWSTR lpDisplayBuf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, (lstrlenW(lpMsgBuf) + lstrlenW(lpszFunction) + 40) * sizeof(WCHAR));
|
||||
if (lpDisplayBuf != NULL)
|
||||
{
|
||||
StringCchPrintfW(lpDisplayBuf,
|
||||
LocalSize(lpDisplayBuf) / sizeof(WCHAR),
|
||||
L"%s failed with error %d: %s",
|
||||
lpszFunction,
|
||||
dw,
|
||||
lpMsgBuf);
|
||||
MessageBoxW(NULL, (LPCTSTR)lpDisplayBuf, L"Error", MB_OK);
|
||||
LocalFree(lpDisplayBuf);
|
||||
}
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (token) {
|
||||
WindowState get_window_state(HWND hwnd)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
placement.length = sizeof(WINDOWPLACEMENT);
|
||||
|
||||
if (GetWindowPlacement(hwnd, &placement) == 0)
|
||||
{
|
||||
return UNKNONW;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED || IsIconic(hwnd))
|
||||
{
|
||||
return MINIMIZED;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MAXIMIZE || placement.showCmd == SW_SHOWMAXIMIZED)
|
||||
{
|
||||
return MAXIMIZED;
|
||||
}
|
||||
|
||||
auto rectp = get_window_pos(hwnd);
|
||||
if (!rectp)
|
||||
{
|
||||
return UNKNONW;
|
||||
}
|
||||
|
||||
auto rect = *rectp;
|
||||
MONITORINFO monitor;
|
||||
monitor.cbSize = sizeof(MONITORINFO);
|
||||
auto h_monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
GetMonitorInfo(h_monitor, &monitor);
|
||||
bool top_left = monitor.rcWork.top == rect.top && monitor.rcWork.left == rect.left;
|
||||
bool bottom_left = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.left == rect.left;
|
||||
bool top_right = monitor.rcWork.top == rect.top && monitor.rcWork.right == rect.right;
|
||||
bool bottom_right = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.right == rect.right;
|
||||
|
||||
if (top_left && bottom_left)
|
||||
return SNAPED_LEFT;
|
||||
if (top_left)
|
||||
return SNAPED_TOP_LEFT;
|
||||
if (bottom_left)
|
||||
return SNAPED_BOTTOM_LEFT;
|
||||
if (top_right && bottom_right)
|
||||
return SNAPED_RIGHT;
|
||||
if (top_right)
|
||||
return SNAPED_TOP_RIGHT;
|
||||
if (bottom_right)
|
||||
return SNAPED_BOTTOM_RIGHT;
|
||||
|
||||
return RESTORED;
|
||||
}
|
||||
|
||||
bool is_process_elevated()
|
||||
{
|
||||
HANDLE token = nullptr;
|
||||
bool elevated = false;
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||
{
|
||||
TOKEN_ELEVATION elevation;
|
||||
DWORD size;
|
||||
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size))
|
||||
{
|
||||
elevated = (elevation.TokenIsElevated != 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (token)
|
||||
{
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
return elevated;
|
||||
}
|
||||
|
||||
bool drop_elevated_privileges()
|
||||
{
|
||||
HANDLE token = nullptr;
|
||||
LPCTSTR lpszPrivilege = SE_SECURITY_NAME;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT | WRITE_OWNER, &token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PSID medium_sid = NULL;
|
||||
if (!::ConvertStringSidToSid(SDDL_ML_MEDIUM, &medium_sid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOKEN_MANDATORY_LABEL label = { 0 };
|
||||
label.Label.Attributes = SE_GROUP_INTEGRITY;
|
||||
label.Label.Sid = medium_sid;
|
||||
DWORD size = (DWORD)sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(medium_sid);
|
||||
|
||||
BOOL result = SetTokenInformation(token, TokenIntegrityLevel, &label, size);
|
||||
LocalFree(medium_sid);
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
return elevated;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool drop_elevated_privileges() {
|
||||
HANDLE token = nullptr;
|
||||
LPCTSTR lpszPrivilege = SE_SECURITY_NAME;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT | WRITE_OWNER, &token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PSID medium_sid = NULL;
|
||||
if (!::ConvertStringSidToSid(SDDL_ML_MEDIUM, &medium_sid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TOKEN_MANDATORY_LABEL label = { 0 };
|
||||
label.Label.Attributes = SE_GROUP_INTEGRITY;
|
||||
label.Label.Sid = medium_sid;
|
||||
DWORD size = (DWORD)sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(medium_sid);
|
||||
|
||||
BOOL result = SetTokenInformation(token, TokenIntegrityLevel, &label, size);
|
||||
LocalFree(medium_sid);
|
||||
CloseHandle(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring get_process_path(DWORD pid) noexcept {
|
||||
auto process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid);
|
||||
std::wstring name;
|
||||
if (process != INVALID_HANDLE_VALUE) {
|
||||
name.resize(MAX_PATH);
|
||||
DWORD name_length = static_cast<DWORD>(name.length());
|
||||
if (QueryFullProcessImageNameW(process, 0, (LPWSTR)name.data(), &name_length) == 0) {
|
||||
name_length = 0;
|
||||
std::wstring get_process_path(DWORD pid) noexcept
|
||||
{
|
||||
auto process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid);
|
||||
std::wstring name;
|
||||
if (process != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
name.resize(MAX_PATH);
|
||||
DWORD name_length = static_cast<DWORD>(name.length());
|
||||
if (QueryFullProcessImageNameW(process, 0, (LPWSTR)name.data(), &name_length) == 0)
|
||||
{
|
||||
name_length = 0;
|
||||
}
|
||||
name.resize(name_length);
|
||||
CloseHandle(process);
|
||||
}
|
||||
name.resize(name_length);
|
||||
CloseHandle(process);
|
||||
}
|
||||
return name;
|
||||
return name;
|
||||
}
|
||||
|
||||
bool run_elevated(const std::wstring& file, const std::wstring& params) {
|
||||
SHELLEXECUTEINFOW exec_info = { 0 };
|
||||
exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
|
||||
exec_info.lpVerb = L"runas";
|
||||
exec_info.lpFile = file.c_str();
|
||||
exec_info.lpParameters = params.c_str();
|
||||
exec_info.hwnd = 0;
|
||||
exec_info.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
exec_info.lpDirectory = 0;
|
||||
exec_info.hInstApp = 0;
|
||||
bool run_elevated(const std::wstring& file, const std::wstring& params)
|
||||
{
|
||||
SHELLEXECUTEINFOW exec_info = { 0 };
|
||||
exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
|
||||
exec_info.lpVerb = L"runas";
|
||||
exec_info.lpFile = file.c_str();
|
||||
exec_info.lpParameters = params.c_str();
|
||||
exec_info.hwnd = 0;
|
||||
exec_info.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
exec_info.lpDirectory = 0;
|
||||
exec_info.hInstApp = 0;
|
||||
|
||||
if (ShellExecuteExW(&exec_info)) {
|
||||
return exec_info.hProcess != nullptr;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool run_non_elevated(const std::wstring& file, const std::wstring& params) {
|
||||
auto executable_args = file;
|
||||
if (!params.empty()) {
|
||||
executable_args += L" " + params;
|
||||
}
|
||||
|
||||
HWND hwnd = GetShellWindow();
|
||||
if (!hwnd) {
|
||||
return false;
|
||||
}
|
||||
DWORD pid;
|
||||
GetWindowThreadProcessId(hwnd, &pid);
|
||||
|
||||
winrt::handle process{ OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid) };
|
||||
if (!process) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SIZE_T size = 0;
|
||||
|
||||
InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
|
||||
auto pproc_buffer = std::make_unique<char[]>(size);
|
||||
auto pptal = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(pproc_buffer.get());
|
||||
|
||||
if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE process_handle = process.get();
|
||||
if (!pptal || !UpdateProcThreadAttribute(pptal,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
|
||||
&process_handle,
|
||||
sizeof(process_handle),
|
||||
nullptr,
|
||||
nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTUPINFOEX siex = { 0 };
|
||||
siex.lpAttributeList = pptal;
|
||||
siex.StartupInfo.cb = sizeof(siex);
|
||||
|
||||
PROCESS_INFORMATION process_info = { 0 };
|
||||
auto succedded = CreateProcessW(file.c_str(),
|
||||
const_cast<LPWSTR>(executable_args.c_str()),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
EXTENDED_STARTUPINFO_PRESENT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&siex.StartupInfo,
|
||||
&process_info);
|
||||
if (process_info.hProcess) {
|
||||
CloseHandle(process_info.hProcess);
|
||||
}
|
||||
if (process_info.hThread) {
|
||||
CloseHandle(process_info.hThread);
|
||||
}
|
||||
return succedded;
|
||||
}
|
||||
|
||||
bool run_same_elevation(const std::wstring& file, const std::wstring& params) {
|
||||
auto executable_args = file;
|
||||
if (!params.empty()) {
|
||||
executable_args += L" " + params;
|
||||
}
|
||||
STARTUPINFO si = { 0 };
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
auto succedded = CreateProcessW(file.c_str(),
|
||||
const_cast<LPWSTR>(executable_args.c_str()),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&si,
|
||||
&pi);
|
||||
if (pi.hProcess) {
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
if (pi.hThread) {
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
return succedded;
|
||||
}
|
||||
|
||||
|
||||
std::wstring get_process_path(HWND window) noexcept {
|
||||
const static std::wstring app_frame_host = L"ApplicationFrameHost.exe";
|
||||
DWORD pid{};
|
||||
GetWindowThreadProcessId(window, &pid);
|
||||
auto name = get_process_path(pid);
|
||||
if (name.length() >= app_frame_host.length() &&
|
||||
name.compare(name.length() - app_frame_host.length(), app_frame_host.length(), app_frame_host) == 0) {
|
||||
// It is a UWP app. We will enumarate the windows and look for one created
|
||||
// by something with a different PID
|
||||
DWORD new_pid = pid;
|
||||
EnumChildWindows(window, [](HWND hwnd, LPARAM param) -> BOOL {
|
||||
auto new_pid_ptr = reinterpret_cast<DWORD*>(param);
|
||||
DWORD pid;
|
||||
GetWindowThreadProcessId(hwnd, &pid);
|
||||
if (pid != *new_pid_ptr) {
|
||||
*new_pid_ptr = pid;
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}, reinterpret_cast<LPARAM>(&new_pid));
|
||||
// If we have a new pid, get the new name.
|
||||
if (new_pid != pid) {
|
||||
return get_process_path(new_pid);
|
||||
if (ShellExecuteExW(&exec_info))
|
||||
{
|
||||
return exec_info.hProcess != nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::wstring get_product_version() {
|
||||
static std::wstring version = std::to_wstring(VERSION_MAJOR) +
|
||||
L"." + std::to_wstring(VERSION_MINOR) +
|
||||
L"." + std::to_wstring(VERSION_REVISION) +
|
||||
L"." + std::to_wstring(VERSION_BUILD);
|
||||
bool run_non_elevated(const std::wstring& file, const std::wstring& params)
|
||||
{
|
||||
auto executable_args = file;
|
||||
if (!params.empty())
|
||||
{
|
||||
executable_args += L" " + params;
|
||||
}
|
||||
|
||||
return version;
|
||||
HWND hwnd = GetShellWindow();
|
||||
if (!hwnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DWORD pid;
|
||||
GetWindowThreadProcessId(hwnd, &pid);
|
||||
|
||||
winrt::handle process{ OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid) };
|
||||
if (!process)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SIZE_T size = 0;
|
||||
|
||||
InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
|
||||
auto pproc_buffer = std::make_unique<char[]>(size);
|
||||
auto pptal = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(pproc_buffer.get());
|
||||
|
||||
if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE process_handle = process.get();
|
||||
if (!pptal || !UpdateProcThreadAttribute(pptal,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
|
||||
&process_handle,
|
||||
sizeof(process_handle),
|
||||
nullptr,
|
||||
nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTUPINFOEX siex = { 0 };
|
||||
siex.lpAttributeList = pptal;
|
||||
siex.StartupInfo.cb = sizeof(siex);
|
||||
|
||||
PROCESS_INFORMATION process_info = { 0 };
|
||||
auto succedded = CreateProcessW(file.c_str(),
|
||||
const_cast<LPWSTR>(executable_args.c_str()),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
EXTENDED_STARTUPINFO_PRESENT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&siex.StartupInfo,
|
||||
&process_info);
|
||||
if (process_info.hProcess)
|
||||
{
|
||||
CloseHandle(process_info.hProcess);
|
||||
}
|
||||
if (process_info.hThread)
|
||||
{
|
||||
CloseHandle(process_info.hThread);
|
||||
}
|
||||
return succedded;
|
||||
}
|
||||
|
||||
std::wstring get_resource_string(UINT resource_id, HINSTANCE instance, const wchar_t* fallback) {
|
||||
wchar_t* text_ptr;
|
||||
auto length = LoadStringW(instance, resource_id, reinterpret_cast<wchar_t*>(&text_ptr), 0);
|
||||
if (length == 0) {
|
||||
return fallback;
|
||||
} else {
|
||||
return { text_ptr, static_cast<std::size_t>(length) };
|
||||
}
|
||||
bool run_same_elevation(const std::wstring& file, const std::wstring& params)
|
||||
{
|
||||
auto executable_args = file;
|
||||
if (!params.empty())
|
||||
{
|
||||
executable_args += L" " + params;
|
||||
}
|
||||
STARTUPINFO si = { 0 };
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
auto succedded = CreateProcessW(file.c_str(),
|
||||
const_cast<LPWSTR>(executable_args.c_str()),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&si,
|
||||
&pi);
|
||||
if (pi.hProcess)
|
||||
{
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
if (pi.hThread)
|
||||
{
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
return succedded;
|
||||
}
|
||||
|
||||
// function to return the string as a to a wchar_t* (to enable localization in cases where the return type did not accept wstring)
|
||||
wchar_t* get_resource_string_wchar(UINT resource_id, HINSTANCE instance)
|
||||
std::wstring get_process_path(HWND window) noexcept
|
||||
{
|
||||
const static std::wstring app_frame_host = L"ApplicationFrameHost.exe";
|
||||
DWORD pid{};
|
||||
GetWindowThreadProcessId(window, &pid);
|
||||
auto name = get_process_path(pid);
|
||||
if (name.length() >= app_frame_host.length() &&
|
||||
name.compare(name.length() - app_frame_host.length(), app_frame_host.length(), app_frame_host) == 0)
|
||||
{
|
||||
// It is a UWP app. We will enumarate the windows and look for one created
|
||||
// by something with a different PID
|
||||
DWORD new_pid = pid;
|
||||
EnumChildWindows(
|
||||
window, [](HWND hwnd, LPARAM param) -> BOOL {
|
||||
auto new_pid_ptr = reinterpret_cast<DWORD*>(param);
|
||||
DWORD pid;
|
||||
GetWindowThreadProcessId(hwnd, &pid);
|
||||
if (pid != *new_pid_ptr)
|
||||
{
|
||||
*new_pid_ptr = pid;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
},
|
||||
reinterpret_cast<LPARAM>(&new_pid));
|
||||
// If we have a new pid, get the new name.
|
||||
if (new_pid != pid)
|
||||
{
|
||||
return get_process_path(new_pid);
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::wstring get_product_version()
|
||||
{
|
||||
static std::wstring version = std::to_wstring(VERSION_MAJOR) +
|
||||
L"." + std::to_wstring(VERSION_MINOR) +
|
||||
L"." + std::to_wstring(VERSION_REVISION) +
|
||||
L"." + std::to_wstring(VERSION_BUILD);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
std::wstring get_resource_string(UINT resource_id, HINSTANCE instance, const wchar_t* fallback)
|
||||
{
|
||||
wchar_t* text_ptr;
|
||||
unsigned int length = LoadStringW(instance, resource_id, reinterpret_cast<wchar_t*>(&text_ptr), 0);
|
||||
std::wstring res_string = { *reinterpret_cast<wchar_t**>(&text_ptr), length };
|
||||
length++;
|
||||
|
||||
if (length > 1)
|
||||
auto length = LoadStringW(instance, resource_id, reinterpret_cast<wchar_t*>(&text_ptr), 0);
|
||||
if (length == 0)
|
||||
{
|
||||
wchar_t* tmp_res_ptr;
|
||||
tmp_res_ptr = new wchar_t[length];
|
||||
wmemcpy(tmp_res_ptr, res_string.c_str(), length);
|
||||
return tmp_res_ptr;
|
||||
return fallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
return { text_ptr, static_cast<std::size_t>(length) };
|
||||
}
|
||||
|
||||
return (wchar_t*)L"test";
|
||||
}
|
||||
|
||||
std::wstring get_module_filename(HMODULE mod)
|
||||
|
@ -14,9 +14,10 @@ std::optional<POINT> get_mouse_pos();
|
||||
// Gets active window, filtering out all "non standard" windows like the taskbar, etc.
|
||||
HWND get_filtered_active_window();
|
||||
// Gets window ancestor (usualy the window we want to do stuff with), filtering out all "non standard" windows like the taskbar, etc. and provide the app process path
|
||||
struct WindowAndProcPath {
|
||||
HWND hwnd = nullptr;
|
||||
std::wstring process_path;
|
||||
struct WindowAndProcPath
|
||||
{
|
||||
HWND hwnd = nullptr;
|
||||
std::wstring process_path;
|
||||
};
|
||||
WindowAndProcPath get_filtered_base_window_and_path(HWND window);
|
||||
|
||||
@ -32,17 +33,18 @@ int run_message_loop();
|
||||
|
||||
void show_last_error_message(LPCWSTR lpszFunction, DWORD dw);
|
||||
|
||||
enum WindowState {
|
||||
UNKNONW,
|
||||
MINIMIZED,
|
||||
MAXIMIZED,
|
||||
SNAPED_TOP_LEFT,
|
||||
SNAPED_LEFT,
|
||||
SNAPED_BOTTOM_LEFT,
|
||||
SNAPED_TOP_RIGHT,
|
||||
SNAPED_RIGHT,
|
||||
SNAPED_BOTTOM_RIGHT,
|
||||
RESTORED
|
||||
enum WindowState
|
||||
{
|
||||
UNKNONW,
|
||||
MINIMIZED,
|
||||
MAXIMIZED,
|
||||
SNAPED_TOP_LEFT,
|
||||
SNAPED_LEFT,
|
||||
SNAPED_BOTTOM_LEFT,
|
||||
SNAPED_TOP_RIGHT,
|
||||
SNAPED_RIGHT,
|
||||
SNAPED_BOTTOM_RIGHT,
|
||||
RESTORED
|
||||
};
|
||||
WindowState get_window_state(HWND hwnd);
|
||||
|
||||
@ -78,15 +80,3 @@ std::wstring get_resource_string(UINT resource_id, HINSTANCE instance, const wch
|
||||
// extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
// is added to the .cpp file.
|
||||
#define GET_RESOURCE_STRING(resource_id) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), L#resource_id)
|
||||
|
||||
// Function which takes a pointer ptr and allocates space before populating it with the string from the resource table
|
||||
// using this approach as wstring cannot be cast to PCWSTR without allocating space
|
||||
// hence, we have to malloc and free the pointer after each use
|
||||
wchar_t* get_resource_string_wchar(UINT resource_id, HINSTANCE instance);
|
||||
|
||||
// Wrapper for getting a string from the resource file.
|
||||
// Requires that
|
||||
// extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
// is added to the .cpp file.
|
||||
// used when the return type must be a wchar_t* instead of a wstring.
|
||||
#define GET_RES_STRING_WCHAR(resource_id) get_resource_string_wchar(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase))
|
||||
|
@ -197,8 +197,8 @@ DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
|
||||
|
||||
HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
|
||||
{
|
||||
app_name = GET_RES_STRING_WCHAR(IDS_POWERRENAME);
|
||||
return SHStrDup(app_name, ppszName);
|
||||
app_name = GET_RESOURCE_STRING(IDS_POWERRENAME);
|
||||
return SHStrDup(app_name.c_str(), ppszName);
|
||||
}
|
||||
|
||||
HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
|
||||
|
@ -71,5 +71,5 @@ private:
|
||||
std::atomic<long> m_refCount = 1;
|
||||
HBITMAP m_hbmpIcon = nullptr;
|
||||
CComPtr<IDataObject> m_spdo;
|
||||
wchar_t* app_name;
|
||||
std::wstring app_name;
|
||||
};
|
||||
|
@ -161,14 +161,14 @@ class PowerRenameModule : public PowertoyModuleIface
|
||||
private:
|
||||
// Enabled by default
|
||||
bool m_enabled = true;
|
||||
wchar_t* app_name;
|
||||
std::wstring app_name;
|
||||
|
||||
public:
|
||||
// Return the display name of the powertoy, this will be cached
|
||||
virtual PCWSTR get_name() override
|
||||
{
|
||||
app_name = GET_RES_STRING_WCHAR(IDS_POWERRENAME);
|
||||
return app_name;
|
||||
app_name = GET_RESOURCE_STRING(IDS_POWERRENAME);
|
||||
return app_name.c_str();
|
||||
}
|
||||
|
||||
// Enable the powertoy
|
||||
@ -303,10 +303,7 @@ public:
|
||||
init_settings();
|
||||
}
|
||||
|
||||
~PowerRenameModule()
|
||||
{
|
||||
delete app_name;
|
||||
}
|
||||
~PowerRenameModule(){};
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
||||
|
Loading…
Reference in New Issue
Block a user