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.

640 lines
14 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. vs_wmxml.cxx
  5. Abstract:
  6. Implementation of CVssMetadataHelper class
  7. Brian Berkowitz [brianb] 3/13/2000
  8. TBD:
  9. Add comments.
  10. Revision History:
  11. Name Date Comments
  12. brianb 03/30/2000 Created
  13. --*/
  14. #include "stdafx.hxx"
  15. #include "vs_inc.hxx"
  16. #include "vs_idl.hxx"
  17. #include "vswriter.h"
  18. #include "vsbackup.h"
  19. #include "vs_wmxml.hxx"
  20. #include "vssmsg.h"
  21. #include "rpcdce.h"
  22. ////////////////////////////////////////////////////////////////////////
  23. // Standard foo for file name aliasing. This code block must be after
  24. // all includes of VSS header files.
  25. //
  26. #ifdef VSS_FILE_ALIAS
  27. #undef VSS_FILE_ALIAS
  28. #endif
  29. #define VSS_FILE_ALIAS "BUEHELPC"
  30. //
  31. ////////////////////////////////////////////////////////////////////////
  32. // boolean type string values
  33. static LPCWSTR x_wszYes = L"yes";
  34. static LPCWSTR x_wszNo = L"no";
  35. // usage type string values
  36. static LPCWSTR x_wszBOOTABLESYSTEMSTATE = L"BOOTABLE_SYSTEM_STATE";
  37. static LPCWSTR x_wszSYSTEMSERVICE = L"SYSTEM_SERVICE";
  38. static LPCWSTR x_wszUSERDATA = L"USER_DATA";
  39. static LPCWSTR x_wszOTHER = L"OTHER";
  40. // source type string values
  41. static LPCWSTR x_wszTRANSACTEDDB = L"TRANSACTION_DB";
  42. static LPCWSTR x_wszNONTRANSACTEDDB = L"NONTRANSACTIONAL_DB";
  43. // component ELEMENT type strings
  44. static LPCWSTR x_wszElementDatabase = L"DATABASE";
  45. static LPCWSTR x_wszElementFilegroup = L"FILE_GROUP";
  46. // component value type strings
  47. static LPCWSTR x_wszValueDatabase = L"database";
  48. static LPCWSTR x_wszValueFilegroup = L"filegroup";
  49. // writerRestore value type strings
  50. static LPCWSTR x_wszNever = L"never";
  51. static LPCWSTR x_wszAlways = L"always";
  52. static LPCWSTR x_wszIfReplaceFails = L"ifReplaceFails";
  53. // string restore methods
  54. static LPCWSTR x_wszRESTOREIFNOTTHERE = L"RESTORE_IF_NONE_THERE";
  55. static LPCWSTR x_wszRESTOREIFCANREPLACE = L"RESTORE_IF_CAN_BE_REPLACED";
  56. static LPCWSTR x_wszSTOPRESTORESTART = L"STOP_RESTART_SERVICE";
  57. static LPCWSTR x_wszRESTORETOALTERNATE = L"RESTORE_TO_ALTERNATE_LOCATION";
  58. static LPCWSTR x_wszRESTOREATREBOOT = L"REPLACE_AT_REBOOT";
  59. static LPCWSTR x_wszCUSTOM = L"CUSTOM";
  60. // string backup types
  61. static LPCWSTR x_wszValueFull = L"full";
  62. static LPCWSTR x_wszValueDifferential = L"differential";
  63. static LPCWSTR x_wszValueIncremental = L"incremental";
  64. static LPCWSTR x_wszValueOther = L"other";
  65. // convert boolean value to "yes" or "no"
  66. LPCWSTR CVssMetadataHelper::WszFromBoolean(IN bool b)
  67. {
  68. return b ? x_wszYes : x_wszNo;
  69. }
  70. // convert from "yes", "no" to a boolean value
  71. bool CVssMetadataHelper::ConvertToBoolean
  72. (
  73. IN CVssFunctionTracer &ft,
  74. IN BSTR bstr
  75. ) throw(HRESULT)
  76. {
  77. if (wcscmp(bstr, x_wszYes) == 0)
  78. return true;
  79. else if (wcscmp(bstr, x_wszNo) == 0)
  80. return false;
  81. else
  82. ft.Throw
  83. (
  84. VSSDBG_XML,
  85. E_INVALIDARG,
  86. L"Value %s is neither yes nor no.",
  87. bstr
  88. );
  89. return false;
  90. }
  91. // convert a string to a VSS_ID value
  92. void CVssMetadataHelper::ConvertToVSS_ID
  93. (
  94. IN CVssFunctionTracer &ft,
  95. IN BSTR bstr,
  96. OUT VSS_ID *pId
  97. ) throw(HRESULT)
  98. {
  99. RPC_STATUS status = UuidFromString(bstr, pId);
  100. if (status != RPC_S_OK)
  101. ft.Throw
  102. (
  103. VSSDBG_XML,
  104. E_INVALIDARG,
  105. L"Value %s is not a valid guid.",
  106. bstr
  107. );
  108. }
  109. // convert from VSS_USAGE_TYPE to string value
  110. LPCWSTR CVssMetadataHelper::WszFromUsageType
  111. (
  112. IN CVssFunctionTracer &ft,
  113. IN VSS_USAGE_TYPE usage
  114. ) throw(HRESULT)
  115. {
  116. switch(usage)
  117. {
  118. default:
  119. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid usage type");
  120. case VSS_UT_OTHER:
  121. return(x_wszOTHER);
  122. case VSS_UT_BOOTABLESYSTEMSTATE:
  123. return(x_wszBOOTABLESYSTEMSTATE);
  124. case VSS_UT_SYSTEMSERVICE:
  125. return(x_wszSYSTEMSERVICE);
  126. case VSS_UT_USERDATA:
  127. return(x_wszUSERDATA);
  128. }
  129. }
  130. // convert from string to VSS_USAGE_TYPE
  131. VSS_USAGE_TYPE CVssMetadataHelper::ConvertToUsageType
  132. (
  133. IN CVssFunctionTracer &ft,
  134. IN BSTR bstr
  135. ) throw(HRESULT)
  136. {
  137. if (wcscmp(bstr, x_wszBOOTABLESYSTEMSTATE) == 0)
  138. return(VSS_UT_BOOTABLESYSTEMSTATE);
  139. else if (wcscmp(bstr, x_wszSYSTEMSERVICE) == 0)
  140. return(VSS_UT_SYSTEMSERVICE);
  141. else if (wcscmp(bstr, x_wszUSERDATA) == 0)
  142. return(VSS_UT_USERDATA);
  143. else if (wcscmp(bstr, x_wszOTHER) == 0)
  144. return(VSS_UT_OTHER);
  145. else
  146. ft.Throw
  147. (
  148. VSSDBG_XML,
  149. E_INVALIDARG,
  150. L"The string %s is not a valid usage type",
  151. bstr
  152. );
  153. return VSS_UT_UNDEFINED;
  154. }
  155. // convert from a VSS_SOURCE_TYPE value to a string
  156. LPCWSTR CVssMetadataHelper::WszFromSourceType
  157. (
  158. IN CVssFunctionTracer &ft,
  159. IN VSS_SOURCE_TYPE source
  160. ) throw(HRESULT)
  161. {
  162. switch(source)
  163. {
  164. default:
  165. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid data source type");
  166. case VSS_ST_OTHER:
  167. return(x_wszOTHER);
  168. case VSS_ST_TRANSACTEDDB:
  169. return(x_wszTRANSACTEDDB);
  170. case VSS_ST_NONTRANSACTEDDB:
  171. return(x_wszNONTRANSACTEDDB);
  172. }
  173. }
  174. // convert from a string to a VSS_SOURCE_TYPE value
  175. VSS_SOURCE_TYPE CVssMetadataHelper::ConvertToSourceType
  176. (
  177. IN CVssFunctionTracer &ft,
  178. IN BSTR bstr
  179. )
  180. {
  181. if (wcscmp(bstr, x_wszTRANSACTEDDB) == 0)
  182. return(VSS_ST_TRANSACTEDDB);
  183. else if (wcscmp(bstr, x_wszNONTRANSACTEDDB) == 0)
  184. return(VSS_ST_NONTRANSACTEDDB);
  185. else if (wcscmp(bstr, x_wszOTHER) == 0)
  186. return(VSS_ST_OTHER);
  187. else
  188. ft.Throw
  189. (
  190. VSSDBG_XML,
  191. E_INVALIDARG,
  192. L"The string %s is not a valid source type.",
  193. bstr
  194. );
  195. return VSS_ST_UNDEFINED;
  196. }
  197. // convert from VSS_COMPONENT_TYPE to string value
  198. LPCWSTR CVssMetadataHelper::WszFromComponentType
  199. (
  200. IN CVssFunctionTracer &ft,
  201. VSS_COMPONENT_TYPE ct,
  202. bool bValue
  203. ) throw(HRESULT)
  204. {
  205. switch(ct)
  206. {
  207. default:
  208. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid component type");
  209. case VSS_CT_DATABASE:
  210. return (bValue ? x_wszValueDatabase : x_wszElementDatabase);
  211. case VSS_CT_FILEGROUP:
  212. return(bValue ? x_wszValueDatabase : x_wszElementFilegroup);
  213. }
  214. }
  215. // convert from string value to VSS_COMPONENT_TYPE
  216. VSS_COMPONENT_TYPE CVssMetadataHelper::ConvertToComponentType
  217. (
  218. IN CVssFunctionTracer &ft,
  219. IN BSTR bstrName,
  220. bool bValue
  221. )
  222. {
  223. LPCWSTR wszDatabase = bValue ? x_wszValueDatabase : x_wszElementDatabase;
  224. LPCWSTR wszFilegroup = bValue ? x_wszValueFilegroup : x_wszElementFilegroup;
  225. if (wcscmp(bstrName, wszDatabase) == 0)
  226. return VSS_CT_DATABASE;
  227. else if (wcscmp(bstrName, wszFilegroup) == 0)
  228. return VSS_CT_FILEGROUP;
  229. else
  230. ft.Throw
  231. (
  232. VSSDBG_XML,
  233. E_INVALIDARG,
  234. L"The string %s is not a valid component type",
  235. bstrName
  236. );
  237. return VSS_CT_UNDEFINED;
  238. }
  239. // convert from restore method to string
  240. LPCWSTR CVssMetadataHelper::WszFromRestoreMethod
  241. (
  242. IN CVssFunctionTracer &ft,
  243. IN VSS_RESTOREMETHOD_ENUM method
  244. )
  245. {
  246. switch(method)
  247. {
  248. default:
  249. ft.Throw
  250. (
  251. VSSDBG_XML,
  252. E_INVALIDARG,
  253. L"Invalid method type %d",
  254. method
  255. );
  256. case VSS_RME_RESTORE_IF_NOT_THERE:
  257. return (x_wszRESTOREIFNOTTHERE);
  258. case VSS_RME_RESTORE_IF_CAN_REPLACE:
  259. return(x_wszRESTOREIFCANREPLACE);
  260. case VSS_RME_STOP_RESTORE_START:
  261. return(x_wszSTOPRESTORESTART);
  262. case VSS_RME_RESTORE_TO_ALTERNATE_LOCATION:
  263. return(x_wszRESTORETOALTERNATE);
  264. case VSS_RME_RESTORE_AT_REBOOT:
  265. return(x_wszRESTOREATREBOOT);
  266. case VSS_RME_CUSTOM:
  267. return(x_wszCUSTOM);
  268. }
  269. }
  270. // convert from string to VSS_RESTOREMETHOD_ENUM
  271. VSS_RESTOREMETHOD_ENUM CVssMetadataHelper::ConvertToRestoreMethod
  272. (
  273. IN CVssFunctionTracer &ft,
  274. IN BSTR bstr
  275. )
  276. {
  277. if (wcscmp(bstr, x_wszRESTOREIFNOTTHERE) == 0)
  278. return(VSS_RME_RESTORE_IF_NOT_THERE);
  279. else if (wcscmp(bstr, x_wszRESTOREIFCANREPLACE) == 0)
  280. return(VSS_RME_RESTORE_IF_CAN_REPLACE);
  281. else if (wcscmp(bstr, x_wszSTOPRESTORESTART) == 0)
  282. return(VSS_RME_STOP_RESTORE_START);
  283. else if (wcscmp(bstr, x_wszRESTORETOALTERNATE) == 0)
  284. return(VSS_RME_RESTORE_TO_ALTERNATE_LOCATION);
  285. else if (wcscmp(bstr, x_wszRESTOREATREBOOT) == 0)
  286. return(VSS_RME_RESTORE_AT_REBOOT);
  287. else if (wcscmp(bstr, x_wszCUSTOM) == 0)
  288. return(VSS_RME_CUSTOM);
  289. else
  290. ft.Throw
  291. (
  292. VSSDBG_XML,
  293. E_INVALIDARG,
  294. L"The string %s is not a valid restore method.",
  295. bstr
  296. );
  297. return VSS_RME_UNDEFINED;
  298. }
  299. // convert from restore method to string
  300. LPCWSTR CVssMetadataHelper::WszFromWriterRestore
  301. (
  302. IN CVssFunctionTracer &ft,
  303. IN VSS_WRITERRESTORE_ENUM method
  304. )
  305. {
  306. switch(method)
  307. {
  308. default:
  309. ft.Throw
  310. (
  311. VSSDBG_XML,
  312. E_INVALIDARG,
  313. L"Invalid writerRestore type %d",
  314. method
  315. );
  316. case VSS_WRE_NEVER:
  317. return x_wszNever;
  318. case VSS_WRE_IF_REPLACE_FAILS:
  319. return x_wszIfReplaceFails;
  320. case VSS_WRE_ALWAYS:
  321. return x_wszAlways;
  322. }
  323. }
  324. // convert from string to VSS_RESTOREMETHOD_ENUM
  325. VSS_WRITERRESTORE_ENUM CVssMetadataHelper::ConvertToWriterRestore
  326. (
  327. IN CVssFunctionTracer &ft,
  328. IN BSTR bstr
  329. )
  330. {
  331. if (wcscmp(bstr, x_wszNever) == 0)
  332. return VSS_WRE_NEVER;
  333. else if (wcscmp(bstr, x_wszIfReplaceFails) == 0)
  334. return VSS_WRE_IF_REPLACE_FAILS;
  335. else if (wcscmp(bstr, x_wszAlways) == 0)
  336. return VSS_WRE_ALWAYS;
  337. else
  338. ft.Throw
  339. (
  340. VSSDBG_XML,
  341. E_INVALIDARG,
  342. L"The string %s is not a valid restore method.",
  343. bstr
  344. );
  345. return VSS_WRE_UNDEFINED;
  346. }
  347. // convert VSS_BACKUP_TYPE to string
  348. LPCWSTR CVssMetadataHelper::WszFromBackupType
  349. (
  350. IN CVssFunctionTracer &ft,
  351. IN VSS_BACKUP_TYPE bt
  352. )
  353. {
  354. switch(bt)
  355. {
  356. default:
  357. ft.Throw
  358. (
  359. VSSDBG_XML,
  360. E_INVALIDARG,
  361. L"Invalid backupType %d",
  362. bt
  363. );
  364. case VSS_BT_INCREMENTAL:
  365. return x_wszValueIncremental;
  366. case VSS_BT_DIFFERENTIAL:
  367. return x_wszValueDifferential;
  368. case VSS_BT_FULL:
  369. return x_wszValueFull;
  370. case VSS_BT_OTHER:
  371. return x_wszValueOther;
  372. }
  373. }
  374. // convert from string to backup type
  375. VSS_BACKUP_TYPE CVssMetadataHelper::ConvertToBackupType
  376. (
  377. IN CVssFunctionTracer &ft,
  378. IN BSTR bstr
  379. )
  380. {
  381. if (wcscmp(bstr, x_wszValueIncremental) == 0)
  382. return VSS_BT_INCREMENTAL;
  383. else if (wcscmp(bstr, x_wszValueDifferential) == 0)
  384. return VSS_BT_DIFFERENTIAL;
  385. else if (wcscmp(bstr, x_wszValueFull) == 0)
  386. return VSS_BT_FULL;
  387. else if (wcscmp(bstr, x_wszValueOther) == 0)
  388. return VSS_BT_OTHER;
  389. else
  390. ft.Throw
  391. (
  392. VSSDBG_XML,
  393. E_INVALIDARG,
  394. L"The string %s is not a valid backup type.",
  395. bstr
  396. );
  397. return VSS_BT_UNDEFINED;
  398. }
  399. // obtain the value of a string valued attribute. Returns S_FALSE if
  400. // attribute doesn't exist
  401. HRESULT CVssMetadataHelper::GetStringAttributeValue
  402. (
  403. IN CVssFunctionTracer &ft,
  404. IN LPCWSTR wszAttrName,
  405. IN bool bRequired,
  406. OUT BSTR *pbstrValue
  407. )
  408. {
  409. try
  410. {
  411. // check output parameter
  412. if (pbstrValue == NULL)
  413. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output pointer");
  414. // null output parameter
  415. *pbstrValue = NULL;
  416. // find attribute value
  417. if (m_doc.FindAttribute(wszAttrName, pbstrValue))
  418. return S_OK;
  419. else
  420. {
  421. if (bRequired)
  422. MissingAttribute(ft, wszAttrName);
  423. else
  424. return S_FALSE;
  425. }
  426. }
  427. VSS_STANDARD_CATCH(ft)
  428. return ft.hr;
  429. }
  430. // obtain the value of a boolean ("yes", "no") attribute. Return S_FALSE if
  431. // attribute is not assigned a value.
  432. HRESULT CVssMetadataHelper::GetBooleanAttributeValue
  433. (
  434. IN CVssFunctionTracer &ft,
  435. IN LPCWSTR wszAttrName,
  436. IN bool bRequired,
  437. OUT bool *pbValue
  438. )
  439. {
  440. try
  441. {
  442. // check output parameter
  443. if (pbValue == NULL)
  444. ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output pointer");
  445. // initialize output paramter
  446. *pbValue = false;
  447. CComBSTR bstrVal = NULL;
  448. // obtain string value of attribute
  449. if (!m_doc.FindAttribute(wszAttrName, &bstrVal))
  450. {
  451. if (bRequired)
  452. MissingAttribute(ft, wszAttrName);
  453. else
  454. return S_FALSE;
  455. }
  456. // convert attribute to a boolean value
  457. *pbValue = ConvertToBoolean(ft, bstrVal);
  458. return S_OK;
  459. }
  460. VSS_STANDARD_CATCH(ft)
  461. return ft.hr;
  462. }
  463. bool CVssMetadataHelper::get_stringValue
  464. (
  465. IN LPCWSTR wszAttrName,
  466. OUT BSTR *pbstrValue
  467. )
  468. {
  469. // iniitialize value to null
  470. *pbstrValue = NULL;
  471. // obtain string value if exists
  472. return m_doc.FindAttribute(wszAttrName, pbstrValue);
  473. }
  474. void CVssMetadataHelper::get_VSS_IDValue
  475. (
  476. IN CVssFunctionTracer &ft,
  477. IN LPCWSTR wszAttrName,
  478. OUT VSS_ID *pidValue
  479. ) throw(HRESULT)
  480. {
  481. // initialize id value to GUID_NULL
  482. *pidValue = GUID_NULL;
  483. CComBSTR bstrVal = NULL;
  484. // obtain string value if it exists and convert it to GUID
  485. if (m_doc.FindAttribute(wszAttrName, &bstrVal))
  486. ConvertToVSS_ID(ft, bstrVal, pidValue);
  487. else
  488. MissingAttribute(ft, wszAttrName);
  489. }
  490. bool CVssMetadataHelper::get_boolValue
  491. (
  492. IN CVssFunctionTracer &ft,
  493. IN LPCWSTR wszAttrName,
  494. OUT bool *pb
  495. )
  496. {
  497. // initialize boolean value
  498. *pb = FALSE;
  499. CComBSTR bstrVal = NULL;
  500. // find attribute if it exists and convert its value to a boolean
  501. if (!m_doc.FindAttribute( wszAttrName, &bstrVal))
  502. return false;
  503. *pb = ConvertToBoolean(ft, bstrVal);
  504. return true;
  505. }
  506. void CVssMetadataHelper::MissingElement
  507. (
  508. IN CVssFunctionTracer &ft,
  509. IN LPCWSTR wszElement
  510. )
  511. {
  512. ft.LogError(VSS_ERROR_CORRUPTXMLDOCUMENT_MISSING_ELEMENT, VSSDBG_XML << wszElement);
  513. ft.Throw
  514. (
  515. VSSDBG_XML,
  516. VSS_E_CORRUPT_XML_DOCUMENT,
  517. L"The %s element is missing.",
  518. wszElement
  519. );
  520. }
  521. void CVssMetadataHelper::MissingAttribute
  522. (
  523. IN CVssFunctionTracer &ft,
  524. IN LPCWSTR wszAttribute
  525. )
  526. {
  527. ft.LogError(VSS_ERROR_CORRUPTXMLDOCUMENT_MISSING_ATTRIBUTE, VSSDBG_XML << wszAttribute);
  528. ft.Throw
  529. (
  530. VSSDBG_XML,
  531. VSS_E_CORRUPT_XML_DOCUMENT,
  532. L"The %s attribute is missing.",
  533. wszAttribute
  534. );
  535. }