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.

427 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // File: crecover.cxx
  4. //
  5. // Contents: Implementation for the CRecover support class.
  6. //
  7. // History: 09-Mar-93 SudK Created
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "headers.hxx"
  11. #pragma hdrstop
  12. #include "crecover.hxx"
  13. //+------------------------------------------------------------------------
  14. //
  15. // Method: CRecover::CRecover
  16. //
  17. // Synopsis: The Constructor for this Class. This constructor sets the
  18. // Operation Stage and Operation in its private section to 0.
  19. // No persistent storage operations are done here.
  20. //
  21. // Arguments: [iprop] -- The IProperty instance. Without this it does not
  22. // make sense to instantiate this class.
  23. //
  24. // Returns: Nothing.
  25. //
  26. // History: 09-Mar-1993 SudK Created.
  27. //
  28. //-------------------------------------------------------------------------
  29. CRecover::CRecover(void)
  30. {
  31. IDfsVolInlineDebOut((
  32. DEB_TRACE, "CRecover::+CRecover(0x%x)\n",
  33. this));
  34. _Operation = 0;
  35. _OperStage = 0;
  36. _RecoveryState = 0;
  37. _RecoveryBuffer = _ulongBuffer;
  38. _pPSStg = NULL;
  39. }
  40. //+------------------------------------------------------------------------
  41. //
  42. // Method: CRecover::~CRecover
  43. //
  44. // Synopsis: The Destructor.
  45. //
  46. // Arguments: None
  47. //
  48. // Returns: It does nothing actually except to deallocate any memory.
  49. //
  50. // History: 09-Mar-1993 SudK Created.
  51. //
  52. //-------------------------------------------------------------------------
  53. CRecover::~CRecover(void)
  54. {
  55. IDfsVolInlineDebOut((
  56. DEB_TRACE, "CRecover::~CRecover(0x%x)\n",
  57. this));
  58. if (_RecoveryBuffer != _ulongBuffer)
  59. delete [] _RecoveryBuffer;
  60. if (_pPSStg != NULL)
  61. _pPSStg->Release();
  62. }
  63. //+------------------------------------------------------------------------
  64. //
  65. // Method: CRecover::Initialise
  66. //
  67. // Synopsis: Set the IProperty interface. This should not be called twice!!
  68. //
  69. // Arguments: [pPSStg] -- The IPropertySetStg from here we get to Props
  70. //
  71. // Returns: Nothing.
  72. //
  73. // History: 09-Mar-1993 SudK Created.
  74. //
  75. //-------------------------------------------------------------------------
  76. VOID
  77. CRecover::Initialize(
  78. CStorage *pPSStg)
  79. {
  80. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::Initialize()\n"));
  81. ASSERT(_pPSStg == NULL);
  82. if (_pPSStg != NULL)
  83. _pPSStg->Release();
  84. _pPSStg = pPSStg;
  85. _pPSStg->AddRef();
  86. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::Initialize() exit\n"));
  87. }
  88. //+------------------------------------------------------------------------
  89. //
  90. // Method: CRecover::SetOperationStart
  91. //
  92. // Synopsis: Used when one is about to start an operation. Takes Operation
  93. // Code and any recovery arg if necessary.
  94. //
  95. // Arguments: [Operation] -- The operation code for which this class is
  96. // being instantiated.
  97. // [RecoverySvc]-- The Recovery Svc if any associated with this
  98. // Operation.
  99. //
  100. // Returns: Nothing. If it cant set properties it will throw an exception.
  101. //
  102. // Notes: Caller should take care of freeing the Service passed in.
  103. //
  104. // History: 09-Mar-1993 SudK Created.
  105. //
  106. //-------------------------------------------------------------------------
  107. DWORD
  108. CRecover::SetOperationStart(ULONG fOperation, CDfsService *pRecoverySvc)
  109. {
  110. ULONG size;
  111. DWORD dwErr = ERROR_SUCCESS;
  112. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationStart()\n"));
  113. //
  114. // There could be a recovery buffer from a previous different operation.
  115. // So we need to get rid of it and create an appropriate sized one again.
  116. //
  117. if (_RecoveryBuffer != _ulongBuffer) {
  118. delete [] _RecoveryBuffer;
  119. _RecoveryBuffer = _ulongBuffer;
  120. }
  121. //
  122. // Set the private section variables first.
  123. //
  124. _Operation = fOperation;
  125. _OperStage = DFS_OPER_STAGE_START;
  126. //
  127. // Create the RecoverState and the RecoverySvc in private section.
  128. //
  129. _RecoveryState = DFS_COMPOSE_RECOVERY_STATE(_Operation, _OperStage);
  130. //
  131. // Let us figure out the marshalled buffer for the Service and create it.
  132. //
  133. if (pRecoverySvc != NULL) {
  134. size = pRecoverySvc->GetMarshalSize();
  135. _RecoveryBuffer = new BYTE[size + sizeof(ULONG)];
  136. if (_RecoveryBuffer == NULL) {
  137. dwErr = ERROR_OUTOFMEMORY;
  138. return dwErr;
  139. }
  140. _PutULong(_RecoveryBuffer, size);
  141. pRecoverySvc->Serialize(_RecoveryBuffer + sizeof(ULONG), size);
  142. }
  143. else {
  144. //
  145. // In this case also we add a BLOB but however, this is only an Empty
  146. // BLOB. So this is easy to handle.
  147. //
  148. _PutULong(_RecoveryBuffer, 0);
  149. }
  150. SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
  151. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationStart() exit\n"));
  152. return dwErr;
  153. }
  154. //+------------------------------------------------------------------------
  155. //
  156. // Method: CRecover::SetDefaultProps
  157. //
  158. // Synopsis: This method sets null recovery props to start.
  159. //
  160. // Arguments: None
  161. //
  162. // Returns: Nothing.
  163. //
  164. // Notes: This may throw an exception. Failure of this is truly an
  165. // appropriate time to throw an exception.
  166. //
  167. // History: 12-21-1993 SudK Created.
  168. //
  169. //-------------------------------------------------------------------------
  170. VOID
  171. CRecover::SetDefaultProps(void)
  172. {
  173. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetDefaultProps()\n"));
  174. _RecoveryState = DFS_RECOVERY_STATE_NONE;
  175. _Operation = 0;
  176. _OperStage = 0;
  177. _PutULong(_RecoveryBuffer, 0);
  178. SetRecoveryProps(_RecoveryState, _RecoveryBuffer, TRUE);
  179. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetDefaultProps() exit\n"));
  180. }
  181. //+------------------------------------------------------------------------
  182. //
  183. // Method: CRecover::SetOperationDone
  184. //
  185. // Synopsis: This method deletes all recovery properties to signify end of
  186. // the Operation that was in progress.
  187. //
  188. // Arguments: [Operation] -- The Operation Code.
  189. //
  190. // Returns: Nothing.
  191. //
  192. // Notes: This may throw an exception. Failure of this is truly an
  193. // appropriate time to throw an exception.
  194. //
  195. // History: 09-Mar-1993 SudK Created.
  196. //
  197. //-------------------------------------------------------------------------
  198. VOID
  199. CRecover::SetOperationDone(void)
  200. {
  201. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationDone()\n"));
  202. _RecoveryState = DFS_RECOVERY_STATE_NONE;
  203. _Operation = 0;
  204. _OperStage = 0;
  205. _PutULong(_RecoveryBuffer, 0);
  206. SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
  207. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperationDone() exit\n"));
  208. }
  209. //+------------------------------------------------------------------------
  210. //
  211. // Method: CRecover::SetOperStage
  212. //
  213. // Synopsis: This methods sets the operation stage in its private section
  214. // and at the same time updates the VolumeObject.
  215. //
  216. // Arguments: [OperStage] -- Operation Stage.
  217. //
  218. // Returns: Nothing. It throws an exception if it has any problems.
  219. //
  220. // History: 09-Mar-1993 SudK Created.
  221. //
  222. //-------------------------------------------------------------------------
  223. VOID
  224. CRecover::SetOperStage(ULONG OperStage)
  225. {
  226. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperStage()\n"));
  227. _OperStage = OperStage;
  228. _RecoveryState = DFS_COMPOSE_RECOVERY_STATE(_Operation, _OperStage);
  229. SetRecoveryProps(_RecoveryState, _RecoveryBuffer, FALSE);
  230. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetOperStage() exit\n"));
  231. }
  232. //+------------------------------------------------------------------------
  233. //
  234. // Method: CRecover::SetRecoveryProps
  235. //
  236. // Synopsis: This method interacts with the actual property interface
  237. // to set the recovery properties.
  238. //
  239. // Arguments: [RecoveryState] -- Recovery State.
  240. // [RecoveryBuffer] -- Recovery Argument if any.
  241. // [bCreate] -- Whether to create Propset or not.
  242. //
  243. // Returns: Nothing. Will throw exception if anything goes wrong.
  244. //
  245. // Notes: Caller must free the buffer that he passed in.
  246. //
  247. // History: 09-Mar-1993 SudK Created.
  248. //
  249. //-------------------------------------------------------------------------
  250. VOID
  251. CRecover::SetRecoveryProps(
  252. ULONG RecoveryState,
  253. PBYTE RecoveryBuffer,
  254. BOOLEAN bCreate
  255. )
  256. {
  257. DWORD dwErr;
  258. DWORD cbSize;
  259. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetRecoveryProps()\n"));
  260. _GetULong(RecoveryBuffer, cbSize);
  261. _PutULong(RecoveryBuffer, RecoveryState);
  262. dwErr = _pPSStg->SetRecoveryProps(RecoveryBuffer, cbSize+sizeof(ULONG));
  263. _PutULong(RecoveryBuffer, cbSize);
  264. if (dwErr != ERROR_SUCCESS) {
  265. IDfsVolInlineDebOut((
  266. DEB_ERROR, "Unable to Set RecoveryProperties %08lx\n",dwErr));
  267. RaiseException ( dwErr, 0, 0, 0 );
  268. }
  269. IDfsVolInlineDebOut((DEB_TRACE, "CRecover::SetRecoveryProps() exit\n"));
  270. }
  271. //+-------------------------------------------------------------------------
  272. //
  273. // Method: CRecover::GetRecoveryProps, private
  274. //
  275. // Synopsis: Get the recovery related properties off the volume object.
  276. //
  277. // Arguments:[RecoveryState] -- The RecoveryState is returned here.
  278. // [ppRecoverySvc] -- If there is a recovery Svc it is returned here.
  279. //
  280. // Returns:
  281. //
  282. // History: 09-Feb-1993 SudK Created.
  283. //
  284. //--------------------------------------------------------------------------
  285. DWORD
  286. CRecover :: GetRecoveryProps(
  287. ULONG *RecoveryState,
  288. CDfsService **ppRecoverySvc
  289. )
  290. {
  291. DWORD dwErr = ERROR_SUCCESS;
  292. PBYTE buffer, svcBuffer;
  293. ULONG size;
  294. IDfsVolInlineDebOut((DEB_TRACE, "CDfsVolume::GetRecoveryProps()\n"));
  295. //
  296. // Initialize all the arguments to NULL
  297. //
  298. *RecoveryState = 0;
  299. *ppRecoverySvc = NULL;
  300. dwErr = _pPSStg->GetRecoveryProps( &buffer, &size );
  301. if (dwErr != ERROR_SUCCESS) {
  302. IDfsVolInlineDebOut((
  303. DEB_ERROR, "Unable to read recovery Props %08lx\n", dwErr));
  304. SetOperationDone();
  305. return(dwErr);
  306. }
  307. //
  308. // First let us extract the RecoveryState property.
  309. //
  310. _GetULong(buffer, (*RecoveryState));
  311. //
  312. // Next let us extract the RecoveryArg property.
  313. //
  314. svcBuffer = buffer + sizeof(ULONG);
  315. size -= sizeof(ULONG);
  316. //
  317. // Now that we have a buffer we have to create a service out of this.
  318. // If the buffer is of size Zero we will just return back a NULL ptr.
  319. //
  320. if (size != 0) {
  321. dwErr = CDfsService::DeSerialize(svcBuffer, size, ppRecoverySvc);
  322. if (dwErr != ERROR_SUCCESS) {
  323. IDfsVolInlineDebOut((
  324. DEB_ERROR, "Failed %d to unmarshall RecoverySvc\n", dwErr));
  325. *ppRecoverySvc = NULL;
  326. }
  327. }
  328. delete [] buffer;
  329. IDfsVolInlineDebOut((DEB_TRACE, "CDfsVolume::GetRecoveryProps() exit\n"));
  330. return dwErr;
  331. }
  332. #if (DBG == 1) || (_CT_TEST_HOOK == 1)
  333. INIT_RECOVERY_BREAK_INFO()
  334. //+-------------------------------------------------------------------------
  335. //
  336. // Function: DfsSetRecoveryBreakPoint
  337. //
  338. // Synopsis: Sets the globals that determine when a recovery break point
  339. // is activated
  340. //
  341. // Arguments:[pBuffer] -- Marshalled buffer
  342. // [cbSize] -- Size of the marhalled buffer
  343. //
  344. // Returns: STATUS_SUCCESS -- Success
  345. //
  346. //--------------------------------------------------------------------------
  347. NTSTATUS DfsSetRecoveryBreakPoint(PBYTE pBuffer,
  348. ULONG cbSize)
  349. {
  350. NTSTATUS Status;
  351. MARSHAL_BUFFER marshalBuffer;
  352. MarshalBufferFree(gRecoveryBkptInfo.pwszApiBreak);
  353. MarshalBufferInitialize(&marshalBuffer, cbSize, pBuffer);
  354. Status = DfsRtlGet(&marshalBuffer, &MiRecoveryBkpt, &gRecoveryBkptInfo);
  355. return(Status);
  356. }
  357. #endif