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.

344 lines
8.0 KiB

  1. #ifndef __SECTION_H_
  2. #define __SECTION_H_
  3. #include <windows.h>
  4. #include <vector>
  5. #include <string>
  6. #include <map>
  7. #include <iostream>
  8. extern "C" {
  9. #include <compliance.h>
  10. }
  11. using namespace std;
  12. class ComplianceFile;
  13. //
  14. // This class represents a section in the compliance
  15. // data file
  16. //
  17. class Section {
  18. public:
  19. Section(const string &name, const vector<string>& lines,
  20. const ComplianceFile& file) : m_file(file) {
  21. m_name = name;
  22. m_lines = lines;
  23. }
  24. Section(const Section& rhs) : m_file(rhs.m_file){
  25. *this = rhs;
  26. }
  27. virtual ~Section() {}
  28. //
  29. // accessors
  30. //
  31. const string& name() const { return m_name; }
  32. const vector<string>& lines() const { return m_lines; }
  33. const ComplianceFile& file() const{ return m_file; }
  34. //
  35. // parses the section content
  36. //
  37. virtual void parse() {}
  38. //
  39. // exceptions which methods of this class
  40. // can throw
  41. //
  42. struct SectionException {
  43. SectionException(const string& sectionName) : m_name(sectionName) {}
  44. string m_name;
  45. friend ostream& operator<<(ostream& os, const struct SectionException& rhs) {
  46. os << "Exception : Section Error : " << rhs.m_name;
  47. return os;
  48. }
  49. };
  50. struct InvalidSectionFormat : public SectionException {
  51. InvalidSectionFormat(const string& sectionName) : SectionException(sectionName) {}
  52. friend ostream& operator<<(ostream& os, const struct InvalidSectionFormat& rhs) {
  53. os << "Exception : Invalid Section Format : " << rhs.m_name;
  54. return os;
  55. }
  56. };
  57. struct InvalidSectionName : public SectionException {
  58. InvalidSectionName(const string &sectionName) : SectionException(sectionName) {}
  59. friend ostream& operator<<(ostream& os, const struct InvalidSectionName &rhs) {
  60. os << "Exception : Invalid Section Name : " << rhs.m_name;
  61. return os;
  62. }
  63. };
  64. struct InvalidMedia : public SectionException {
  65. InvalidMedia(const string &sectionName) : SectionException(sectionName) {}
  66. friend ostream& operator<<(ostream& os, const struct InvalidMedia &rhs) {
  67. os << "Exception : Invalid Media : " << rhs.m_name;
  68. return os;
  69. }
  70. };
  71. //
  72. // overloaded operators
  73. //
  74. Section& operator=(const Section& rhs) {
  75. m_name = rhs.m_name;
  76. m_lines = rhs.m_lines;
  77. return *this;
  78. }
  79. protected:
  80. //
  81. // data members
  82. //
  83. string m_name;
  84. vector<string> m_lines;
  85. const ComplianceFile& m_file;
  86. };
  87. //
  88. // This class represents a value section in the compliance
  89. // data file
  90. //
  91. class ValueSection : public Section {
  92. public:
  93. ValueSection(const string& name, const vector<string>& lines,
  94. const ComplianceFile& file) : Section(name, lines, file) {
  95. parse();
  96. }
  97. //
  98. // parse the section and create <name, value> pairs
  99. //
  100. virtual void parse();
  101. unsigned long value(const string &key) const{
  102. map<string, unsigned long>::const_iterator iter = m_values.find(key);
  103. if (iter == m_values.end())
  104. throw ValueNotFound(name(), key);
  105. return (*iter).second;
  106. }
  107. //
  108. // exceptions which can be thrown by the methods
  109. // of this class
  110. //
  111. struct ValueNotFound : public Section::SectionException {
  112. ValueNotFound(const string& name, const string &valname) :
  113. SectionException(name), m_valname(valname){}
  114. string m_valname;
  115. friend ostream& operator<<(ostream& os, const struct ValueNotFound& rhs) {
  116. os << "Exception : Value " << rhs.m_valname << " was not found in "
  117. << rhs.m_name;
  118. return os;
  119. }
  120. };
  121. protected:
  122. //
  123. // data members
  124. //
  125. map<string, unsigned long> m_values;
  126. };
  127. //
  128. // this class represents a single test case in an test
  129. // section
  130. //
  131. class TestCase {
  132. public:
  133. TestCase(const Section& section, const string& line) :
  134. m_section(section), m_line(line) {
  135. }
  136. virtual ~TestCase() {}
  137. //
  138. // accessors
  139. //
  140. const string& line() const { return m_line; }
  141. const Section& section() const { return m_section; }
  142. virtual void parse() = 0;
  143. virtual void execute(ostream &os) = 0;
  144. virtual bool passed() = 0;
  145. virtual void dump(ostream& os) = 0;
  146. bool mediamatched() { return m_mediamatched;};
  147. //
  148. // exceptions
  149. //
  150. struct InvalidFormat {
  151. InvalidFormat(const string& line, const string& section) {
  152. m_line = line;
  153. m_section = section;
  154. };
  155. string m_section, m_line;
  156. friend ostream& operator<<(ostream& os, const struct InvalidFormat& rhs) {
  157. os << "Exception : Invalid Test Case : " << rhs.m_line << " in section : "
  158. << rhs.m_section;
  159. return os;
  160. }
  161. };
  162. protected:
  163. //
  164. // data members
  165. //
  166. const Section& m_section;
  167. string m_line;
  168. bool m_mediamatched;
  169. };
  170. //
  171. // this class represents a test case (single line
  172. // in an test section)
  173. //
  174. class ComplianceTestCase : public TestCase {
  175. public:
  176. ComplianceTestCase(const Section& section, const string& line) :
  177. TestCase(section, line) {
  178. ::memset(&m_cd, 0, sizeof(COMPLIANCE_DATA));
  179. m_passed = false;
  180. m_allowUpgrade = false;
  181. parse();
  182. }
  183. virtual void execute(ostream &os);
  184. virtual bool passed();
  185. virtual void parse();
  186. virtual void dump(ostream& os);
  187. protected:
  188. void sourceDetails();
  189. void installationDetails(const vector<string>& tokens);
  190. //
  191. // data members
  192. //
  193. bool m_passed;
  194. COMPLIANCE_DATA m_cd;
  195. unsigned long m_sourceSKU;
  196. unsigned long m_sourceVAR;
  197. unsigned long m_sourceVer;
  198. unsigned long m_sourceBuild;
  199. bool m_expectedResult;
  200. UINT m_reason;
  201. BOOL m_noUpgrade;
  202. bool m_allowUpgrade;
  203. UINT m_errExpected;
  204. };
  205. //
  206. // default factory to create test cases
  207. //
  208. class TestCaseFactory {
  209. public:
  210. virtual TestCase* create(const Section& section, const string& line) const {
  211. TestCase *pTestCase = new ComplianceTestCase(section, line);
  212. return pTestCase;
  213. }
  214. virtual TestCase* create(const TestCase& tc) const {
  215. return create(tc.section(), tc.line());
  216. }
  217. };
  218. //
  219. // this class represents the test section in the compliance
  220. // data file
  221. //
  222. class TestSection : public Section {
  223. public:
  224. TestSection(const string& name, const vector<string>& lines,
  225. const ComplianceFile& file) : Section(name, lines, file){
  226. bindFactory();
  227. parse();
  228. }
  229. ~TestSection() {
  230. vector<TestCase*>::iterator iter = m_testCases.begin();
  231. while (iter != m_testCases.end())
  232. delete (*iter++);
  233. delete m_tcFactory;
  234. }
  235. TestSection& operator=(const TestSection& rhs);
  236. void executeTestCases(ostream& os);
  237. //
  238. // accessors
  239. //
  240. // const vector<TestCase *> testCases() const{ return m_testCases; }
  241. const TestCaseFactory& testCaseFactory() const{ return *m_tcFactory; }
  242. void parse();
  243. protected:
  244. void bindFactory() {
  245. m_tcFactory = new TestCaseFactory();
  246. }
  247. //
  248. // data members
  249. //
  250. vector<TestCase *> m_testCases;
  251. TestCaseFactory *m_tcFactory;
  252. };
  253. //
  254. // default factory to create sections
  255. //
  256. class SectionFactory {
  257. public:
  258. virtual Section* create(const string& name,
  259. const vector<string>& lines, const ComplianceFile& file) const {
  260. return new Section(name, lines, file);
  261. }
  262. virtual Section* create(const Section& section) const {
  263. return create(section.name(), section.lines(), section.file());
  264. }
  265. };
  266. //
  267. // current factory to create sections
  268. //
  269. class OldFormatSectionFactory : public SectionFactory {
  270. public:
  271. virtual Section* create(const string& name,
  272. const vector<string>& lines, const ComplianceFile& file) const {
  273. if (name.find("[test#") != name.npos)
  274. return new TestSection(name, lines, file);
  275. else if (name.find("#values]") != name.npos)
  276. return new ValueSection(name, lines, file);
  277. else
  278. return new Section(name, lines, file);
  279. }
  280. };
  281. #endif // for __SECTION_H_