Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
6.0 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002-2004 Microsoft Corporation
  4. //
  5. // Module Name: CmdProc.cpp
  6. //
  7. // Description:
  8. // Implementation of Command Processor class
  9. // CCommandProcessor initializes, starts and waits for processes.
  10. //
  11. // Author: Jim Benton (jbenton) 08-April-2002
  12. //
  13. //////////////////////////////////////////////////////////////////////////////
  14. #include "pch.h"
  15. #include <userenv.h>
  16. #include <strsafe.h>
  17. #include "cmdproc.h"
  18. CCmdProcessor::CCmdProcessor()
  19. {
  20. m_pwszCommand = NULL;
  21. m_pwszApplication = NULL;
  22. m_pvEnvironment = NULL;
  23. m_hProcess = INVALID_HANDLE_VALUE;
  24. m_hToken = INVALID_HANDLE_VALUE;
  25. memset (&m_ProcessInfo, 0, sizeof (m_ProcessInfo));
  26. m_ProcessInfo.hProcess = INVALID_HANDLE_VALUE;
  27. m_ProcessInfo.hThread = INVALID_HANDLE_VALUE;
  28. }
  29. CCmdProcessor::~CCmdProcessor()
  30. {
  31. delete [] m_pwszApplication;
  32. delete [] m_pwszCommand;
  33. if (m_pvEnvironment)
  34. DestroyEnvironmentBlock(m_pvEnvironment);
  35. if (m_hProcess != INVALID_HANDLE_VALUE)
  36. CloseHandle(m_hProcess);
  37. if (m_hToken != INVALID_HANDLE_VALUE)
  38. CloseHandle(m_hToken);
  39. if (m_ProcessInfo.hProcess != INVALID_HANDLE_VALUE)
  40. CloseHandle(m_ProcessInfo.hProcess);
  41. if (m_ProcessInfo.hThread != INVALID_HANDLE_VALUE)
  42. CloseHandle(m_ProcessInfo.hThread);
  43. }
  44. HRESULT
  45. CCmdProcessor::InitializeAsClient(
  46. IN WCHAR* pwszApplication,
  47. IN WCHAR* pwszCommand)
  48. {
  49. HRESULT hr = E_FAIL;
  50. HANDLE hTokenImpersonate = INVALID_HANDLE_VALUE;
  51. do
  52. {
  53. DWORD cchBuf = 0;
  54. BOOL bStatus = FALSE;
  55. if (pwszApplication == NULL || pwszCommand == NULL)
  56. {
  57. hr = E_INVALIDARG;
  58. break;
  59. }
  60. cchBuf = wcslen(pwszApplication) + 1;
  61. m_pwszApplication = new WCHAR[cchBuf];
  62. if (m_pwszApplication == NULL)
  63. {
  64. hr = E_OUTOFMEMORY;
  65. break;
  66. }
  67. hr = StringCchCopy(m_pwszApplication, cchBuf, pwszApplication);
  68. if (FAILED(hr)) break;
  69. cchBuf = wcslen(pwszCommand) + 1;
  70. m_pwszCommand = new WCHAR[cchBuf];
  71. if (m_pwszCommand == NULL)
  72. {
  73. hr = E_OUTOFMEMORY;
  74. break;
  75. }
  76. hr = StringCchCopy(m_pwszCommand, cchBuf, pwszCommand);
  77. if (FAILED(hr)) break;
  78. bStatus = OpenThreadToken(
  79. GetCurrentThread(),
  80. TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
  81. TRUE,
  82. &hTokenImpersonate);
  83. if (!bStatus)
  84. {
  85. hr = HRESULT_FROM_WIN32(GetLastError());
  86. break;
  87. }
  88. bStatus = DuplicateTokenEx(
  89. hTokenImpersonate,
  90. TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
  91. NULL,
  92. SecurityImpersonation,
  93. TokenPrimary,
  94. &m_hToken);
  95. if (!bStatus)
  96. {
  97. hr = HRESULT_FROM_WIN32(GetLastError());
  98. break;
  99. }
  100. bStatus = CreateEnvironmentBlock(
  101. &m_pvEnvironment,
  102. m_hToken,
  103. FALSE);
  104. if (!bStatus)
  105. {
  106. hr = HRESULT_FROM_WIN32(GetLastError());
  107. break;
  108. }
  109. hr = S_OK;
  110. }
  111. while (false);
  112. if (hTokenImpersonate != INVALID_HANDLE_VALUE)
  113. CloseHandle(hTokenImpersonate);
  114. return hr;
  115. }
  116. HRESULT
  117. CCmdProcessor::LaunchProcess()
  118. {
  119. HRESULT hr = S_OK;
  120. STARTUPINFO StartupInfo ;
  121. memset (&StartupInfo, 0, sizeof (StartupInfo));
  122. StartupInfo.cb = sizeof (STARTUPINFO) ;
  123. StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
  124. StartupInfo.wShowWindow = SW_HIDE;
  125. BOOL bStatus = FALSE;
  126. bStatus = CreateProcessAsUser(
  127. m_hToken,
  128. m_pwszApplication,
  129. m_pwszCommand,
  130. NULL, // default process security descriptor, not inheritable
  131. NULL, // default thread security descriptor, not inheritable
  132. FALSE, // no handles inherited from this process
  133. NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT,
  134. m_pvEnvironment,
  135. NULL, // use current working directory; this is SYSTEM32 directory for the WMI provider
  136. &StartupInfo,
  137. &m_ProcessInfo);
  138. if (!bStatus)
  139. hr = HRESULT_FROM_WIN32(GetLastError());
  140. return hr;
  141. }
  142. HRESULT
  143. CCmdProcessor::Wait(
  144. IN DWORD cMilliseconds,
  145. OUT DWORD* pdwStatus)
  146. {
  147. HRESULT hr = E_FAIL;
  148. BOOL bStatus = FALSE;
  149. if (pdwStatus == NULL)
  150. return E_INVALIDARG;
  151. switch(WaitForSingleObject(m_ProcessInfo.hProcess, cMilliseconds))
  152. {
  153. case WAIT_OBJECT_0:
  154. bStatus = GetExitCodeProcess(m_ProcessInfo.hProcess, pdwStatus);
  155. if (!bStatus)
  156. hr = HRESULT_FROM_WIN32(GetLastError());
  157. else
  158. hr = S_OK;
  159. break;
  160. case WAIT_TIMEOUT:
  161. *pdwStatus = STILL_ACTIVE;
  162. hr = S_OK;
  163. break;
  164. default:
  165. *pdwStatus = WAIT_FAILED;
  166. hr = HRESULT_FROM_WIN32(GetLastError());
  167. }
  168. return hr;
  169. }
  170. HRESULT
  171. CCmdProcessor::QueryStatus(
  172. OUT DWORD* pdwStatus)
  173. {
  174. if (pdwStatus == NULL)
  175. return E_INVALIDARG;
  176. if (!GetExitCodeProcess(m_ProcessInfo.hProcess, pdwStatus))
  177. return HRESULT_FROM_WIN32(GetLastError());
  178. else
  179. return S_OK;
  180. }