|
- /**
- * This is an unfinished experiment.
- * It's a windows only command line program that
- * find the Rack process in memory, and sets its
- * priority class to realtime.
- */
-
- #include <stdio.h>
- #include <windows.h>
- #include <psapi.h>
- #include <string>
-
- class ProcessNameAndHandle
- {
- public:
- std::string name;
- HANDLE handle = INVALID_HANDLE_VALUE;
- };
-
- ProcessNameAndHandle getProcessNameAndHandle(DWORD pid);
- bool setRealtimePriority(HANDLE pHandle);
- bool enablePrivilege(HANDLE hProcess, const char * privilege);
- std::string GetLastErrorAsString();
-
- int main(int argc, char** argv)
- {
-
- HANDLE realHandle = GetCurrentProcess();
- bool b = enablePrivilege(realHandle, SE_DEBUG_NAME);
- printf("try set debug on us: %d\n", b);
- if (!b) {
- // TODO: we should re-run here
- printf("can't get debug right from system. Try running as admin\n");
- fflush(stdout);
-
- // Spawn a copy of ourselves, via ShellExecuteEx().
- // The "runas" verb is important because that's what
- // internally triggers Windows to open up a UAC prompt.
- // HANDLE child = ShellExecuteEx(argc, argv, "runas");
- SHELLEXECUTEINFO sinfo;
- memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
- sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
- sinfo.fMask = SEE_MASK_FLAG_DDEWAIT |
- SEE_MASK_NOCLOSEPROCESS;
- sinfo.hwnd = NULL;
- sinfo.lpFile = argv[0];
- sinfo.lpParameters = "";
- sinfo.lpVerb = "runas"; // <<-- this is what makes a UAC prompt show up
- sinfo.nShow = SW_SHOWMAXIMIZED;
-
- // The only way to get a UAC prompt to show up
- // is by calling ShellExecuteEx() with the correct
- // SHELLEXECUTEINFO struct. Non privlidged applications
- // cannot open/start a UAC prompt by simply spawning
- // a process that has the correct XML manifest.
- BOOL result = ShellExecuteEx(&sinfo);
- if (!result) {
- printf("re-exec as admin failed\n");
- return -1;
- }
-
- // HINSTANCE appInstance = sinfo.hInstApp;
-
-
- printf("exec worked. hp=%x\n", sinfo.hProcess);
- fflush(stdout);
- // User accepted UAC prompt (gave permission).
- // The unprivileged parent should wait for
- // the privileged child to finish.
- WaitForSingleObject(sinfo.hProcess, INFINITE);
- printf("orig proc finished waiting\n");
-
- DWORD exitCode=666;
- GetExitCodeProcess(sinfo.hProcess, &exitCode);
- printf("EXIT CODE %d\n", exitCode);
- CloseHandle(sinfo.hProcess);
- }
-
- // here were able to set debug
- DWORD aProcesses[1024], cbNeeded, cProcesses;
- unsigned int i;
-
- if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
- printf("enum proc failed\n");
- return 1;
- }
-
-
- // Calculate how many process identifiers were returned.
- cProcesses = cbNeeded / sizeof(DWORD);
-
- // find the pid for Rack.
- HANDLE rackProcessHandle = INVALID_HANDLE_VALUE;
- std::string rackName("Rack.exe");
- for (i = 0; i < cProcesses; i++) {
- if (aProcesses[i] != 0) {
- //PrintProcessNameAndID( aProcesses[i] );
- ProcessNameAndHandle proc = getProcessNameAndHandle(aProcesses[i]);
- if (proc.name == rackName) {
- rackProcessHandle = proc.handle;
- } else {
- CloseHandle(proc.handle);
- }
- }
- }
-
- printf("rack pid = %d\n", rackProcessHandle);
- if (rackProcessHandle == INVALID_HANDLE_VALUE) {
- printf("could not find rack process\n");
- return -1;
- }
-
- bool bSet = setRealtimePriority(rackProcessHandle);
- CloseHandle(rackProcessHandle);
- }
-
-
-
- /**
- *
- */
- ProcessNameAndHandle getProcessNameAndHandle(DWORD processID)
- {
- TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
-
- // Get a handle to the process.
- HANDLE hProcess = OpenProcess(PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, processID);
-
- // Get the process name
- if (NULL != hProcess) {
- HMODULE hMod;
- DWORD cbNeeded;
-
- if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),
- &cbNeeded)) {
- GetModuleBaseName(hProcess, hMod, szProcessName,
- sizeof(szProcessName) / sizeof(TCHAR));
- } else printf("could not enum proc\n");
- } else {
- return {};
- }
-
- // Release the handle to the process.
- // CloseHandle(hProcess);
- return {szProcessName, hProcess};
- }
-
- #if 0
- // Returns the last Win32 error, in string format. Returns an empty string if there is no error.//Returns
- std::string GetLastErrorAsString()
- {
- //Get the error message, if any.
- DWORD errorMessageID = ::GetLastError();
- if (errorMessageID == 0)
- return std::string(); //No error message has been recorded
-
- LPSTR messageBuffer = nullptr;
- size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &messageBuffer, 0, NULL);
-
- std::string message(messageBuffer, size);
-
- //Free the buffer.
- LocalFree(messageBuffer);
-
- return message;
- }
- #endif
-
- bool setClassRealtime(HANDLE h)
- {
- auto x = GetPriorityClass(h);
- auto b = SetPriorityClass(h, REALTIME_PRIORITY_CLASS);
- auto c = GetPriorityClass(h);
-
- #if 0
- printf("setrealtime(%d) %d, %d, %d\n", REALTIME_PRIORITY_CLASS, x, b, c);
- if (!b) {
- printf("SetP call failed with %d (%s)\n", GetLastError(), GetLastErrorAsString().c_str());
- }
- #endif
-
- return c == REALTIME_PRIORITY_CLASS;
- }
-
-
- bool enablePrivilege(HANDLE hProcess, const char * privilege)
- {
- printf("called ep with %s\n", privilege);
- struct
- {
- DWORD Count;
- LUID_AND_ATTRIBUTES Privilege[1];
- } Info;
-
- HANDLE Token;
- BOOL Result;
-
- // Open the token.
-
- Result = OpenProcessToken(hProcess,
- TOKEN_ADJUST_PRIVILEGES,
- &Token);
-
- if (Result != TRUE) {
- printf("ep Cannot open process token.\n");
- return FALSE;
- }
-
-
- Info.Count = 1;
- Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
-
-
- // Get the LUID.
- Result = LookupPrivilegeValue(NULL,
- privilege,
- &(Info.Privilege[0].Luid));
-
- if (Result != TRUE) {
- printf("ep Cannot get privilege for %s.\n", privilege);
- return FALSE;
- }
-
- // Adjust the privilege.
- Result = AdjustTokenPrivileges(Token, FALSE,
- (PTOKEN_PRIVILEGES) &Info,
- 0, NULL, NULL);
-
- CloseHandle(Token);
-
- // Check the result.
-
- if (Result != TRUE) {
- printf("ep Cannot adjust token privileges (%u)\n", GetLastError());
- return FALSE;
- } else {
- if (GetLastError() != ERROR_SUCCESS) {
- // printf("getlasterror = %d, %s\n", GetLastError(), GetLastErrorAsString().c_str());
- printf("Cannot enable the %s privilege; ", privilege
- );
- printf("please check the local policy.\n");
- return FALSE;
- }
- }
-
- return TRUE;
- }
-
- /**
- *
- */
- bool setRealtimePriority(HANDLE hRackProcess)
- {
- auto set = setClassRealtime(hRackProcess);
- printf("set pri class at start ret %d\n", set);
- return set;
- }
|