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.

514 lines
18 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Job Schedule Object Handler
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  7. //
  8. // File: job_cls.hxx
  9. //
  10. // Contents: job and triggers class objects header
  11. //
  12. // History: 23-May-95 EricB created
  13. // 06-Oct-95 EricB converted to produce lib
  14. //
  15. //-----------------------------------------------------------------------------
  16. #ifndef _JOB_CLS_HXX_
  17. #define _JOB_CLS_HXX_
  18. #include "dll.hxx"
  19. #include "common.hxx"
  20. #include "dynarray.hxx"
  21. #include "time.hxx"
  22. #include "runobj.hxx"
  23. #include <mstask.h>
  24. #include <msterr.h>
  25. class CJob;
  26. class CJobCF;
  27. class CSchedule;
  28. class CSchedWorker;
  29. #undef IsFlagSet
  30. #define SIGNATURE_SIZE 64
  31. //
  32. // Bit mask for the internal reserved portion of the bit flags.
  33. //
  34. #define JOB_INTERNAL_FLAG_MASK (0xffff8000)
  35. //
  36. // Values for CJob::m_rgFlags
  37. //
  38. // The upper word of the job flag property is reserved for internal use.
  39. // Lower word (public) values are defined in mstask.h (mstask.idl).
  40. //
  41. // Note that a job can have both JOB_I_FLAG_HAS_TRIGGERS and
  42. // JOB_I_FLAG_NO_VALID_TRIGGERS set. That means the triggers are either unset
  43. // or disabled.
  44. //
  45. #define JOB_I_FLAG_APPNAME_CHANGE (0x00010000)
  46. #define JOB_I_FLAG_SET_ACCOUNT_INFO (0x00020000)
  47. #define JOB_I_FLAG_NO_VALID_TRIGGERS (0x00040000)
  48. #define JOB_I_FLAG_LAST_LAUNCH_FAILED (0x00080000)
  49. #define JOB_I_FLAG_ERROR_IN_LAST_RUN (0x00100000)
  50. #define JOB_I_FLAG_NET_SCHEDULE (0x00200000)
  51. #define JOB_I_FLAG_NO_MORE_RUNS (0x00400000)
  52. //
  53. // The following flags are for determining job validity when the string
  54. // properties and triggers haven't been loaded.
  55. //
  56. #define JOB_I_FLAG_HAS_TRIGGERS (0x00800000)
  57. #define JOB_I_FLAG_HAS_APPNAME (0x01000000)
  58. #define JOB_I_FLAG_HAS_ACCOUNT (0x02000000)
  59. //
  60. // These flags are for job interface communication with the service.
  61. //
  62. #define JOB_I_FLAG_RUN_NOW (0x04000000)
  63. #define JOB_I_FLAG_ABORT_NOW (0x08000000)
  64. //
  65. // The following two flags are used to prevent unnecessary Wait List rebuilds.
  66. // CheckDir is called whenever there are changes made to job file objects.
  67. // If a change is caused by the service (when it updates the run status of a
  68. // job), we do not want the wait list to be rebuilt. If a change is caused by
  69. // a scheduler client, we do not want the wait list to be rebuilt *unless* the
  70. // change affects the job's run-ability. Those things that affect the run-
  71. // ability are run-time (triggers), adding or deleting an app name, or
  72. // toggling the disabled flag. We need both flags because we cannot control
  73. // the order that clients call the property and trigger modification methods.
  74. // See additonal comments about this in SaveP in persist.cxx.
  75. //
  76. #define JOB_I_FLAG_RUN_PROP_CHANGE (0x10000000)
  77. #define JOB_I_FLAG_NO_RUN_PROP_CHANGE (0x20000000)
  78. //
  79. // The top two bits are used as non-persistent dirty state flags.
  80. //
  81. #define JOB_DIRTY_FLAG_MASK (0xC0000000)
  82. #define JOB_I_FLAG_PROPERTIES_DIRTY (0x40000000)
  83. #define JOB_I_FLAG_TRIGGERS_DIRTY (0x80000000)
  84. #define JOB_I_FLAG_MISSED (0x00008000)
  85. //
  86. // Mask of non-persisted job flags. Masked off on save.
  87. //
  88. #define NON_PERSISTED_JOB_FLAGS (JOB_DIRTY_FLAG_MASK | \
  89. JOB_I_FLAG_SET_ACCOUNT_INFO)
  90. //
  91. // Values for CTrigger::m_rgFlags
  92. //
  93. // The upper word of the trigger flag member is reserved for internal use.
  94. // Lower word (public) values are defined in mstask.h (mstask.idl).
  95. //
  96. #define JOB_TRIGGER_I_FLAG_NOT_SET (0x00010000)
  97. #define JOB_TRIGGER_I_FLAG_DURATION_AS_TIME (0x00020000)
  98. //
  99. // Values for CJob::SaveP flOptions parameter
  100. //
  101. #define SAVEP_VARIABLE_LENGTH_DATA (0x00000001)
  102. #define SAVEP_RUNNING_INSTANCE_COUNT (0x00000002)
  103. #define SAVEP_PRESERVE_NET_SCHEDULE (0x00000004)
  104. //
  105. // This macro can be used within methods of CJob
  106. //
  107. #define DELETE_CJOB_FIELD(m_pField) \
  108. if (!m_MainBlock.Contains(m_pField)) \
  109. { \
  110. delete [] (m_pField); \
  111. } \
  112. m_pField = NULL;
  113. // else it will be deleted by m_MainBlock.Set() or ~m_MainBlock()
  114. //+----------------------------------------------------------------------------
  115. //
  116. // Class: CTrigger
  117. //
  118. // Purpose: Trigger object - represents a job run time repetition period
  119. //
  120. //-----------------------------------------------------------------------------
  121. class CTrigger : public ITaskTrigger
  122. {
  123. friend CJob;
  124. friend CSchedule;
  125. public:
  126. CTrigger(WORD iTrigger, CJob * pJob);
  127. ~CTrigger(void);
  128. // IUnknown methods
  129. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  130. STDMETHOD_(ULONG, AddRef)(void);
  131. STDMETHOD_(ULONG, Release)(void);
  132. // ITaskTrigger methods
  133. STDMETHOD(SetTrigger)(const PTASK_TRIGGER pTrigger);
  134. STDMETHOD(GetTrigger)(PTASK_TRIGGER pTrigger);
  135. STDMETHOD(GetTriggerString)(LPWSTR * ppwszTrigger);
  136. private:
  137. CJob * m_pJob; // Parent job object.
  138. WORD m_iTrigger; // TASK_TRIGGER index.
  139. ULONG m_cReferences;
  140. };
  141. //+----------------------------------------------------------------------------
  142. //
  143. // Class: CInputBuffer
  144. //
  145. // Synopsis: Used by CJob::LoadP to parse a buffer containing the contents
  146. // of a task file. Using this class is less bug-prone than
  147. // using two pointer variables.
  148. // BOOL methods return FALSE on buffer overrun.
  149. //
  150. //-----------------------------------------------------------------------------
  151. class CInputBuffer
  152. {
  153. private:
  154. const BYTE * _pCurrent; // Current position in buffer
  155. const BYTE * const _pEnd; // First invalid position in buffer
  156. public:
  157. CInputBuffer(const BYTE * pCurrent, const BYTE * pEnd)
  158. : _pCurrent(pCurrent), _pEnd(pEnd) { }
  159. BYTE * CurrentPosition()
  160. { return (BYTE *) _pCurrent; }
  161. BOOL Advance(DWORD cb)
  162. { _pCurrent += cb; return (_pCurrent <= _pEnd); }
  163. BOOL Read(void * pDest, DWORD cb)
  164. {
  165. if (_pCurrent + cb <= _pEnd)
  166. {
  167. CopyMemory(pDest, _pCurrent, cb);
  168. _pCurrent += cb;
  169. return TRUE;
  170. }
  171. else
  172. {
  173. return FALSE;
  174. }
  175. }
  176. };
  177. //+----------------------------------------------------------------------------
  178. //
  179. // Class: CHeapBlock
  180. //
  181. // Synopsis: Variable-length properties of CJob that are read by LoadP
  182. // are held in a single heap block, the original block which
  183. // the task file was read from disk into, as long as they are
  184. // not dirtied. If any one is dirtied a separate heap block
  185. // is allocated for it. This class helps manage the original
  186. // heap block.
  187. //
  188. //-----------------------------------------------------------------------------
  189. class CHeapBlock
  190. {
  191. private:
  192. BYTE * _pStart; // Start of the heap block
  193. const BYTE * _pEnd; // First byte past the end of the heap block
  194. public:
  195. CHeapBlock() : _pStart(NULL), _pEnd(NULL) { }
  196. ~CHeapBlock() { delete [] _pStart; }
  197. void Set(BYTE * pStart, DWORD dwSize)
  198. {
  199. delete [] _pStart;
  200. _pStart = pStart;
  201. _pEnd = _pStart + dwSize;
  202. }
  203. BOOL Contains(void * p)
  204. { return (_pStart <= (BYTE *)p && (BYTE *)p < _pEnd); }
  205. };
  206. typedef struct _FIXDLENDATA {
  207. WORD wVersion;
  208. WORD wFileObjVer;
  209. UUID uuidJob;
  210. WORD wAppNameLenOffset;
  211. WORD wTriggerOffset;
  212. WORD wErrorRetryCount;
  213. WORD wErrorRetryInterval;
  214. WORD wIdleDeadline;
  215. WORD wIdleWait;
  216. DWORD dwPriority;
  217. DWORD dwMaxRunTime;
  218. HRESULT ExitCode;
  219. HRESULT hrStatus;
  220. DWORD rgFlags;
  221. SYSTEMTIME stMostRecentRunTime;
  222. } FIXDLEN_DATA, * PFIXDLEN_DATA;
  223. typedef struct _TASKRESERVED1 {
  224. HRESULT hrStartError;
  225. DWORD rgTaskFlags;
  226. } TASKRESERVED1, * PTASKRESERVED1;
  227. typedef struct _JOB_ACCOUNT_INFO {
  228. WCHAR * pwszAccount;
  229. WCHAR * pwszPassword;
  230. } JOB_ACCOUNT_INFO, * PJOB_ACCOUNT_INFO;
  231. //+----------------------------------------------------------------------------
  232. //
  233. // Class: CJob
  234. //
  235. // Purpose: Job object
  236. //
  237. //-----------------------------------------------------------------------------
  238. class CJob : public ITask, public IPersistFile, public IProvideTaskPage
  239. {
  240. friend CTrigger;
  241. friend CJobCF;
  242. friend CSchedule;
  243. friend CSchedWorker;
  244. public:
  245. CJob();
  246. ~CJob();
  247. // IUnknown methods
  248. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject);
  249. STDMETHOD_(ULONG, AddRef)(void);
  250. STDMETHOD_(ULONG, Release)(void);
  251. // ITask methods
  252. STDMETHOD(Run)(void);
  253. STDMETHOD(Terminate)(void);
  254. STDMETHOD(EditWorkItem)(HWND hParent, DWORD dwReserved);
  255. STDMETHOD(CreateTrigger)(WORD * piNewTrigger, ITaskTrigger ** ppTrigger);
  256. STDMETHOD(DeleteTrigger)(WORD iTrigger);
  257. STDMETHOD(GetTriggerCount)(WORD * pwCount);
  258. STDMETHOD(GetTrigger)(WORD iTrigger, ITaskTrigger ** ppTrigger);
  259. STDMETHOD(GetTriggerString)(WORD iTrigger, LPWSTR * ppwszTrigger);
  260. STDMETHOD(GetRunTimes)(const LPSYSTEMTIME pstBegin,
  261. const LPSYSTEMTIME pstEnd,
  262. WORD * pwCount, LPSYSTEMTIME * rgstJobTimes);
  263. // ITask properties
  264. STDMETHOD(SetApplicationName)(LPCWSTR pwszApplicationName);
  265. STDMETHOD(GetApplicationName)(LPWSTR * ppwszApplicationName);
  266. STDMETHOD(SetParameters)(LPCWSTR pwszParameters);
  267. STDMETHOD(GetParameters)(LPWSTR * ppwszParameters);
  268. STDMETHOD(SetWorkingDirectory)(LPCWSTR pwszWorkingDirectory);
  269. STDMETHOD(GetWorkingDirectory)(LPWSTR * ppwszWorkingDirectory);
  270. STDMETHOD(SetAccountInformation)(LPCWSTR pwszAccountName,
  271. LPCWSTR pwszPassword);
  272. STDMETHOD(GetAccountInformation)(LPWSTR * ppwszAccountName);
  273. STDMETHOD(SetComment)(LPCWSTR pwszComment);
  274. STDMETHOD(GetComment)(LPWSTR * ppwszComment);
  275. STDMETHOD(SetPriority)(DWORD dwPriority);
  276. STDMETHOD(GetPriority)(DWORD * pdwPriority);
  277. STDMETHOD(SetMaxRunTime)(DWORD dwMaxRunTime);
  278. STDMETHOD(GetMaxRunTime)(DWORD * pdwMaxRunTime);
  279. STDMETHOD(SetIdleWait)(WORD wIdleMinutes, WORD wDeadlineMinutes);
  280. STDMETHOD(GetIdleWait)(WORD * pwIdleMinutes, WORD * pwDeadlineMinutes);
  281. STDMETHOD(SetErrorRetryCount)(WORD wRetryCount);
  282. STDMETHOD(GetErrorRetryCount)(WORD * pwRetryCount);
  283. STDMETHOD(SetErrorRetryInterval)(WORD wRetryInterval);
  284. STDMETHOD(GetErrorRetryInterval)(WORD * pwRetryInterval);
  285. STDMETHOD(SetFlags)(DWORD dwJobFlags);
  286. STDMETHOD(GetFlags)(DWORD * pdwJobFlags);
  287. STDMETHOD(SetTaskFlags)(DWORD dwJobFlags);
  288. STDMETHOD(GetTaskFlags)(DWORD * pdwJobFlags);
  289. STDMETHOD(SetWorkItemData)(WORD cbData, BYTE rgbData[]);
  290. STDMETHOD(GetWorkItemData)(PWORD pcbData, PBYTE * prgbData);
  291. STDMETHOD(GetMostRecentRunTime)(SYSTEMTIME * pstLastRun);
  292. STDMETHOD(GetNextRunTime)(SYSTEMTIME * pstNextRun);
  293. STDMETHOD(GetExitCode)(DWORD * pExitCode);
  294. STDMETHOD(GetStatus)(HRESULT * pStatus);
  295. STDMETHOD(SetCreator)(LPCWSTR pwszCreator);
  296. STDMETHOD(GetCreator)(LPWSTR * ppwszCreator);
  297. // IPersist method
  298. STDMETHOD(GetClassID)(CLSID * pClsID);
  299. // IPersistFile methods
  300. STDMETHOD(IsDirty)(void);
  301. STDMETHOD(Load)(LPCOLESTR pwszFileName, DWORD dwMode);
  302. STDMETHOD(Save)(LPCOLESTR pwszFileName, BOOL fRemember);
  303. STDMETHOD(SaveCompleted)(LPCOLESTR pwszFileName);
  304. STDMETHOD(GetCurFile)(LPOLESTR * ppwszFileName);
  305. // IProvideTaskPage method
  306. STDMETHOD(GetPage)(TASKPAGE tpType, BOOL fPersistChanges,
  307. HPROPSHEETPAGE * phPage);
  308. // CJob methods
  309. static CJob * Create(void)
  310. { return (new CJob); }
  311. HRESULT LoadP(LPCTSTR ptszFileName, DWORD dwMode,
  312. BOOL fRemember, BOOL fAllData);
  313. HRESULT SaveP(LPCTSTR ptszFileName, BOOL fRemember,
  314. ULONG flOptions = 0);
  315. HRESULT SaveWithRetry(LPCTSTR ptszFileName,
  316. BOOL fRemember,
  317. ULONG flOptions = 0);
  318. HRESULT LoadTriggers(void);
  319. HRESULT UpdateJobState(BOOL fRunning);
  320. HRESULT PostRunUpdate(long ExitCode, BOOL fFinishedOK);
  321. LPCWSTR GetCommand(void) const { return(m_pwszApplicationName); }
  322. LPTSTR GetFileName(void) const { return(m_ptszFileName); }
  323. HRESULT SetTrigger(WORD iTrigger, PTASK_TRIGGER pTrigger);
  324. HRESULT GetTrigger(WORD iTrigger, PTASK_TRIGGER pTrigger);
  325. void GetAllFlags(DWORD * pFlags) {*pFlags = m_rgFlags;}
  326. HRESULT GetRunTimesP(const SYSTEMTIME * pstBegin,
  327. const SYSTEMTIME * pstEnd,
  328. WORD * pCount, WORD cLimit,
  329. CTimeRunList * pRunList,
  330. LPTSTR ptszShortJobName);
  331. void SetStartError(HRESULT hrStartError)
  332. { m_hrStartError = hrStartError; }
  333. HRESULT Sign(void);
  334. BOOL VerifySignature(DWORD dwHashMethod = 1) const;
  335. HRESULT GetAtInfo(PAT_INFO pAt, LPWSTR pwszCommand,
  336. DWORD * pcchCommand);
  337. BOOL IsFlagSet(DWORD dwBitFlag) {return m_rgFlags & dwBitFlag;}
  338. protected:
  339. void SetTriggersDirty(void);
  340. void SetFlag(DWORD dwBitFlag) {m_rgFlags |= dwBitFlag;}
  341. void ClearFlag(DWORD dwBitFlag) {m_rgFlags &= ~dwBitFlag;}
  342. DWORD GetUserFlags(void)
  343. {return m_rgFlags & ~JOB_INTERNAL_FLAG_MASK;}
  344. BOOL IsStatus(HRESULT hr) {return m_hrStatus == hr;}
  345. void SetStatus(HRESULT hr) {m_hrStatus = hr;}
  346. HRESULT IfStartupJobAddToList(LPTSTR ptszJobName,
  347. CRunList * pRunList,
  348. CIdleRunList * pIdleWaitList);
  349. HRESULT IfLogonJobAddToList(LPTSTR ptszJobName,
  350. CRunList * pRunList,
  351. CIdleRunList * pIdleWaitList);
  352. HRESULT IfIdleJobAddToList(LPTSTR ptszJobName,
  353. CIdleRunList * pRunList);
  354. HRESULT Delete(void);
  355. private:
  356. HRESULT IfEventJobAddToList(TASK_TRIGGER_TYPE Type,
  357. LPCTSTR ptszJobName,
  358. CRunList * pRunList,
  359. CIdleRunList * pIdleWaitList);
  360. void FreeProperties(void);
  361. TASK_TRIGGER * _GetTrigger(WORD iTrigger);
  362. HRESULT _LoadTriggers(HANDLE hFile);
  363. HRESULT _LoadTriggersFromBuffer(CInputBuffer * pBuf);
  364. HRESULT _SaveTriggers(HANDLE hFile);
  365. HRESULT _SetSignature(const BYTE * pbSignature);
  366. // Properties:
  367. CDynamicArray<TASK_TRIGGER> m_Triggers;
  368. WORD m_wVersion;
  369. WORD m_wFileObjVer;
  370. UUID m_uuidJob;
  371. WORD m_wTriggerOffset;
  372. WORD m_wErrorRetryCount;
  373. WORD m_wErrorRetryInterval;
  374. WORD m_cRunningInstances;
  375. WORD m_wIdleWait;
  376. WORD m_wIdleDeadline;
  377. DWORD m_dwPriority;
  378. DWORD m_dwMaxRunTime;
  379. DWORD m_ExitCode;
  380. HRESULT m_hrStatus;
  381. DWORD m_rgFlags;
  382. DWORD m_rgTaskFlags;
  383. SYSTEMTIME m_stMostRecentRunTime;
  384. LPWSTR m_pwszApplicationName; // [*]
  385. LPWSTR m_pwszParameters; // [*]
  386. LPWSTR m_pwszWorkingDirectory; // [*]
  387. LPWSTR m_pwszCreator; // [*]
  388. LPWSTR m_pwszComment; // [*]
  389. LPTSTR m_ptszFileName;
  390. BOOL m_fFileCreated;
  391. PBYTE m_pbTaskData; // [*]
  392. WORD m_cbTaskData;
  393. WORD m_cReserved;
  394. PBYTE m_pbReserved; // [*]
  395. HRESULT m_hrStartError;
  396. PJOB_ACCOUNT_INFO m_pAccountInfo; // Allocated exclusively in
  397. // the SetAccountInformation member.
  398. PBYTE m_pbSignature; // [*]
  399. CHeapBlock m_MainBlock; // Initially holds properties marked [*]
  400. // State data:
  401. ITypeInfo * m_pIJobTypeInfo;
  402. unsigned long m_cReferences;
  403. CDllRef m_DllRef;
  404. // Static members
  405. static LPWSTR CJob::* const s_StringField[];
  406. };
  407. //+----------------------------------------------------------------------------
  408. //
  409. // Class: CJobCF
  410. //
  411. // Purpose: job object class factory
  412. //
  413. //-----------------------------------------------------------------------------
  414. class CJobCF : public IClassFactory
  415. {
  416. public:
  417. CJobCF();
  418. // IUnknown methods
  419. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);
  420. STDMETHOD_(ULONG, AddRef)();
  421. STDMETHOD_(ULONG, Release)();
  422. // IClassFactory methods
  423. STDMETHOD(CreateInstance)(IUnknown *pUnkOuter,
  424. REFIID riid,
  425. void **ppvObject);
  426. STDMETHOD(LockServer)(BOOL fLock);
  427. static IClassFactory * Create(void);
  428. protected:
  429. ~CJobCF();
  430. unsigned long m_uRefs;
  431. CDllRef m_DllRef;
  432. };
  433. #endif // _JOB_CLS_HXX_