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.

443 lines
13 KiB

  1. /*
  2. **++
  3. **
  4. ** Copyright (c) 2002 Microsoft Corporation
  5. **
  6. **
  7. ** Module Name:
  8. **
  9. ** writerconfig.cpp
  10. **
  11. **
  12. ** Abstract:
  13. **
  14. ** defines classes that encapsulate the Test writer's configuration
  15. **
  16. ** Author:
  17. **
  18. ** Reuven Lax [reuvenl] 04-June-2002
  19. **
  20. **
  21. **
  22. ** Revision History:
  23. **
  24. **--
  25. */
  26. ////////////////////////////////////////////////////////////////////////
  27. // Includes
  28. #include "stdafx.h"
  29. #include "writerconfig.h"
  30. #include "vs_xml.hxx"
  31. #include "msxml2.h"
  32. #include <string>
  33. #include <sstream>
  34. #include <algorithm>
  35. ////////////////////////////////////////////////////////////////////////
  36. // Declarations
  37. using Utility::checkReturn;
  38. using Utility::AutoCS;
  39. using std::wstring;
  40. using std::wstringstream;
  41. namespace XMLData {
  42. // names of attributes and elements
  43. wchar_t Name[] =L"name";
  44. wchar_t Xmlns[] = L"xmlns";
  45. wchar_t SchemaPointer[] = L"x-schema:#VssTestWriterConfig";
  46. wchar_t RootStart[] = L"<root>";
  47. wchar_t RootEnd[] = L"</root>\n";
  48. wchar_t Root[] = L"root";
  49. wchar_t TestWriter[] = L"TestWriter";
  50. wchar_t Verbosity[] = L"verbosity";
  51. wchar_t CheckExcludes[] = L"checkExcludes";
  52. wchar_t CheckIncludes[] = L"checkIncludes";
  53. wchar_t Path[] = L"path";
  54. wchar_t Filespec[] = L"filespec";
  55. wchar_t Recursive[] = L"recursive";
  56. wchar_t AlternatePath[] = L"alternatePath";
  57. wchar_t Usage[] = L"usage";
  58. wchar_t RestoreMethod[] = L"RestoreMethod";
  59. wchar_t Method[] = L"method";
  60. wchar_t WriterRestore[] = L"writerRestore";
  61. wchar_t Service[] = L"service";
  62. wchar_t RebootRequired[] = L"rebootRequired";
  63. wchar_t AlternateLocationMapping[] = L"AlternateLocationMapping";
  64. wchar_t Component[] = L"Component";
  65. wchar_t ComponentType[] = L"componentType";
  66. wchar_t LogicalPath[] = L"logicalPath";
  67. wchar_t Selectable[] = L"selectable";
  68. wchar_t SelectableForRestore[] = L"selectableForRestore";
  69. wchar_t ComponentName[] = L"componentName";
  70. wchar_t ComponentFile[] = L"ComponentFile";
  71. wchar_t Dependency[] = L"Dependency";
  72. wchar_t WriterId[] = L"writerId";
  73. wchar_t ExcludeFile[] = L"ExcludeFile";
  74. wchar_t RestoreTarget[] = L"restoreTarget";
  75. wchar_t NewTarget[] = L"NewTarget";
  76. wchar_t FailEvent[] = L"FailEvent";
  77. wchar_t WriterEvent[] = L"writerEvent";
  78. wchar_t Retryable[] = L"retryable";
  79. wchar_t NumFailures[] = L"numFailures";
  80. // string containing the Test writer schema
  81. #include "schema.h"
  82. }
  83. ////////////////////////////////////////////////////////////////////////
  84. // Implementation for the File struct
  85. File::File(CXMLDocument node)
  86. {
  87. // read the attributes from the document and store in the structure
  88. CComBSTR path;
  89. if (!node.FindAttribute(XMLData::Path, &path))
  90. missingAttribute(XMLData::Path);
  91. CComBSTR filespec;
  92. if (!node.FindAttribute(XMLData::Filespec, &filespec))
  93. missingAttribute(XMLData::Filespec);
  94. CComBSTR recursive;
  95. if (!node.FindAttribute(XMLData::Recursive, &recursive))
  96. missingAttribute(XMLData::Recursive);
  97. m_path = (BSTR)path;
  98. std::transform(m_path.begin(), m_path.end(), m_path.begin(), towupper);
  99. m_filespec = (BSTR)filespec;
  100. std::transform(m_filespec.begin(), m_filespec.end(), m_filespec.begin(), towupper);
  101. // path and filespec should never be empty.
  102. if (m_path.empty())
  103. throw Utility::TestWriterException(L"File specification has empty path");
  104. if (m_filespec.empty())
  105. throw Utility::TestWriterException(L"File specification has empty filespec");
  106. if (m_path[m_path.size() -1] != L'\\')
  107. m_path += L'\\';
  108. m_recursive = Utility::toBoolean(recursive);
  109. }
  110. wstring File::toString() const
  111. {
  112. wstringstream msg;
  113. msg << L"Path: " << m_path << std::endl <<
  114. L"Filespec: " << m_filespec << std::endl <<
  115. L"Recursive: " << Utility::toString(m_recursive);
  116. return msg.str();
  117. }
  118. ////////////////////////////////////////////////////////////////////////
  119. // Implementation for the TargetedFile struct
  120. TargetedFile::TargetedFile(CXMLDocument node) : File(node)
  121. {
  122. // read the alternatePath attribute and store it
  123. CComBSTR alternatePath;
  124. if (!node.FindAttribute(XMLData::AlternatePath, &alternatePath))
  125. return;
  126. assert(alternatePath);
  127. m_alternatePath = (BSTR)alternatePath;
  128. std::transform(m_alternatePath.begin(), m_alternatePath.end(), m_alternatePath.begin(), towupper);
  129. if (m_alternatePath.empty())
  130. throw Utility::TestWriterException(L"File specification has empty alternate path");
  131. if (m_alternatePath[m_alternatePath.size()-1] != L'\\')
  132. m_alternatePath += L'\\';
  133. }
  134. wstring TargetedFile::toString() const
  135. {
  136. wstringstream msg;
  137. msg << File::toString() << std::endl <<
  138. L"AlternatePath: " << m_alternatePath;
  139. return msg.str();
  140. }
  141. ////////////////////////////////////////////////////////////////////////
  142. // Implementation for the RestoreMethod struct
  143. RestoreMethod::RestoreMethod(CXMLDocument node)
  144. {
  145. node.SetToplevel();
  146. CComBSTR method, writerRestore, service, rebootRequired;
  147. // read attributes and elements from document
  148. if (!node.FindAttribute(XMLData::Method, &method))
  149. missingAttribute(XMLData::Method);
  150. if (!node.FindAttribute(XMLData::WriterRestore, &writerRestore))
  151. missingAttribute(XMLData::WriterRestore);
  152. node.FindAttribute(XMLData::Service, &service);
  153. if(!node.FindAttribute(XMLData::RebootRequired, &rebootRequired))
  154. missingAttribute(XMLData::RebootRequired);
  155. if (node.FindElement(XMLData::AlternateLocationMapping, true))
  156. m_alternateLocations = AlternateList(node);
  157. m_method = Utility::toMethod(method);
  158. m_writerRestore = Utility::toWriterRestore(writerRestore);
  159. m_service = (service.Length() > 0) ? service : L"";
  160. m_rebootRequired = Utility::toBoolean(rebootRequired);
  161. }
  162. wstring RestoreMethod::toString() const
  163. {
  164. wstringstream msg;
  165. msg << L"method: " << Utility::toString(m_method) << std::endl <<
  166. L"service: " << m_service << std::endl <<
  167. L"writerRestore: " << Utility::toString(m_writerRestore) << std::endl <<
  168. L"reboot: " << Utility::toString(m_rebootRequired);
  169. return msg.str();
  170. }
  171. ////////////////////////////////////////////////////////////////////////
  172. // Implementation for the Dependency struct
  173. Dependency::Dependency(CXMLDocument node)
  174. {
  175. node.SetToplevel();
  176. CComBSTR logicalPath, componentName, writerId;
  177. if(!node.FindAttribute(XMLData::WriterId, &writerId))
  178. missingAttribute(XMLData::WriterId);
  179. node.FindAttribute(XMLData::LogicalPath, &logicalPath);
  180. if(!node.FindAttribute(XMLData::ComponentName, &componentName))
  181. missingAttribute(XMLData::ComponentName);
  182. HRESULT hr = ::UuidFromString(writerId, &m_writerId);
  183. checkReturn(hr, L"CLSIDFromString");
  184. m_logicalPath = (logicalPath.Length() > 0) ? logicalPath : L"";
  185. m_componentName = componentName;
  186. }
  187. wstring Dependency::toString() const
  188. {
  189. wstringstream msg;
  190. msg << L"WriterId: " << (wchar_t*)CComBSTR(m_writerId) << std::endl <<
  191. L"Logical Path: " << m_logicalPath << std::endl <<
  192. L"Component Name: " << m_componentName;
  193. return msg.str();
  194. }
  195. ////////////////////////////////////////////////////////////////////////
  196. // Implementation for the Component struct
  197. Component::Component(CXMLDocument node)
  198. {
  199. node.SetToplevel();
  200. CComBSTR componentType, restoreTarget, logicalPath, name, selectable,
  201. selectableForRestore;
  202. // read attributes from document and store them
  203. if (!node.FindAttribute(XMLData::ComponentType, &componentType))
  204. missingAttribute(XMLData::ComponentType);
  205. node.FindAttribute(XMLData::RestoreTarget, &restoreTarget);
  206. node.FindAttribute(XMLData::LogicalPath, &logicalPath);
  207. if (!node.FindAttribute(XMLData::ComponentName, &name))
  208. missingAttribute(XMLData::ComponentName);
  209. if (!node.FindAttribute(XMLData::Selectable, &selectable))
  210. missingAttribute(XMLData::Selectable);
  211. if (!node.FindAttribute(XMLData::SelectableForRestore, &selectableForRestore))
  212. missingAttribute(XMLData::SelectableForRestore);
  213. m_componentType = Utility::toComponentType(componentType);
  214. m_restoreTarget = (restoreTarget.Length() > 0) ? Utility::toRestoreTarget(restoreTarget) : VSS_RT_UNDEFINED;
  215. m_logicalPath = (logicalPath.Length() > 0) ? logicalPath : L"";
  216. m_selectable = Utility::toBoolean(selectable);
  217. m_selectableForRestore = Utility::toBoolean(selectableForRestore);
  218. m_name = name;
  219. if (m_name.empty())
  220. throw Utility::TestWriterException(L"Component has empty name");
  221. // read elements from document and store them
  222. if (node.FindElement(XMLData::ComponentFile, true))
  223. m_files = ComponentFileList(node);
  224. node.ResetToDocument();
  225. if (node.FindElement(XMLData::Dependency, true))
  226. m_dependencies = DependencyList(node);
  227. }
  228. wstring ComponentBase::toString() const
  229. {
  230. wstringstream msg;
  231. msg << L"Logical Path: " << m_logicalPath << std::endl <<
  232. L"Name: " << m_name << std::endl;
  233. return msg.str();
  234. }
  235. // comparison operations for writer components
  236. bool operator==(const ComponentBase& left, const ComponentBase& right)
  237. {
  238. return (left.m_name == right.m_name) &&
  239. (left.m_logicalPath == right.m_logicalPath);
  240. }
  241. bool operator!=(const ComponentBase& left, const ComponentBase& right)
  242. {
  243. return !(left == right);
  244. }
  245. bool operator==(const Component& left, const Component& right)
  246. {
  247. return ((ComponentBase&)left == (ComponentBase&)right) &&
  248. (left.m_componentType == right.m_componentType) &&
  249. (left.m_restoreTarget == right.m_restoreTarget) &&
  250. (left.m_selectable == right.m_selectable) &&
  251. (left.m_selectableForRestore == right.m_selectableForRestore) &&
  252. (left.m_files == right.m_files) &&
  253. (left.m_newTargets == right.m_newTargets);
  254. }
  255. bool operator!=(const Component& left, const Component& right)
  256. {
  257. return !(left == right);
  258. }
  259. ////////////////////////////////////////////////////////////////////////
  260. // Implementation for the WriterEvent struct
  261. WriterEvent::WriterEvent(CXMLDocument node)
  262. {
  263. CComBSTR event;
  264. if (!node.FindAttribute(XMLData::WriterEvent, &event))
  265. missingAttribute(XMLData::WriterEvent);
  266. CComBSTR retryable;
  267. if (!node.FindAttribute(XMLData::Retryable, &retryable))
  268. missingAttribute(XMLData::Retryable);
  269. CComBSTR numFailures;
  270. if (!node.FindAttribute(XMLData::NumFailures, &numFailures))
  271. missingAttribute(XMLData::NumFailures);
  272. m_writerEvent = Utility::toWriterEvent(event);
  273. m_retryable = Utility::toBoolean(retryable);
  274. m_numFailures = Utility::toLong(numFailures);
  275. }
  276. ////////////////////////////////////////////////////////////////////////
  277. // Implementation for the WriterConfiguration class
  278. // load configuration from the XML file
  279. void WriterConfiguration::loadFromXML(const wstring& xml)
  280. {
  281. AutoCS critical(m_section);
  282. // load the document from the XML string
  283. wstring xmlString = XMLData::RootStart;
  284. xmlString += XMLData::Schema;
  285. xmlString += xml;
  286. xmlString += XMLData::RootEnd;
  287. // load twice so we can do schema validation the second time
  288. for (int x = 0; x < 2; x++) {
  289. if (!m_doc.LoadFromXML(const_cast<wchar_t*> (xmlString.c_str())))
  290. Utility::parseError(m_doc);
  291. // --- skip to the part of the document we care about
  292. if (!m_doc.FindElement(XMLData::Root, true))
  293. missingElement(XMLData::Root);
  294. if (!m_doc.FindElement(XMLData::TestWriter, true))
  295. missingElement(XMLData::TestWriter);
  296. // --- set the schema namespace
  297. if (x == 0) {
  298. CXMLNode testNode(m_doc.GetCurrentNode(), m_doc.GetInterface());
  299. testNode.SetAttribute(XMLData::Xmlns, XMLData::SchemaPointer);
  300. xmlString = m_doc.SaveAsXML();
  301. }
  302. }
  303. m_doc.SetToplevel();
  304. }
  305. VSS_USAGE_TYPE WriterConfiguration::usage() const
  306. {
  307. assert(m_doc.GetLevel() == 0);
  308. AutoCS critical(m_section);
  309. Resetter reset(m_doc);
  310. CComBSTR value;
  311. if (!m_doc.FindAttribute(XMLData::Usage, &value))
  312. missingAttribute(XMLData::Usage);
  313. return Utility::toUsage(value);
  314. }
  315. Utility::Verbosity WriterConfiguration::verbosity() const
  316. {
  317. assert(m_doc.GetLevel() == 0);
  318. AutoCS critical(m_section);
  319. Resetter reset(m_doc);
  320. CComBSTR value;
  321. if (!m_doc.FindAttribute(XMLData::Verbosity, &value))
  322. missingAttribute(XMLData::Verbosity);
  323. return Utility::toVerbosity(value);
  324. }
  325. bool WriterConfiguration::checkExcludes() const
  326. {
  327. assert(m_doc.GetLevel() == 0);
  328. AutoCS critical(m_section);
  329. Resetter reset(m_doc);
  330. CComBSTR value;
  331. if (!m_doc.FindAttribute(XMLData::CheckExcludes, &value))
  332. missingAttribute(XMLData::CheckExcludes);
  333. return Utility::toBoolean(value);
  334. }
  335. bool WriterConfiguration::checkIncludes() const
  336. {
  337. assert(m_doc.GetLevel() == 0);
  338. AutoCS critical(m_section);
  339. Resetter reset(m_doc);
  340. CComBSTR value;
  341. if (!m_doc.FindAttribute(XMLData::CheckIncludes, &value))
  342. missingAttribute(XMLData::CheckIncludes);
  343. return Utility::toBoolean(value);
  344. }
  345. // get the writer's restore method
  346. RestoreMethod WriterConfiguration::restoreMethod() const
  347. {
  348. assert(m_doc.GetLevel() == 0);
  349. AutoCS critical(m_section);
  350. Resetter reset(m_doc);
  351. if (!m_doc.FindElement(XMLData::RestoreMethod, true))
  352. missingElement(XMLData::RestoreMethod);
  353. return RestoreMethod(m_doc);
  354. }