From 038a4eb34d40abac8d0242f9ca881b0dac344723 Mon Sep 17 00:00:00 2001 From: fireice-uk Date: Mon, 25 Dec 2017 16:36:44 +0000 Subject: [PATCH 1/3] On-demand elevation --- .../backend/cpu/crypto/cryptonight_common.cpp | 4 +++ xmrstak/cli/cli-miner.cpp | 31 +++++++++---------- xmrstak/misc/uac.hpp | 20 ++++++++++-- xmrstak/params.hpp | 4 +++ 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp index 8b2207d..583deff 100644 --- a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp +++ b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp @@ -73,6 +73,8 @@ void do_skein_hash(const void* input, size_t len, char* output) { void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; #ifdef _WIN32 +#include "xmrstak/misc/uac.hpp" + BOOL bRebootDesirable = FALSE; //If VirtualAlloc fails, suggest a reboot BOOL AddPrivilege(TCHAR* pszPrivilege) @@ -176,6 +178,8 @@ size_t cryptonight_init(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg) if(AddPrivilege(TEXT("SeLockMemoryPrivilege")) == 0) { + RequestElevation(); + if(AddLargePageRights()) { msg->warning = "Added SeLockMemoryPrivilege to the current account. You need to reboot for it to work"; diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index b84b783..4904604 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -342,7 +342,14 @@ int main(int argc, char *argv[]) params::inst().executablePrefix += seperator; } - bool uacDialog = true; + params::inst().minerArg0 = argv[0]; + params::inst().minerArgs.reserve(argc * 16); + for(int i = 1; i < argc; i++) + { + params::inst().minerArgs += " "; + params::inst().minerArgs += argv[i]; + } + bool pool_url_set = false; for(size_t i = 1; i < argc-1; i++) { @@ -506,7 +513,7 @@ int main(int argc, char *argv[]) } else if(opName.compare("--noUAC") == 0) { - uacDialog = false; + params::inst().allowUAC = false; } else { @@ -516,20 +523,6 @@ int main(int argc, char *argv[]) } } -#ifdef _WIN32 - if(uacDialog && !IsElevated()) - { - std::string minerArgs; - for(int i = 1; i < argc; i++) - { - minerArgs += " "; - minerArgs += argv[i]; - } - - SelfElevate(argv[0], minerArgs); - } -#endif - // check if we need a guided start if(!configEditor::file_exist(params::inst().configFile)) do_guided_config(); @@ -540,6 +533,12 @@ int main(int argc, char *argv[]) return 1; } +#ifdef _WIN32 + /* For Windows 7 and 8 request elevation at all times unless we are using slow memory */ + if(jconf::inst()->GetSlowMemSetting() != jconf::slow_mem_cfg::always_use && LOBYTE(LOWORD(GetVersion())) < 10) + RequestElevation(); +#endif + if (!BackendConnector::self_test()) { win_exit(); diff --git a/xmrstak/misc/uac.hpp b/xmrstak/misc/uac.hpp index 55c5f1a..4fb5b0c 100644 --- a/xmrstak/misc/uac.hpp +++ b/xmrstak/misc/uac.hpp @@ -2,6 +2,7 @@ #ifdef _WIN32 #include "xmrstak/misc/console.hpp" +#include "xmrstak/params.hpp" #include #include @@ -22,7 +23,7 @@ BOOL IsElevated() return fRet; } -BOOL SelfElevate(const char* my_path, const std::string& params) +BOOL SelfElevate(const std::string& my_path, const std::string& params) { if (IsElevated()) return FALSE; @@ -32,7 +33,7 @@ BOOL SelfElevate(const char* my_path, const std::string& params) shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; shExecInfo.hwnd = NULL; shExecInfo.lpVerb = "runas"; - shExecInfo.lpFile = my_path; + shExecInfo.lpFile = my_path.c_str(); shExecInfo.lpParameters = params.c_str(); shExecInfo.lpDirectory = NULL; shExecInfo.nShow = SW_SHOW; @@ -48,4 +49,19 @@ BOOL SelfElevate(const char* my_path, const std::string& params) return TRUE; } + +VOID RequestElevation() +{ + if(IsElevated()) + return; + + if(!xmrstak::params::inst().allowUAC) + { + printer::inst()->print_msg(L0, "The miner needs to run as administrator, but you passed --noUAC option. Please remove it or set use_slow_memory to always."); + win_exit(); + return; + } + + SelfElevate(xmrstak::params::inst().minerArg0, xmrstak::params::inst().minerArgs); +} #endif diff --git a/xmrstak/params.hpp b/xmrstak/params.hpp index bc32612..4cc041c 100644 --- a/xmrstak/params.hpp +++ b/xmrstak/params.hpp @@ -38,6 +38,10 @@ struct params std::string configFileNVIDIA; std::string configFileCPU; + bool allowUAC = true; + std::string minerArg0; + std::string minerArgs; + params() : binaryName("xmr-stak"), executablePrefix(""), From 5e5888bff84eb98932df1852ef57ff6ebfc0be56 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 25 Dec 2017 17:30:52 +0000 Subject: [PATCH 2/3] fix windows build --- xmrstak/misc/uac.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++ xmrstak/misc/uac.hpp | 64 ++---------------------------------------- 2 files changed, 70 insertions(+), 61 deletions(-) create mode 100644 xmrstak/misc/uac.cpp diff --git a/xmrstak/misc/uac.cpp b/xmrstak/misc/uac.cpp new file mode 100644 index 0000000..4fb5b0c --- /dev/null +++ b/xmrstak/misc/uac.cpp @@ -0,0 +1,67 @@ +#pragma once + +#ifdef _WIN32 +#include "xmrstak/misc/console.hpp" +#include "xmrstak/params.hpp" + +#include +#include + +BOOL IsElevated() +{ + BOOL fRet = FALSE; + HANDLE hToken = NULL; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) + fRet = Elevation.TokenIsElevated; + } + if (hToken) + CloseHandle(hToken); + return fRet; +} + +BOOL SelfElevate(const std::string& my_path, const std::string& params) +{ + if (IsElevated()) + return FALSE; + + SHELLEXECUTEINFO shExecInfo = { 0 }; + shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + shExecInfo.hwnd = NULL; + shExecInfo.lpVerb = "runas"; + shExecInfo.lpFile = my_path.c_str(); + shExecInfo.lpParameters = params.c_str(); + shExecInfo.lpDirectory = NULL; + shExecInfo.nShow = SW_SHOW; + shExecInfo.hInstApp = NULL; + + if (!ShellExecuteEx(&shExecInfo)) + return FALSE; + + // Loiter in the background to make scripting easier + printer::inst()->print_msg(L0, "This window has been opened because xmr-stak needed to run as administrator. It can be safely closed now."); + WaitForSingleObject(shExecInfo.hProcess, INFINITE); + std::exit(0); + + return TRUE; +} + +VOID RequestElevation() +{ + if(IsElevated()) + return; + + if(!xmrstak::params::inst().allowUAC) + { + printer::inst()->print_msg(L0, "The miner needs to run as administrator, but you passed --noUAC option. Please remove it or set use_slow_memory to always."); + win_exit(); + return; + } + + SelfElevate(xmrstak::params::inst().minerArg0, xmrstak::params::inst().minerArgs); +} +#endif diff --git a/xmrstak/misc/uac.hpp b/xmrstak/misc/uac.hpp index 4fb5b0c..82cdf42 100644 --- a/xmrstak/misc/uac.hpp +++ b/xmrstak/misc/uac.hpp @@ -1,67 +1,9 @@ #pragma once #ifdef _WIN32 -#include "xmrstak/misc/console.hpp" -#include "xmrstak/params.hpp" - #include -#include -BOOL IsElevated() -{ - BOOL fRet = FALSE; - HANDLE hToken = NULL; - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) - { - TOKEN_ELEVATION Elevation; - DWORD cbSize = sizeof(TOKEN_ELEVATION); - if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) - fRet = Elevation.TokenIsElevated; - } - if (hToken) - CloseHandle(hToken); - return fRet; -} - -BOOL SelfElevate(const std::string& my_path, const std::string& params) -{ - if (IsElevated()) - return FALSE; - - SHELLEXECUTEINFO shExecInfo = { 0 }; - shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); - shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExecInfo.hwnd = NULL; - shExecInfo.lpVerb = "runas"; - shExecInfo.lpFile = my_path.c_str(); - shExecInfo.lpParameters = params.c_str(); - shExecInfo.lpDirectory = NULL; - shExecInfo.nShow = SW_SHOW; - shExecInfo.hInstApp = NULL; - - if (!ShellExecuteEx(&shExecInfo)) - return FALSE; - - // Loiter in the background to make scripting easier - printer::inst()->print_msg(L0, "This window has been opened because xmr-stak needed to run as administrator. It can be safely closed now."); - WaitForSingleObject(shExecInfo.hProcess, INFINITE); - std::exit(0); - - return TRUE; -} - -VOID RequestElevation() -{ - if(IsElevated()) - return; - - if(!xmrstak::params::inst().allowUAC) - { - printer::inst()->print_msg(L0, "The miner needs to run as administrator, but you passed --noUAC option. Please remove it or set use_slow_memory to always."); - win_exit(); - return; - } - - SelfElevate(xmrstak::params::inst().minerArg0, xmrstak::params::inst().minerArgs); -} +BOOL IsElevated(); +BOOL SelfElevate(const std::string& my_path, const std::string& params); +VOID RequestElevation(); #endif From b216f39a52d87e48b2399da5e3272a9a464ac359 Mon Sep 17 00:00:00 2001 From: fireice-uk Date: Tue, 26 Dec 2017 21:11:22 +0000 Subject: [PATCH 3/3] Busywork courtesy of Microsoft Add messages Missing include 1 --- CMakeLists.txt | 10 +++--- .../backend/cpu/crypto/cryptonight_common.cpp | 2 ++ xmrstak/cli/cli-miner.cpp | 5 ++- xmrstak/cli/xmr-stak.manifest | 34 +++++++++++++++++++ xmrstak/misc/uac.cpp | 12 +++++++ xmrstak/misc/uac.hpp | 1 + 6 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 xmrstak/cli/xmr-stak.manifest diff --git a/CMakeLists.txt b/CMakeLists.txt index 10f33bd..3b3c7eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(xmr-stak) -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.4.0) # enforce C++11 set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -522,9 +522,11 @@ endif() file(GLOB SRCFILES_CPP "xmrstak/cli/*.cpp") set_source_files_properties(${SRCFILES_CPP} PROPERTIES LANGUAGE CXX) -add_executable(xmr-stak - ${SRCFILES_CPP} -) +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + add_executable(xmr-stak ${SRCFILES_CPP} xmrstak/cli/xmr-stak.manifest) +else() + add_executable(xmr-stak ${SRCFILES_CPP}) +endif() set(EXECUTABLE_OUTPUT_PATH "bin") set(LIBRARY_OUTPUT_PATH "bin") diff --git a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp index 583deff..547b104 100644 --- a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp +++ b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp @@ -31,6 +31,7 @@ extern "C" #include "cryptonight.h" #include "cryptonight_aesni.h" #include "xmrstak/backend/cryptonight.hpp" +#include "xmrstak/misc/console.hpp" #include "xmrstak/jconf.hpp" #include #include @@ -178,6 +179,7 @@ size_t cryptonight_init(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg) if(AddPrivilege(TEXT("SeLockMemoryPrivilege")) == 0) { + printer::inst()->print_msg(L0, "Elevating because we need to set up fast memory privileges."); RequestElevation(); if(AddLargePageRights()) diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 4904604..0daa4e8 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -535,8 +535,11 @@ int main(int argc, char *argv[]) #ifdef _WIN32 /* For Windows 7 and 8 request elevation at all times unless we are using slow memory */ - if(jconf::inst()->GetSlowMemSetting() != jconf::slow_mem_cfg::always_use && LOBYTE(LOWORD(GetVersion())) < 10) + if(jconf::inst()->GetSlowMemSetting() != jconf::slow_mem_cfg::always_use && !IsWindows10OrNewer()) + { + printer::inst()->print_msg(L0, "Elevating due to Windows 7 or 8. You need Windows 10 to use fast memory without UAC elevation."); RequestElevation(); + } #endif if (!BackendConnector::self_test()) diff --git a/xmrstak/cli/xmr-stak.manifest b/xmrstak/cli/xmr-stak.manifest new file mode 100644 index 0000000..ed65c97 --- /dev/null +++ b/xmrstak/cli/xmr-stak.manifest @@ -0,0 +1,34 @@ + + + + XMR-Stak Monero Miner + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmrstak/misc/uac.cpp b/xmrstak/misc/uac.cpp index 4fb5b0c..5e8d08a 100644 --- a/xmrstak/misc/uac.cpp +++ b/xmrstak/misc/uac.cpp @@ -64,4 +64,16 @@ VOID RequestElevation() SelfElevate(xmrstak::params::inst().minerArg0, xmrstak::params::inst().minerArgs); } + +BOOL IsWindows10OrNewer() +{ + OSVERSIONINFOEX osvi = { 0 }; + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 10; + osvi.dwMinorVersion = 0; + DWORDLONG dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + return ::VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); +} #endif diff --git a/xmrstak/misc/uac.hpp b/xmrstak/misc/uac.hpp index 82cdf42..33c79ae 100644 --- a/xmrstak/misc/uac.hpp +++ b/xmrstak/misc/uac.hpp @@ -6,4 +6,5 @@ BOOL IsElevated(); BOOL SelfElevate(const std::string& my_path, const std::string& params); VOID RequestElevation(); +BOOL IsWindows10OrNewer(); #endif