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.

487 lines
13 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. #include "aclapi.h"
  18. #ifndef INITGUID
  19. #define INITGUID
  20. #include <guiddef.h>
  21. #undef INITGUID
  22. #else
  23. #include <guiddef.h>
  24. #endif
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. DEFINE_GUID(RSS_WRITER_GUID, 0xb959d2c3L, 0x18bb, 0x4607, 0xb0, 0xca,
  29. 0x68, 0x8c, 0xd0, 0xd4, 0x1a, 0x50); // {b959d2c3-18bb-4607-b0ca-688cd0d41a50}
  30. #ifdef __cplusplus
  31. }
  32. #endif
  33. #define FILES_TO_EXCLUDE OLESTR("%SystemRoot%\\System32\\RemoteStorage\\FsaDb\\*;%SystemRoot%\\System32\\RemoteStorage\\Trace\\*")
  34. #define FILES_TO_INCLUDE OLESTR("")
  35. CRssJetWriter::CRssJetWriter()
  36. /*++
  37. Routine Description:
  38. Constructor
  39. Arguments:
  40. None
  41. Return Value:
  42. None
  43. Notes:
  44. We create the events in the constructor because these events might be required
  45. before the Init code could be done (Init must be called after Jet is initialized
  46. --*/
  47. {
  48. HRESULT hr = S_OK;
  49. PSID pSystemSID = NULL;
  50. PACL pACL = NULL;
  51. PSECURITY_DESCRIPTOR pSD = NULL;
  52. #define WRITER_EVENTS_NUM_ACE 1
  53. EXPLICIT_ACCESS ea[WRITER_EVENTS_NUM_ACE];
  54. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  55. SECURITY_ATTRIBUTES sa;
  56. WsbTraceIn(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR(""));
  57. m_bTerminating = FALSE;
  58. try {
  59. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  60. m_syncHandles[index] = NULL;
  61. }
  62. // Create the events
  63. // Note: Currently Engine and IDB sync events are created here, FSA event already should already exist
  64. // If initializtion order of RSS modles is changed - the CreateEent and OpenEvent calls for these
  65. // named events may need to switch.
  66. // Method of interest for this matter (of init order) are CHsmServer::Init and CFsaServer::Init
  67. // Create an SD with ACL for local-system only
  68. memset(ea, 0, sizeof(EXPLICIT_ACCESS) * WRITER_EVENTS_NUM_ACE);
  69. WsbAssertStatus( AllocateAndInitializeSid( &SIDAuthNT, 1,
  70. SECURITY_LOCAL_SYSTEM_RID,
  71. 0, 0, 0, 0, 0, 0, 0,
  72. &pSystemSID) );
  73. ea[0].grfAccessPermissions = FILE_ALL_ACCESS;
  74. ea[0].grfAccessMode = SET_ACCESS;
  75. ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  76. ea[0].Trustee.pMultipleTrustee = NULL;
  77. ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  78. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  79. ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
  80. ea[0].Trustee.ptstrName = (LPTSTR) pSystemSID;
  81. WsbAffirmNoError(SetEntriesInAcl(WRITER_EVENTS_NUM_ACE, ea, NULL, &pACL));
  82. pSD = (PSECURITY_DESCRIPTOR) WsbAlloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
  83. WsbAffirmPointer(pSD);
  84. WsbAffirmStatus(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
  85. WsbAffirmStatus(SetSecurityDescriptorDacl(
  86. pSD,
  87. TRUE, // fDaclPresent flag
  88. pACL,
  89. FALSE)); // not a default DACL
  90. sa.nLength = sizeof (SECURITY_ATTRIBUTES);
  91. sa.lpSecurityDescriptor = pSD;
  92. sa.bInheritHandle = FALSE;
  93. // Create teh actual events
  94. WsbAffirmHandle(m_syncHandles[INTERNAL_EVENT_INDEX] = CreateEvent(NULL, FALSE, TRUE, NULL));
  95. WsbAffirmHandle(m_syncHandles[1] = OpenEvent(EVENT_ALL_ACCESS, FALSE, HSM_FSA_STATE_EVENT));
  96. WsbAffirmHandle(m_syncHandles[2] = CreateEvent(&sa, FALSE, TRUE, HSM_ENGINE_STATE_EVENT));
  97. WsbAffirmHandle(m_syncHandles[3] = CreateEvent(&sa, FALSE, TRUE, HSM_IDB_STATE_EVENT));
  98. } WsbCatch(hr);
  99. m_hrInit = hr;
  100. if (pSystemSID) {
  101. FreeSid(pSystemSID);
  102. }
  103. if (pACL) {
  104. LocalFree(pACL);
  105. }
  106. if (pSD) {
  107. WsbFree(pSD);
  108. }
  109. WsbTraceOut(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  110. }
  111. CRssJetWriter::~CRssJetWriter( )
  112. /*++
  113. Routine Description:
  114. Destructor - free resources
  115. Arguments:
  116. None
  117. Return Value:
  118. None
  119. --*/
  120. {
  121. WsbTraceIn(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
  122. // Close event handles
  123. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  124. if (NULL != m_syncHandles[index]) {
  125. CloseHandle(m_syncHandles[index]);
  126. m_syncHandles[index] = NULL;
  127. }
  128. }
  129. WsbTraceOut(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
  130. }
  131. HRESULT CRssJetWriter::Init(void)
  132. /*++
  133. Routine Description:
  134. Initialize Snapshot synchronization
  135. Arguments:
  136. None
  137. Return Value:
  138. S_OK - Success
  139. --*/
  140. {
  141. HRESULT hr = S_OK;
  142. WsbTraceIn(OLESTR("CRssJetWriter::Init"), OLESTR(""));
  143. try {
  144. // Don't do anything if the basic initialization done in the constructor failed
  145. WsbAffirmHr(m_hrInit);
  146. GUID rssGuid = RSS_WRITER_GUID;
  147. WsbAffirmHr(Initialize(
  148. rssGuid,
  149. RSS_BACKUP_NAME,
  150. TRUE,
  151. FALSE,
  152. FILES_TO_INCLUDE,
  153. FILES_TO_EXCLUDE
  154. ));
  155. } WsbCatch(hr);
  156. WsbTraceOut(OLESTR("CRssJetWriter::Init"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  157. return hr;
  158. }
  159. HRESULT CRssJetWriter::Terminate(void)
  160. /*++
  161. Routine Description:
  162. Terminate Snapshot synchronization
  163. Arguments:
  164. None
  165. Return Value:
  166. S_OK - Success
  167. --*/
  168. {
  169. HRESULT hr = S_OK;
  170. WsbTraceIn(OLESTR("CRssJetWriter::Terminate"), OLESTR(""));
  171. try {
  172. DWORD status, errWait;
  173. WsbAffirmHr(m_hrInit);
  174. // Avoid terminating in the middle of snapshot
  175. status = WaitForSingleObject(m_syncHandles[INTERNAL_EVENT_INDEX], INTERNAL_WAIT_TIMEOUT);
  176. errWait = GetLastError();
  177. // Whatever the status is - uninitialize underlying writer mechanizm
  178. m_bTerminating = TRUE;
  179. Uninitialize();
  180. // Check Wait status:
  181. if (status == WAIT_OBJECT_0) {
  182. // The expected case
  183. if (! SetEvent(m_syncHandles[INTERNAL_EVENT_INDEX])) {
  184. // Don't abort, just trace error
  185. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: SetEvent returned unexpected error %lu\n"), GetLastError());
  186. }
  187. WsbTrace(OLESTR("CRssJetWriter::Terminate: Terminating after a successful wait\n"));
  188. } else {
  189. // In case of failure we cannot trust Thaw/Abort to be called so we signal the evnets
  190. InternalEnd();
  191. switch (status) {
  192. case WAIT_TIMEOUT:
  193. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object timed out after %lu ms\n"), INTERNAL_WAIT_TIMEOUT);
  194. hr = E_FAIL;
  195. break;
  196. case WAIT_FAILED:
  197. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned error %lu\n"), errWait);
  198. hr = HRESULT_FROM_WIN32(errWait);
  199. break;
  200. default:
  201. WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned unexpected status %lu\n"), status);
  202. hr = E_UNEXPECTED;
  203. break;
  204. }
  205. }
  206. } WsbCatch(hr);
  207. WsbTraceOut(OLESTR("CRssJetWriter::Terminate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  208. return hr;
  209. }
  210. HRESULT CRssJetWriter::InternalEnd(void)
  211. /*++
  212. Routine Description:
  213. Set all events
  214. Arguments:
  215. None
  216. Return Value:
  217. S_OK - Success
  218. --*/
  219. {
  220. HRESULT hr = S_OK;
  221. WsbTraceIn(OLESTR("CRssJetWriter::InternalEnd"), OLESTR(""));
  222. try {
  223. WsbAffirmHr(m_hrInit);
  224. // Set all events
  225. DWORD errSet;
  226. for (int index=0; index<WRITER_EVENTS_NUM; index++) {
  227. if (NULL != m_syncHandles[index]) {
  228. if (! SetEvent(m_syncHandles[index])) {
  229. // Don't abort, just save error
  230. errSet = GetLastError();
  231. WsbTraceAlways(OLESTR("CRssJetWriter::InternalEnd: SetEvent returned error %lu for event number %d\n"), errSet, index);
  232. hr = HRESULT_FROM_WIN32(errSet);
  233. }
  234. }
  235. }
  236. } WsbCatch(hr);
  237. WsbTraceOut(OLESTR("CRssJetWriter::InternalEnd"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  238. return hr;
  239. }
  240. //
  241. // CVssJetWriter overloaded methods
  242. //
  243. bool STDMETHODCALLTYPE CRssJetWriter::OnFreezeBegin()
  244. /*++
  245. Routine Description:
  246. Handles Freeze Start event
  247. Arguments:
  248. None
  249. Return Value:
  250. TRUE - Success, OK to freeze
  251. FALSE - Failure, Don't freeze
  252. --*/
  253. {
  254. HRESULT hr = S_OK;
  255. bool bRet;
  256. WsbTraceIn(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR(""));
  257. try {
  258. WsbAffirmHr(m_hrInit);
  259. // Just wait for all sync events
  260. DWORD status = WaitForMultipleObjects(WRITER_EVENTS_NUM, m_syncHandles, TRUE, EVENT_WAIT_TIMEOUT);
  261. // Comparing (status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0) intsead of (status >= WAIT_OBJECT_0)
  262. // to avoid error C4296 - "expression is always true"
  263. if ( ((status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0)) &&
  264. (status <= WAIT_OBJECT_0 + WRITER_EVENTS_NUM - 1) ) {
  265. // Freeze is ready to go...
  266. WsbTrace(OLESTR("CRssJetWriter::OnFreezeBegin: All events are nonsignaled, freeze is reday to go\n"));
  267. // If we are terminating, no Thaw/Abort will be called - therefore, set the events
  268. if (m_bTerminating) {
  269. InternalEnd();
  270. }
  271. } else {
  272. // Something wrong...
  273. DWORD errWait = GetLastError();
  274. // Set all events in case of an error
  275. InternalEnd();
  276. switch(status) {
  277. case WAIT_FAILED:
  278. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned error %lu\n"), errWait);
  279. WsbThrow(HRESULT_FROM_WIN32(errWait));
  280. break;
  281. case WAIT_TIMEOUT:
  282. // Timeout means that one of the sync components is taking too long
  283. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects timed out after %lu ms\n"), EVENT_WAIT_TIMEOUT);
  284. WsbThrow(VSS_E_WRITERERROR_TIMEOUT);
  285. break;
  286. default:
  287. WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned unexpected status %lu\n"), status);
  288. WsbThrow(E_UNEXPECTED);
  289. break;
  290. }
  291. }
  292. } WsbCatch(hr);
  293. if (S_OK == hr) {
  294. bRet = CVssJetWriter::OnFreezeBegin();
  295. } else {
  296. bRet = false;
  297. }
  298. WsbTraceOut(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR("hr = <%ls> , bRet = <%ls>"), WsbHrAsString(hr), WsbBoolAsString(bRet));
  299. return bRet;
  300. }
  301. bool STDMETHODCALLTYPE CRssJetWriter::OnThawEnd(IN bool fJetThawSucceeded)
  302. /*++
  303. Routine Description:
  304. Handles Thaw End event
  305. Arguments:
  306. fJetThawSucceeded - Ignored
  307. Return Value:
  308. TRUE - Success
  309. FALSE - Failure
  310. --*/
  311. {
  312. bool bRet;
  313. WsbTraceIn(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR(""));
  314. // Return value is determined by base class, ignore internal errors here
  315. bRet = CVssJetWriter::OnThawEnd(fJetThawSucceeded);
  316. // Release all waiting events
  317. InternalEnd();
  318. WsbTraceOut(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR("bRet = <%ls>"), WsbBoolAsString(bRet));
  319. return bRet;
  320. }
  321. void STDMETHODCALLTYPE CRssJetWriter::OnAbortEnd()
  322. /*++
  323. Routine Description:
  324. Handles Abort End event
  325. Arguments:
  326. None
  327. Return Value:
  328. None
  329. --*/
  330. {
  331. WsbTraceIn(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
  332. // Call base class imp.
  333. CVssJetWriter::OnAbortEnd();
  334. // Release all waiting events
  335. InternalEnd();
  336. WsbTraceOut(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
  337. }