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.

792 lines
23 KiB

  1. #include "precomp.h"
  2. #include <stdio.h>
  3. #include <wbemutil.h>
  4. #include <GroupsForUser.h>
  5. #include "ProcKiller.h"
  6. #include <GenUtils.h>
  7. #include <ArrTempl.h>
  8. #include <sddl.h>
  9. #include <ErrorObj.h>
  10. #include "cmdline.h"
  11. #include <Wtsapi32.h>
  12. #include <winntsec.h>
  13. #include <lm.h>
  14. #include <malloc.h>
  15. #define CMDLINE_PROPNAME_EXECUTABLE L"ExecutablePath"
  16. #define CMDLINE_PROPNAME_COMMANDLINE L"CommandLineTemplate"
  17. #define CMDLINE_PROPNAME_USEDEFAULTERRORMODE L"UseDefaultErrorMode"
  18. #define CMDLINE_PROPNAME_CREATENEWCONSOLE L"CreateNewConsole"
  19. #define CMDLINE_PROPNAME_CREATENEWPROCESSGROUP L"CreateNewProcessGroup"
  20. #define CMDLINE_PROPNAME_CREATESEPARATEWOWVDM L"CreateSeparateWowVdm"
  21. #define CMDLINE_PROPNAME_CREATESHAREDWOWVDM L"CreateSharedWowVdm"
  22. #define CMDLINE_PROPNAME_PRIORITY L"Priority"
  23. #define CMDLINE_PROPNAME_WORKINGDIRECTORY L"WorkingDirectory"
  24. #define CMDLINE_PROPNAME_DESKTOP L"DesktopName"
  25. #define CMDLINE_PROPNAME_TITLE L"WindowTitle"
  26. #define CMDLINE_PROPNAME_X L"XCoordinate"
  27. #define CMDLINE_PROPNAME_Y L"YCoordinate"
  28. #define CMDLINE_PROPNAME_XSIZE L"XSize"
  29. #define CMDLINE_PROPNAME_YSIZE L"YSize"
  30. #define CMDLINE_PROPNAME_XCOUNTCHARS L"XNumCharacters"
  31. #define CMDLINE_PROPNAME_YCOUNTCHARS L"YNumCharacters"
  32. #define CMDLINE_PROPNAME_FILLATTRIBUTE L"FillAttribute"
  33. #define CMDLINE_PROPNAME_SHOWWINDOW L"ShowWindowCommand"
  34. #define CMDLINE_PROPNAME_FORCEON L"ForceOnFeedback"
  35. #define CMDLINE_PROPNAME_FORCEOFF L"ForceOffFeedback"
  36. #define CMDLINE_PROPNAME_INTERACTIVE L"RunInteractively"
  37. #define CMDLINE_PROPNAME_KILLTIMEOUT L"KillTimeout"
  38. #define CMDLINE_PROPNAME_CREATORSID L"CreatorSid"
  39. HRESULT STDMETHODCALLTYPE CCommandLineConsumer::XProvider::FindConsumer(
  40. IWbemClassObject* pLogicalConsumer,
  41. IWbemUnboundObjectSink** ppConsumer)
  42. {
  43. CCommandLineSink* pSink = new CCommandLineSink(m_pObject->m_pControl);
  44. if (!pSink)
  45. return WBEM_E_OUT_OF_MEMORY;
  46. HRESULT hres = pSink->Initialize(pLogicalConsumer);
  47. if(FAILED(hres))
  48. {
  49. delete pSink;
  50. *ppConsumer = NULL;
  51. return hres;
  52. }
  53. else return pSink->QueryInterface(IID_IWbemUnboundObjectSink,
  54. (void**)ppConsumer);
  55. }
  56. void* CCommandLineConsumer::GetInterface(REFIID riid)
  57. {
  58. if(riid == IID_IWbemEventConsumerProvider)
  59. return &m_XProvider;
  60. else return NULL;
  61. }
  62. HRESULT CCommandLineSink::Initialize(IWbemClassObject* pLogicalConsumer)
  63. {
  64. // this is actually a pointer to a static object
  65. // if it fails, something is Very, Very Wrong.
  66. m_pErrorObj = ErrorObj::GetErrorObj();
  67. if (!m_pErrorObj)
  68. return WBEM_E_CRITICAL_ERROR;
  69. // Get the information
  70. // ===================
  71. HRESULT hres;
  72. VARIANT v;
  73. VariantInit(&v);
  74. // only one of the pair Executable & commandLine may be null
  75. // this var counts...
  76. int nNulls = 0;
  77. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_EXECUTABLE, 0, &v,
  78. NULL, NULL);
  79. if(FAILED(hres) || V_VT(&v) != VT_BSTR)
  80. {
  81. m_wsExecutable = L"";
  82. nNulls++;
  83. }
  84. else
  85. m_wsExecutable = V_BSTR(&v);
  86. VariantClear(&v);
  87. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_COMMANDLINE, 0, &v,
  88. NULL, NULL);
  89. if(FAILED(hres) || V_VT(&v) != VT_BSTR)
  90. {
  91. m_CommandLine.SetTemplate(L"");
  92. nNulls++;
  93. }
  94. else
  95. m_CommandLine.SetTemplate(V_BSTR(&v));
  96. VariantClear(&v);
  97. if (nNulls > 1)
  98. return WBEM_E_INVALID_PARAMETER;
  99. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_WORKINGDIRECTORY, 0, &v,
  100. NULL, NULL);
  101. if(SUCCEEDED(hres) && V_VT(&v) == VT_BSTR)
  102. m_wsWorkingDirectory = V_BSTR(&v);
  103. VariantClear(&v);
  104. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_DESKTOP, 0, &v,
  105. NULL, NULL);
  106. if(SUCCEEDED(hres) && V_VT(&v) == VT_BSTR)
  107. m_wsDesktop = V_BSTR(&v);
  108. VariantClear(&v);
  109. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_TITLE, 0, &v,
  110. NULL, NULL);
  111. if(FAILED(hres) || V_VT(&v) != VT_BSTR)
  112. m_title.SetTemplate(L"");
  113. else
  114. m_title.SetTemplate(V_BSTR(&v));
  115. VariantClear(&v);
  116. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_INTERACTIVE, 0, &v,
  117. NULL, NULL);
  118. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  119. m_bInteractive = TRUE;
  120. else
  121. m_bInteractive = FALSE;
  122. m_dwCreationFlags = 0;
  123. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_USEDEFAULTERRORMODE, 0, &v,
  124. NULL, NULL);
  125. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  126. m_dwCreationFlags |= CREATE_DEFAULT_ERROR_MODE;
  127. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATENEWCONSOLE, 0, &v,
  128. NULL, NULL);
  129. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  130. m_dwCreationFlags |= CREATE_NEW_CONSOLE;
  131. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATENEWPROCESSGROUP, 0, &v,
  132. NULL, NULL);
  133. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  134. m_dwCreationFlags |= CREATE_NEW_PROCESS_GROUP;
  135. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATESEPARATEWOWVDM, 0, &v,
  136. NULL, NULL);
  137. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  138. m_dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
  139. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATESHAREDWOWVDM, 0, &v,
  140. NULL, NULL);
  141. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  142. m_dwCreationFlags |= CREATE_SHARED_WOW_VDM;
  143. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_PRIORITY, 0, &v,
  144. NULL, NULL);
  145. if(V_VT(&v) == VT_I4)
  146. {
  147. if(V_I4(&v) == HIGH_PRIORITY_CLASS ||
  148. V_I4(&v) == IDLE_PRIORITY_CLASS ||
  149. V_I4(&v) == NORMAL_PRIORITY_CLASS ||
  150. V_I4(&v) == REALTIME_PRIORITY_CLASS)
  151. {
  152. m_dwCreationFlags |= V_I4(&v);
  153. }
  154. else
  155. return WBEM_E_INVALID_PARAMETER;
  156. }
  157. m_dwStartFlags = 0;
  158. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_X, 0, &v,
  159. NULL, NULL);
  160. if(V_VT(&v) == VT_I4)
  161. {
  162. m_dwX = V_I4(&v);
  163. m_dwStartFlags |= STARTF_USEPOSITION;
  164. }
  165. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_Y, 0, &v,
  166. NULL, NULL);
  167. if(V_VT(&v) == VT_I4)
  168. {
  169. m_dwY = V_I4(&v);
  170. m_dwStartFlags |= STARTF_USEPOSITION;
  171. }
  172. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_XSIZE, 0, &v,
  173. NULL, NULL);
  174. if(V_VT(&v) == VT_I4)
  175. {
  176. m_dwXSize = V_I4(&v);
  177. m_dwStartFlags |= STARTF_USESIZE;
  178. }
  179. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_YSIZE, 0, &v,
  180. NULL, NULL);
  181. if(V_VT(&v) == VT_I4)
  182. {
  183. m_dwYSize = V_I4(&v);
  184. m_dwStartFlags |= STARTF_USESIZE;
  185. }
  186. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_XCOUNTCHARS, 0, &v,
  187. NULL, NULL);
  188. if(V_VT(&v) == VT_I4)
  189. {
  190. m_dwXNumCharacters = V_I4(&v);
  191. m_dwStartFlags |= STARTF_USECOUNTCHARS;
  192. }
  193. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_YCOUNTCHARS, 0, &v,
  194. NULL, NULL);
  195. if(V_VT(&v) == VT_I4)
  196. {
  197. m_dwYNumCharacters = V_I4(&v);
  198. m_dwStartFlags |= STARTF_USECOUNTCHARS;
  199. }
  200. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FILLATTRIBUTE, 0, &v,
  201. NULL, NULL);
  202. if(V_VT(&v) == VT_I4)
  203. {
  204. m_dwFillAttribute = V_I4(&v);
  205. m_dwStartFlags |= STARTF_USEFILLATTRIBUTE;
  206. }
  207. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_SHOWWINDOW, 0, &v,
  208. NULL, NULL);
  209. if(V_VT(&v) == VT_I4)
  210. {
  211. m_dwShowWindow = V_I4(&v);
  212. m_dwStartFlags |= STARTF_USESHOWWINDOW;
  213. }
  214. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FORCEON, 0, &v,
  215. NULL, NULL);
  216. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  217. m_dwStartFlags |= STARTF_FORCEONFEEDBACK;
  218. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FORCEOFF, 0, &v,
  219. NULL, NULL);
  220. if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
  221. m_dwStartFlags |= STARTF_FORCEOFFFEEDBACK;
  222. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_KILLTIMEOUT, 0, &v,
  223. NULL, NULL);
  224. if(V_VT(&v) == VT_I4)
  225. m_dwKillTimeout = V_I4(&v);
  226. else
  227. m_dwKillTimeout = 0;
  228. VariantClear(&v);
  229. hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATORSID, 0, &v,
  230. NULL, NULL);
  231. if (SUCCEEDED(hres))
  232. {
  233. HRESULT hDebug;
  234. long ubound;
  235. hDebug = SafeArrayGetUBound(V_ARRAY(&v), 1, &ubound);
  236. if(SUCCEEDED(hDebug))
  237. {
  238. PVOID pVoid;
  239. hDebug = SafeArrayAccessData(V_ARRAY(&v), &pVoid);
  240. if(SUCCEEDED(hDebug))
  241. {
  242. m_pSidCreator = new BYTE[ubound +1];
  243. if (m_pSidCreator)
  244. memcpy(m_pSidCreator, pVoid, ubound + 1);
  245. else
  246. hres = WBEM_E_OUT_OF_MEMORY;
  247. SafeArrayUnaccessData(V_ARRAY(&v));
  248. }
  249. }
  250. }
  251. else
  252. {
  253. ERRORTRACE((LOG_ESS, "Command Line Consumer could not retrieve creator sid (0x%08X)\n",hres));
  254. return hres;
  255. }
  256. return hres;
  257. }
  258. BOOL IsInteractive(HWINSTA hWinsta)
  259. {
  260. USEROBJECTFLAGS uof;
  261. DWORD dwLen;
  262. BOOL bRes = GetUserObjectInformation(hWinsta, UOI_FLAGS,
  263. (void*)&uof, sizeof(uof), &dwLen);
  264. if(!bRes)
  265. return FALSE;
  266. return ((uof.dwFlags & WSF_VISIBLE) != 0);
  267. }
  268. BOOL WinstaEnumProc(LPTSTR szWindowStation, LPARAM lParam)
  269. {
  270. WString* pws = (WString*)lParam;
  271. HWINSTA hWinsta = OpenWindowStation(szWindowStation, FALSE,
  272. WINSTA_ENUMERATE | WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES);
  273. if(hWinsta == NULL)
  274. return TRUE;
  275. if(IsInteractive(hWinsta))
  276. {
  277. *pws = szWindowStation;
  278. }
  279. CloseWindowStation(hWinsta);
  280. return TRUE;
  281. }
  282. BOOL GetInteractiveWinstation(WString& wsName)
  283. {
  284. wsName.Empty();
  285. BOOL bRes = EnumWindowStations(WinstaEnumProc,
  286. (LPARAM)&wsName);
  287. return bRes;
  288. }
  289. HRESULT CCommandLineSink::FindInteractiveInfo()
  290. {
  291. BOOL bRes = GetInteractiveWinstation(m_wsWindowStation);
  292. if(!bRes)
  293. {
  294. return WBEM_E_FAILED;
  295. }
  296. if(m_wsWindowStation.Length() == 0)
  297. return WBEM_E_NOT_FOUND;
  298. return WBEM_S_NO_ERROR;
  299. }
  300. HRESULT GetSidUse(PSID pSid, SID_NAME_USE& use)
  301. {
  302. DWORD dwNameLen = 0;
  303. DWORD dwDomainLen = 0;
  304. LPWSTR pUser = 0;
  305. LPWSTR pDomain = 0;
  306. use = SidTypeInvalid;
  307. // Do the first lookup to get the buffer sizes required.
  308. // =====================================================
  309. BOOL bRes = LookupAccountSidW(
  310. NULL,
  311. pSid,
  312. pUser,
  313. &dwNameLen,
  314. pDomain,
  315. &dwDomainLen,
  316. &use
  317. );
  318. DWORD dwLastErr = GetLastError();
  319. if (dwLastErr != ERROR_INSUFFICIENT_BUFFER)
  320. {
  321. return WBEM_E_FAILED;
  322. }
  323. // Allocate the required buffers and look them up again.
  324. // =====================================================
  325. pUser = new wchar_t[dwNameLen + 1];
  326. if (!pUser)
  327. return WBEM_E_OUT_OF_MEMORY;
  328. pDomain = new wchar_t[dwDomainLen + 1];
  329. if (!pDomain)
  330. {
  331. delete pUser;
  332. return WBEM_E_OUT_OF_MEMORY;
  333. }
  334. bRes = LookupAccountSidW(
  335. NULL,
  336. pSid,
  337. pUser,
  338. &dwNameLen,
  339. pDomain,
  340. &dwDomainLen,
  341. &use
  342. );
  343. delete [] pUser;
  344. delete [] pDomain;
  345. if (bRes)
  346. return WBEM_S_NO_ERROR;
  347. else
  348. return WBEM_E_FAILED;
  349. }
  350. bool GetLoggedOnUserViaTS(
  351. CNtSid& sidLoggedOnUser)
  352. {
  353. bool fRet = false;
  354. bool fCont = true;
  355. PWTS_SESSION_INFO psesinfo = NULL;
  356. DWORD dwSessions = 0;
  357. LPWSTR wstrUserName = NULL;
  358. LPWSTR wstrDomainName = NULL;
  359. LPWSTR wstrWinstaName = NULL;
  360. DWORD dwSize = 0L;
  361. try
  362. {
  363. if(!(::WTSEnumerateSessions(
  364. WTS_CURRENT_SERVER_HANDLE,
  365. 0,
  366. 1,
  367. &psesinfo,
  368. &dwSessions) && psesinfo))
  369. {
  370. fCont = false;
  371. }
  372. if(fCont)
  373. {
  374. for(int j = 0; j < dwSessions && !fRet; j++, fCont = true)
  375. {
  376. if(psesinfo[j].State != WTSActive)
  377. {
  378. fCont = false;
  379. }
  380. if(fCont)
  381. {
  382. if(!(::WTSQuerySessionInformation(
  383. WTS_CURRENT_SERVER_HANDLE,
  384. psesinfo[j].SessionId,
  385. WTSUserName,
  386. &wstrUserName,
  387. &dwSize) && wstrUserName))
  388. {
  389. fCont = false;
  390. }
  391. }
  392. if(fCont)
  393. {
  394. if(!(::WTSQuerySessionInformation(
  395. WTS_CURRENT_SERVER_HANDLE,
  396. psesinfo[j].SessionId,
  397. WTSDomainName,
  398. &wstrDomainName,
  399. &dwSize) && wstrDomainName))
  400. {
  401. fCont = false;
  402. }
  403. }
  404. if(fCont)
  405. {
  406. if(!(::WTSQuerySessionInformation(
  407. WTS_CURRENT_SERVER_HANDLE,
  408. psesinfo[j].SessionId,
  409. WTSWinStationName,
  410. &wstrWinstaName,
  411. &dwSize) && wstrWinstaName))
  412. {
  413. fCont = false;
  414. }
  415. }
  416. if(fCont)
  417. {
  418. if(wbem_wcsicmp(wstrWinstaName, L"Console") != 0)
  419. {
  420. fCont = false;
  421. }
  422. }
  423. if(fCont)
  424. {
  425. WCHAR buf[256];
  426. DWORD bufSize = 255;
  427. if (GetComputerNameW(buf, &bufSize))
  428. {
  429. DWORD nRet = 0;
  430. // if it's a local account, we look it up locally
  431. // else we find a DC to look up.
  432. WCHAR* pServer = NULL;
  433. if (0 == wbem_wcsicmp(buf, wstrDomainName))
  434. pServer = NULL;
  435. else
  436. nRet = NetGetDCName(NULL, wstrDomainName, (LPBYTE *)&pServer);
  437. if (nRet == 0)
  438. {
  439. // That establishes that this user
  440. // is associated with the interactive
  441. // desktop.
  442. CNtSid sidInteractive(wstrUserName, pServer);
  443. if(sidInteractive.GetStatus() == CNtSid::NoError)
  444. {
  445. sidLoggedOnUser = sidInteractive;
  446. fRet = true;
  447. }
  448. if (pServer)
  449. NetApiBufferFree(pServer);
  450. }
  451. else
  452. fRet = false;
  453. }
  454. }
  455. if(wstrUserName)
  456. {
  457. WTSFreeMemory(wstrUserName);
  458. wstrUserName = NULL;
  459. }
  460. if(wstrDomainName)
  461. {
  462. WTSFreeMemory(wstrDomainName);
  463. wstrDomainName = NULL;
  464. }
  465. if(wstrWinstaName)
  466. {
  467. WTSFreeMemory(wstrWinstaName);
  468. wstrWinstaName = NULL;
  469. }
  470. }
  471. if (psesinfo)
  472. WTSFreeMemory(psesinfo);
  473. }
  474. }
  475. catch(...)
  476. {
  477. if(wstrUserName)
  478. {
  479. WTSFreeMemory(wstrUserName);
  480. wstrUserName = NULL;
  481. }
  482. if(wstrDomainName)
  483. {
  484. WTSFreeMemory(wstrDomainName);
  485. wstrDomainName = NULL;
  486. }
  487. if(wstrWinstaName)
  488. {
  489. WTSFreeMemory(wstrWinstaName);
  490. wstrWinstaName = NULL;
  491. }
  492. if (psesinfo)
  493. WTSFreeMemory(psesinfo);
  494. fRet = false;
  495. }
  496. return fRet;
  497. }
  498. HRESULT STDMETHODCALLTYPE CCommandLineSink::XSink::CreateProcessNT(WCHAR* pCommandLine, WCHAR* pTitle, PROCESS_INFORMATION& pi, FILETIME& now)
  499. {
  500. HRESULT hr = WBEM_S_NO_ERROR;
  501. WCHAR* pDesktop = NULL;
  502. WString wsDesktop;
  503. if(m_pObject->m_bInteractive)
  504. {
  505. if(FAILED(m_pObject->FindInteractiveInfo()))
  506. {
  507. ERRORTRACE((LOG_ESS, "No interactive window station found!\n"));
  508. return WBEM_E_FAILED;
  509. }
  510. wsDesktop = m_pObject->m_wsWindowStation;
  511. wsDesktop += L"\\Default";
  512. pDesktop = (wchar_t*)wsDesktop;
  513. CNtSid user;
  514. if (!GetLoggedOnUserViaTS(user))
  515. {
  516. ERRORTRACE((LOG_ESS, "Could not determine logged on user\n"));
  517. return WBEM_E_FAILED;
  518. }
  519. SID_NAME_USE use;
  520. if (FAILED(hr =GetSidUse(m_pObject->m_pSidCreator, use)))
  521. return hr;
  522. if (use == SidTypeUser)
  523. {
  524. if (!EqualSid(m_pObject->m_pSidCreator, user.GetPtr()))
  525. {
  526. ERRORTRACE((LOG_ESS, "Command line event consumer will only run interactively\non a workstation that the creator is logged into.\n"));
  527. m_pObject->m_pErrorObj->ReportError(L"AccessCheck", L"RunInteractively",
  528. NULL, WBEM_E_ACCESS_DENIED, true);
  529. return WBEM_E_ACCESS_DENIED;
  530. }
  531. // else we're fine continue.
  532. DEBUGTRACE((LOG_ESS, "User and creator are one in the same\n"));
  533. }
  534. else
  535. {
  536. if (0 != IsUserInGroup(user.GetPtr(), m_pObject->m_pSidCreator))
  537. {
  538. ERRORTRACE((LOG_ESS, "Command line event consumer will only run interactively\non a workstation that the creator is logged into.\n"));
  539. m_pObject->m_pErrorObj->ReportError(L"AccessCheck", L"RunInteractively",
  540. NULL, WBEM_E_ACCESS_DENIED, true);
  541. return WBEM_E_ACCESS_DENIED;
  542. }
  543. else
  544. {
  545. DEBUGTRACE((LOG_ESS, "User is in the group!\n"));
  546. }
  547. }
  548. }
  549. WCHAR* szApplicationName = (m_pObject->m_wsExecutable.Length() == 0) ? NULL : ((wchar_t*)m_pObject->m_wsExecutable);
  550. WCHAR* szWorkingDirectory = (m_pObject->m_wsWorkingDirectory.Length() == 0) ? NULL : ((wchar_t*)m_pObject->m_wsWorkingDirectory);
  551. struct _STARTUPINFOW si;
  552. si.cb = sizeof(si);
  553. si.lpReserved = NULL;
  554. si.cbReserved2 = 0;
  555. si.lpReserved2 = NULL;
  556. si.lpDesktop = pDesktop;
  557. si.lpTitle = pTitle;
  558. si.dwX = m_pObject->m_dwX;
  559. si.dwY = m_pObject->m_dwY;
  560. si.dwXSize = m_pObject->m_dwXSize;
  561. si.dwYSize = m_pObject->m_dwYSize;
  562. si.dwXCountChars = m_pObject->m_dwXNumCharacters;
  563. si.dwYCountChars = m_pObject->m_dwYNumCharacters;
  564. si.dwFillAttribute = m_pObject->m_dwFillAttribute;
  565. si.dwFlags = m_pObject->m_dwStartFlags;
  566. si.wShowWindow = (WORD)m_pObject->m_dwShowWindow;
  567. #ifdef HHANCE_DEBUG_CODE
  568. DEBUGTRACE((LOG_ESS, "Calling Create process\n"));
  569. #endif
  570. BOOL bRes = CreateProcessW(szApplicationName, pCommandLine,
  571. NULL, NULL, FALSE, m_pObject->m_dwCreationFlags,
  572. NULL, szWorkingDirectory, &si, &pi);
  573. if (!bRes)
  574. {
  575. DWORD dwErr = GetLastError();
  576. m_pObject->m_pErrorObj->ReportError(L"CreateProcess", szApplicationName ? szApplicationName : pCommandLine, NULL, dwErr, true);
  577. ERRORTRACE((LOG_ESS, "CreateProcess failed, 0x%08X\n", dwErr));
  578. }
  579. #ifdef HHANCE_DEBUG_CODE
  580. else
  581. DEBUGTRACE((LOG_ESS, "Create Process succeeded\n"));
  582. #endif
  583. // get current time for shutdown info
  584. GetSystemTimeAsFileTime(&now);
  585. if (!bRes)
  586. hr = WBEM_E_FAILED;
  587. return hr;
  588. }
  589. HRESULT STDMETHODCALLTYPE CCommandLineSink::XSink::IndicateToConsumer(
  590. IWbemClassObject* pLogicalConsumer, long lNumObjects,
  591. IWbemClassObject** apObjects)
  592. {
  593. HRESULT hr = S_OK;
  594. PSID pSidSystem;
  595. SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
  596. if (AllocateAndInitializeSid(&id, 1,
  597. SECURITY_LOCAL_SYSTEM_RID,
  598. 0, 0,0,0,0,0,0,&pSidSystem))
  599. {
  600. // guilty until proven innocent
  601. hr = WBEM_E_ACCESS_DENIED;
  602. // check to see if sid is either Local System or an admin of some sort...
  603. if ((EqualSid(pSidSystem, m_pObject->m_pSidCreator)) ||
  604. (S_OK == IsUserAdministrator(m_pObject->m_pSidCreator)))
  605. hr = WBEM_S_NO_ERROR;
  606. // We're done with this
  607. FreeSid(pSidSystem);
  608. if (FAILED(hr))
  609. {
  610. if (hr == WBEM_E_ACCESS_DENIED)
  611. ERRORTRACE((LOG_ESS, "Command line event consumer may only be used by an administrator\n"));
  612. return hr;
  613. }
  614. }
  615. else
  616. return WBEM_E_OUT_OF_MEMORY;
  617. for(int i = 0; i < lNumObjects; i++)
  618. {
  619. BSTR strCommandLine = m_pObject->m_CommandLine.Apply(apObjects[i]);
  620. if(strCommandLine == NULL)
  621. {
  622. ERRORTRACE((LOG_ESS, "Invalid command line!\n"));
  623. return WBEM_E_INVALID_PARAMETER;
  624. }
  625. WString wsCommandLine = strCommandLine;
  626. SysFreeString(strCommandLine);
  627. BSTR bstrTitle = m_pObject->m_title.Apply(apObjects[i]);
  628. WString wsTitle = bstrTitle;
  629. if (bstrTitle)
  630. SysFreeString(bstrTitle);
  631. FILETIME now;
  632. PROCESS_INFORMATION pi;
  633. WCHAR* pCommandLine = ((wsCommandLine.Length() == 0) ? NULL : (wchar_t *)wsCommandLine);;
  634. WCHAR* pTitle = ((wsTitle.Length() == 0) ? NULL : (wchar_t *)wsTitle);
  635. hr = CreateProcessNT(pCommandLine, pTitle, pi, now);
  636. if (FAILED(hr))
  637. {
  638. ERRORTRACE((LOG_ESS, "Failed to CreateProcess %S. Error 0x%X\n", (LPCWSTR)wsCommandLine, hr));
  639. return hr;
  640. }
  641. else
  642. {
  643. if (m_pObject->m_dwKillTimeout)
  644. {
  645. WAYCOOL_FILETIME then(now);
  646. then.AddSeconds(m_pObject->m_dwKillTimeout);
  647. hr = g_procKillerTimer.ScheduleAssassination(pi.hProcess, (FILETIME)then);
  648. if (FAILED(hr))
  649. DEBUGTRACE((LOG_ESS, "Could not schedule process termination\n"));
  650. }
  651. CloseHandle(pi.hProcess);
  652. CloseHandle(pi.hThread);
  653. }
  654. }
  655. return hr;
  656. }
  657. void* CCommandLineSink::GetInterface(REFIID riid)
  658. {
  659. if(riid == IID_IWbemUnboundObjectSink)
  660. return &m_XSink;
  661. else return NULL;
  662. }