diff options
author | psychocrypt <psychocrypt@users.noreply.github.com> | 2017-10-05 22:15:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-05 22:15:32 +0200 |
commit | e96a761d5a748ab06749a18db5e16d87739d7716 (patch) | |
tree | 5619ff90e4701dd22a39cac4cee27a217b00f54c /xmrstak | |
parent | 34a87c64a19cbdd9f73eb0142b9e6f3f573e726e (diff) | |
parent | f6b310dc86ec437c6df0f0f036f763bbdf010cba (diff) | |
download | xmr-stak-e96a761d5a748ab06749a18db5e16d87739d7716.zip xmr-stak-e96a761d5a748ab06749a18db5e16d87739d7716.tar.gz |
Merge pull request #12 from fireice-uk/topic-large-pages-win
Fix large pages on Windows and make them more user-friendly
Diffstat (limited to 'xmrstak')
-rw-r--r-- | xmrstak/backend/backendConnector.cpp | 3 | ||||
-rw-r--r-- | xmrstak/backend/cpu/crypto/cryptonight_common.cpp | 93 | ||||
-rw-r--r-- | xmrstak/cli/cli-miner.cpp | 11 | ||||
-rw-r--r-- | xmrstak/misc/uac.hpp | 44 |
4 files changed, 145 insertions, 6 deletions
diff --git a/xmrstak/backend/backendConnector.cpp b/xmrstak/backend/backendConnector.cpp index 6106267..28ba1ac 100644 --- a/xmrstak/backend/backendConnector.cpp +++ b/xmrstak/backend/backendConnector.cpp @@ -52,8 +52,7 @@ namespace xmrstak bool BackendConnector::self_test() { - - return true; + return cpu::minethd::self_test(); } std::vector<iBackend*>* BackendConnector::thread_starter(miner_work& pWork) diff --git a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp index 9d03ed7..0690415 100644 --- a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp +++ b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp @@ -45,6 +45,7 @@ extern "C" #ifdef _WIN32 #include <windows.h> +#include <ntsecapi.h> #else #include <sys/mman.h> #include <errno.h> @@ -70,6 +71,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 +BOOL bRebootDesirable = FALSE; //If VirtualAlloc fails, suggest a reboot + BOOL AddPrivilege(TCHAR* pszPrivilege) { HANDLE hToken; @@ -92,16 +95,97 @@ BOOL AddPrivilege(TCHAR* pszPrivilege) CloseHandle(hToken); return TRUE; } + +BOOL AddLargePageRights() +{ + HANDLE hToken; + PTOKEN_USER user = NULL; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == TRUE) + { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + BOOL bIsElevated = FALSE; + + if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) + bIsElevated = Elevation.TokenIsElevated; + + DWORD size = 0; + GetTokenInformation(hToken, TokenUser, NULL, 0, &size); + + if (size > 0 && bIsElevated) + { + user = (PTOKEN_USER)LocalAlloc(LPTR, size); + GetTokenInformation(hToken, TokenUser, user, size, &size); + } + + CloseHandle(hToken); + } + + if (!user) + return FALSE; + + LSA_HANDLE handle; + LSA_OBJECT_ATTRIBUTES attributes; + ZeroMemory(&attributes, sizeof(attributes)); + + BOOL result = FALSE; + if (LsaOpenPolicy(NULL, &attributes, POLICY_ALL_ACCESS, &handle) == 0) + { + LSA_UNICODE_STRING lockmem; + lockmem.Buffer = L"SeLockMemoryPrivilege"; + lockmem.Length = 42; + lockmem.MaximumLength = 44; + + PLSA_UNICODE_STRING rights = NULL; + ULONG cnt = 0; + BOOL bHasRights = FALSE; + if (LsaEnumerateAccountRights(handle, user->User.Sid, &rights, &cnt) == 0) + { + for (size_t i = 0; i < cnt; i++) + { + if (rights[i].Length == lockmem.Length && + memcmp(rights[i].Buffer, lockmem.Buffer, 42) == 0) + { + bHasRights = TRUE; + break; + } + } + + LsaFreeMemory(rights); + } + + if(!bHasRights) + result = LsaAddAccountRights(handle, user->User.Sid, &lockmem, 1) == 0; + + LsaClose(handle); + } + + LocalFree(user); + return result; +} #endif size_t cryptonight_init(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg) { #ifdef _WIN32 - if (AddPrivilege(TEXT("SeLockMemoryPrivilege")) == 0) + if(use_fast_mem == 0) + return 1; + + if(AddPrivilege(TEXT("SeLockMemoryPrivilege")) == 0) { - msg->warning = "Obtaning SeLockMemoryPrivilege failed."; + if(AddLargePageRights()) + { + msg->warning = "Added SeLockMemoryPrivilege to the current account. You need to reboot for it to work"; + bRebootDesirable = TRUE; + } + else + msg->warning = "Obtaning SeLockMemoryPrivilege failed."; + return 0; } + + bRebootDesirable = TRUE; return 1; #else return 1; @@ -133,7 +217,10 @@ cryptonight_ctx* cryptonight_alloc_ctx(size_t use_fast_mem, size_t use_mlock, al if(ptr->long_state == NULL) { _mm_free(ptr); - msg->warning = "VirtualAlloc failed."; + if(bRebootDesirable) + msg->warning = "VirtualAlloc failed. Reboot might help."; + else + msg->warning = "VirtualAlloc failed."; return NULL; } else diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index a2d950d..9be93a4 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -33,7 +33,11 @@ #include "xmrstak/version.hpp" #ifndef CONF_NO_HTTPD -# include "xmrstak/http//httpd.hpp" +# include "xmrstak/http/httpd.hpp" +#endif + +#ifdef _WIN32 +# include "xmrstak/misc/uac.hpp" #endif #include <stdlib.h> @@ -88,6 +92,11 @@ void help() int main(int argc, char *argv[]) { +#ifdef _WIN32 + if (!IsElevated() && SelfElevate(argv[0])) + return 0; +#endif + #ifndef CONF_NO_TLS SSL_library_init(); SSL_load_error_strings(); diff --git a/xmrstak/misc/uac.hpp b/xmrstak/misc/uac.hpp new file mode 100644 index 0000000..fdf3be9 --- /dev/null +++ b/xmrstak/misc/uac.hpp @@ -0,0 +1,44 @@ +#pragma once +#include <windows.h> + +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 char* my_path) +{ + if (IsElevated()) + return FALSE; + + SHELLEXECUTEINFO shExecInfo = { 0 }; + shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + shExecInfo.fMask = NULL; + shExecInfo.hwnd = NULL; + shExecInfo.lpVerb = "runas"; + shExecInfo.lpFile = my_path; + shExecInfo.lpParameters = NULL; + shExecInfo.lpDirectory = NULL; + shExecInfo.nShow = SW_SHOW; + shExecInfo.hInstApp = NULL; + + if (!ShellExecuteEx(&shExecInfo)) + return FALSE; + + // Hide our window and loiter in the background to make scripting easier + // ShowWindow(GetConsoleWindow(), SW_HIDE); + // WaitForSingleObject(shExecInfo.hProcess, INFINITE); + + return TRUE; +} |