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.

569 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: trigprop.cxx
  7. //
  8. // Contents: Implementation of trigger container.
  9. //
  10. // History: 01-04-96 DavidMun Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <headers.hxx>
  14. #pragma hdrstop
  15. #include "jt.hxx"
  16. //+---------------------------------------------------------------------------
  17. //
  18. // Member: CTrigProp::CTrigProp
  19. //
  20. // Synopsis: Init this.
  21. //
  22. // History: 01-04-96 DavidMun Created
  23. //
  24. //----------------------------------------------------------------------------
  25. CTrigProp::CTrigProp()
  26. {
  27. Clear();
  28. }
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Member: CTrigProp::Clear
  32. //
  33. // Synopsis: Clear all fields of trigger.
  34. //
  35. // History: 01-04-96 DavidMun Created
  36. //
  37. //----------------------------------------------------------------------------
  38. VOID CTrigProp::Clear()
  39. {
  40. ZeroMemory(&Trigger, sizeof Trigger);
  41. Trigger.cbTriggerSize = sizeof Trigger;
  42. flSetFlags = 0;
  43. flSet = 0;
  44. }
  45. //+---------------------------------------------------------------------------
  46. //
  47. // Member: CTrigProp::InitFromActual
  48. //
  49. // Synopsis: Set this to contain the same properties as an actual
  50. // trigger.
  51. //
  52. // Arguments: [pTrigger] - interface on actual trigger
  53. //
  54. // Returns: S_OK - properties set
  55. // E_* - error retrieving properties
  56. //
  57. // History: 01-08-96 DavidMun Created
  58. //
  59. //----------------------------------------------------------------------------
  60. HRESULT CTrigProp::InitFromActual(ITaskTrigger *pTrigger)
  61. {
  62. HRESULT hr = S_OK;
  63. TASK_TRIGGER ActualTrigger;
  64. do
  65. {
  66. Clear();
  67. ActualTrigger.cbTriggerSize = sizeof ActualTrigger;
  68. hr = pTrigger->GetTrigger(&ActualTrigger);
  69. LOG_AND_BREAK_ON_FAIL(hr, "ITrigger::GetTrigger");
  70. Trigger = ActualTrigger;
  71. }
  72. while (0);
  73. return hr;
  74. }
  75. //+---------------------------------------------------------------------------
  76. //
  77. // Member: CTrigProp::Dump
  78. //
  79. // Synopsis: Write trigger properties to log.
  80. //
  81. // History: 01-04-96 DavidMun Created
  82. //
  83. //----------------------------------------------------------------------------
  84. VOID CTrigProp::Dump()
  85. {
  86. g_Log.Write(LOG_TEXT, " Type: %s",
  87. GetTriggerTypeString(Trigger.TriggerType));
  88. _DumpTypeArguments();
  89. g_Log.Write(LOG_TEXT, " StartDate: %02d/%02d/%04d",
  90. Trigger.wBeginMonth,
  91. Trigger.wBeginDay,
  92. Trigger.wBeginYear);
  93. g_Log.Write(LOG_TEXT, " EndDate: %02d/%02d/%04d",
  94. Trigger.wEndMonth,
  95. Trigger.wEndDay,
  96. Trigger.wEndYear);
  97. g_Log.Write(LOG_TEXT, " StartTime: %02d:%02d",
  98. Trigger.wStartHour,
  99. Trigger.wStartMinute);
  100. g_Log.Write(LOG_TEXT, " MinutesDuration: %u",
  101. Trigger.MinutesDuration);
  102. g_Log.Write(LOG_TEXT, " MinutesInterval: %u",
  103. Trigger.MinutesInterval);
  104. g_Log.Write(LOG_TEXT, " Flags:");
  105. g_Log.Write(LOG_TEXT, " HasEndDate = %u",
  106. (Trigger.rgFlags & TASK_TRIGGER_FLAG_HAS_END_DATE) != 0);
  107. g_Log.Write(LOG_TEXT, " KillAtDuration = %u",
  108. (Trigger.rgFlags & TASK_TRIGGER_FLAG_KILL_AT_DURATION_END) != 0);
  109. g_Log.Write(LOG_TEXT, " Disabled = %u",
  110. (Trigger.rgFlags & TASK_TRIGGER_FLAG_DISABLED) != 0);
  111. }
  112. //+---------------------------------------------------------------------------
  113. //
  114. // Member: CTrigProp::_DumpTypeArguments, private
  115. //
  116. // Synopsis: Write trigger properties that are determined by its type
  117. // to the log.
  118. //
  119. // History: 01-04-96 DavidMun Created
  120. //
  121. //----------------------------------------------------------------------------
  122. VOID CTrigProp::_DumpTypeArguments()
  123. {
  124. switch (Trigger.TriggerType)
  125. {
  126. case TASK_TIME_TRIGGER_ONCE:
  127. case TASK_EVENT_TRIGGER_ON_IDLE:
  128. case TASK_EVENT_TRIGGER_AT_SYSTEMSTART:
  129. case TASK_EVENT_TRIGGER_AT_LOGON:
  130. //
  131. // No type-specific data.
  132. //
  133. break;
  134. case TASK_TIME_TRIGGER_DAILY:
  135. g_Log.Write(LOG_TEXT, " DaysInterval: %u",
  136. Trigger.Type.Daily.DaysInterval);
  137. break;
  138. case TASK_TIME_TRIGGER_WEEKLY:
  139. g_Log.Write(LOG_TEXT, " WeeksInterval: %u",
  140. Trigger.Type.Weekly.WeeksInterval);
  141. g_Log.Write(LOG_TEXT, " DaysOfTheWeek: %s",
  142. GetDaysOfWeekString(Trigger.Type.Weekly.rgfDaysOfTheWeek));
  143. break;
  144. case TASK_TIME_TRIGGER_MONTHLYDATE:
  145. g_Log.Write(LOG_TEXT, " Days: %s",
  146. GetDaysString(Trigger.Type.MonthlyDate.rgfDays));
  147. g_Log.Write(LOG_TEXT, " Months: %S",
  148. GetMonthsString(Trigger.Type.MonthlyDate.rgfMonths));
  149. break;
  150. case TASK_TIME_TRIGGER_MONTHLYDOW:
  151. g_Log.Write(LOG_TEXT, " Week: %u",
  152. Trigger.Type.MonthlyDOW.wWhichWeek);
  153. g_Log.Write(LOG_TEXT, " DaysOfTheWeek: %s",
  154. GetDaysOfWeekString(Trigger.Type.MonthlyDOW.rgfDaysOfTheWeek));
  155. g_Log.Write(LOG_TEXT, " Months: %S",
  156. GetMonthsString(Trigger.Type.MonthlyDOW.rgfMonths));
  157. break;
  158. default:
  159. g_Log.Write(LOG_TEXT, " Invalid Type: %u",
  160. Trigger.TriggerType);
  161. }
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Member: CTrigProp::Parse
  166. //
  167. // Synopsis: Read trigger properties from the command line.
  168. //
  169. // Arguments: [ppwsz] - command line.
  170. //
  171. // Returns: S_OK - filled in trigger property values.
  172. //
  173. // History: 01-04-96 DavidMun Created
  174. //
  175. // Notes: Sets members flSet and flSetFlags to indicate which
  176. // properties were set from the command line. This is used
  177. // by the edit trigger command to know which props to modify
  178. // on the actual trigger.
  179. //
  180. //----------------------------------------------------------------------------
  181. HRESULT CTrigProp::Parse(WCHAR **ppwsz)
  182. {
  183. HRESULT hr = S_OK;
  184. TOKEN tkn;
  185. TOKEN tknProp;
  186. Clear();
  187. tkn = PeekToken(ppwsz);
  188. while (tkn != TKN_SWITCH && tkn != TKN_EOL && tkn != TKN_INVALID)
  189. {
  190. //
  191. // Get the property name token in tknProp, then eat the equal sign
  192. // and, depending on the property, get the appropriate type and number
  193. // of values.
  194. //
  195. tknProp = GetToken(ppwsz);
  196. hr = Expect(TKN_EQUAL, ppwsz, L"=");
  197. BREAK_ON_FAILURE(hr);
  198. switch (tknProp)
  199. {
  200. case TKN_STARTDATE:
  201. flSet |= TP_STARTDATE;
  202. hr = ParseDate(
  203. ppwsz,
  204. &Trigger.wBeginMonth,
  205. &Trigger.wBeginDay,
  206. &Trigger.wBeginYear);
  207. break;
  208. case TKN_ENDDATE:
  209. flSet |= TP_ENDDATE;
  210. hr = ParseDate(
  211. ppwsz,
  212. &Trigger.wEndMonth,
  213. &Trigger.wEndDay,
  214. &Trigger.wEndYear);
  215. break;
  216. case TKN_STARTTIME:
  217. flSet |= TP_STARTTIME;
  218. hr = ParseTime(
  219. ppwsz,
  220. &Trigger.wStartHour,
  221. &Trigger.wStartMinute);
  222. break;
  223. case TKN_MINUTESDURATION:
  224. flSet |= TP_MINUTESDURATION;
  225. hr = Expect(TKN_NUMBER, ppwsz, L"numeric value for MinutesDuration property");
  226. Trigger.MinutesDuration = g_ulLastNumberToken;
  227. break;
  228. case TKN_HASENDDATE:
  229. flSetFlags |= TASK_TRIGGER_FLAG_HAS_END_DATE;
  230. hr = Expect(TKN_NUMBER, ppwsz, L"1 or 0 for HasEndDate property");
  231. if (g_ulLastNumberToken)
  232. {
  233. Trigger.rgFlags |= TASK_TRIGGER_FLAG_HAS_END_DATE;
  234. }
  235. break;
  236. case TKN_KILLATDURATION:
  237. flSetFlags |= TASK_TRIGGER_FLAG_KILL_AT_DURATION_END;
  238. hr = Expect(TKN_NUMBER, ppwsz, L"1 or 0 for KillAtDuration property");
  239. if (g_ulLastNumberToken)
  240. {
  241. Trigger.rgFlags |= TASK_TRIGGER_FLAG_KILL_AT_DURATION_END;
  242. }
  243. break;
  244. case TKN_DISABLED:
  245. flSetFlags |= TASK_TRIGGER_FLAG_DISABLED;
  246. hr = Expect(TKN_NUMBER, ppwsz, L"1 or 0 for Disabled property");
  247. if (g_ulLastNumberToken)
  248. {
  249. Trigger.rgFlags |= TASK_TRIGGER_FLAG_DISABLED;
  250. }
  251. break;
  252. case TKN_MINUTESINTERVAL:
  253. flSet |= TP_MINUTESINTERVAL;
  254. hr = Expect(TKN_NUMBER, ppwsz, L"minutes interval");
  255. Trigger.MinutesInterval = (DWORD) g_ulLastNumberToken;
  256. break;
  257. case TKN_TYPE:
  258. flSet |= TP_TYPE;
  259. tkn = GetToken(ppwsz);
  260. switch (tkn)
  261. {
  262. case TKN_ONEDAY:
  263. Trigger.TriggerType = TASK_TIME_TRIGGER_ONCE;
  264. break;
  265. case TKN_DAILY:
  266. Trigger.TriggerType = TASK_TIME_TRIGGER_DAILY;
  267. break;
  268. case TKN_WEEKLY:
  269. Trigger.TriggerType = TASK_TIME_TRIGGER_WEEKLY;
  270. break;
  271. case TKN_MONTHLYDATE:
  272. Trigger.TriggerType = TASK_TIME_TRIGGER_MONTHLYDATE;
  273. break;
  274. case TKN_MONTHLYDOW:
  275. Trigger.TriggerType = TASK_TIME_TRIGGER_MONTHLYDOW;
  276. break;
  277. case TKN_ONIDLE:
  278. Trigger.TriggerType = TASK_EVENT_TRIGGER_ON_IDLE;
  279. break;
  280. case TKN_ATSTARTUP:
  281. Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
  282. break;
  283. case TKN_ATLOGON:
  284. Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_LOGON;
  285. break;
  286. default:
  287. hr = E_FAIL;
  288. LogSyntaxError(
  289. tkn,
  290. L"Once, Daily, Weekly, MonthlyDate, MonthlyDOW, OnIdle, AtStartup, or AtLogon");
  291. break;
  292. }
  293. break;
  294. case TKN_TYPEARGUMENTS:
  295. flSet |= TP_TYPEARGUMENTS;
  296. //
  297. // BUGBUG this forces user to specify type even if editing type
  298. // arguments of an existing trigger with a valid type.
  299. //
  300. if (flSet & TP_TYPE)
  301. {
  302. hr = _ParseTriggerArguments(ppwsz, Trigger.TriggerType);
  303. }
  304. else
  305. {
  306. hr = _ParseTriggerArguments(ppwsz, TASK_TIME_TRIGGER_DAILY);
  307. }
  308. break;
  309. }
  310. BREAK_ON_FAILURE(hr);
  311. tkn = PeekToken(ppwsz);
  312. }
  313. return hr;
  314. }
  315. //+---------------------------------------------------------------------------
  316. //
  317. // Member: CTrigProp::_ParseTriggerArguments
  318. //
  319. // Synopsis: Parse the command line for the trigger arguments required
  320. // by trigger type [TriggerType].
  321. //
  322. // Arguments: [ppwsz] - command line
  323. // [TriggerType] - type of trigger to parse args for
  324. //
  325. // Returns: S_OK - Appropriate member of Trigger.Type set.
  326. // E_* - error logged
  327. //
  328. // History: 01-04-96 DavidMun Created
  329. //
  330. //----------------------------------------------------------------------------
  331. HRESULT CTrigProp::_ParseTriggerArguments(
  332. WCHAR **ppwsz,
  333. TASK_TRIGGER_TYPE TriggerType)
  334. {
  335. HRESULT hr = S_OK;
  336. TOKEN tkn;
  337. switch (TriggerType)
  338. {
  339. case TASK_TIME_TRIGGER_ONCE:
  340. case TASK_EVENT_TRIGGER_AT_SYSTEMSTART:
  341. case TASK_EVENT_TRIGGER_AT_LOGON:
  342. case TASK_EVENT_TRIGGER_ON_IDLE:
  343. break;
  344. case TASK_TIME_TRIGGER_DAILY:
  345. hr = Expect(TKN_NUMBER, ppwsz, L"days interval");
  346. Trigger.Type.Daily.DaysInterval = (WORD) g_ulLastNumberToken;
  347. break;
  348. case TASK_TIME_TRIGGER_WEEKLY:
  349. hr = Expect(TKN_NUMBER, ppwsz, L"weeks interval");
  350. Trigger.Type.Weekly.WeeksInterval = (WORD) g_ulLastNumberToken;
  351. BREAK_ON_FAILURE(hr);
  352. hr = Expect(
  353. TKN_COMMA,
  354. ppwsz,
  355. L"comma separating weeks interval and days of the week string");
  356. BREAK_ON_FAILURE(hr);
  357. hr = ParseDaysOfWeek(ppwsz, &Trigger.Type.Weekly.rgfDaysOfTheWeek);
  358. break;
  359. case TASK_TIME_TRIGGER_MONTHLYDATE:
  360. hr = ParseDaysOfMonth(ppwsz, &Trigger.Type.MonthlyDate.rgfDays);
  361. BREAK_ON_FAILURE(hr);
  362. //
  363. // Note ParseDaysOfMonth() will eat the comma separating the days of
  364. // the month from the month names.
  365. //
  366. hr = ParseMonths(ppwsz, &Trigger.Type.MonthlyDate.rgfMonths);
  367. break;
  368. case TASK_TIME_TRIGGER_MONTHLYDOW:
  369. hr = Expect(TKN_NUMBER, ppwsz, L"week number");
  370. Trigger.Type.MonthlyDOW.wWhichWeek = (WORD) g_ulLastNumberToken;
  371. BREAK_ON_FAILURE(hr);
  372. hr = Expect(
  373. TKN_COMMA,
  374. ppwsz,
  375. L"comma separating week number and days of the week string");
  376. BREAK_ON_FAILURE(hr);
  377. hr = ParseDaysOfWeek(ppwsz, &Trigger.Type.MonthlyDOW.rgfDaysOfTheWeek);
  378. BREAK_ON_FAILURE(hr);
  379. hr = Expect(
  380. TKN_COMMA,
  381. ppwsz,
  382. L"comma separating days of the week string and months");
  383. BREAK_ON_FAILURE(hr);
  384. hr = ParseMonths(ppwsz, &Trigger.Type.MonthlyDOW.rgfMonths);
  385. break;
  386. default:
  387. hr = E_FAIL;
  388. g_Log.Write(
  389. LOG_FAIL,
  390. "Invalid trigger type %u discovered while parsing trigger arguments");
  391. }
  392. return hr;
  393. }
  394. //+---------------------------------------------------------------------------
  395. //
  396. // Member: CTrigProp::SetActual
  397. //
  398. // Synopsis: Set the properties of an actual trigger object.
  399. //
  400. // Arguments: [pTrigger] - interface to actual object to set
  401. //
  402. // Returns: S_OK - props set
  403. // E_* - couldn't get actual trigger's current props
  404. //
  405. // History: 01-05-96 DavidMun Created
  406. //
  407. // Notes: Changes only the properties of the trigger that the user
  408. // specified on the commandline.
  409. //
  410. //----------------------------------------------------------------------------
  411. HRESULT CTrigProp::SetActual(ITaskTrigger *pTrigger)
  412. {
  413. HRESULT hr = S_OK;
  414. TASK_TRIGGER CurTrigger;
  415. do
  416. {
  417. CurTrigger.cbTriggerSize = sizeof CurTrigger;
  418. hr = pTrigger->GetTrigger(&CurTrigger);
  419. LOG_AND_BREAK_ON_FAIL(hr, "ITaskTrigger::GetTrigger");
  420. if (flSet & TP_STARTDATE)
  421. {
  422. CurTrigger.wBeginMonth = Trigger.wBeginMonth;
  423. CurTrigger.wBeginDay = Trigger.wBeginDay;
  424. CurTrigger.wBeginYear = Trigger.wBeginYear;
  425. }
  426. if (flSet & TP_ENDDATE)
  427. {
  428. CurTrigger.wEndMonth = Trigger.wEndMonth;
  429. CurTrigger.wEndDay = Trigger.wEndDay;
  430. CurTrigger.wEndYear = Trigger.wEndYear;
  431. }
  432. if (flSet & TP_STARTTIME)
  433. {
  434. CurTrigger.wStartHour = Trigger.wStartHour;
  435. CurTrigger.wStartMinute = Trigger.wStartMinute;
  436. }
  437. if (flSet & TP_MINUTESDURATION)
  438. {
  439. CurTrigger.MinutesDuration = Trigger.MinutesDuration;
  440. }
  441. if (flSet & TP_MINUTESINTERVAL)
  442. {
  443. CurTrigger.MinutesInterval = Trigger.MinutesInterval;
  444. }
  445. if (flSet & TP_TYPE)
  446. {
  447. CurTrigger.TriggerType = Trigger.TriggerType;
  448. }
  449. if (flSet & TP_TYPEARGUMENTS)
  450. {
  451. CurTrigger.Type = Trigger.Type;
  452. }
  453. //
  454. // Turn off all the flag bits that user specified a value for. Then
  455. // turn back on the ones that the user specified a nonzero value for.
  456. //
  457. CurTrigger.rgFlags &= ~flSetFlags;
  458. CurTrigger.rgFlags |= Trigger.rgFlags;
  459. hr = pTrigger->SetTrigger(&CurTrigger);
  460. LOG_AND_BREAK_ON_FAIL(hr, "ITrigger::SetTrigger");
  461. } while (0);
  462. return hr;
  463. }