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.

523 lines
12 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Abstract:
  4. @doc
  5. @module Writer.h | Declaration of Writer
  6. @end
  7. Author:
  8. Adi Oltean [aoltean] 08/18/1999
  9. TBD:
  10. Add comments.
  11. Revision History:
  12. Name Date Comments
  13. aoltean 08/18/1999 Created
  14. brianb 05/03/2000 Changed for new security model
  15. brianb 05/09/2000 fix problem with autolocks
  16. mikejohn 06/23/2000 Add connection for SetWriterFailure()
  17. --*/
  18. #ifndef __CVSS_WRITER_IMPL_H_
  19. #define __CVSS_WRITER_IMPL_H_
  20. // forward declarations
  21. class CVssWriterImplStateMachine;
  22. class CVssCreateWriterMetadata;
  23. class CVssWriterComponents;
  24. class IVssWriterComponentsInt;
  25. ////////////////////////////////////////////////////////////////////////
  26. // Standard foo for file name aliasing. This code block must be after
  27. // all includes of VSS header files.
  28. //
  29. #ifdef VSS_FILE_ALIAS
  30. #undef VSS_FILE_ALIAS
  31. #endif
  32. #define VSS_FILE_ALIAS "INCWRMPH"
  33. //
  34. ////////////////////////////////////////////////////////////////////////
  35. // implementation class for writers
  36. class IVssWriterImpl : public IVssWriter
  37. {
  38. public:
  39. // initialize writer
  40. virtual void Initialize
  41. (
  42. VSS_ID writerId,
  43. LPCWSTR wszWriterName,
  44. VSS_USAGE_TYPE ut,
  45. VSS_SOURCE_TYPE st,
  46. VSS_APPLICATION_LEVEL nLevel,
  47. DWORD dwTimeout
  48. ) = 0;
  49. // subscribe to events
  50. virtual void Subscribe
  51. (
  52. ) = 0;
  53. // unsubscribe from events
  54. virtual void Unsubscribe
  55. (
  56. ) = 0;
  57. // get array of volume names
  58. virtual LPCWSTR *GetCurrentVolumeArray() const = 0;
  59. // get # of volumes in volume array
  60. virtual UINT GetCurrentVolumeCount() const = 0;
  61. // get id of snapshot set
  62. virtual VSS_ID GetCurrentSnapshotSetId() const = 0;
  63. // determine which Freeze event writer responds to
  64. virtual VSS_APPLICATION_LEVEL GetCurrentLevel() const = 0;
  65. // determine if path is included in the snapshot
  66. virtual bool IsPathAffected(IN LPCWSTR wszPath) const = 0;
  67. // determine if bootable state is backed up
  68. virtual bool IsBootableSystemStateBackedUp() const = 0;
  69. // determine if the backup application is selecting components
  70. virtual bool AreComponentsSelected() const = 0;
  71. // determine the backup type for the backup
  72. virtual VSS_BACKUP_TYPE GetBackupType() const = 0;
  73. // let writer pass back indication of reason for failure
  74. virtual HRESULT SetWriterFailure(HRESULT hr) = 0;
  75. };
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CVssWriterImpl
  78. class ATL_NO_VTABLE CVssWriterImpl :
  79. public CComObjectRootEx<CComMultiThreadModel>,
  80. public IVssWriterImpl
  81. {
  82. public:
  83. friend class CVssWriterImplLock;
  84. // Constructors & Destructors
  85. CVssWriterImpl();
  86. ~CVssWriterImpl();
  87. // Exposed operations
  88. public:
  89. // create a writer implementation for a specific writer
  90. static void CreateWriter
  91. (
  92. CVssWriter *pWriter,
  93. IVssWriterImpl **ppImpl
  94. );
  95. // set external writer object
  96. void SetWriter(CVssWriter *pWriter)
  97. {
  98. BS_ASSERT(pWriter);
  99. m_pWriter = pWriter;
  100. }
  101. // initialize class
  102. void Initialize
  103. (
  104. IN VSS_ID WriterID,
  105. IN LPCWSTR wszWriterName,
  106. IN VSS_USAGE_TYPE ut,
  107. IN VSS_SOURCE_TYPE st,
  108. IN VSS_APPLICATION_LEVEL nLevel,
  109. IN DWORD dwTimeoutFreeze
  110. );
  111. // subscribe to writer events
  112. void Subscribe
  113. (
  114. );
  115. // unsubscribe from writer events
  116. void Unsubscribe
  117. (
  118. );
  119. // get array of volume names
  120. LPCWSTR* GetCurrentVolumeArray() const { return (LPCWSTR *) m_ppwszVolumesArray; };
  121. // get count of volumes in array
  122. UINT GetCurrentVolumeCount() const { return m_nVolumesCount; };
  123. // get id of snapshot
  124. VSS_ID GetCurrentSnapshotSetId() const { return m_CurrentSnapshotSetId; };
  125. // get level at which freeze takes place
  126. VSS_APPLICATION_LEVEL GetCurrentLevel() const { return m_nLevel; };
  127. // determine if path is included in the snapshot
  128. bool IsPathAffected(IN LPCWSTR wszPath) const;
  129. // determine if the backup is including bootable system state
  130. bool IsBootableSystemStateBackedUp() const
  131. { return m_bBootableSystemStateBackup ? true : false; }
  132. // determine if the backup selects components
  133. bool AreComponentsSelected() const
  134. { return m_bComponentsSelected ? true : false; }
  135. // return the type of backup
  136. VSS_BACKUP_TYPE GetBackupType() const { return m_backupType; }
  137. // indicate why the writer failed
  138. HRESULT SetWriterFailure(HRESULT hr);
  139. // IVssWriter ovverides
  140. public:
  141. BEGIN_COM_MAP(CVssWriterImpl)
  142. COM_INTERFACE_ENTRY(IVssWriter)
  143. END_COM_MAP()
  144. // request WRITER_METADATA or writer state
  145. STDMETHOD(RequestWriterInfo)(
  146. IN BSTR bstrSnapshotSetId,
  147. IN BOOL bWriterMetadata,
  148. IN BOOL bWriterState,
  149. IN IDispatch* pWriterCallback
  150. );
  151. // prepare for backup event
  152. STDMETHOD(PrepareForBackup)(
  153. IN BSTR bstrSnapshotSetId,
  154. IN IDispatch* pWriterCallback
  155. );
  156. // prepare for snapshot event
  157. STDMETHOD(PrepareForSnapshot)(
  158. IN BSTR bstrSnapshotSetId,
  159. IN BSTR VolumeNamesList
  160. );
  161. // freeze event
  162. STDMETHOD(Freeze)(
  163. IN BSTR bstrSnapshotSetId,
  164. IN INT nApplicationLevel
  165. );
  166. // thaw event
  167. STDMETHOD(Thaw)(
  168. IN BSTR bstrSnapshotSetId
  169. );
  170. // backup complete event
  171. STDMETHOD(BackupComplete)(
  172. IN BSTR bstrSnapshotSetId,
  173. IN IDispatch* pWriterCallback
  174. );
  175. // backup shutdown event
  176. STDMETHOD(BackupShutdown)(
  177. IN BSTR bstrSnapshotSetId
  178. );
  179. // abort event
  180. STDMETHOD(Abort)(
  181. IN BSTR bstrSnapshotSetId
  182. );
  183. STDMETHOD(PostRestore)(
  184. IN IDispatch* pWriterCallback
  185. );
  186. STDMETHOD(PreRestore)(
  187. IN IDispatch* pWriterCallback
  188. );
  189. STDMETHOD(PostSnapshot)(
  190. IN BSTR bstrSnapshotSestId,
  191. IN IDispatch* pWriterCallback,
  192. IN BSTR SnapshotDevicesList
  193. );
  194. // Implementation - methods
  195. private:
  196. enum VSS_EVENT_MASK
  197. {
  198. VSS_EVENT_PREPAREBACKUP = 0x00000001,
  199. VSS_EVENT_PREPARESNAPSHOT = 0x00000002,
  200. VSS_EVENT_FREEZE = 0x00000004,
  201. VSS_EVENT_THAW = 0x00000008,
  202. VSS_EVENT_ABORT = 0x00000010,
  203. VSS_EVENT_BACKUPCOMPLETE = 0x00000020,
  204. VSS_EVENT_REQUESTINFO = 0x00000040,
  205. VSS_EVENT_RESTORE = 0x00000080,
  206. VSS_EVENT_ALL = 0xff,
  207. };
  208. // get WRITER callback from IDispatch
  209. void GetCallback
  210. (
  211. IN IDispatch *pWriterCallback,
  212. OUT IVssWriterCallback **ppCallback
  213. );
  214. // reset state machine
  215. void ResetSequence
  216. (
  217. IN bool bCalledFromTimerThread
  218. );
  219. // abort the current snapshot sequence
  220. void DoAbort
  221. (
  222. IN bool bCalledFromTimerThread
  223. );
  224. // obtain components for this writer
  225. void InternalGetWriterComponents
  226. (
  227. IN IVssWriterCallback *pCallback,
  228. OUT IVssWriterComponentsInt **ppWriter,
  229. bool bWriteable
  230. );
  231. // create WRITER_METADATA XML document
  232. CVssCreateWriterMetadata *CreateBasicWriterMetadata
  233. (
  234. );
  235. // startup routine for timer thread
  236. static DWORD StartTimerThread(void *pv);
  237. // function to run in timer thread
  238. void TimerFunc(VSS_ID id);
  239. // enter a state
  240. bool EnterState
  241. (
  242. IN const CVssWriterImplStateMachine &vwsm,
  243. IN BSTR bstrSnapshotSetId
  244. ) throw(HRESULT);
  245. // leave a state
  246. void LeaveState
  247. (
  248. IN const CVssWriterImplStateMachine &vwsm,
  249. IN bool fSuccessful
  250. );
  251. // create a Handle to an event
  252. void SetupEvent
  253. (
  254. IN HANDLE *phevt
  255. ) throw(HRESULT);
  256. // begin a sequence to create a snapshot
  257. void BeginSequence
  258. (
  259. IN CVssID &SnapshotSetId
  260. ) throw(HRESULT);
  261. INT SearchForPreviousSequence(
  262. IN VSS_ID& idSnapshotSet
  263. );
  264. // terminate timer thread
  265. void TerminateTimerThread();
  266. // lock critical section
  267. inline void Lock()
  268. {
  269. m_cs.Lock();
  270. m_bLocked = true;
  271. }
  272. // unlock critical section
  273. inline void Unlock()
  274. {
  275. m_bLocked = false;
  276. m_cs.Unlock();
  277. }
  278. // assert that critical section is locked
  279. inline void AssertLocked()
  280. {
  281. BS_ASSERT(m_bLocked);
  282. }
  283. // Implementation - members
  284. private:
  285. enum VSS_TIMER_COMMAND
  286. {
  287. VSS_TC_UNDEFINED,
  288. VSS_TC_ABORT_CURRENT_SEQUENCE,
  289. VSS_TC_TERMINATE_THREAD,
  290. VSS_TIMEOUT_FREEZE = 60*1000, // 30 seconds
  291. VSS_STACK_SIZE = 256 * 1024 // 256K
  292. };
  293. enum
  294. {
  295. x_MAX_SUBSCRIPTIONS = 32
  296. };
  297. // data related to writer
  298. // writer class id
  299. VSS_ID m_WriterID;
  300. // writer instance id
  301. VSS_ID m_InstanceID;
  302. // usage type for writer
  303. VSS_USAGE_TYPE m_usage;
  304. // data source type for writer
  305. VSS_SOURCE_TYPE m_source;
  306. // writer name
  307. LPWSTR m_wszWriterName;
  308. // Data related to the current sequence
  309. // snapshot set id
  310. VSS_ID m_CurrentSnapshotSetId;
  311. // volume array list passed in as a string
  312. LPWSTR m_pwszLocalVolumeNameList;
  313. // # of volumes in volume array
  314. INT m_nVolumesCount;
  315. // volume array
  316. LPWSTR* m_ppwszVolumesArray;
  317. // pointer to writer callback
  318. CComPtr<IVssWriterCallback> m_pWriterCallback;
  319. // are we currently in a sequence
  320. bool m_bSequenceInProgress;
  321. // current state of the writer
  322. VSS_WRITER_STATE m_state;
  323. // Subscription-related data
  324. CComBSTR m_bstrSubscriptionName;
  325. // actual subscription ids
  326. CComBSTR m_rgbstrSubscriptionId[x_MAX_SUBSCRIPTIONS];
  327. // number of allocated subscription ids
  328. UINT m_cbstrSubscriptionId;
  329. // Data related with the Writer object
  330. // which freeze event is handled
  331. VSS_APPLICATION_LEVEL m_nLevel;
  332. // what events are subscribed to
  333. DWORD m_dwEventMask;
  334. // count of subscriptions
  335. INT m_nSubscriptionsCount;
  336. // Critical section or avoiding race between tasks
  337. CVssSafeCriticalSection m_cs;
  338. // was critical section initialized
  339. bool m_bLockCreated;
  340. // flag indicating if critical section is locked
  341. bool m_bLocked;
  342. // timeout and queuing mechanisms
  343. HANDLE m_hevtTimerThread; // event used to signal timer thread if timer is aborted
  344. HANDLE m_hmtxTimerThread; // mutex used to guarantee only one timer thread exists at a time
  345. HANDLE m_hThreadTimerThread; // handle to timer thread
  346. VSS_TIMER_COMMAND m_command; // timer command when it exits the wait
  347. DWORD m_dwTimeoutFreeze; // timeout for freeze
  348. // actual writer implementation
  349. CVssWriter *m_pWriter;
  350. // state of backup components
  351. BOOL m_bBootableSystemStateBackup;
  352. BOOL m_bComponentsSelected;
  353. VSS_BACKUP_TYPE m_backupType;
  354. // indication why the writer failed
  355. HRESULT m_hrWriterFailure;
  356. // structures to keep track of writer status from previous snapshots
  357. enum
  358. {
  359. MAX_PREVIOUS_SNAPSHOTS = 8,
  360. INVALID_SEQUENCE_INDEX = -1
  361. };
  362. // snapshot ids of previous snapshots
  363. VSS_ID m_rgidPreviousSnapshots[MAX_PREVIOUS_SNAPSHOTS];
  364. // status from previous snapshots
  365. VSS_WRITER_STATE m_rgstatePreviousSnapshots[MAX_PREVIOUS_SNAPSHOTS];
  366. // failure reasons from previous snapshots
  367. HRESULT m_rghrWriterFailurePreviousSnapshots[MAX_PREVIOUS_SNAPSHOTS];
  368. // current slot for dumping a previous snapshots result
  369. UINT m_iPreviousSnapshots;
  370. // TRUE if an OnPrepareForBackup/Freeze/Thaw
  371. // was sent and without a corresponding OnAbort
  372. bool m_bOnAbortPermitted;
  373. // FALSE if an previous OnIdentify failed
  374. // TRUE if OnIdentify succeeded or was not called at all
  375. bool m_bFailedAtIdentify;
  376. };
  377. // auto class for locks
  378. class CVssWriterImplLock
  379. {
  380. public:
  381. CVssWriterImplLock(CVssWriterImpl *pImpl) :
  382. m_pImpl(pImpl)
  383. {
  384. m_pImpl->Lock();
  385. }
  386. ~CVssWriterImplLock()
  387. {
  388. m_pImpl->Unlock();
  389. }
  390. private:
  391. CVssWriterImpl *m_pImpl;
  392. };
  393. #endif //__CVSS_WRITER_IMPL_H_