UAC_Thread.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "stdafx.h"
  2. #include "UAC_Thread.h"
  3. #include "Misc.h"
  4. #include "Options.h"
  5. #include "QPasteWnd.h"
  6. #include "cp_main.h"
  7. CUAC_Thread::CUAC_Thread(int processId)
  8. {
  9. m_processId = processId;
  10. AddEvent(UAC_PASTE, StrF(_T("Global\\UAC_PASTE_%d"), m_processId));
  11. AddEvent(UAC_COPY, StrF(_T("Global\\UAC_COPY_%d"), m_processId));
  12. AddEvent(UAC_CUT, StrF(_T("Global\\UAC_CUT_%d"), m_processId));
  13. AddEvent(UAC_EXIT, StrF(_T("Global\\UAC_EXIT_%d"), m_processId));
  14. m_waitTimeout = 30000;
  15. }
  16. CUAC_Thread::~CUAC_Thread(void)
  17. {
  18. }
  19. void CUAC_Thread::OnTimeOut(void *param)
  20. {
  21. bool close = false;
  22. DWORD exitCode = 0;
  23. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, m_processId);
  24. if(hProcess == NULL)
  25. {
  26. close = true;
  27. }
  28. else
  29. {
  30. if(GetExitCodeProcess(hProcess, &exitCode) == 0)
  31. {
  32. close = true;
  33. }
  34. else if(exitCode != STILL_ACTIVE)
  35. {
  36. close = true;
  37. }
  38. }
  39. if(close)
  40. {
  41. Log(StrF(_T("Found parent process id (%d) is not running, Exit Code %d closing uac aware app"), m_processId, exitCode));
  42. this->CancelThread();
  43. }
  44. CloseHandle(hProcess);
  45. }
  46. void CUAC_Thread::OnEvent(int eventId, void *param)
  47. {
  48. DWORD startTick = GetTickCount();
  49. Log(StrF(_T("Start of OnEvent, eventId: %s"), EnumName((eUacThreadEvents)eventId)));
  50. switch((eUacThreadEvents)eventId)
  51. {
  52. case UAC_PASTE:
  53. theApp.m_activeWnd.SendPaste(false);
  54. break;
  55. case UAC_COPY:
  56. theApp.m_activeWnd.SendCopy(CopyReasonEnum::COPY_TO_UNKOWN);
  57. break;
  58. case UAC_CUT:
  59. theApp.m_activeWnd.SendCut();
  60. break;
  61. case UAC_EXIT:
  62. this->CancelThread();
  63. break;
  64. }
  65. DWORD length = GetTickCount() - startTick;
  66. Log(StrF(_T("End of OnEvent, eventId: %s, Time: %d(ms)"), EnumName((eUacThreadEvents)eventId), length));
  67. }
  68. CString CUAC_Thread::EnumName(eUacThreadEvents e)
  69. {
  70. switch(e)
  71. {
  72. case UAC_PASTE:
  73. return _T("Paste Elevated");
  74. case UAC_COPY:
  75. return _T("COPY Elevated");
  76. case UAC_CUT:
  77. return _T("Cut Elevated");
  78. case UAC_EXIT:
  79. return _T("Save Startup Elevated");
  80. }
  81. return _T("");
  82. }
  83. bool CUAC_Thread::UACPaste()
  84. {
  85. bool ret = StartProcess();
  86. FirePaste();
  87. return ret;
  88. }
  89. bool CUAC_Thread::UACCopy()
  90. {
  91. bool ret = StartProcess();
  92. FireCopy();
  93. return ret;
  94. }
  95. bool CUAC_Thread::UACCut()
  96. {
  97. bool ret = StartProcess();
  98. FireCut();
  99. return ret;
  100. }
  101. bool CUAC_Thread::StartProcess()
  102. {
  103. bool ret = true;
  104. CString mutexName;
  105. mutexName.Format(_T("DittoAdminPaste_%d"), GetCurrentProcessId());
  106. HANDLE mutex = CreateMutex(NULL, FALSE, mutexName);
  107. DWORD dwError = GetLastError();
  108. if(dwError == ERROR_ALREADY_EXISTS)
  109. {
  110. Log(_T("Paste uac admin exe is already running just signalling paste"));
  111. }
  112. else
  113. {
  114. wchar_t szPath[MAX_PATH];
  115. if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)))
  116. {
  117. // Launch itself as administrator.
  118. SHELLEXECUTEINFO sei = { sizeof(sei) };
  119. sei.lpVerb = L"runas";
  120. sei.lpFile = szPath;
  121. CString csParam;
  122. csParam.Format(_T("/uacpaste:%d"), GetCurrentProcessId());
  123. sei.lpParameters = csParam;
  124. sei.nShow = SW_NORMAL;
  125. if (!ShellExecuteEx(&sei))
  126. {
  127. Log(_T("Failed to startup paste as admin app, we are not pasting using admin app"));
  128. ret = false;
  129. }
  130. else
  131. {
  132. Log(_T("Startup up ditto paste as admin app, this will send ctrl-v to the admin app"));
  133. }
  134. }
  135. }
  136. CloseHandle(mutex);
  137. return ret;
  138. }