Source code of Windows XP (NT5)
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.

1984 lines
49 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: commands.cxx
  7. //
  8. // Contents: Implementation of command-line switches.
  9. //
  10. // History: 01-03-96 DavidMun Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <headers.hxx>
  14. #pragma hdrstop
  15. #include "jt.hxx"
  16. #include "..\..\inc\defines.hxx"
  17. #define MAX_TRIGGER_STRING 160
  18. #define DEFAULT_FETCH_COUNT 2
  19. #define MSTASK_DLL TEXT("MSTASK.DLL")
  20. typedef HRESULT (WINAPI * PSETNSACCOUNTINFO)(LPCWSTR, LPCWSTR, LPCWSTR);
  21. typedef HRESULT (WINAPI * PGETNSACCOUNTINFO)(LPCWSTR, DWORD, LPWSTR);
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Function: Abort
  25. //
  26. // Synopsis: Parse and execute the abort job command.
  27. //
  28. // Arguments: [ppwsz] - command line
  29. // [fJob] - TRUE=>operate on job, FALSE=>operate on queue
  30. //
  31. // Returns: S_OK - command executed
  32. // E_* - error logged
  33. //
  34. // Modifies: *[ppwsz]
  35. //
  36. // History: 01-05-96 DavidMun Created
  37. //
  38. //----------------------------------------------------------------------------
  39. HRESULT Abort(WCHAR **ppwsz, BOOL fJob)
  40. {
  41. HRESULT hr = S_OK;
  42. if (fJob)
  43. {
  44. g_Log.Write(LOG_TRACE, "Aborting job");
  45. hr = g_pJob->Terminate();
  46. if (FAILED(hr))
  47. {
  48. g_Log.Write(LOG_FAIL, "ITask::Terminate hr=%#010x", hr);
  49. }
  50. }
  51. else
  52. {
  53. g_Log.Write(LOG_TRACE, "Aborting Queue");
  54. #ifdef NOT_YET
  55. hr = g_pJobQueue->Terminate();
  56. if (FAILED(hr))
  57. {
  58. g_Log.Write(LOG_FAIL, "ITaskQueue::Terminate hr=%#010x", hr);
  59. }
  60. #endif // NOT_YET
  61. hr = E_NOTIMPL;
  62. }
  63. return hr;
  64. }
  65. //+---------------------------------------------------------------------------
  66. //
  67. // Function: ConvertSage
  68. //
  69. // Synopsis: Execute the convert sage tasks to jobs command, but only
  70. // if this binary was built for and is running on Win9x.
  71. //
  72. // Returns: Built for or runnong on NT - S_OK
  73. // Otherwise - result of ConvertSageTasksToJobs()
  74. //
  75. // History: 03-25-96 DavidMun Created
  76. //
  77. //----------------------------------------------------------------------------
  78. HRESULT ConvertSage()
  79. {
  80. HRESULT hr = S_OK;
  81. #ifdef _CHICAGO_
  82. OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
  83. GetVersionEx(&VersionInfo);
  84. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  85. {
  86. hr = ConvertSageTasksToJobs();
  87. }
  88. else
  89. {
  90. g_Log.Write(
  91. LOG_WARN,
  92. "This command cannot be executed when running under Windows NT.");
  93. }
  94. #else
  95. g_Log.Write(
  96. LOG_WARN,
  97. "This version of JT was built for NT and cannot execute this command.");
  98. #endif // !_CHICAGO_
  99. return hr;
  100. }
  101. //+---------------------------------------------------------------------------
  102. //
  103. // Function: SetNSAccountInfo
  104. //
  105. // Synopsis:
  106. //
  107. // Returns:
  108. //
  109. // History:
  110. //
  111. //----------------------------------------------------------------------------
  112. HRESULT SetNSAccountInfo(WCHAR ** ppwsz)
  113. {
  114. #define SET_NS_ACCOUNT_INFO "SetNetScheduleAccountInformation"
  115. HRESULT hr = S_OK;
  116. #ifndef _CHICAGO_
  117. OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
  118. GetVersionEx(&VersionInfo);
  119. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  120. {
  121. WCHAR wszAccount[MAX_USERNAME + 1];
  122. WCHAR wszPassword[MAX_PASSWORD + 1];
  123. hr = Expect(TKN_STRING, ppwsz, L"Account name");
  124. if (FAILED(hr))
  125. {
  126. return hr;
  127. }
  128. wcsncpy(wszAccount, g_wszLastStringToken,
  129. min(wcslen(g_wszLastStringToken) + 1, MAX_USERNAME));
  130. hr = Expect(TKN_STRING, ppwsz, L"Account password");
  131. if (FAILED(hr))
  132. {
  133. return hr;
  134. }
  135. wcsncpy(wszPassword, g_wszLastStringToken,
  136. min(wcslen(g_wszLastStringToken) + 1, MAX_PASSWORD));
  137. PSETNSACCOUNTINFO pSetNSAccountInfo;
  138. HMODULE hMod = LoadLibrary(MSTASK_DLL);
  139. if (hMod == NULL)
  140. {
  141. hr = HRESULT_FROM_WIN32(GetLastError());
  142. g_Log.Write(LOG_FAIL, "LoadLibrary hr=%#010x", hr);
  143. return hr;
  144. }
  145. else
  146. {
  147. pSetNSAccountInfo = (PSETNSACCOUNTINFO)GetProcAddress(
  148. hMod,
  149. SET_NS_ACCOUNT_INFO);
  150. if (pSetNSAccountInfo == NULL)
  151. {
  152. FreeLibrary(hMod);
  153. hr = HRESULT_FROM_WIN32(GetLastError());
  154. g_Log.Write(LOG_FAIL, "GetProcAddress hr=%#010x", hr);
  155. return hr;
  156. }
  157. }
  158. hr = pSetNSAccountInfo(
  159. NULL,
  160. lstrcmpiW(wszAccount, L"NULL") == 0 ? NULL : wszAccount,
  161. wszPassword);
  162. if (FAILED(hr))
  163. {
  164. g_Log.Write(LOG_FAIL,
  165. "SetNetScheduleAccountInformation hr=%#010x", hr);
  166. }
  167. FreeLibrary(hMod);
  168. }
  169. else
  170. {
  171. g_Log.Write(
  172. LOG_WARN,
  173. "This command cannot be executed when running under Windows 95.");
  174. }
  175. #else
  176. g_Log.Write(
  177. LOG_WARN,
  178. "This version of JT was built for Win95 and cannot execute this command.");
  179. #endif // !_CHICAGO_
  180. return hr;
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Function: PrintNSAccountInfo
  185. //
  186. // Synopsis:
  187. //
  188. // Returns:
  189. //
  190. // History:
  191. //
  192. //----------------------------------------------------------------------------
  193. HRESULT PrintNSAccountInfo(void)
  194. {
  195. #define GET_NS_ACCOUNT_INFO "GetNetScheduleAccountInformation"
  196. HRESULT hr = S_OK;
  197. #ifndef _CHICAGO_
  198. OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
  199. GetVersionEx(&VersionInfo);
  200. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  201. {
  202. PGETNSACCOUNTINFO pGetNSAccountInfo;
  203. HMODULE hMod = LoadLibrary(MSTASK_DLL);
  204. if (hMod == NULL)
  205. {
  206. hr = HRESULT_FROM_WIN32(GetLastError());
  207. g_Log.Write(LOG_FAIL, "LoadLibrary hr=%#010x", hr);
  208. return hr;
  209. }
  210. else
  211. {
  212. pGetNSAccountInfo = (PGETNSACCOUNTINFO)GetProcAddress(
  213. hMod,
  214. GET_NS_ACCOUNT_INFO);
  215. if (pGetNSAccountInfo == NULL)
  216. {
  217. FreeLibrary(hMod);
  218. hr = HRESULT_FROM_WIN32(GetLastError());
  219. g_Log.Write(LOG_FAIL, "GetProcAddress hr=%#010x", hr);
  220. return hr;
  221. }
  222. }
  223. WCHAR wszAccount[MAX_USERNAME + 1];
  224. DWORD ccAccount = MAX_USERNAME + 1;
  225. hr = pGetNSAccountInfo(NULL, ccAccount, wszAccount);
  226. if (SUCCEEDED(hr))
  227. {
  228. if (hr == S_FALSE)
  229. {
  230. g_Log.Write(LOG_TRACE, "NetSchedule account not specified");
  231. }
  232. else
  233. {
  234. g_Log.Write(LOG_TRACE,
  235. "NetSchedule account name = '%S'", wszAccount);
  236. }
  237. }
  238. else
  239. {
  240. g_Log.Write(LOG_FAIL,
  241. "GetNetScheduleAccountInformation hr=%#010x", hr);
  242. }
  243. FreeLibrary(hMod);
  244. }
  245. else
  246. {
  247. g_Log.Write(
  248. LOG_WARN,
  249. "This command cannot be executed when running under Windows 95.");
  250. }
  251. #else
  252. g_Log.Write(
  253. LOG_WARN,
  254. "This version of JT was built for Win95 and cannot execute this command.");
  255. #endif // !_CHICAGO_
  256. return hr;
  257. }
  258. //+---------------------------------------------------------------------------
  259. //
  260. // Function: CreateTrigger
  261. //
  262. // Synopsis: Parse and execute the create trigger command.
  263. //
  264. // Arguments: [ppwsz] - command line
  265. //
  266. // Returns: S_OK - created trigger
  267. // E_* - error logged
  268. //
  269. // History: 01-04-96 DavidMun Created
  270. //
  271. //----------------------------------------------------------------------------
  272. HRESULT CreateTrigger(WCHAR **ppwsz, BOOL fJob)
  273. {
  274. HRESULT hr = S_OK;
  275. CTrigProp TriggerProps;
  276. USHORT usTrigger;
  277. SpIJobTrigger spTrigger;
  278. do
  279. {
  280. hr = TriggerProps.Parse(ppwsz);
  281. BREAK_ON_FAILURE(hr);
  282. //
  283. // Ask job or queue to create trigger
  284. //
  285. if (fJob)
  286. {
  287. hr = g_pJob->CreateTrigger(&usTrigger, &spTrigger);
  288. LOG_AND_BREAK_ON_FAIL(hr, "ITask::CreateTrigger");
  289. }
  290. else
  291. {
  292. #ifdef NOT_YET
  293. hr = g_pJobQueue->CreateTrigger(&usTrigger, &spTrigger);
  294. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::CreateTrigger");
  295. #endif // NOT_YET
  296. hr = E_NOTIMPL;
  297. }
  298. g_Log.Write(LOG_TRACE, "Created trigger %u", usTrigger);
  299. //
  300. // Now set the trigger's properties to the values we parsed already
  301. //
  302. hr = TriggerProps.SetActual(spTrigger);
  303. }
  304. while (0);
  305. return hr;
  306. }
  307. //+---------------------------------------------------------------------------
  308. //
  309. // Function: DeleteTrigger
  310. //
  311. // Synopsis: Parse and execute the delete trigger command.
  312. //
  313. // Arguments: [ppwsz] - command line
  314. //
  315. // Returns: S_OK - trigger deleted
  316. // E_* - error logged
  317. //
  318. // Modifies: *[ppwsz]
  319. //
  320. // History: 01-05-96 DavidMun Created
  321. //
  322. //----------------------------------------------------------------------------
  323. HRESULT DeleteTrigger(WCHAR **ppwsz, BOOL fJob)
  324. {
  325. HRESULT hr = S_OK;
  326. USHORT usTrigger = 0;
  327. do
  328. {
  329. if (PeekToken(ppwsz) == TKN_NUMBER)
  330. {
  331. GetToken(ppwsz);
  332. usTrigger = (SHORT) g_ulLastNumberToken;
  333. }
  334. g_Log.Write(LOG_TRACE, "Deleting trigger %u", usTrigger);
  335. if (fJob)
  336. {
  337. hr = g_pJob->DeleteTrigger(usTrigger);
  338. LOG_AND_BREAK_ON_FAIL(hr, "ITask::DeleteTrigger");
  339. }
  340. else
  341. {
  342. #ifdef NOT_YET
  343. hr = g_pJobQueue->DeleteTrigger(usTrigger);
  344. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::DeleteTrigger");
  345. #endif // NOT_YET
  346. hr = E_NOTIMPL;
  347. }
  348. }
  349. while (0);
  350. return hr;
  351. }
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Function: EditJob
  355. //
  356. // Synopsis: Invoke the edit job command
  357. //
  358. // Arguments: [ppwsz] - command line
  359. // [fJob] - TRUE=>edit g_pJob, FALSE=>edit a job in g_pJobQueue
  360. //
  361. // Returns: S_OK - UI invoked
  362. // E_* - error logged
  363. //
  364. // History: 01-11-96 DavidMun Created
  365. // 06-28-96 DavidMun Support individual prop pages
  366. //
  367. //----------------------------------------------------------------------------
  368. HRESULT EditJob(WCHAR **ppwsz, BOOL fJob)
  369. {
  370. HRESULT hr = S_OK;
  371. SpIJob spJob;
  372. ITask *pJob; // Do not Release this
  373. SpIUnknown spunkJob;
  374. SpIProvideTaskPage spProvideTaskPage;
  375. TOKEN tkn;
  376. ULONG ulType = 0;
  377. BOOL fPersist = TRUE;
  378. PROPSHEETHEADER psh;
  379. HPROPSHEETPAGE hPage;
  380. LONG lResult;
  381. ZeroMemory(&psh, sizeof(psh));
  382. do
  383. {
  384. if (fJob)
  385. {
  386. pJob = g_pJob;
  387. }
  388. else
  389. {
  390. #ifdef NOT_YET
  391. hr = Expect(TKN_STRING, ppwsz, L"job name");
  392. BREAK_ON_FAILURE(hr);
  393. hr = g_pJobQueue->GetTask(
  394. g_wszLastStringToken,
  395. IID_IUnknown,
  396. &spunkJob);
  397. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTask");
  398. hr = spunkJob->QueryInterface(IID_ITask, (VOID**)(ITask**)&spJob);
  399. LOG_AND_BREAK_ON_FAIL(hr, "QI for ITask");
  400. pJob = spJob;
  401. #endif // NOT_YET
  402. hr = E_NOTIMPL;
  403. }
  404. //
  405. // See if the optional property sheet page argument has been
  406. // specified. If so, retrieve and open just that page, otherwise use
  407. // the EditJob method to open all the pages.
  408. //
  409. tkn = PeekToken(ppwsz);
  410. if (tkn == TKN_NUMBER)
  411. {
  412. GetToken(ppwsz);
  413. ulType = g_ulLastNumberToken;
  414. //
  415. // Now see if the optional value for fPersistChanges was
  416. // provided.
  417. //
  418. tkn = PeekToken(ppwsz);
  419. if (tkn == TKN_STRING)
  420. {
  421. GetToken(ppwsz);
  422. fPersist = g_wszLastStringToken[0] == L't' ||
  423. g_wszLastStringToken[0] == L'T';
  424. }
  425. //
  426. // Get the interface that has the method that returns a page.
  427. // Then retrieve the page the user asked for.
  428. //
  429. hr = pJob->QueryInterface(
  430. IID_IProvideTaskPage,
  431. (VOID**)(IProvideTaskPage**)&spProvideTaskPage);
  432. LOG_AND_BREAK_ON_FAIL(hr, "QI for IProvideTaskPage");
  433. g_Log.Write(
  434. LOG_TRACE,
  435. "Opening page %u, changes will%s be persisted",
  436. ulType,
  437. fPersist ? "" : " not");
  438. hr = spProvideTaskPage->GetPage((TASKPAGE)ulType, fPersist, &hPage);
  439. LOG_AND_BREAK_ON_FAIL(hr, "IProvideTaskPage::GetPage");
  440. //
  441. // Now that we have the page, display it in its very own
  442. // property sheet.
  443. //
  444. psh.dwSize = sizeof(PROPSHEETHEADER);
  445. psh.dwFlags = PSH_DEFAULT;
  446. psh.hwndParent = NULL;
  447. psh.hInstance = NULL;
  448. psh.pszCaption = TEXT("jt job object");
  449. psh.phpage = &hPage;
  450. psh.nPages = 1;
  451. lResult = PropertySheet(&psh);
  452. if (lResult == -1)
  453. {
  454. g_Log.Write(LOG_FAIL, "PropertySheet (%u)", GetLastError());
  455. hr = HRESULT_FROM_WIN32(GetLastError());
  456. }
  457. }
  458. else
  459. {
  460. hr = pJob->EditWorkItem(NULL, TRUE);
  461. LOG_AND_BREAK_ON_FAIL(hr, "ITask::EditWorkItem");
  462. }
  463. }
  464. while (0);
  465. return hr;
  466. }
  467. //+---------------------------------------------------------------------------
  468. //
  469. // Function: EnumClone
  470. //
  471. // Synopsis: Invoke the IEnumJobs::Clone command
  472. //
  473. // Arguments: [ppwsz] - command line
  474. //
  475. // Returns: S_OK - a slot has been filled with cloned enumerator
  476. // E_INVALIDARG - bad slot number
  477. //
  478. // Modifies: g_apEnumJobs
  479. //
  480. // History: 01-30-96 DavidMun Created
  481. //
  482. //----------------------------------------------------------------------------
  483. HRESULT EnumClone(WCHAR **ppwsz)
  484. {
  485. HRESULT hr = S_OK;
  486. ULONG idxDestSlot;
  487. ULONG idxSourceSlot;
  488. do
  489. {
  490. hr = GetAndPrepareEnumeratorSlot(ppwsz, &idxDestSlot);
  491. BREAK_ON_FAILURE(hr);
  492. hr = GetEnumeratorSlot(ppwsz, &idxSourceSlot);
  493. BREAK_ON_FAILURE(hr);
  494. hr = VerifySlotFilled(idxSourceSlot);
  495. BREAK_ON_FAILURE(hr);
  496. g_Log.Write(
  497. LOG_TRACE,
  498. "Cloning enumerator in slot %u into slot %u",
  499. idxSourceSlot,
  500. idxDestSlot);
  501. hr = g_apEnumJobs[idxSourceSlot]->Clone(&g_apEnumJobs[idxDestSlot]);
  502. if (FAILED(hr))
  503. {
  504. g_Log.Write(
  505. LOG_FAIL,
  506. "IEnumJobs::Clone hr=%#010x",
  507. hr);
  508. }
  509. }
  510. while (0);
  511. return hr;
  512. }
  513. //+---------------------------------------------------------------------------
  514. //
  515. // Function: EnumNext
  516. //
  517. // Synopsis: Invoke the IEnumJobs::Next command
  518. //
  519. // Arguments: [ppwsz] - command line
  520. //
  521. // Returns: S_OK - Next performed successfully
  522. // E_INVALIDARG - bad slot number
  523. //
  524. // History: 01-30-96 DavidMun Created
  525. //
  526. //----------------------------------------------------------------------------
  527. HRESULT EnumNext(WCHAR **ppwsz)
  528. {
  529. HRESULT hr = S_OK;
  530. ULONG idxSlot;
  531. LPWSTR *ppwszFetched;
  532. LPWSTR *ppwszCur;
  533. ULONG cFetched;
  534. ULONG i;
  535. do
  536. {
  537. hr = GetEnumeratorSlot(ppwsz, &idxSlot);
  538. BREAK_ON_FAILURE(hr);
  539. hr = VerifySlotFilled(idxSlot);
  540. BREAK_ON_FAILURE(hr);
  541. hr = Expect(TKN_NUMBER, ppwsz, L"number of items to enumerate");
  542. BREAK_ON_FAILURE(hr);
  543. g_Log.Write(
  544. LOG_TRACE,
  545. "Enumerating next %u items using enumerator in slot %u",
  546. g_ulLastNumberToken,
  547. idxSlot);
  548. hr = g_apEnumJobs[idxSlot]->Next(g_ulLastNumberToken, &ppwszFetched, &cFetched);
  549. LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Next");
  550. if (hr == S_FALSE)
  551. {
  552. g_Log.Write(LOG_INFO, "IEnumJobs::Next returned S_FALSE");
  553. }
  554. if (cFetched != g_ulLastNumberToken)
  555. {
  556. g_Log.Write(
  557. LOG_INFO,
  558. "IEnumJobs::Next fetched only %u jobs",
  559. cFetched);
  560. }
  561. for (i = 0, ppwszCur = ppwszFetched; i < cFetched; i++, ppwszCur++)
  562. {
  563. g_Log.Write(LOG_TEXT, "%u: %S", idxSlot, *ppwszCur);
  564. CoTaskMemFree(*ppwszCur);
  565. }
  566. CoTaskMemFree(ppwszFetched);
  567. }
  568. while (0);
  569. return hr;
  570. }
  571. //+---------------------------------------------------------------------------
  572. //
  573. // Function: EnumReset
  574. //
  575. // Synopsis: Invoke the IEnumJobs::Reset command
  576. //
  577. // Arguments: [ppwsz] - command line
  578. //
  579. // Returns: S_OK - Reset performed successfully
  580. // E_INVALIDARG - bad slot number
  581. //
  582. // History: 01-30-96 DavidMun Created
  583. //
  584. //----------------------------------------------------------------------------
  585. HRESULT EnumReset(WCHAR **ppwsz)
  586. {
  587. HRESULT hr = S_OK;
  588. ULONG idxSlot;
  589. do
  590. {
  591. hr = GetEnumeratorSlot(ppwsz, &idxSlot);
  592. BREAK_ON_FAILURE(hr);
  593. hr = VerifySlotFilled(idxSlot);
  594. BREAK_ON_FAILURE(hr);
  595. g_Log.Write(LOG_TRACE, "Resetting enumerator in slot %u", idxSlot);
  596. hr = g_apEnumJobs[idxSlot]->Reset();
  597. LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Reset");
  598. }
  599. while (0);
  600. return hr;
  601. }
  602. //+---------------------------------------------------------------------------
  603. //
  604. // Function: EnumSkip
  605. //
  606. // Synopsis: Invoke the IEnumJobs::Skip command
  607. //
  608. // Arguments: [ppwsz] - command line
  609. //
  610. // Returns: S_OK - Skip performed successfully
  611. // E_INVALIDARG - bad slot number
  612. //
  613. // History: 01-30-96 DavidMun Created
  614. //
  615. //----------------------------------------------------------------------------
  616. HRESULT EnumSkip(WCHAR **ppwsz)
  617. {
  618. HRESULT hr = S_OK;
  619. ULONG idxSlot;
  620. do
  621. {
  622. hr = GetEnumeratorSlot(ppwsz, &idxSlot);
  623. BREAK_ON_FAILURE(hr);
  624. hr = VerifySlotFilled(idxSlot);
  625. BREAK_ON_FAILURE(hr);
  626. hr = Expect(TKN_NUMBER, ppwsz, L"number of items to skip");
  627. BREAK_ON_FAILURE(hr);
  628. g_Log.Write(
  629. LOG_TRACE,
  630. "Skipping next %u items using enumerator in slot %u",
  631. g_ulLastNumberToken,
  632. idxSlot);
  633. hr = g_apEnumJobs[idxSlot]->Skip(g_ulLastNumberToken);
  634. LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Skip");
  635. if (hr == S_FALSE)
  636. {
  637. g_Log.Write(LOG_INFO, "IEnumJobs::Skip returned S_FALSE");
  638. }
  639. }
  640. while (0);
  641. return hr;
  642. }
  643. //+---------------------------------------------------------------------------
  644. //
  645. // Function: Load
  646. //
  647. // Synopsis: Load the job or queue file specified on the command line
  648. // into the global job or queue object.
  649. //
  650. // Arguments: [ppwsz] - command line.
  651. // [szJobOrQueue] - "Job" or "Queue"
  652. // [fJob] - TRUE=>use global job, FALSE=>use global queue
  653. //
  654. // Returns: S_OK - job or queue loaded
  655. // E_* - error logged
  656. //
  657. // History: 01-10-96 DavidMun Created
  658. //
  659. //----------------------------------------------------------------------------
  660. HRESULT Load(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
  661. {
  662. HRESULT hr = S_OK;
  663. SpIPersistFile spPersistFile;
  664. do
  665. {
  666. hr = GetFilename(ppwsz, L"file to load");
  667. BREAK_ON_FAILURE(hr);
  668. g_Log.Write(
  669. LOG_TRACE,
  670. "Loading %s %S",
  671. szJobOrQueue,
  672. g_wszLastStringToken);
  673. if (fJob)
  674. {
  675. g_pJob->QueryInterface(
  676. IID_IPersistFile,
  677. (VOID**)(IPersistFile**)&spPersistFile);
  678. LOG_AND_BREAK_ON_FAIL(hr, "ITask::QI(IPersistFile)");
  679. }
  680. else
  681. {
  682. g_pJobQueue->QueryInterface(
  683. IID_IPersistFile,
  684. (VOID**)(IPersistFile**)&spPersistFile);
  685. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::QI(IPersistFile)");
  686. }
  687. DWORD ulTicks = GetTickCount();
  688. hr = spPersistFile->Load(
  689. g_wszLastStringToken,
  690. STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
  691. ulTicks = GetTickCount() - ulTicks;
  692. g_Log.Write(LOG_PERF, "Load took %lu ms", ulTicks);
  693. LOG_AND_BREAK_ON_FAIL(hr, "IPersistFile::Load");
  694. }
  695. while (0);
  696. return hr;
  697. }
  698. //+---------------------------------------------------------------------------
  699. //
  700. // Function: PrintAll
  701. //
  702. // Synopsis: Print all properties of global job or queue.
  703. //
  704. // Arguments: [ppwsz] - command line
  705. // [fJob] - TRUE=>use global job, FALSE=>use global queue
  706. //
  707. // Returns: S_OK - command executed
  708. // E_* - error logged
  709. //
  710. // Modifies: *[ppwsz]
  711. //
  712. // History: 01-10-96 DavidMun Created
  713. //
  714. //----------------------------------------------------------------------------
  715. HRESULT PrintAll(WCHAR **ppwsz, BOOL fJob)
  716. {
  717. HRESULT hr = S_OK;
  718. do
  719. {
  720. if (!fJob)
  721. {
  722. g_Log.Write(LOG_ERROR, "this command is not yet implemented");
  723. break;
  724. }
  725. else
  726. {
  727. hr = DumpJob(g_pJob);
  728. BREAK_ON_FAILURE(hr);
  729. hr = DumpJobTriggers(g_pJob);
  730. }
  731. }
  732. while (0);
  733. return hr;
  734. }
  735. //+---------------------------------------------------------------------------
  736. //
  737. // Function: PrintRunTimes
  738. //
  739. // Synopsis: Parse and execute the print job run times command
  740. //
  741. // Arguments: [ppwsz] - command line
  742. // [fJob] - TRUE=>use global job, FALSE=>use global queue
  743. //
  744. // Returns: S_OK - command executed
  745. // E_* - error logged
  746. //
  747. // Modifies: *[ppwsz]
  748. //
  749. // History: 01-05-96 DavidMun Created
  750. //
  751. //----------------------------------------------------------------------------
  752. HRESULT PrintRunTimes(WCHAR **ppwsz, BOOL fJob)
  753. {
  754. HRESULT hr = S_OK;
  755. TOKEN tkn;
  756. USHORT cRuns = 0;
  757. SYSTEMTIME stNow;
  758. LPSYSTEMTIME pstRuns = NULL;
  759. USHORT i;
  760. do
  761. {
  762. tkn = PeekToken(ppwsz);
  763. if (tkn == TKN_NUMBER)
  764. {
  765. GetToken(ppwsz);
  766. cRuns = (USHORT) g_ulLastNumberToken;
  767. }
  768. GetLocalTime(&stNow);
  769. //
  770. // If the optional number of runs was not specified or was 0,
  771. // print remaining runs for today only.
  772. //
  773. if (cRuns == 0)
  774. {
  775. SYSTEMTIME stEnd;
  776. stEnd = stNow;
  777. stEnd.wHour = 23;
  778. stEnd.wMinute = 59;
  779. if (fJob)
  780. {
  781. hr = g_pJob->GetRunTimes(&stNow, &stEnd, &cRuns, &pstRuns);
  782. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
  783. }
  784. else
  785. {
  786. #ifdef NOT_YET
  787. hr = g_pJobQueue->GetRunTimes(&stNow, &stEnd, &cRuns, &pstRuns);
  788. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetRunTimes");
  789. #endif // NOT_YET
  790. hr = E_NOTIMPL;
  791. }
  792. if (cRuns == 0)
  793. {
  794. g_Log.Write(LOG_TEXT, "No runs are scheduled for today.");
  795. break;
  796. }
  797. g_Log.Write(LOG_TEXT, "The remaining %u run", cRuns);
  798. g_Log.Write(LOG_TEXT, "times for today:");
  799. g_Log.Write(LOG_TEXT, "--------------------");
  800. }
  801. else
  802. {
  803. //
  804. // cRuns > 0. Get at most the next cRuns run times.
  805. //
  806. if (fJob)
  807. {
  808. hr = g_pJob->GetRunTimes(&stNow, NULL, &cRuns, &pstRuns);
  809. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
  810. }
  811. else
  812. {
  813. #ifdef NOT_YET
  814. hr = g_pJobQueue->GetRunTimes(&stNow, NULL, &cRuns, &pstRuns);
  815. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
  816. #endif // NOT_YET
  817. hr = E_NOTIMPL;
  818. }
  819. if (cRuns == 0)
  820. {
  821. g_Log.Write(LOG_TEXT, "No runs are scheduled. hr = %#lx", hr);
  822. break;
  823. }
  824. g_Log.Write(LOG_TEXT, "ITask::GetRunTimes succeeded, hr = %#lx", hr);
  825. g_Log.Write(LOG_TEXT, "The next %u run times:", cRuns);
  826. g_Log.Write(LOG_TEXT, "----------------------");
  827. }
  828. for (i = 0; i < cRuns; i++)
  829. {
  830. g_Log.Write(
  831. LOG_TEXT,
  832. "%02d/%02d/%d at %02d:%02d:%02d",
  833. pstRuns[i].wMonth,
  834. pstRuns[i].wDay,
  835. pstRuns[i].wYear,
  836. pstRuns[i].wHour,
  837. pstRuns[i].wMinute,
  838. pstRuns[i].wSecond);
  839. }
  840. }
  841. while (0);
  842. CoTaskMemFree(pstRuns);
  843. return hr;
  844. }
  845. //+---------------------------------------------------------------------------
  846. //
  847. // Function: PrintTrigger
  848. //
  849. // Synopsis: Print one or more trigger's properties
  850. //
  851. // Arguments: [ppwsz] - command line
  852. // [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
  853. //
  854. // Returns: S_OK - trigger(s) printed
  855. // E_* - error logged
  856. //
  857. // History: 01-10-96 DavidMun Created
  858. //
  859. //----------------------------------------------------------------------------
  860. HRESULT PrintTrigger(WCHAR **ppwsz, BOOL fJob)
  861. {
  862. HRESULT hr = S_OK;
  863. USHORT usTrigger = 0;
  864. BOOL fPrintAll = FALSE;
  865. SpIJobTrigger spTrigger;
  866. do
  867. {
  868. if (PeekToken(ppwsz) == TKN_NUMBER)
  869. {
  870. GetToken(ppwsz);
  871. usTrigger = (USHORT) g_ulLastNumberToken;
  872. }
  873. else
  874. {
  875. fPrintAll = TRUE;
  876. }
  877. if (fPrintAll)
  878. {
  879. hr = DumpTriggers(fJob);
  880. }
  881. else
  882. {
  883. hr = DumpTrigger(fJob, usTrigger);
  884. }
  885. }
  886. while (0);
  887. return hr;
  888. }
  889. //+---------------------------------------------------------------------------
  890. //
  891. // Function: PrintTriggerStrings
  892. //
  893. // Synopsis: Parse and execute the command to print one or all trigger
  894. // strings for a job.
  895. //
  896. // Arguments: [ppwsz] - command line
  897. // [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
  898. //
  899. // Returns: S_OK - string(s) printed
  900. // E_* - error logged
  901. //
  902. // Modifies: *[ppwsz]
  903. //
  904. // History: 01-05-96 DavidMun Created
  905. //
  906. //----------------------------------------------------------------------------
  907. HRESULT PrintTriggerStrings(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
  908. {
  909. HRESULT hr = S_OK;
  910. TOKEN tkn;
  911. BOOL fAllTriggers = TRUE;
  912. USHORT usTrigger;
  913. USHORT cTriggers;
  914. SHORT i;
  915. WCHAR * pwszTriggerString;
  916. do
  917. {
  918. tkn = PeekToken(ppwsz);
  919. if (tkn == TKN_NUMBER)
  920. {
  921. GetToken(ppwsz);
  922. fAllTriggers = FALSE;
  923. usTrigger = (USHORT) g_ulLastNumberToken;
  924. }
  925. if (fJob)
  926. {
  927. hr = g_pJob->GetTriggerCount(&cTriggers);
  928. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerCount");
  929. }
  930. else
  931. {
  932. #ifdef NOT_YET
  933. hr = g_pJobQueue->GetTriggerCount(&cTriggers);
  934. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTriggerCount");
  935. #endif // NOT_YET
  936. hr = E_NOTIMPL;
  937. }
  938. if (!cTriggers)
  939. {
  940. g_Log.Write(LOG_TEXT, "There are no triggers on the %s", szJobOrQueue);
  941. break;
  942. }
  943. if (fAllTriggers)
  944. {
  945. g_Log.Write(LOG_TEXT, "All %u triggers on %s:", cTriggers, szJobOrQueue);
  946. g_Log.Write(LOG_TEXT, "Index Value");
  947. g_Log.Write(LOG_TEXT, "----- -----------------------------------------------------");
  948. for (i = 0; i < cTriggers; i++)
  949. {
  950. if (fJob)
  951. {
  952. hr = g_pJob->GetTriggerString(i, &pwszTriggerString);
  953. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
  954. }
  955. else
  956. {
  957. #ifdef NOT_YET
  958. hr = g_pJobQueue->GetTriggerString(i, &pwszTriggerString);
  959. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
  960. #endif // NOT_YET
  961. hr = E_NOTIMPL;
  962. }
  963. g_Log.Write(LOG_TEXT, "% 5d %S", i, pwszTriggerString);
  964. CoTaskMemFree(pwszTriggerString);
  965. if (i < cTriggers - 1)
  966. {
  967. g_Log.Write(LOG_TEXT, "");
  968. }
  969. }
  970. }
  971. else
  972. {
  973. g_Log.Write(LOG_TEXT, "Trigger %u:", usTrigger);
  974. if (fJob)
  975. {
  976. hr = g_pJob->GetTriggerString(usTrigger,
  977. &pwszTriggerString);
  978. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
  979. }
  980. else
  981. {
  982. #ifdef NOT_YET
  983. hr = g_pJobQueue->GetTriggerString(usTrigger,
  984. &pwszTriggerString);
  985. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTriggerString");
  986. #endif // NOT_YET
  987. hr = E_NOTIMPL;
  988. }
  989. g_Log.Write(LOG_TEXT, "%S", pwszTriggerString);
  990. CoTaskMemFree(pwszTriggerString);
  991. }
  992. }
  993. while (0);
  994. return hr;
  995. }
  996. //+---------------------------------------------------------------------------
  997. //
  998. // Function: Run
  999. //
  1000. // Synopsis: Run job or queue object.
  1001. //
  1002. // Arguments: [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
  1003. //
  1004. // Returns: Result of ITask[Queue]::Run
  1005. //
  1006. // History: 01-11-96 DavidMun Created
  1007. //
  1008. //----------------------------------------------------------------------------
  1009. HRESULT Run(BOOL fJob)
  1010. {
  1011. HRESULT hr = S_OK;
  1012. if (fJob)
  1013. {
  1014. g_Log.Write(LOG_TRACE, "Running job");
  1015. hr = g_pJob->Run();
  1016. if (FAILED(hr))
  1017. {
  1018. g_Log.Write(LOG_FAIL, "ITask::Run hr=%#010x", hr);
  1019. }
  1020. }
  1021. else
  1022. {
  1023. #ifdef NOT_YET
  1024. g_Log.Write(LOG_TRACE, "Running queue");
  1025. hr = g_pJobQueue->Run();
  1026. if (FAILED(hr))
  1027. {
  1028. g_Log.Write(LOG_FAIL, "ITaskQueue::Run hr=%#010x", hr);
  1029. }
  1030. #endif // NOT_YET
  1031. hr = E_NOTIMPL;
  1032. }
  1033. return hr;
  1034. }
  1035. //+---------------------------------------------------------------------------
  1036. //
  1037. // Function: Save
  1038. //
  1039. // Synopsis: Persist the global job or queue to the file specified in
  1040. // the command line
  1041. //
  1042. // Arguments: [ppwsz] - command line.
  1043. // [szJobOrQueue] - "Job" or "Queue"
  1044. // [fJob] - TRUE=>use global job, FALSE=>use global queue
  1045. //
  1046. // Returns: S_OK - job or queue persisted
  1047. // E_* - error logged
  1048. //
  1049. // History: 01-10-96 DavidMun Created
  1050. //
  1051. //----------------------------------------------------------------------------
  1052. HRESULT Save(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
  1053. {
  1054. HRESULT hr = S_OK;
  1055. TOKEN tkn;
  1056. WCHAR *pwszFilename = NULL;
  1057. SpIPersistFile spPersistFile;
  1058. do
  1059. {
  1060. tkn = PeekToken(ppwsz);
  1061. if (tkn == TKN_STRING)
  1062. {
  1063. hr = GetFilename(ppwsz, L"filename for save");
  1064. BREAK_ON_FAILURE(hr);
  1065. pwszFilename = g_wszLastStringToken;
  1066. g_Log.Write(LOG_TRACE, "Saving %s to %S", szJobOrQueue, g_wszLastStringToken);
  1067. }
  1068. else
  1069. {
  1070. g_Log.Write(LOG_TRACE, "Saving %s", szJobOrQueue);
  1071. }
  1072. if (fJob)
  1073. {
  1074. g_pJob->QueryInterface(
  1075. IID_IPersistFile,
  1076. (VOID**)(IPersistFile**)&spPersistFile);
  1077. LOG_AND_BREAK_ON_FAIL(hr, "ITask::QI(IPersistFile)");
  1078. }
  1079. else
  1080. {
  1081. g_pJobQueue->QueryInterface(
  1082. IID_IPersistFile,
  1083. (VOID**)(IPersistFile**)&spPersistFile);
  1084. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::QI(IPersistFile)");
  1085. }
  1086. DWORD ulTicks = GetTickCount();
  1087. hr = spPersistFile->Save(pwszFilename, TRUE);
  1088. ulTicks = GetTickCount() - ulTicks;
  1089. g_Log.Write(LOG_PERF, "Save took %lu ms", ulTicks);
  1090. LOG_AND_BREAK_ON_FAIL(hr, "IPersistFile::Save");
  1091. }
  1092. while (0);
  1093. return hr;
  1094. }
  1095. //+---------------------------------------------------------------------------
  1096. //
  1097. // Function: SchedActivate
  1098. //
  1099. // Synopsis: Perform activate job/queue command.
  1100. //
  1101. // Arguments: [ppwsz] - commandline.
  1102. //
  1103. // Returns: S_OK - activated job or queue
  1104. // E_* - error logged
  1105. //
  1106. // History: 01-11-96 DavidMun Created
  1107. //
  1108. // Notes: This is the command-line front end to the utility routine
  1109. // Activate. That routine is also called by other routines;
  1110. // see SchedEnum.
  1111. //
  1112. //----------------------------------------------------------------------------
  1113. HRESULT SchedActivate(WCHAR **ppwsz)
  1114. {
  1115. HRESULT hr = S_OK;
  1116. BOOL fJob;
  1117. do
  1118. {
  1119. hr = Expect(TKN_STRING, ppwsz, L"job or queue filename");
  1120. BREAK_ON_FAILURE(hr);
  1121. hr = Activate(g_wszLastStringToken, &g_pJob, &g_pJobQueue, &fJob);
  1122. }
  1123. while (0);
  1124. return hr;
  1125. }
  1126. //+---------------------------------------------------------------------------
  1127. //
  1128. // Function: SchedAddJob
  1129. //
  1130. // Synopsis: Perform add job command.
  1131. //
  1132. // Arguments: [ppwsz] - commandline.
  1133. //
  1134. // Returns: S_OK - added job
  1135. // E_* - error logged
  1136. //
  1137. // History: 01-11-96 DavidMun Created
  1138. //
  1139. //----------------------------------------------------------------------------
  1140. HRESULT SchedAddJob(WCHAR **ppwsz)
  1141. {
  1142. HRESULT hr = S_OK;
  1143. do
  1144. {
  1145. //
  1146. // Note this filename may be a path relative to the job folder, so we
  1147. // don't want to expand it to a full path name by calling GetFilename.
  1148. // Just read it as a string instead.
  1149. //
  1150. hr = Expect(TKN_STRING, ppwsz, L"job filename");
  1151. BREAK_ON_FAILURE(hr);
  1152. g_Log.Write(LOG_TRACE, "Adding job '%S'", g_wszLastStringToken);
  1153. hr = g_pJobScheduler->AddWorkItem(g_wszLastStringToken, g_pJob);
  1154. LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::AddWorkItemn");
  1155. }
  1156. while (0);
  1157. return hr;
  1158. }
  1159. //+---------------------------------------------------------------------------
  1160. //
  1161. // Function: SchedCreateEnum
  1162. //
  1163. // Synopsis: Create a new jobs folder enumerator in the slot specified
  1164. // by command line
  1165. //
  1166. // Arguments: [ppwsz] - command line
  1167. //
  1168. // Returns: S_OK - new enumerator created
  1169. // E_INVALIDARG - command line has bad slot number
  1170. // E_* - from ITaskScheduler::EnumJobs
  1171. //
  1172. // Modifies: g_apEnumJobs
  1173. //
  1174. // History: 01-30-96 DavidMun Created
  1175. //
  1176. //----------------------------------------------------------------------------
  1177. HRESULT SchedCreateEnum(WCHAR **ppwsz)
  1178. {
  1179. HRESULT hr = S_OK;
  1180. ULONG idxSlot;
  1181. do
  1182. {
  1183. hr = GetAndPrepareEnumeratorSlot(ppwsz, &idxSlot);
  1184. BREAK_ON_FAILURE(hr);
  1185. g_Log.Write(LOG_TRACE, "Creating new enumerator in slot %u", idxSlot);
  1186. hr = g_pJobScheduler->Enum(&g_apEnumJobs[idxSlot]);
  1187. LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Enum");
  1188. }
  1189. while (0);
  1190. return hr;
  1191. }
  1192. //+---------------------------------------------------------------------------
  1193. //
  1194. // Function: SchedDelete
  1195. //
  1196. // Synopsis: Perform delete job/queue command.
  1197. //
  1198. // Arguments: [ppwsz] - commandline.
  1199. //
  1200. // Returns: S_OK - deleted job or queue
  1201. // E_* - error logged
  1202. //
  1203. // History: 01-11-96 DavidMun Created
  1204. //
  1205. //----------------------------------------------------------------------------
  1206. HRESULT SchedDelete(WCHAR **ppwsz)
  1207. {
  1208. HRESULT hr = S_OK;
  1209. do
  1210. {
  1211. hr = Expect(TKN_STRING, ppwsz, L"job or queue filename to delete");
  1212. BREAK_ON_FAILURE(hr);
  1213. g_Log.Write(LOG_TRACE, "Deleting '%S'", g_wszLastStringToken);
  1214. hr = g_pJobScheduler->Delete(g_wszLastStringToken);
  1215. LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Delete");
  1216. }
  1217. while (0);
  1218. return hr;
  1219. }
  1220. //+---------------------------------------------------------------------------
  1221. //
  1222. // Function: SchedEnum
  1223. //
  1224. // Synopsis: Perform enumerate jobs/queues command.
  1225. //
  1226. // Arguments: [ppwsz] - commandline.
  1227. //
  1228. // Returns: S_OK - job/queue names enumerated
  1229. // E_* - error logged
  1230. //
  1231. // History: 01-12-96 DavidMun Created
  1232. //
  1233. //----------------------------------------------------------------------------
  1234. HRESULT SchedEnum(WCHAR **ppwsz)
  1235. {
  1236. HRESULT hr = S_OK;
  1237. SpIEnumJobs spEnum;
  1238. TOKEN tkn;
  1239. ULONG i;
  1240. ULONG cToFetch = DEFAULT_FETCH_COUNT;
  1241. ULONG cFetched;
  1242. BOOL fPrint = FALSE;
  1243. do
  1244. {
  1245. g_Log.Write(LOG_TRACE, "Enumerating jobs and queues");
  1246. tkn = PeekToken(ppwsz);
  1247. while (tkn == TKN_NUMBER || tkn == TKN_STRING)
  1248. {
  1249. GetToken(ppwsz);
  1250. if (tkn == TKN_NUMBER)
  1251. {
  1252. cToFetch = g_ulLastNumberToken;
  1253. }
  1254. else
  1255. {
  1256. if (towupper(g_wszLastStringToken[0]) == L'P')
  1257. {
  1258. fPrint = TRUE;
  1259. }
  1260. }
  1261. tkn = PeekToken(ppwsz);
  1262. }
  1263. hr = g_pJobScheduler->Enum(&spEnum);
  1264. LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Enum");
  1265. do
  1266. {
  1267. LPWSTR *ppwszFetched;
  1268. LPWSTR *ppwszCur;
  1269. hr = spEnum->Next(cToFetch, &ppwszFetched, &cFetched);
  1270. LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Next");
  1271. for (i = 0, ppwszCur = ppwszFetched; i < cFetched; i++, ppwszCur++)
  1272. {
  1273. if (fPrint)
  1274. {
  1275. SpIJob spJob;
  1276. SpIUnknown spQueue;
  1277. BOOL fJob;
  1278. hr = Activate(*ppwszCur, &spJob, &spQueue, &fJob);
  1279. if (SUCCEEDED(hr))
  1280. {
  1281. if (fJob)
  1282. {
  1283. DumpJob(spJob);
  1284. DumpJobTriggers(spJob);
  1285. }
  1286. else
  1287. {
  1288. // BUGBUG call DumpQueue here
  1289. g_Log.Write(
  1290. LOG_WARN,
  1291. "Ignoring %S: DumpQueue not implemented",
  1292. *ppwszCur);
  1293. }
  1294. }
  1295. g_Log.Write(LOG_TEXT, "");
  1296. g_Log.Write(LOG_TEXT, "");
  1297. }
  1298. else
  1299. {
  1300. g_Log.Write(LOG_TEXT, " %S", *ppwszCur);
  1301. }
  1302. CoTaskMemFree(*ppwszCur);
  1303. }
  1304. CoTaskMemFree(ppwszFetched);
  1305. } while (cFetched);
  1306. }
  1307. while (0);
  1308. return hr;
  1309. }
  1310. //+---------------------------------------------------------------------------
  1311. //
  1312. // Function: GetCredentials
  1313. //
  1314. // Synopsis: Retrieve the account name associated with the job's
  1315. // credentials.
  1316. //
  1317. // Returns: Result of GetTargetComputer call.
  1318. //
  1319. // History: 06-04-96 DavidMun Created
  1320. //
  1321. //----------------------------------------------------------------------------
  1322. HRESULT GetCredentials(void)
  1323. {
  1324. HRESULT hr;
  1325. LPWSTR pwszAccount;
  1326. if (g_pJob == NULL)
  1327. {
  1328. g_Log.Write(
  1329. LOG_FAIL,
  1330. "A job object must be specified to get account information.");
  1331. return(E_FAIL);
  1332. }
  1333. hr = g_pJob->GetAccountInformation(&pwszAccount);
  1334. if (FAILED(hr))
  1335. {
  1336. g_Log.Write(LOG_FAIL,
  1337. "ITaskScheduler::GetAccountInformation hr=%#010x", hr);
  1338. }
  1339. else
  1340. {
  1341. g_Log.Write(LOG_TRACE, "Credential account name = '%S'", pwszAccount);
  1342. CoTaskMemFree(pwszAccount);
  1343. }
  1344. return(hr);
  1345. }
  1346. //+---------------------------------------------------------------------------
  1347. //
  1348. // Function: SchedGetMachine
  1349. //
  1350. // Synopsis: Perform Get Machine command (print target computer).
  1351. //
  1352. // Returns: Result of GetTargetComputer call.
  1353. //
  1354. // History: 06-04-96 DavidMun Created
  1355. //
  1356. //----------------------------------------------------------------------------
  1357. HRESULT SchedGetMachine()
  1358. {
  1359. HRESULT hr;
  1360. LPWSTR pwszComputer;
  1361. hr = g_pJobScheduler->GetTargetComputer(&pwszComputer);
  1362. if (FAILED(hr))
  1363. {
  1364. g_Log.Write(LOG_FAIL, "ITaskScheduler::GetTargetComputer hr=%#010x", hr);
  1365. }
  1366. else
  1367. {
  1368. g_Log.Write(LOG_TRACE, "TargetComputer = '%S'", pwszComputer);
  1369. CoTaskMemFree(pwszComputer);
  1370. }
  1371. return hr;
  1372. }
  1373. //+---------------------------------------------------------------------------
  1374. //
  1375. // Function: SchedIsJobOrQueue
  1376. //
  1377. // Synopsis: Call the ITaskScheduler::IsJob and IsQueue commands on the
  1378. // specified filename and report the results.
  1379. //
  1380. // Arguments: [ppwsz] - commandline.
  1381. //
  1382. // Returns: S_OK - methods called
  1383. // E_* - invalid commandline
  1384. //
  1385. // History: 03-11-96 DavidMun Created
  1386. //
  1387. // Notes: Don't consider errors returned by the IsJob and IsQueue
  1388. // methods as errors in calling this routine. That would
  1389. // halt a script that purposely gives them bad paths.
  1390. //
  1391. //----------------------------------------------------------------------------
  1392. HRESULT SchedIsJobOrQueue(WCHAR **ppwsz)
  1393. {
  1394. HRESULT hr = S_OK;
  1395. do
  1396. {
  1397. hr = Expect(TKN_STRING, ppwsz, L"filename to test");
  1398. BREAK_ON_FAILURE(hr);
  1399. hr = g_pJobScheduler->IsOfType(g_wszLastStringToken, IID_ITask);
  1400. g_Log.Write(
  1401. LOG_TRACE,
  1402. "ITaskScheduler::IsOfType(%S) returned %#010x",
  1403. g_wszLastStringToken,
  1404. hr);
  1405. #ifdef NOT_YET
  1406. hr = g_pJobScheduler->IsQueue(g_wszLastStringToken);
  1407. g_Log.Write(
  1408. LOG_TRACE,
  1409. "ITaskScheduler::IsQueue(%S) returned %#010x",
  1410. g_wszLastStringToken,
  1411. hr);
  1412. #endif
  1413. hr = S_OK;
  1414. }
  1415. while (0);
  1416. return hr;
  1417. }
  1418. //+---------------------------------------------------------------------------
  1419. //
  1420. // Function: SchedNewJob
  1421. //
  1422. // Synopsis: Perform new job command.
  1423. //
  1424. // Arguments: [ppwsz] - commandline.
  1425. //
  1426. // Returns: S_OK - created new job
  1427. // E_* - error logged
  1428. //
  1429. // History: 01-11-96 DavidMun Created
  1430. //
  1431. //----------------------------------------------------------------------------
  1432. HRESULT SchedNewJob(WCHAR **ppwsz)
  1433. {
  1434. HRESULT hr = S_OK;
  1435. SpIJob spNewJob;
  1436. do
  1437. {
  1438. hr = Expect(TKN_STRING, ppwsz, L"job filename");
  1439. BREAK_ON_FAILURE(hr);
  1440. g_Log.Write(LOG_TRACE, "Creating new job '%S'", g_wszLastStringToken);
  1441. DWORD ulTicks = GetTickCount();
  1442. hr = g_pJobScheduler->NewWorkItem(
  1443. g_wszLastStringToken,
  1444. CLSID_CTask,
  1445. IID_ITask,
  1446. (IUnknown**)(ITask**)&spNewJob);
  1447. ulTicks = GetTickCount() - ulTicks;
  1448. g_Log.Write(LOG_PERF, "NewWorkItem call took %lu ms", ulTicks);
  1449. LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::NewWorkItem");
  1450. //
  1451. // Replace the global job object with the new one.
  1452. //
  1453. g_pJob->Release();
  1454. spNewJob.Transfer(&g_pJob);
  1455. }
  1456. while (0);
  1457. return hr;
  1458. }
  1459. //+---------------------------------------------------------------------------
  1460. //
  1461. // Function: SetCredentials
  1462. //
  1463. // Synopsis: Call SetAccountInformation to set the job credentials.
  1464. //
  1465. // Arguments: [ppwsz] - command line.
  1466. //
  1467. // Returns: Result of calling ITaskScheduler::SetAccountInformation
  1468. //
  1469. // History: 06-22-96 MarkBl Created
  1470. // 07-22-96 DavidMun Method now takes just two arguments
  1471. //
  1472. //----------------------------------------------------------------------------
  1473. HRESULT SetCredentials(WCHAR **ppwsz)
  1474. {
  1475. WCHAR wszAccountNew[MAX_USERNAME + 1]; //see sched\inc\defines.hxx
  1476. WCHAR wszPasswordNew[MAX_PASSWORD + 1];
  1477. HRESULT hr;
  1478. TOKEN tkn;
  1479. ZeroMemory(wszAccountNew, sizeof(wszAccountNew));
  1480. ZeroMemory(wszPasswordNew, sizeof(wszPasswordNew));
  1481. do
  1482. {
  1483. hr = Expect(TKN_STRING, ppwsz, L"new account name");
  1484. BREAK_ON_FAILURE(hr);
  1485. wcsncpy(wszAccountNew,
  1486. g_wszLastStringToken,
  1487. min(wcslen(g_wszLastStringToken) + 1, MAX_USERNAME));
  1488. wszAccountNew[MAX_USERNAME] = L'\0';
  1489. hr = Expect(TKN_STRING, ppwsz, L"new account password");
  1490. BREAK_ON_FAILURE(hr);
  1491. wcsncpy(wszPasswordNew,
  1492. g_wszLastStringToken,
  1493. min(wcslen(g_wszLastStringToken) + 1, MAX_PASSWORD));
  1494. wszPasswordNew[MAX_PASSWORD] = L'\0';
  1495. g_Log.Write(LOG_TRACE, "Setting account information");
  1496. hr = g_pJob->SetAccountInformation(wszAccountNew,
  1497. wcscmp(wszPasswordNew, L"NULL") ? wszPasswordNew :
  1498. NULL);
  1499. if (FAILED(hr))
  1500. {
  1501. g_Log.Write(
  1502. LOG_FAIL,
  1503. "ITaskScheduler::SetAccountInformation hr=%#010x",
  1504. hr);
  1505. }
  1506. } while (0);
  1507. return hr;
  1508. }
  1509. //+---------------------------------------------------------------------------
  1510. //
  1511. // Function: SchedSetMachine
  1512. //
  1513. // Synopsis: Call SetTargetComputer with computer name (NULL if not
  1514. // specified on command line).
  1515. //
  1516. // Arguments: [ppwsz] - command line.
  1517. //
  1518. // Returns: Result of calling ITaskScheduler::SetTargetComputer
  1519. //
  1520. // History: 06-04-96 DavidMun Created
  1521. //
  1522. //----------------------------------------------------------------------------
  1523. HRESULT SchedSetMachine(WCHAR **ppwsz)
  1524. {
  1525. HRESULT hr;
  1526. TOKEN tkn;
  1527. LPWSTR pwszComputer = NULL;
  1528. tkn = PeekToken(ppwsz);
  1529. if (tkn == TKN_STRING)
  1530. {
  1531. GetToken(ppwsz);
  1532. pwszComputer = g_wszLastStringToken;
  1533. }
  1534. g_Log.Write(LOG_TRACE, "Setting target computer to '%S'", pwszComputer);
  1535. hr = g_pJobScheduler->SetTargetComputer(pwszComputer);
  1536. if (FAILED(hr))
  1537. {
  1538. g_Log.Write(
  1539. LOG_FAIL,
  1540. "ITaskScheduler::SetTargetComputer hr=%#010x",
  1541. hr);
  1542. }
  1543. return hr;
  1544. }
  1545. //+---------------------------------------------------------------------------
  1546. //
  1547. // Function: SetJob
  1548. //
  1549. // Synopsis: Set one or more properties on the global job.
  1550. //
  1551. // Arguments: [ppwsz] - command line.
  1552. //
  1553. // Returns: S_OK - job properties set
  1554. // E_* - error logged
  1555. //
  1556. // History: 01-10-96 DavidMun Created
  1557. //
  1558. //----------------------------------------------------------------------------
  1559. HRESULT SetJob(WCHAR **ppwsz)
  1560. {
  1561. HRESULT hr = S_OK;
  1562. CJobProp JobProperties;
  1563. do
  1564. {
  1565. g_Log.Write(LOG_TRACE, "Setting job's properties");
  1566. hr = JobProperties.Parse(ppwsz);
  1567. BREAK_ON_FAILURE(hr);
  1568. //
  1569. // Set the job's properties to the values we just parsed
  1570. //
  1571. hr = JobProperties.SetActual(g_pJob);
  1572. }
  1573. while (0);
  1574. return hr;
  1575. }
  1576. //+---------------------------------------------------------------------------
  1577. //
  1578. // Function: SetTrigger
  1579. //
  1580. // Synopsis: Parse and execute the set trigger command.
  1581. //
  1582. // Arguments: [ppwsz] - command line
  1583. //
  1584. // Returns: S_OK - trigger modified
  1585. // E_* - error logged
  1586. //
  1587. // Modifies: *[ppwsz]
  1588. //
  1589. // History: 01-05-96 DavidMun Created
  1590. //
  1591. //----------------------------------------------------------------------------
  1592. HRESULT SetTrigger(WCHAR **ppwsz, BOOL fJob)
  1593. {
  1594. HRESULT hr = S_OK;
  1595. CTrigProp TriggerProps;
  1596. SHORT usTrigger = 0;
  1597. SpIJobTrigger spTrigger;
  1598. do
  1599. {
  1600. if (PeekToken(ppwsz) == TKN_NUMBER)
  1601. {
  1602. GetToken(ppwsz);
  1603. usTrigger = (SHORT) g_ulLastNumberToken;
  1604. }
  1605. g_Log.Write(
  1606. LOG_TRACE,
  1607. "Setting properties on trigger %u",
  1608. usTrigger);
  1609. hr = TriggerProps.Parse(ppwsz);
  1610. BREAK_ON_FAILURE(hr);
  1611. if (fJob)
  1612. {
  1613. hr = g_pJob->GetTrigger(usTrigger, &spTrigger);
  1614. LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTrigger");
  1615. }
  1616. else
  1617. {
  1618. #ifdef NOT_YET
  1619. hr = g_pJobQueue->GetTrigger(usTrigger, &spTrigger);
  1620. LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTrigger");
  1621. #endif // NOT_YET
  1622. hr = E_NOTIMPL;
  1623. }
  1624. hr = TriggerProps.SetActual(spTrigger);
  1625. }
  1626. while (0);
  1627. return hr;
  1628. }