| 
							- /**
 -  * 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;
 - }
 
 
  |