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.

771 lines
22 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Abstract:
  4. @doc
  5. @module VsWriter.cpp | Implementation of Writer
  6. @end
  7. Author:
  8. Adi Oltean [aoltean] 02/02/2000
  9. TBD:
  10. Add comments.
  11. Revision History:
  12. Name Date Comments
  13. brianb 03/28/2000 Created
  14. mikejohn 05/18/2000 ~CVssWriter() should check that wrapper exists
  15. before calling it
  16. mikejohn 06/23/2000 Add external entry point for SetWriterFailure()
  17. mikejohn 09/01/2000 Add extra tracing to identify writers in trace output
  18. mikejohn 09/18/2000 176860: Added calling convention methods where missing
  19. ssteiner 02/14/2001 Changed class interface to version 2.
  20. --*/
  21. #include <stdafx.h>
  22. #include "vs_inc.hxx"
  23. #include "vs_sec.hxx"
  24. #include "vs_idl.hxx"
  25. #include "vs_reg.hxx"
  26. #include "comadmin.hxx"
  27. #include "vswriter.h"
  28. #include "vsevent.h"
  29. #include "vsbackup.h"
  30. #include "vswrtimp.h"
  31. #include "vs_wmxml.hxx"
  32. #include "vs_cmxml.hxx"
  33. extern WCHAR g_ComponentMetadataXML[];
  34. static LPCWSTR x_wszElementRoot = L"root";
  35. static LPCWSTR x_wszElementSnapshotSetDescription = L"SNAPSHOT_SET_DESCRIPTION";
  36. static LPCWSTR x_wszAttrSnapshotSetId = L"snapshotSetId";
  37. static LPCWSTR x_wszAttrXmlns = L"xmlns";
  38. static LPCWSTR x_wszValueXmlns = L"x-schema:#VssComponentMetadata";
  39. static LPCWSTR x_wszAttrContext = L"context";
  40. ////////////////////////////////////////////////////////////////////////
  41. // Standard foo for file name aliasing. This code block must be after
  42. // all includes of VSS header files.
  43. //
  44. #ifdef VSS_FILE_ALIAS
  45. #undef VSS_FILE_ALIAS
  46. #endif
  47. #define VSS_FILE_ALIAS "WSHVWRTC"
  48. //
  49. ////////////////////////////////////////////////////////////////////////
  50. static LPCWSTR GetStringFromUsageType (VSS_USAGE_TYPE eUsageType)
  51. {
  52. LPCWSTR pwszRetString = L"UNDEFINED";
  53. switch (eUsageType)
  54. {
  55. case VSS_UT_BOOTABLESYSTEMSTATE: pwszRetString = L"BootableSystemState"; break;
  56. case VSS_UT_SYSTEMSERVICE: pwszRetString = L"SystemService"; break;
  57. case VSS_UT_USERDATA: pwszRetString = L"UserData"; break;
  58. case VSS_UT_OTHER: pwszRetString = L"Other"; break;
  59. default:
  60. break;
  61. }
  62. return (pwszRetString);
  63. }
  64. static LPCWSTR GetStringFromSourceType (VSS_SOURCE_TYPE eSourceType)
  65. {
  66. LPCWSTR pwszRetString = L"UNDEFINED";
  67. switch (eSourceType)
  68. {
  69. case VSS_ST_TRANSACTEDDB: pwszRetString = L"TransactionDb"; break;
  70. case VSS_ST_NONTRANSACTEDDB: pwszRetString = L"NonTransactionDb"; break;
  71. case VSS_ST_OTHER: pwszRetString = L"Other"; break;
  72. default:
  73. break;
  74. }
  75. return (pwszRetString);
  76. }
  77. static LPCWSTR GetStringFromAlternateWriterState (VSS_ALTERNATE_WRITER_STATE aws)
  78. {
  79. LPCWSTR pwszRetString = L"UNDEFINED";
  80. switch (aws)
  81. {
  82. case VSS_AWS_UNDEFINED: pwszRetString = L"Undefined"; break;
  83. case VSS_AWS_NO_ALTERNATE_WRITER: pwszRetString = L"No alternate writer"; break;
  84. case VSS_AWS_ALTERNATE_WRITER_EXISTS: pwszRetString = L"Alternate writer exists"; break;
  85. case VSS_AWS_THIS_IS_ALTERNATE_WRITER: pwszRetString = L"This is the alternate writer"; break;
  86. default:
  87. break;
  88. }
  89. return (pwszRetString);
  90. }
  91. static LPCWSTR GetStringFromApplicationLevel (VSS_APPLICATION_LEVEL eApplicationLevel)
  92. {
  93. LPCWSTR pwszRetString = L"UNDEFINED";
  94. switch (eApplicationLevel)
  95. {
  96. case VSS_APP_UNKNOWN: pwszRetString = L"Unknown"; break;
  97. case VSS_APP_SYSTEM: pwszRetString = L"System"; break;
  98. case VSS_APP_BACK_END: pwszRetString = L"BackEnd"; break;
  99. case VSS_APP_FRONT_END: pwszRetString = L"FrontEnd"; break;
  100. case VSS_APP_AUTO: pwszRetString = L"Automatic"; break;
  101. default:
  102. break;
  103. }
  104. return (pwszRetString);
  105. }
  106. // constructor
  107. __declspec(dllexport)
  108. STDMETHODCALLTYPE CVssWriter::CVssWriter() :
  109. m_pWrapper(NULL)
  110. {
  111. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::CVssWriter");
  112. ft.Trace(VSSDBG_GEN, L"**** Constructor: THIS = %p", this);
  113. }
  114. // destructor
  115. __declspec(dllexport)
  116. STDMETHODCALLTYPE CVssWriter::~CVssWriter()
  117. {
  118. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::CVssWriter");
  119. ft.Trace(VSSDBG_GEN, L"**** Destructor: THIS = %p", this);
  120. if (NULL != m_pWrapper)
  121. {
  122. ft.Trace(VSSDBG_GEN, L"**** Calling CVssWriter::Uninitialize() [%p]", this);
  123. m_pWrapper->Uninitialize();
  124. #ifdef _DEBUG
  125. LONG cRef =
  126. #endif
  127. m_pWrapper->Release();
  128. #ifdef _DEBUG
  129. ft.Trace(VSSDBG_GEN, L"**** Final reference count for Wrapper = %ld - [%p]", cRef, this);
  130. #endif
  131. // disable for now
  132. // BS_ASSERT(cRef == 0);
  133. }
  134. }
  135. // default OnPrepareBackup method
  136. __declspec(dllexport)
  137. bool STDMETHODCALLTYPE CVssWriter::OnPrepareBackup(IN IVssWriterComponents *pComponent)
  138. {
  139. UNREFERENCED_PARAMETER(pComponent);
  140. return true;
  141. }
  142. // default OnIdentify method
  143. __declspec(dllexport)
  144. bool STDMETHODCALLTYPE CVssWriter::OnIdentify(IN IVssCreateWriterMetadata *pMetadata)
  145. {
  146. UNREFERENCED_PARAMETER(pMetadata);
  147. return true;
  148. }
  149. // default OnBackupComplete method
  150. __declspec(dllexport)
  151. bool STDMETHODCALLTYPE CVssWriter::OnBackupComplete(IN IVssWriterComponents *pComponent)
  152. {
  153. UNREFERENCED_PARAMETER(pComponent);
  154. return true;
  155. }
  156. // default OnBackupShutdown method
  157. __declspec(dllexport)
  158. bool STDMETHODCALLTYPE CVssWriter::OnBackupShutdown(IN VSS_ID SnapshotSetId)
  159. {
  160. UNREFERENCED_PARAMETER(SnapshotSetId);
  161. return true;
  162. }
  163. // default OnPreRestore method
  164. __declspec(dllexport)
  165. bool STDMETHODCALLTYPE CVssWriter::OnPreRestore(IN IVssWriterComponents *pComponent)
  166. {
  167. UNREFERENCED_PARAMETER(pComponent);
  168. return true;
  169. }
  170. // default OnPostRestore method
  171. __declspec(dllexport)
  172. bool STDMETHODCALLTYPE CVssWriter::OnPostRestore(IN IVssWriterComponents *pComponent)
  173. {
  174. UNREFERENCED_PARAMETER(pComponent);
  175. return true;
  176. }
  177. // default OnPostSnapshot method
  178. __declspec(dllexport)
  179. bool STDMETHODCALLTYPE CVssWriter::OnPostSnapshot(IN IVssWriterComponents *pComponent)
  180. {
  181. UNREFERENCED_PARAMETER(pComponent);
  182. return true;
  183. }
  184. // default OnBackOffIOOnVolume
  185. __declspec(dllexport)
  186. bool STDMETHODCALLTYPE CVssWriter::OnBackOffIOOnVolume
  187. (
  188. IN VSS_PWSZ wszVolumeName,
  189. IN VSS_ID snapshotId,
  190. IN VSS_ID providerId
  191. )
  192. {
  193. UNREFERENCED_PARAMETER(wszVolumeName);
  194. UNREFERENCED_PARAMETER(snapshotId);
  195. UNREFERENCED_PARAMETER(providerId);
  196. return true;
  197. }
  198. // default OnContinueIOOnVolume
  199. __declspec(dllexport)
  200. bool STDMETHODCALLTYPE CVssWriter::OnContinueIOOnVolume
  201. (
  202. IN VSS_PWSZ wszVolumeName,
  203. IN VSS_ID snapshotId,
  204. IN VSS_ID providerId
  205. )
  206. {
  207. UNREFERENCED_PARAMETER(wszVolumeName);
  208. UNREFERENCED_PARAMETER(snapshotId);
  209. UNREFERENCED_PARAMETER(providerId);
  210. return true;
  211. }
  212. // default OnVSSShutdown
  213. __declspec(dllexport)
  214. bool STDMETHODCALLTYPE CVssWriter::OnVSSShutdown()
  215. {
  216. return true;
  217. }
  218. // default OnVSSApplicationStartup
  219. __declspec(dllexport)
  220. bool STDMETHODCALLTYPE CVssWriter::OnVSSApplicationStartup()
  221. {
  222. return true;
  223. }
  224. // initialize the writer
  225. // This function returns S_FALSE when the writer is inactive (setup or safe mode)
  226. __declspec(dllexport)
  227. HRESULT STDMETHODCALLTYPE CVssWriter::Initialize
  228. (
  229. IN VSS_ID WriterID,
  230. IN LPCWSTR wszWriterName,
  231. IN VSS_USAGE_TYPE ut,
  232. IN VSS_SOURCE_TYPE st,
  233. IN VSS_APPLICATION_LEVEL nLevel,
  234. IN DWORD dwTimeoutFreeze,
  235. IN VSS_ALTERNATE_WRITER_STATE aws,
  236. IN bool bIOThrottlingOnly,
  237. IN LPCWSTR wszReserved
  238. )
  239. {
  240. UNREFERENCED_PARAMETER(wszReserved);
  241. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::Initialize");
  242. try
  243. {
  244. ft.Trace (VSSDBG_SHIM, L"Called CVssWriter::Initialize() with:");
  245. ft.Trace (VSSDBG_SHIM, L" WriterId = " WSTR_GUID_FMT, GUID_PRINTF_ARG (WriterID));
  246. ft.Trace (VSSDBG_SHIM, L" WriterName = %s", (NULL == wszWriterName) ? L"(NULL)" : wszWriterName);
  247. ft.Trace (VSSDBG_SHIM, L" UsageType = %s", GetStringFromUsageType (ut));
  248. ft.Trace (VSSDBG_SHIM, L" SourceType = %s", GetStringFromSourceType (st));
  249. ft.Trace (VSSDBG_SHIM, L" AppLevel = %s", GetStringFromApplicationLevel (nLevel));
  250. ft.Trace (VSSDBG_SHIM, L" FreezeTimeout = %d (ms)", dwTimeoutFreeze);
  251. ft.Trace (VSSDBG_SHIM, L" AlternateWriterState = %s", GetStringFromAlternateWriterState(aws));
  252. ft.Trace (VSSDBG_SHIM, L" IOThrottlingOnly = %s", bIOThrottlingOnly ? L"True" : L"False");
  253. // The V2 parameters can only be set with default values
  254. if (aws != VSS_AWS_NO_ALTERNATE_WRITER ||
  255. bIOThrottlingOnly != false)
  256. return E_INVALIDARG;
  257. if (ut != VSS_UT_BOOTABLESYSTEMSTATE &&
  258. ut != VSS_UT_SYSTEMSERVICE &&
  259. ut != VSS_UT_USERDATA &&
  260. ut != VSS_UT_OTHER)
  261. return E_INVALIDARG;
  262. // [aoltean] Previous comment was:
  263. // return S_OK for now since there is a bug in the iis writer
  264. // return S_OK;
  265. if (st != VSS_ST_NONTRANSACTEDDB &&
  266. st != VSS_ST_TRANSACTEDDB &&
  267. st != VSS_ST_OTHER)
  268. return E_INVALIDARG;
  269. // [aoltean] Previous comment was:
  270. // return S_OK for now since there is a bug in the IIS writer
  271. // return S_OK;
  272. CVssWriterImpl::CreateWriter(this, &m_pWrapper);
  273. BS_ASSERT(m_pWrapper);
  274. // call Initialize method on core instance
  275. m_pWrapper->Initialize
  276. (
  277. WriterID,
  278. wszWriterName,
  279. ut,
  280. st,
  281. nLevel,
  282. dwTimeoutFreeze
  283. );
  284. }
  285. VSS_STANDARD_CATCH(ft)
  286. return ft.hr;
  287. }
  288. // This function returns S_FALSE when the writer is inactive (setup or safe mode)
  289. __declspec(dllexport)
  290. HRESULT STDMETHODCALLTYPE CVssWriter::Subscribe
  291. (
  292. IN DWORD dwEventFlags
  293. )
  294. {
  295. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::Subscribe");
  296. try
  297. {
  298. ft.Trace (VSSDBG_GEN, L"**** Called CVssWriter::Subscribe(%p) with:", this);
  299. ft.Trace (VSSDBG_GEN, L" dwEventFlags = 0x%08x ", dwEventFlags);
  300. // Only the default parameter setting is supported in V1
  301. if ( dwEventFlags != ( VSS_SM_BACKUP_EVENTS_FLAG | VSS_SM_RESTORE_EVENTS_FLAG ) )
  302. return E_INVALIDARG;
  303. if (m_pWrapper == NULL)
  304. ft.Throw(VSSDBG_GEN, E_FAIL, L"CVssWriter class was not initialized.");
  305. m_pWrapper->Subscribe();
  306. }
  307. VSS_STANDARD_CATCH(ft)
  308. return ft.hr;
  309. }
  310. // This function returns S_FALSE when the writer is inactive (setup or safe mode)
  311. __declspec(dllexport)
  312. HRESULT STDMETHODCALLTYPE CVssWriter::Unsubscribe()
  313. {
  314. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::Unsubscribe");
  315. try
  316. {
  317. if (m_pWrapper == NULL)
  318. ft.Throw(VSSDBG_GEN, E_FAIL, L"CVssWriter class was not initialized.");
  319. ft.Trace (VSSDBG_GEN, L"**** Called CVssWriter::Unsubscribe(%p):", this);
  320. m_pWrapper->Unsubscribe();
  321. }
  322. VSS_STANDARD_CATCH(ft)
  323. return ft.hr;
  324. }
  325. __declspec(dllexport)
  326. HRESULT STDMETHODCALLTYPE CVssWriter::InstallAlternateWriter
  327. (
  328. IN VSS_ID writerId,
  329. IN CLSID persistentWriterClassId
  330. )
  331. {
  332. UNREFERENCED_PARAMETER(writerId);
  333. UNREFERENCED_PARAMETER(persistentWriterClassId);
  334. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::InstallAlternateWriter");
  335. // Not supported in V1
  336. ft.hr = E_NOTIMPL;
  337. return ft.hr;
  338. }
  339. __declspec(dllexport)
  340. LPCWSTR* STDMETHODCALLTYPE CVssWriter::GetCurrentVolumeArray() const
  341. {
  342. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetCurrentVolumeArray");
  343. BS_ASSERT(m_pWrapper);
  344. if (m_pWrapper == NULL)
  345. return NULL;
  346. else
  347. return m_pWrapper->GetCurrentVolumeArray();
  348. }
  349. __declspec(dllexport)
  350. UINT STDMETHODCALLTYPE CVssWriter::GetCurrentVolumeCount() const
  351. {
  352. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetCurrentVolumeCount");
  353. BS_ASSERT(m_pWrapper);
  354. if (m_pWrapper == NULL)
  355. return 0;
  356. else
  357. return m_pWrapper->GetCurrentVolumeCount();
  358. }
  359. __declspec(dllexport)
  360. HRESULT STDMETHODCALLTYPE CVssWriter::GetSnapshotDeviceName
  361. (
  362. IN LPCWSTR wszOriginalVolume,
  363. OUT LPCWSTR* ppwszSnapshotDevice
  364. ) const
  365. {
  366. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetSnapshotDeviceName");
  367. BS_ASSERT(m_pWrapper);
  368. if (m_pWrapper == NULL)
  369. return E_FAIL;
  370. else
  371. return m_pWrapper->GetSnapshotDeviceName(wszOriginalVolume, ppwszSnapshotDevice);
  372. }
  373. __declspec(dllexport)
  374. VSS_ID STDMETHODCALLTYPE CVssWriter::GetCurrentSnapshotSetId() const
  375. {
  376. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetCurrentSnapshotSetId");
  377. BS_ASSERT(m_pWrapper);
  378. if (m_pWrapper == NULL)
  379. return GUID_NULL;
  380. else
  381. return m_pWrapper->GetCurrentSnapshotSetId();
  382. }
  383. __declspec(dllexport)
  384. LONG STDMETHODCALLTYPE CVssWriter::GetContext() const
  385. {
  386. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetContext");
  387. BS_ASSERT(m_pWrapper);
  388. if (m_pWrapper == NULL)
  389. return 0;
  390. else
  391. return m_pWrapper->GetContext();
  392. }
  393. __declspec(dllexport)
  394. VSS_APPLICATION_LEVEL STDMETHODCALLTYPE CVssWriter::GetCurrentLevel() const
  395. {
  396. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetCurrentLevel");
  397. BS_ASSERT(m_pWrapper);
  398. if (m_pWrapper == NULL)
  399. return VSS_APP_AUTO;
  400. else
  401. return m_pWrapper->GetCurrentLevel();
  402. }
  403. __declspec(dllexport)
  404. bool STDMETHODCALLTYPE CVssWriter::IsPathAffected(IN LPCWSTR wszPath) const
  405. {
  406. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::IsPathAffected");
  407. BS_ASSERT(m_pWrapper);
  408. if (m_pWrapper == NULL)
  409. return NULL;
  410. else
  411. return m_pWrapper->IsPathAffected(wszPath);
  412. }
  413. // determine if bootable state is backed up
  414. __declspec(dllexport)
  415. bool STDMETHODCALLTYPE CVssWriter::IsBootableSystemStateBackedUp() const
  416. {
  417. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::IsBootableSystemStateBackedUp");
  418. BS_ASSERT(m_pWrapper);
  419. if (m_pWrapper == NULL)
  420. return false;
  421. else
  422. return m_pWrapper->IsBootableSystemStateBackedUp();
  423. }
  424. // determine if bootable state is backed up
  425. __declspec(dllexport)
  426. bool STDMETHODCALLTYPE CVssWriter::IsPartialFileSupportEnabled() const
  427. {
  428. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::IsPartialFileSupportEnabled");
  429. BS_ASSERT(m_pWrapper);
  430. if (m_pWrapper == NULL)
  431. return false;
  432. else
  433. return m_pWrapper->IsPartialFileSupportEnabled();
  434. }
  435. // determine if the backup application is selecting components
  436. __declspec(dllexport)
  437. bool STDMETHODCALLTYPE CVssWriter::AreComponentsSelected() const
  438. {
  439. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::AreComponentsSelected");
  440. BS_ASSERT(m_pWrapper);
  441. if (m_pWrapper == NULL)
  442. return false;
  443. else
  444. return m_pWrapper->AreComponentsSelected();
  445. }
  446. __declspec(dllexport)
  447. VSS_BACKUP_TYPE STDMETHODCALLTYPE CVssWriter::GetBackupType() const
  448. {
  449. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetBackupType");
  450. BS_ASSERT(m_pWrapper);
  451. if (m_pWrapper == NULL)
  452. return VSS_BT_UNDEFINED;
  453. else
  454. return m_pWrapper->GetBackupType();
  455. }
  456. __declspec(dllexport)
  457. VSS_RESTORE_TYPE STDMETHODCALLTYPE CVssWriter::GetRestoreType() const
  458. {
  459. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::GetBackupType");
  460. BS_ASSERT(m_pWrapper);
  461. if (m_pWrapper == NULL)
  462. return VSS_RTYPE_UNDEFINED;
  463. else
  464. return m_pWrapper->GetRestoreType();
  465. }
  466. __declspec(dllexport)
  467. HRESULT STDMETHODCALLTYPE CVssWriter::SetWriterFailure(IN HRESULT hrStatus)
  468. {
  469. CVssFunctionTracer ft(VSSDBG_GEN, L"CVssWriter::SetWriterFailure");
  470. BS_ASSERT(m_pWrapper);
  471. if (m_pWrapper == NULL)
  472. return VSS_BT_UNDEFINED;
  473. else
  474. return m_pWrapper->SetWriterFailure(hrStatus);
  475. }
  476. // create backup components
  477. //
  478. // Returns:
  479. // S_OK if the operation is successful
  480. // E_INVALIDARG if ppBackup is NULL
  481. // E_ACCESSDENIED if the caller does not have backup privileges or
  482. // is an administrator
  483. __declspec(dllexport)
  484. HRESULT STDAPICALLTYPE CreateVssBackupComponents(IVssBackupComponents **ppBackup)
  485. {
  486. CVssFunctionTracer ft(VSSDBG_XML, L"CreateVssBackupComponents");
  487. try
  488. {
  489. if (ppBackup == NULL)
  490. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output pointer");
  491. *ppBackup = NULL;
  492. if (!IsProcessBackupOperator())
  493. ft.Throw
  494. (
  495. VSSDBG_XML,
  496. E_ACCESSDENIED,
  497. L"The client process is not running under an administrator account or does not have backup privilege enabled"
  498. );
  499. CComObject<CVssBackupComponents> *pvbc;
  500. CComObject<CVssBackupComponents>::CreateInstance(&pvbc);
  501. pvbc->GetUnknown()->AddRef();
  502. *ppBackup = (IVssBackupComponents *) pvbc;
  503. }
  504. VSS_STANDARD_CATCH(ft)
  505. return ft.hr;
  506. }
  507. __declspec(dllexport)
  508. HRESULT STDAPICALLTYPE CreateVssExamineWriterMetadata
  509. (
  510. IN BSTR bstrXML,
  511. OUT IVssExamineWriterMetadata **ppMetadata
  512. )
  513. {
  514. CVssFunctionTracer ft(VSSDBG_GEN, L"CreateVssExamineWriterMetadata");
  515. CVssExamineWriterMetadata *pMetadata = NULL;
  516. try
  517. {
  518. if (ppMetadata == NULL)
  519. ft.Throw(VSSDBG_GEN, E_INVALIDARG, L"NULL output pointer");
  520. *ppMetadata = NULL;
  521. pMetadata = new CVssExamineWriterMetadata;
  522. if (pMetadata == NULL)
  523. ft.Throw(VSSDBG_GEN, E_OUTOFMEMORY, L"Cannot allocate CVssExamineWriterMetadata");
  524. if (!pMetadata->Initialize(bstrXML))
  525. ft.Throw
  526. (
  527. VSSDBG_GEN,
  528. VSS_E_INVALID_XML_DOCUMENT,
  529. L"XML passed to CreateVssExamineWriterMetdata was invalid"
  530. );
  531. *ppMetadata = (IVssExamineWriterMetadata *) pMetadata;
  532. pMetadata->AddRef();
  533. }
  534. VSS_STANDARD_CATCH(ft)
  535. if (ft.HrFailed())
  536. delete pMetadata;
  537. return ft.hr;
  538. }
  539. // create a snapshot set description
  540. //
  541. // Returns:
  542. // S_OK if it is successful
  543. // E_OUTOFMEMORY if memory could not be allocated
  544. __declspec(dllexport)
  545. HRESULT STDAPICALLTYPE CreateVssSnapshotSetDescription
  546. (
  547. VSS_ID idSnapshotSet,
  548. LONG lContext,
  549. OUT IVssSnapshotSetDescription **ppSnapshotSet
  550. )
  551. {
  552. CVssFunctionTracer ft(VSSDBG_XML, L"CreateVssSnapshotSsetDescription");
  553. CVssSnapshotSetDescription *pSnapshotSetTemp = NULL;
  554. try
  555. {
  556. CXMLDocument doc;
  557. if (ppSnapshotSet == NULL)
  558. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output parameter.");
  559. // intialize document with <root><schema></root>
  560. doc.LoadFromXML(g_ComponentMetadataXML);
  561. // find toplevel <root> element
  562. if (!doc.FindElement(x_wszElementRoot, true))
  563. ft.Throw(VSSDBG_XML, VSS_E_INVALID_XML_DOCUMENT, L"Missing root element");
  564. // create BACKUP_COMPONENTS element under <root> element
  565. CXMLNode nodeRoot(doc.GetCurrentNode(), doc.GetInterface());
  566. CXMLNode nodeSnapshotSet = doc.CreateNode
  567. (
  568. x_wszElementSnapshotSetDescription,
  569. NODE_ELEMENT
  570. );
  571. nodeSnapshotSet.SetAttribute(x_wszAttrSnapshotSetId, idSnapshotSet);
  572. nodeSnapshotSet.SetAttribute(x_wszAttrContext, lContext);
  573. nodeSnapshotSet.SetAttribute(x_wszAttrXmlns, x_wszValueXmlns);
  574. CXMLNode nodeToplevel = nodeRoot.InsertNode(nodeSnapshotSet);
  575. doc.SetToplevelNode(nodeSnapshotSet);
  576. pSnapshotSetTemp = new CVssSnapshotSetDescription
  577. (
  578. doc.GetCurrentNode(),
  579. doc.GetInterface()
  580. );
  581. if (pSnapshotSetTemp == NULL)
  582. ft.Throw(VSSDBG_XML, E_OUTOFMEMORY, L"Can't allocate snapshot set description.");
  583. pSnapshotSetTemp->Initialize(ft);
  584. *ppSnapshotSet = (IVssSnapshotSetDescription *) pSnapshotSetTemp;
  585. ((IVssSnapshotSetDescription *) pSnapshotSetTemp)->AddRef();
  586. pSnapshotSetTemp = NULL;
  587. }
  588. VSS_STANDARD_CATCH(ft)
  589. delete pSnapshotSetTemp;
  590. return ft.hr;
  591. }
  592. __declspec(dllexport)
  593. HRESULT STDAPICALLTYPE LoadVssSnapshotSetDescription
  594. (
  595. IN LPCWSTR wszXML,
  596. OUT IVssSnapshotSetDescription **ppSnapshotSet
  597. )
  598. {
  599. CVssFunctionTracer ft(VSSDBG_XML, L"LoadVssSnapshotSetDescription");
  600. try
  601. {
  602. CVssSnapshotSetDescription *pSnapshotSetDescription = new CVssSnapshotSetDescription;
  603. if (pSnapshotSetDescription == NULL)
  604. ft.Throw(VSSDBG_XML, E_OUTOFMEMORY, L"Cannot allocate snapshot set description.");
  605. pSnapshotSetDescription->Initialize(ft);
  606. pSnapshotSetDescription->LoadFromXML(wszXML);
  607. ((IVssSnapshotSetDescription *) pSnapshotSetDescription)->AddRef();
  608. *ppSnapshotSet = (IVssSnapshotSetDescription *) pSnapshotSetDescription;
  609. }
  610. VSS_STANDARD_CATCH(ft)
  611. return ft.hr;
  612. }