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.

428 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. rswriter.cpp
  5. Abstract:
  6. Implements CRssJetWriter methods
  7. Author:
  8. Ran Kalach [rankala] 4/4/2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "rsevents.h"
  13. #include "rswriter.h"
  14. // Include these 2 files just for VSS_E_WRITERERROR_TIMEOUT definition
  15. #include "vss.h"
  16. #include "vswriter.h"
  17. #ifndef INITGUID
  18. #define INITGUID
  19. #include <guiddef.h>
  20. #undef INITGUID
  21. #else
  22. #include <guiddef.h>
  23. #endif
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. DEFINE_GUID(RSS_WRITER_GUID, 0xb959d2c3L, 0x18bb, 0x4607, 0xb0, 0xca,
  28. 0x68, 0x8c, 0xd0, 0xd4, 0x1a, 0x50); // {b959d2c3-18bb-4607-b0ca-688cd0d41a50}
  29. #ifdef __cplusplus
  30. }
  31. #endif
  32. #define FILES_TO_EXCLUDE OLESTR("%SystemRoot%\\System32\\RemoteStorage\\FsaDb\\*;%SystemRoot%\\System32\\RemoteStorage\\Trace\\*")
  33. #define FILES_TO_INCLUDE OLESTR("")
  34. CRssJetWriter::CRssJetWriter()
  35. /*++
  36. Routine Description:
  37. Constructor
  38. Arguments:
  39. None
  40. Return Value:
  41. None
  42. Notes:
  43. We create the events in the constructor because these events might be required
  44. before the Init code could be done (Init must be called after Jet is initialized
  45. --*/
  46. {
  47. HRESULT hr = S_OK;
  48. WsbTraceIn(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR(""));
  49. m_bTerminating = FALSE;
  50. try {
  51. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  52. m_syncHandles[index] = NULL;
  53. }
  54. // Create the events
  55. WsbAffirmHandle(m_syncHandles[INTERNAL_EVENT_INDEX] = CreateEvent(NULL, FALSE, TRUE, NULL));
  56. WsbAffirmHandle(m_syncHandles[1] = CreateEvent(NULL, FALSE, TRUE, HSM_ENGINE_STATE_EVENT));
  57. WsbAffirmHandle(m_syncHandles[2] = CreateEvent(NULL, FALSE, TRUE, HSM_FSA_STATE_EVENT));
  58. WsbAffirmHandle(m_syncHandles[3] = CreateEvent(NULL, FALSE, TRUE, HSM_IDB_STATE_EVENT));
  59. } WsbCatch(hr);
  60. m_hrInit = hr;
  61. WsbTraceOut(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  62. }
  63. CRssJetWriter::~CRssJetWriter( )
  64. /*++
  65. Routine Description:
  66. Destructor - free resources
  67. Arguments:
  68. None
  69. Return Value:
  70. None
  71. --*/
  72. {
  73. WsbTraceIn(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
  74. // Close event handles
  75. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  76. if (NULL != m_syncHandles[index]) {
  77. CloseHandle(m_syncHandles[index]);
  78. m_syncHandles[index] = NULL;
  79. }
  80. }
  81. WsbTraceOut(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
  82. }
  83. HRESULT CRssJetWriter::Init(void)
  84. /*++
  85. Routine Description:
  86. Initialize Snapshot synchronization
  87. Arguments:
  88. None
  89. Return Value:
  90. S_OK - Success
  91. --*/
  92. {
  93. HRESULT hr = S_OK;
  94. WsbTraceIn(OLESTR("CRssJetWriter::Init"), OLESTR(""));
  95. try {
  96. // Don't do anything if the basic initialization done in the constructor failed
  97. WsbAffirmHr(m_hrInit);
  98. GUID rssGuid = RSS_WRITER_GUID;
  99. WsbAffirmHr(Initialize(
  100. rssGuid,
  101. RSS_BACKUP_NAME,
  102. TRUE,
  103. FALSE,
  104. FILES_TO_INCLUDE,
  105. FILES_TO_EXCLUDE
  106. ));
  107. } WsbCatch(hr);
  108. WsbTraceOut(OLESTR("CRssJetWriter::Init"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  109. return hr;
  110. }
  111. HRESULT CRssJetWriter::Terminate(void)
  112. /*++
  113. Routine Description:
  114. Terminate Snapshot synchronization
  115. Arguments:
  116. None
  117. Return Value:
  118. S_OK - Success
  119. --*/
  120. {
  121. HRESULT hr = S_OK;
  122. WsbTraceIn(OLESTR("CRssJetWriter::Terminate"), OLESTR(""));
  123. try {
  124. DWORD status, errWait;
  125. WsbAffirmHr(m_hrInit);
  126. // Avoid terminating in the middle of snapshot
  127. status = WaitForSingleObject(m_syncHandles[INTERNAL_EVENT_INDEX], INTERNAL_WAIT_TIMEOUT);
  128. errWait = GetLastError();
  129. // Whatever the status is - uninitialize underlying writer mechanizm
  130. m_bTerminating = TRUE;
  131. Uninitialize();
  132. // Check Wait status:
  133. if (status == WAIT_OBJECT_0) {
  134. // The expected case
  135. if (! SetEvent(m_syncHandles[INTERNAL_EVENT_INDEX])) {
  136. // Don't abort, just trace error
  137. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: SetEvent returned unexpected error %lu\n"), GetLastError());
  138. }
  139. WsbTrace(OLESTR("CRssJetWriter::Terminate: Terminating after a successful wait\n"));
  140. } else {
  141. // In case of failure we cannot trust Thaw/Abort to be called so we signal the evnets
  142. InternalEnd();
  143. switch (status) {
  144. case WAIT_TIMEOUT:
  145. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object timed out after %lu ms\n"), INTERNAL_WAIT_TIMEOUT);
  146. hr = E_FAIL;
  147. break;
  148. case WAIT_FAILED:
  149. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned error %lu\n"), errWait);
  150. hr = HRESULT_FROM_WIN32(errWait);
  151. break;
  152. default:
  153. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned unexpected status %lu\n"), status);
  154. hr = E_UNEXPECTED;
  155. break;
  156. }
  157. }
  158. } WsbCatch(hr);
  159. WsbTraceOut(OLESTR("CRssJetWriter::Terminate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  160. return hr;
  161. }
  162. HRESULT CRssJetWriter::InternalEnd(void)
  163. /*++
  164. Routine Description:
  165. Set all events
  166. Arguments:
  167. None
  168. Return Value:
  169. S_OK - Success
  170. --*/
  171. {
  172. HRESULT hr = S_OK;
  173. WsbTraceIn(OLESTR("CRssJetWriter::InternalEnd"), OLESTR(""));
  174. try {
  175. WsbAffirmHr(m_hrInit);
  176. // Set all events
  177. DWORD errSet;
  178. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  179. if (NULL != m_syncHandles[index]) {
  180. if (! SetEvent(m_syncHandles[index])) {
  181. // Don't abort, just save error
  182. errSet = GetLastError();
  183. WsbTraceAlways(OLESTR("CRssJetWriter::InternalEnd: SetEvent returned error %lu for event number %d\n"), errSet, index);
  184. hr = HRESULT_FROM_WIN32(errSet);
  185. }
  186. }
  187. }
  188. } WsbCatch(hr);
  189. WsbTraceOut(OLESTR("CRssJetWriter::InternalEnd"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  190. return hr;
  191. }
  192. //
  193. // CVssJetWriter overloaded methods
  194. //
  195. bool STDMETHODCALLTYPE CRssJetWriter::OnFreezeBegin()
  196. /*++
  197. Routine Description:
  198. Handles Freeze Start event
  199. Arguments:
  200. None
  201. Return Value:
  202. TRUE - Success, OK to freeze
  203. FALSE - Failure, Don't freeze
  204. --*/
  205. {
  206. HRESULT hr = S_OK;
  207. bool bRet;
  208. WsbTraceIn(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR(""));
  209. try {
  210. WsbAffirmHr(m_hrInit);
  211. // Just wait for all sync events
  212. DWORD status = WaitForMultipleObjects(WRITER_EVENTS_NUM, m_syncHandles, TRUE, EVENT_WAIT_TIMEOUT);
  213. // Comparing (status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0) intsead of (status >= WAIT_OBJECT_0)
  214. // to avoid error C4296 - "expression is always true"
  215. if ( ((status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0)) &&
  216. (status <= WAIT_OBJECT_0 + WRITER_EVENTS_NUM - 1) ) {
  217. // Freeze is ready to go...
  218. WsbTrace(OLESTR("CRssJetWriter::OnFreezeBegin: All events are nonsignaled, freeze is reday to go\n"));
  219. // If we are terminating, no Thaw/Abort will be called - therefore, set the events
  220. if (m_bTerminating) {
  221. InternalEnd();
  222. }
  223. } else {
  224. // Something wrong...
  225. DWORD errWait = GetLastError();
  226. // Set all events in case of an error
  227. InternalEnd();
  228. switch(status) {
  229. case WAIT_FAILED:
  230. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned error %lu\n"), errWait);
  231. WsbThrow(HRESULT_FROM_WIN32(errWait));
  232. break;
  233. case WAIT_TIMEOUT:
  234. // Timeout means that one of the sync components is taking too long
  235. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects timed out after %lu ms\n"), EVENT_WAIT_TIMEOUT);
  236. WsbThrow(VSS_E_WRITERERROR_TIMEOUT);
  237. break;
  238. default:
  239. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned unexpected status %lu\n"), status);
  240. WsbThrow(E_UNEXPECTED);
  241. break;
  242. }
  243. }
  244. } WsbCatch(hr);
  245. if (S_OK == hr) {
  246. bRet = CVssJetWriter::OnFreezeBegin();
  247. } else {
  248. bRet = false;
  249. }
  250. WsbTraceOut(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR("hr = <%ls> , bRet = <%ls>"), WsbHrAsString(hr), WsbBoolAsString(bRet));
  251. return bRet;
  252. }
  253. bool STDMETHODCALLTYPE CRssJetWriter::OnThawEnd(IN bool fJetThawSucceeded)
  254. /*++
  255. Routine Description:
  256. Handles Thaw End event
  257. Arguments:
  258. fJetThawSucceeded - Ignored
  259. Return Value:
  260. TRUE - Success
  261. FALSE - Failure
  262. --*/
  263. {
  264. bool bRet;
  265. WsbTraceIn(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR(""));
  266. // Return value is determined by base class, ignore internal errors here
  267. bRet = CVssJetWriter::OnThawEnd(fJetThawSucceeded);
  268. // Release all waiting events
  269. InternalEnd();
  270. WsbTraceOut(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR("bRet = <%ls>"), WsbBoolAsString(bRet));
  271. return bRet;
  272. }
  273. void STDMETHODCALLTYPE CRssJetWriter::OnAbortEnd()
  274. /*++
  275. Routine Description:
  276. Handles Abort End event
  277. Arguments:
  278. None
  279. Return Value:
  280. None
  281. --*/
  282. {
  283. WsbTraceIn(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
  284. // Call base class imp.
  285. CVssJetWriter::OnAbortEnd();
  286. // Release all waiting events
  287. InternalEnd();
  288. WsbTraceOut(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
  289. }