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.

2989 lines
99 KiB

  1. #include "stdinc.h"
  2. #include "actctxgenctx.h"
  3. #define DEFINE_ATTRIBUTE(attributeName, attributeType, typePrefix) \
  4. { \
  5. L ## #attributeName, \
  6. offsetof(CNodeFactory, m_ ## typePrefix ## _ ## attributeName), \
  7. offsetof(CNodeFactory, m_f ## attributeName ## _ ## Present), \
  8. &CNodeFactory::XMLParser_Parse_ ## attributeType \
  9. },
  10. const static ASSEMBLY_VERSION assemblyVersion0 = {0,0,0,0};
  11. typedef enum _in_xml_tag_when_identity_generated_{
  12. SXS_IN_INVALID_XML_TAG_WHEN_ASSEMBLY_IDENTITY_GENERATED,
  13. SXS_IN_ASSEMBLY_TAG,
  14. SXS_IN_DEPENDENCY_TAG
  15. }SXS_IN_XML_TAG_WHEN_IDENTITY_GENERATED;
  16. static
  17. VOID
  18. SxspDbgPrintXmlNodeInfo(
  19. ULONG Level,
  20. XML_NODE_INFO *pNode
  21. );
  22. static
  23. PCSTR
  24. SxspFormatXmlNodeType(
  25. DWORD dwType
  26. );
  27. struct EventIdErrorPair
  28. {
  29. DWORD dwEventId;
  30. LONG nError;
  31. };
  32. const static EventIdErrorPair eventIdToErrorMap[] =
  33. {
  34. #include "Messages.hi" // generated from .x file, like .mc
  35. };
  36. // deliberately no extra paranetheses here
  37. #define NODEFACTORY_STRING_AND_LENGTH(x) x, NUMBER_OF(x) - 1
  38. const static SXS_NAME_LENGTH_PAIR IgnoredAttributesInDependencyTagForIdentity[]={
  39. //maybe more later
  40. { NODEFACTORY_STRING_AND_LENGTH(L"Description") }
  41. };
  42. const DWORD IGNORED_ATTRIBUTE_NUM_IN_DEPENDENCY_TAG = NUMBER_OF(IgnoredAttributesInDependencyTagForIdentity);
  43. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(baseInterface);
  44. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(clsid);
  45. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(description);
  46. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(flags);
  47. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(hash);
  48. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(hashalg);
  49. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(helpdir);
  50. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(iid);
  51. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(language);
  52. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(loadFrom);
  53. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(manifestVersion);
  54. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(metadataSatellite);
  55. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name);
  56. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(newVersion);
  57. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(numMethods);
  58. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(oldVersion);
  59. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(optional);
  60. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(processorArchitecture);
  61. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(progid);
  62. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(proxyStubClsid32);
  63. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(publicKeyToken);
  64. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(publicKey);
  65. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(resourceid);
  66. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(runtimeVersion);
  67. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(size);
  68. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(threadingModel);
  69. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(tlbid);
  70. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(type);
  71. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(version);
  72. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(versioned);
  73. // How to interpret the parser worker rules here:
  74. //
  75. // First, the state of the parser must match m_xps for the rule to be considered.
  76. // If the value eNotParsing is in the table, it matches any current parser
  77. // state. Use this to globally ignore some particular tag type when
  78. // combined with a NULL m_pszTag and NULL m_pfn.
  79. // Second, the type of the tag from the XML parser must match m_dwType.
  80. // If m_pszTag is not NULL, a case-insensitive comparison is done between the
  81. // string m_pszTag points to and the tag from the XML parser. An m_pszTag
  82. // value of NULL matches any tag.
  83. // If the three criteria match, the worker function is called. The worker function
  84. // pointer may be NULL, in which case no action is taken. (This is useful for
  85. // callbacks from the parser about XML_WHITESPACE where we don't really have to do
  86. // anything at all.)
  87. //
  88. #define DEFINE_TAG_WORKER_IGNOREALLOFTYPE(dwType) { CNodeFactory::eNotParsing, (dwType), NULL, NULL, NULL, 0, 0, 0, NULL }
  89. //
  90. // Notes on use of the DEFINE_TAG_WORKER_ELEMENT() macro:
  91. //
  92. // The first parameter, sourceState, is part of the name of a XMLParseState
  93. // enumeration value. It is concatenated onto "eParsing" to form the name of
  94. // the state which the rule will match.
  95. //
  96. // The second parameter is both the text of the tag to match and is used to
  97. // form the name of the function to invoke if the rule matches. The tag is
  98. // compared case-insensitively, and the name of the member function invoked
  99. // is XMLParser_Element_ followed by the sourceState string followed by another
  100. // underscore, followed by the tagName string. So, for example, the following
  101. // rule:
  102. //
  103. // DEFINE_TAG_WORKER_ELEMENT(DepAssy, Version)
  104. //
  105. // says that when the parser is in the eParsingDepAssy state and a "Version"
  106. // tag is found, call the function CNodeFactory::XMLParser_Element_DepAssy_Version().
  107. //
  108. #define DEFINE_TAG_WORKER_ELEMENT(sourceState, tagName) \
  109. { \
  110. CNodeFactory::eParsing_ ## sourceState, \
  111. XML_ELEMENT, \
  112. SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, \
  113. L ## #tagName, \
  114. s_rg_ ## sourceState ## _ ## tagName ## _attributes, \
  115. NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1, \
  116. NUMBER_OF(L ## #tagName) - 1, \
  117. NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \
  118. &CNodeFactory::XMLParser_Element_ ## sourceState ## _ ## tagName, \
  119. CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \
  120. }
  121. #define DEFINE_TAG_WORKER_ELEMENT_NOCB(sourceState, tagName) \
  122. { \
  123. CNodeFactory::eParsing_ ## sourceState, \
  124. XML_ELEMENT, \
  125. SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, \
  126. L ## #tagName, \
  127. s_rg_ ## sourceState ## _ ## tagName ## _attributes, \
  128. NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1, \
  129. NUMBER_OF(L ## #tagName) - 1, \
  130. NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \
  131. NULL, \
  132. CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \
  133. }
  134. #define DEFINE_TAG_WORKER_ELEMENT_NONS(sourceState, tagName) \
  135. { \
  136. CNodeFactory::eParsing_ ## sourceState, \
  137. XML_ELEMENT, \
  138. NULL, \
  139. L ## #tagName, \
  140. s_rg_ ## sourceState ## _ ## tagName ## _attributes, \
  141. 0, \
  142. NUMBER_OF(L ## #tagName) - 1, \
  143. NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \
  144. &CNodeFactory::XMLParser_Element_ ## sourceState ## _ ## tagName, \
  145. CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \
  146. }
  147. #define BEGIN_ELEMENT_LEGAL_ATTRIBUTES(_element) \
  148. const static ELEMENT_LEGAL_ATTRIBUTE s_rg_ ## _element ## _attributes[] = { \
  149. { ELEMENT_LEGAL_ATTRIBUTE_FLAG_IGNORE, NULL, NULL },
  150. #define DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(attributeName, validatorFlags, validator) { ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED, &s_AttributeName_ ## attributeName, validator, validatorFlags },
  151. #define DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(attributeName, validatorFlags, validator) { 0, &s_AttributeName_ ## attributeName, validator, validatorFlags },
  152. #define END_ELEMENT_LEGAL_ATTRIBUTES(_element) };
  153. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly)
  154. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(manifestVersion, 0, NULL)
  155. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly)
  156. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_description)
  157. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_description)
  158. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInherit)
  159. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInherit)
  160. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInheritable)
  161. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInheritable)
  162. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_assemblyIdentity)
  163. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  164. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL)
  165. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL)
  166. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, SXSP_VALIDATE_PROCESSOR_ARCHITECTURE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateProcessorArchitectureAttribute)
  167. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL)
  168. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute)
  169. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKey, 0, NULL)
  170. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_assemblyIdentity)
  171. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency)
  172. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(optional, 0, &::SxspValidateBoolAttribute)
  173. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency)
  174. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly)
  175. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly)
  176. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_assemblyIdentity)
  177. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  178. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL)
  179. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(version, 0, NULL)
  180. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, SXSP_VALIDATE_PROCESSOR_ARCHITECTURE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateProcessorArchitectureAttribute)
  181. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL)
  182. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, SXSP_VALIDATE_LANGUAGE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateLanguageAttribute)
  183. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_assemblyIdentity)
  184. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_bindingRedirect)
  185. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(oldVersion, 0, NULL)
  186. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(newVersion, 0, NULL)
  187. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_bindingRedirect)
  188. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file)
  189. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  190. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(hash, 0, NULL)
  191. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(hashalg, 0, NULL)
  192. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(loadFrom, 0, NULL)
  193. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(size, 0, &::SxspValidateUnsigned64Attribute)
  194. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file)
  195. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass)
  196. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute)
  197. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL)
  198. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(progid, 0, NULL)
  199. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute)
  200. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(description, 0, NULL)
  201. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass)
  202. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass_progid)
  203. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass_progid)
  204. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass)
  205. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  206. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute)
  207. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(progid, 0, NULL)
  208. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute)
  209. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(description, 0, NULL)
  210. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(runtimeVersion, 0, NULL)
  211. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL)
  212. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass)
  213. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrSurrogate)
  214. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute)
  215. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  216. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(runtimeVersion, 0, NULL)
  217. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_clrSurrogate)
  218. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass_progid)
  219. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass_progid)
  220. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comInterfaceProxyStub)
  221. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(iid, 0, &::SxspValidateGuidAttribute)
  222. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute)
  223. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(name, 0, NULL)
  224. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(numMethods, 0, NULL)
  225. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(baseInterface, 0, &::SxspValidateGuidAttribute)
  226. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(proxyStubClsid32, 0, &::SxspValidateGuidAttribute)
  227. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL)
  228. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comInterfaceProxyStub)
  229. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_typelib)
  230. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute)
  231. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL)
  232. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(helpdir, 0, NULL)
  233. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(resourceid, 0, NULL)
  234. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(flags, 0, NULL)
  235. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_typelib)
  236. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_windowClass)
  237. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(versioned, 0, &::SxspValidateBoolAttribute)
  238. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_windowClass)
  239. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_comInterfaceExternalProxyStub)
  240. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(iid, 0, &::SxspValidateGuidAttribute)
  241. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  242. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(proxyStubClsid32, 0, &::SxspValidateGuidAttribute)
  243. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute)
  244. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(numMethods, 0, NULL)
  245. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(baseInterface, 0, &::SxspValidateGuidAttribute)
  246. END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_comInterfaceExternalProxyStub)
  247. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration)
  248. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration)
  249. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows)
  250. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows)
  251. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding)
  252. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding)
  253. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_assemblyIdentity)
  254. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  255. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL)
  256. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL)
  257. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, 0, &::SxspValidateProcessorArchitectureAttribute)
  258. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL)
  259. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute)
  260. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_assemblyIdentity)
  261. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly)
  262. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly)
  263. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity)
  264. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL)
  265. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(processorArchitecture, 0, &::SxspValidateProcessorArchitectureAttribute)
  266. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL)
  267. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL)
  268. DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute)
  269. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity)
  270. BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect)
  271. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(oldVersion, 0, NULL)
  272. DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(newVersion, 0, NULL)
  273. END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect)
  274. static const struct
  275. {
  276. CNodeFactory::XMLParseState m_xpsOld;
  277. DWORD m_dwType;
  278. PCWSTR m_pszNamespace;
  279. PCWSTR m_pszName;
  280. PCELEMENT_LEGAL_ATTRIBUTE m_prgLegalAttributes;
  281. UCHAR m_cchNamespace; // We use UCHAR here just for greater data density. Changing this and rebuilding
  282. UCHAR m_cchName; // this module should work fine if you really need namespaces or names longer than
  283. // 255 characters.
  284. UCHAR m_cLegalAttributes;
  285. CNodeFactory::XMLParserWorkerFunctionPtr m_pfn;
  286. CNodeFactory::XMLParseState m_xpsNew;
  287. } s_rgWorkers[] =
  288. {
  289. DEFINE_TAG_WORKER_IGNOREALLOFTYPE(XML_WHITESPACE),
  290. DEFINE_TAG_WORKER_IGNOREALLOFTYPE(XML_COMMENT),
  291. DEFINE_TAG_WORKER_ELEMENT(doc, assembly),
  292. DEFINE_TAG_WORKER_ELEMENT(doc_assembly, assemblyIdentity),
  293. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, description),
  294. DEFINE_TAG_WORKER_ELEMENT(doc_assembly, noInherit),
  295. DEFINE_TAG_WORKER_ELEMENT(doc_assembly, noInheritable),
  296. DEFINE_TAG_WORKER_ELEMENT(doc_assembly, dependency),
  297. DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency, dependentAssembly),
  298. DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency_dependentAssembly, assemblyIdentity),
  299. DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency_dependentAssembly, bindingRedirect),
  300. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, file),
  301. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, comClass),
  302. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file_comClass, progid),
  303. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, clrClass),
  304. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_clrClass, progid),
  305. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, comInterfaceProxyStub),
  306. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, typelib),
  307. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, windowClass),
  308. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, clrSurrogate),
  309. DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, comInterfaceExternalProxyStub),
  310. // All app config productions go here, just for neatness
  311. DEFINE_TAG_WORKER_ELEMENT_NONS(doc, configuration),
  312. DEFINE_TAG_WORKER_ELEMENT_NONS(doc_configuration, windows),
  313. DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows, assemblyBinding),
  314. DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding, assemblyIdentity),
  315. DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding, dependentAssembly),
  316. DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding_dependentAssembly, assemblyIdentity),
  317. DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding_dependentAssembly, bindingRedirect),
  318. };
  319. BOOL
  320. SxspIsNamespaceDeclaration(XML_NODE_INFO *pNodeInfo)
  321. {
  322. FN_TRACE();
  323. ASSERT(pNodeInfo->dwType == XML_ATTRIBUTE);
  324. if (pNodeInfo->ulLen >= 5)
  325. { // "xmlns" : prefix for namespace declaration, default ns or non-default ns
  326. if ((pNodeInfo->pwcText[0] == L'x') &&
  327. (pNodeInfo->pwcText[1] == L'm') &&
  328. (pNodeInfo->pwcText[2] == L'l') &&
  329. (pNodeInfo->pwcText[3] == L'n') &&
  330. (pNodeInfo->pwcText[4] == L's'))
  331. {
  332. if (pNodeInfo->ulLen == 5) // like xmlns="", default ns declaration
  333. return TRUE;
  334. else
  335. if (pNodeInfo->pwcText[5] == L':')
  336. return TRUE;
  337. }
  338. }
  339. return FALSE;
  340. }
  341. //In this function, two tasks:
  342. // 1) verify PublicKey and StrongName
  343. // 2) create AssemblyIdentity based on xmlnode array
  344. // 3) for (name, processorArchitecure, version. langid) they would be unique with SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE
  345. // 4) if there are dup triples {nsURL, name, value), only one is count, this is done with SxsCreateAssemblyIdentity
  346. BOOL
  347. SxspCreateAssemblyIdentityFromIdentityElement(
  348. DWORD Flags,
  349. PCACTCTXCTB_PARSE_CONTEXT ParseContext,
  350. ULONG Type,
  351. PASSEMBLY_IDENTITY *AssemblyIdentityOut,
  352. DWORD cNumRecs,
  353. PCSXS_NODE_INFO prgNodeInfo
  354. )
  355. {
  356. BOOL fSuccess = FALSE;
  357. FN_TRACE_WIN32(fSuccess);
  358. DWORD i;
  359. PASSEMBLY_IDENTITY AssemblyIdentity = NULL;
  360. CStringBuffer buffValue;
  361. if (AssemblyIdentityOut != NULL)
  362. *AssemblyIdentityOut = NULL;
  363. PARAMETER_CHECK((Flags & ~(SXSP_CREATE_ASSEMBLY_IDENTITY_FROM_IDENTITY_TAG_FLAG_VERIFY_PUBLIC_KEY_IF_PRESENT)) == 0);
  364. PARAMETER_CHECK((Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) || (Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE));
  365. PARAMETER_CHECK(AssemblyIdentityOut != NULL);
  366. PARAMETER_CHECK(prgNodeInfo != NULL);
  367. PARAMETER_CHECK(prgNodeInfo[0].Type == XML_ELEMENT);
  368. IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, Type, &AssemblyIdentity, 0, NULL));
  369. i = 1;
  370. while (i<cNumRecs)
  371. {
  372. ULONG j;
  373. INTERNAL_ERROR_CHECK(prgNodeInfo[i].Type == XML_ATTRIBUTE);
  374. buffValue.Clear();
  375. j = i + 1;
  376. while ((j < cNumRecs) && (prgNodeInfo[j].Type == XML_PCDATA))
  377. {
  378. IFW32FALSE_EXIT(buffValue.Win32Append(prgNodeInfo[j].pszText, prgNodeInfo[j].cchText));
  379. j++;
  380. }
  381. // if this is a special attribute, we'll handle it ... specially.
  382. if ((prgNodeInfo[i].NamespaceStringBuf.Cch() == 0) &&
  383. (::FusionpCompareStrings(
  384. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY,
  385. SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_PUBLIC_KEY_CCH,
  386. prgNodeInfo[i].pszText,
  387. prgNodeInfo[i].cchText,
  388. false) == 0))
  389. {// ignore publicKey if it appears in assembly identity
  390. }
  391. else
  392. {
  393. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  394. Attribute.Flags = 0;
  395. Attribute.NamespaceCch = prgNodeInfo[i].NamespaceStringBuf.Cch();
  396. Attribute.Namespace = prgNodeInfo[i].NamespaceStringBuf;
  397. Attribute.NameCch = prgNodeInfo[i].cchText;
  398. Attribute.Name = prgNodeInfo[i].pszText;
  399. Attribute.ValueCch = buffValue.Cch();
  400. Attribute.Value = buffValue;
  401. IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, AssemblyIdentity, &Attribute));
  402. }
  403. i = j;
  404. }
  405. *AssemblyIdentityOut = AssemblyIdentity;
  406. AssemblyIdentity = NULL;
  407. fSuccess = TRUE;
  408. Exit:
  409. if (AssemblyIdentity != NULL)
  410. ::SxsDestroyAssemblyIdentity(AssemblyIdentity);
  411. return fSuccess;
  412. }
  413. CNodeFactory::CNodeFactory()
  414. : m_ActCtxGenCtx(NULL),
  415. m_Assembly(NULL),
  416. m_fFirstCreateNodeCall(true),
  417. m_cUnknownChildDepth(0),
  418. m_xpsParseState(eParsing_doc),
  419. m_fAssemblyFound(false),
  420. m_fIdentityFound(false),
  421. m_AssemblyContext(NULL),
  422. m_CurrentPolicyDependentAssemblyIdentity(NULL),
  423. m_CurrentPolicyStatement(NULL),
  424. m_IntuitedParseType(eActualParseType_Undetermined),
  425. m_pApplicationPolicyTable(NULL),
  426. m_fNoInheritableFound(false)
  427. {
  428. m_ParseContext.XMLElementDepth = 0;
  429. m_ParseContext.ElementPath = NULL;
  430. m_ParseContext.ElementPathCch = 0;
  431. m_ParseContext.ElementName = NULL;
  432. m_ParseContext.ElementPathCch = 0;
  433. m_ParseContext.ElementHash = 0;
  434. }
  435. CNodeFactory::~CNodeFactory()
  436. {
  437. CSxsPreserveLastError ple;
  438. if ((m_CurrentPolicyStatement != NULL) &&
  439. (m_CurrentPolicyDependentAssemblyIdentity != NULL) &&
  440. (m_pApplicationPolicyTable != NULL))
  441. {
  442. if (m_pApplicationPolicyTable->Find(m_buffCurrentApplicationPolicyIdentityKey, m_CurrentPolicyStatement))
  443. m_CurrentPolicyStatement = NULL;
  444. }
  445. FUSION_DELETE_SINGLETON(m_CurrentPolicyStatement);
  446. if (m_CurrentPolicyDependentAssemblyIdentity != NULL)
  447. ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity);
  448. if (m_Assembly != NULL)
  449. {
  450. m_Assembly->Release();
  451. m_Assembly = NULL;
  452. }
  453. ple.Restore();
  454. }
  455. BOOL
  456. CNodeFactory::Initialize(
  457. PACTCTXGENCTX ActCtxGenCtx,
  458. PASSEMBLY Assembly,
  459. PACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext
  460. )
  461. {
  462. BOOL fSuccess = FALSE;
  463. FN_TRACE_WIN32(fSuccess);
  464. PARAMETER_CHECK(Assembly != NULL);
  465. #if FUSION_XML_TREE
  466. IFW32FALSE_EXIT(m_ParseTreeStringPool.Initialize());
  467. #endif // FUSION_XML_TREE
  468. IFW32FALSE_EXIT(m_XMLNamespaceManager.Initialize());
  469. m_ActCtxGenCtx = ActCtxGenCtx;
  470. Assembly->AddRef();
  471. if (m_Assembly != NULL)
  472. m_Assembly->Release();
  473. m_Assembly = Assembly;
  474. m_AssemblyContext = AssemblyContext;
  475. m_ParseContext.AssemblyContext = AssemblyContext;
  476. m_ParseContext.ErrorCallbacks.MissingRequiredAttribute = &CNodeFactory::ParseErrorCallback_MissingRequiredAttribute;
  477. m_ParseContext.ErrorCallbacks.AttributeNotAllowed = &CNodeFactory::ParseErrorCallback_AttributeNotAllowed;
  478. m_ParseContext.ErrorCallbacks.InvalidAttributeValue = &CNodeFactory::ParseErrorCallback_InvalidAttributeValue;
  479. m_ParseContext.SourceFilePathType = AssemblyContext->ManifestPathType;
  480. m_ParseContext.SourceFile = AssemblyContext->ManifestPath;
  481. m_ParseContext.SourceFileCch = AssemblyContext->ManifestPathCch;
  482. m_ParseContext.LineNumber = 0;
  483. #if FUSION_XML_TREE
  484. m_XmlDocument.Flags = 0;
  485. m_XmlDocument.StringCount = 0;
  486. m_XmlDocument.Strings = NULL;
  487. InitializeListHead(&m_XmlDocument.ElementListHead);
  488. m_CurrentNode = NULL;
  489. m_CurrentParent = NULL;
  490. #endif // FUSION_XML_TREE
  491. fSuccess = TRUE;
  492. Exit:
  493. return fSuccess;
  494. }
  495. VOID
  496. CNodeFactory::ResetParseState()
  497. {
  498. m_fFirstCreateNodeCall = true;
  499. m_fAssemblyFound = false;
  500. m_fIdentityFound = false;
  501. m_fNoInheritableFound = false;
  502. FUSION_DELETE_SINGLETON(m_CurrentPolicyStatement);
  503. m_CurrentPolicyStatement = NULL;
  504. ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity);
  505. m_CurrentPolicyDependentAssemblyIdentity = NULL;
  506. }
  507. HRESULT
  508. CNodeFactory::QueryInterface(
  509. REFIID riid,
  510. LPVOID *ppvObj
  511. )
  512. {
  513. HRESULT hr = NOERROR;
  514. FN_TRACE_HR(hr);
  515. IUnknown *pIUnknown = NULL;
  516. if (ppvObj != NULL)
  517. *ppvObj = NULL;
  518. if (ppvObj == NULL)
  519. {
  520. hr = E_POINTER;
  521. goto Exit;
  522. }
  523. if (riid == __uuidof(this))
  524. pIUnknown = this;
  525. else if ((riid == IID_IUnknown) ||
  526. (riid == IID_IXMLNodeFactory))
  527. pIUnknown = static_cast<IXMLNodeFactory *>(this);
  528. else
  529. {
  530. ::FusionpDbgPrintEx(
  531. FUSION_DBG_LEVEL_ERROR,
  532. "SXS.DLL: Node factory asked for unknown interface\n");
  533. hr = E_NOINTERFACE;
  534. goto Exit;
  535. }
  536. pIUnknown->AddRef();
  537. *ppvObj = pIUnknown;
  538. hr = NOERROR;
  539. Exit:
  540. return hr;
  541. }
  542. HRESULT
  543. CNodeFactory::NotifyEvent(
  544. IXMLNodeSource *pSource,
  545. XML_NODEFACTORY_EVENT iEvt
  546. )
  547. {
  548. return NOERROR;
  549. }
  550. HRESULT
  551. CNodeFactory::ConvertXMLNodeInfoToSXSNodeInfo(
  552. const XML_NODE_INFO *pNodeInfo,
  553. SXS_NODE_INFO &rSXSNodeInfo
  554. )
  555. {
  556. HRESULT hr = NOERROR;
  557. FN_TRACE_HR(hr);
  558. INTERNAL_ERROR_CHECK(pNodeInfo != NULL);
  559. rSXSNodeInfo.Size = pNodeInfo->dwSize;
  560. rSXSNodeInfo.Type = pNodeInfo->dwType;
  561. switch (pNodeInfo->dwType)
  562. {
  563. case XML_ELEMENT:
  564. {
  565. SIZE_T cchNamespacePrefix;
  566. IFCOMFAILED_EXIT(
  567. m_XMLNamespaceManager.Map(
  568. 0,
  569. pNodeInfo,
  570. &rSXSNodeInfo.NamespaceStringBuf,
  571. &cchNamespacePrefix));
  572. // +1 to skip colon
  573. rSXSNodeInfo.pszText = pNodeInfo->pwcText + ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0);
  574. rSXSNodeInfo.cchText = pNodeInfo->ulLen - ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0);
  575. break;
  576. }
  577. case XML_ATTRIBUTE:
  578. {
  579. SIZE_T cchNamespacePrefix;
  580. // if this is a namespace definition, ignore
  581. const PCWSTR pwcText = pNodeInfo->pwcText;
  582. if ((pwcText[0] == L'x') &&
  583. (pwcText[1] == L'm') &&
  584. (pwcText[2] == L'l') &&
  585. (pwcText[3] == L'n') &&
  586. (pwcText[4] == L's') &&
  587. ((pwcText[5] == L':') ||
  588. (pwcText[5] == L'=')))
  589. {
  590. rSXSNodeInfo.pszText = pNodeInfo->pwcText;
  591. rSXSNodeInfo.cchText = pNodeInfo->ulLen;
  592. }
  593. else
  594. {
  595. IFCOMFAILED_EXIT(
  596. m_XMLNamespaceManager.Map(
  597. CXMLNamespaceManager::eMapFlag_DoNotApplyDefaultNamespace,
  598. pNodeInfo,
  599. &rSXSNodeInfo.NamespaceStringBuf,
  600. &cchNamespacePrefix));
  601. // +1 to skip colon
  602. rSXSNodeInfo.pszText = pNodeInfo->pwcText + ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0);
  603. rSXSNodeInfo.cchText = pNodeInfo->ulLen - ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0);
  604. }
  605. break;
  606. }
  607. default:
  608. // Otherwise we'll assume there's no namespace processing to do...
  609. rSXSNodeInfo.NamespaceStringBuf.Clear();
  610. rSXSNodeInfo.pszText = pNodeInfo->pwcText;
  611. rSXSNodeInfo.cchText = pNodeInfo->ulLen;
  612. break;
  613. }
  614. FN_EPILOG
  615. }
  616. HRESULT
  617. CNodeFactory::BeginChildren(
  618. IXMLNodeSource *pSource,
  619. XML_NODE_INFO *pNodeInfo
  620. )
  621. {
  622. HRESULT hr = NOERROR;
  623. FN_TRACE_HR(hr);
  624. ULONG i;
  625. SXS_NODE_INFO SXSNodeInfo;
  626. IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnBeginChildren(pSource, pNodeInfo));
  627. IFCOMFAILED_EXIT(this->ConvertXMLNodeInfoToSXSNodeInfo(pNodeInfo, SXSNodeInfo));
  628. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  629. {
  630. IFW32FALSE_EXIT(
  631. m_ActCtxGenCtx->m_Contributors[i].Fire_BeginChildren(
  632. m_ActCtxGenCtx,
  633. m_AssemblyContext,
  634. &m_ParseContext,
  635. &SXSNodeInfo));
  636. }
  637. FN_EPILOG
  638. }
  639. HRESULT
  640. CNodeFactory::EndChildren(
  641. IXMLNodeSource *pSource,
  642. BOOL Empty,
  643. XML_NODE_INFO *pNodeInfo
  644. )
  645. {
  646. HRESULT hr = NOERROR;
  647. FN_TRACE_HR(hr);
  648. ULONG i;
  649. PWSTR Bang;
  650. SXS_NODE_INFO SXSNodeInfo;
  651. // Short-circuit PIs, XML-decls, whitespace and comments
  652. if ((pNodeInfo->dwType == XML_PI) ||
  653. (pNodeInfo->dwType == XML_XMLDECL) ||
  654. (pNodeInfo->dwType == XML_COMMENT) ||
  655. (pNodeInfo->dwType == XML_WHITESPACE))
  656. {
  657. hr = NOERROR;
  658. goto Exit;
  659. }
  660. IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnEndChildren(pSource, Empty, pNodeInfo));
  661. // We hit the end of something; if we're skipping stuff, we're one level back towards
  662. // paying attention.
  663. if (m_cUnknownChildDepth != 0)
  664. {
  665. m_cUnknownChildDepth--;
  666. }
  667. else
  668. {
  669. ULONG j;
  670. for (j=0; j<NUMBER_OF(s_rgWorkers); j++)
  671. {
  672. if (s_rgWorkers[j].m_xpsNew == m_xpsParseState)
  673. {
  674. m_xpsParseState = s_rgWorkers[j].m_xpsOld;
  675. break;
  676. }
  677. }
  678. if (j == NUMBER_OF(s_rgWorkers))
  679. {
  680. ::FusionpDbgPrintEx(
  681. FUSION_DBG_LEVEL_ERROR,
  682. "SXS.DLL: %s() called when we were not expecting it. m_xpsParseState = %d\n", __FUNCTION__, m_xpsParseState);
  683. INTERNAL_ERROR_CHECK(FALSE);
  684. // Hey, how the heck did we get here?
  685. }
  686. // One time end-of-manifest checks...
  687. if (m_xpsParseState == eParsing_doc)
  688. {
  689. switch (m_ParseType)
  690. {
  691. default:
  692. INTERNAL_ERROR_CHECK(false);
  693. break;
  694. case XML_FILE_TYPE_COMPONENT_CONFIGURATION:
  695. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  696. break;
  697. case XML_FILE_TYPE_MANIFEST:
  698. // If this is not the root assembly, this is not a noInherit actctx and the noInheritable
  699. // element was not found, issue an error.
  700. if (((m_AssemblyContext->Flags & ACTCTXCTB_ASSEMBLY_CONTEXT_IS_ROOT_ASSEMBLY) == 0) &&
  701. m_ActCtxGenCtx->m_NoInherit &&
  702. !m_fNoInheritableFound)
  703. {
  704. this->LogParseError(MSG_SXS_NOINHERIT_REQUIRES_NOINHERITABLE);
  705. ORIGINATE_WIN32_FAILURE_AND_EXIT(NoInheritRequiresNoInheritable, ERROR_SXS_MANIFEST_PARSE_ERROR);
  706. }
  707. break;
  708. }
  709. }
  710. }
  711. #if FUSION_XML_TREE
  712. m_CurrentParent = const_cast<PSXS_XML_NODE>(m_CurrentParent->Parent);
  713. #endif // FUSION_XML_TREE
  714. if (pNodeInfo->dwType != XML_XMLDECL)
  715. {
  716. IFCOMFAILED_EXIT(this->ConvertXMLNodeInfoToSXSNodeInfo(pNodeInfo, SXSNodeInfo));
  717. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  718. {
  719. IFW32FALSE_EXIT(
  720. m_ActCtxGenCtx->m_Contributors[i].Fire_EndChildren(
  721. m_ActCtxGenCtx,
  722. m_AssemblyContext,
  723. &m_ParseContext,
  724. Empty,
  725. &SXSNodeInfo));
  726. }
  727. INTERNAL_ERROR_CHECK(m_ParseContext.XMLElementDepth != 0);
  728. m_ParseContext.XMLElementDepth--;
  729. Bang = wcsrchr(m_buffElementPath, L'!');
  730. INTERNAL_ERROR_CHECK(((Bang == NULL) == (m_ParseContext.XMLElementDepth == 0)));
  731. if (Bang != NULL)
  732. {
  733. m_buffElementPath.Left(Bang - m_buffElementPath);
  734. m_ParseContext.ElementPathCch = m_buffElementPath.Cch();
  735. m_ParseContext.ElementPath = m_buffElementPath;
  736. m_ParseContext.ElementName = wcsrchr(m_buffElementPath, L'!');
  737. if (m_ParseContext.ElementName == NULL)
  738. {
  739. m_ParseContext.ElementName = m_buffElementPath;
  740. m_ParseContext.ElementNameCch = m_buffElementPath.Cch();
  741. }
  742. else
  743. {
  744. m_ParseContext.ElementName++;
  745. m_ParseContext.ElementNameCch = m_buffElementPath.Cch() - (m_ParseContext.ElementName - m_buffElementPath);
  746. }
  747. IFW32FALSE_ORIGINATE_AND_EXIT(
  748. ::SxspHashString(
  749. m_buffElementPath,
  750. m_ParseContext.ElementPathCch,
  751. &m_ParseContext.ElementHash,
  752. false));
  753. }
  754. else
  755. {
  756. m_buffElementPath.Clear();
  757. m_ParseContext.ElementPath = NULL;
  758. m_ParseContext.ElementPathCch = 0;
  759. m_ParseContext.ElementName = NULL;
  760. m_ParseContext.ElementNameCch = 0;
  761. m_ParseContext.ElementHash = 0;
  762. m_ParseContext.XMLElementDepth = 0;
  763. }
  764. }
  765. hr = NOERROR;
  766. Exit:
  767. return hr;
  768. }
  769. HRESULT
  770. CNodeFactory::Error(
  771. IXMLNodeSource *pSource,
  772. HRESULT hrErrorCode,
  773. USHORT cNumRecs,
  774. XML_NODE_INFO **apNodeInfo
  775. )
  776. {
  777. CSxsPreserveLastError ple;
  778. ::FusionpConvertCOMFailure(hrErrorCode);
  779. ::FusionpSetLastErrorFromHRESULT(hrErrorCode);
  780. this->LogParseError(MSG_SXS_WIN32_ERROR_MSG_WHEN_PARSING_MANIFEST, CEventLogLastError());
  781. ple.Restore();
  782. return NOERROR;
  783. }
  784. HRESULT
  785. CNodeFactory::FirstCreateNodeCall(
  786. IXMLNodeSource *pSource,
  787. PVOID pNodeParent,
  788. USHORT NodeCount,
  789. const SXS_NODE_INFO *prgNodeInfo
  790. )
  791. {
  792. HRESULT hr = S_OK;
  793. FN_TRACE_HR(hr);
  794. ULONG i;
  795. const static WCHAR rgch1_0[] = L"1.0";
  796. const static UNICODE_STRING ustr1_0 = CONSTANT_UNICODE_STRING(rgch1_0);
  797. bool fGotGoodManifestVersion = false;
  798. bool fGotAnyManifestVersion = false;
  799. // It's our first IXMLNodeFactory::CreateNode() call. This had better
  800. // be an <ASSEMBLY MANIFESTVERSION="1.0" ...> deal.
  801. for (i=0; i<NodeCount; i++)
  802. {
  803. if (prgNodeInfo[i].Type == XML_ELEMENT)
  804. {
  805. INTERNAL_ERROR_CHECK(i == 0);
  806. switch (m_ParseType)
  807. {
  808. default:
  809. INTERNAL_ERROR_CHECK(false);
  810. break;
  811. case XML_FILE_TYPE_MANIFEST:
  812. case XML_FILE_TYPE_COMPONENT_CONFIGURATION:
  813. if ((prgNodeInfo[i].cchText != (NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_ELEMENT_NAME_ASSEMBLY) - 1)) ||
  814. (prgNodeInfo[i].NamespaceStringBuf.Cch() != (NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1)) ||
  815. (memcmp(prgNodeInfo[i].pszText, SXS_ASSEMBLY_MANIFEST_STD_ELEMENT_NAME_ASSEMBLY, prgNodeInfo[i].cchText * sizeof(WCHAR)) != 0) ||
  816. (memcmp(prgNodeInfo[i].NamespaceStringBuf, SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, prgNodeInfo[i].NamespaceStringBuf.Cch() * sizeof(WCHAR)) != 0))
  817. {
  818. IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_INCORRECT_ROOT_ELEMENT));
  819. }
  820. break;
  821. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  822. if ((prgNodeInfo[i].cchText != SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION_CCH) ||
  823. (prgNodeInfo[i].NamespaceStringBuf.Cch() != 0) ||
  824. (memcmp(prgNodeInfo[i].pszText, SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION,
  825. SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION_CCH * sizeof(WCHAR)) != 0))
  826. {
  827. IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_INCORRECT_ROOT_ELEMENT));
  828. }
  829. break;
  830. }
  831. }
  832. else if (prgNodeInfo[i].Type == XML_ATTRIBUTE)
  833. {
  834. if ((prgNodeInfo[i].cchText == (NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_ATTRIBUTE_NAME_MANIFEST_VERSION) - 1)) &&
  835. (prgNodeInfo[i].NamespaceStringBuf.Cch() == 0) &&
  836. (memcmp(prgNodeInfo[i].pszText, SXS_ASSEMBLY_MANIFEST_STD_ATTRIBUTE_NAME_MANIFEST_VERSION, prgNodeInfo[i].cchText * sizeof(WCHAR)) == 0))
  837. {
  838. fGotAnyManifestVersion = true;
  839. ULONG j = i + 1;
  840. if (j < NodeCount)
  841. {
  842. if (prgNodeInfo[j].Type == XML_PCDATA)
  843. {
  844. if (prgNodeInfo[j].cchText == 3)
  845. {
  846. if (memcmp(prgNodeInfo[j].pszText, L"1.0", prgNodeInfo[j].cchText * sizeof(WCHAR)) == 0)
  847. {
  848. fGotGoodManifestVersion = true;
  849. }
  850. }
  851. }
  852. }
  853. }
  854. }
  855. }
  856. if ((m_ParseType == XML_FILE_TYPE_MANIFEST) ||
  857. (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION))
  858. {
  859. if (fGotAnyManifestVersion)
  860. {
  861. if (!fGotGoodManifestVersion)
  862. IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_VERSION_ERROR));
  863. }
  864. else
  865. IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_VERSION_MISSING));
  866. }
  867. m_Assembly->m_ManifestVersionMajor = 1;
  868. m_Assembly->m_ManifestVersionMinor = 0;
  869. hr = NOERROR;
  870. Exit:
  871. return hr;
  872. }
  873. HRESULT
  874. CNodeFactory::CreateNode(
  875. IXMLNodeSource *pSource,
  876. PVOID pNodeParent,
  877. USHORT NodeCount,
  878. XML_NODE_INFO **apNodeInfo
  879. )
  880. {
  881. HRESULT hr = NOERROR;
  882. FN_TRACE_HR(hr);
  883. ULONG i;
  884. PSXS_XML_NODE pXmlNode = NULL;
  885. PSXS_NODE_INFO pSXSNodeInfo = NULL;
  886. SIZE_T cchTemp;
  887. m_ParseContext.LineNumber = pSource->GetLineNumber();
  888. INTERNAL_ERROR_CHECK(NodeCount != 0);
  889. #if DBG
  890. ::FusionpDbgPrintEx(
  891. FUSION_DBG_LEVEL_NODEFACTORY,
  892. "SXS.DLL: " __FUNCTION__ "() entered\n"
  893. " m_ParseContext.XMLElementDepth = %lu\n",
  894. m_ParseContext.XMLElementDepth);
  895. for (i=0; i<NodeCount; i++)
  896. ::SxspDbgPrintXmlNodeInfo(FUSION_DBG_LEVEL_NODEFACTORY, apNodeInfo[i]);
  897. #endif
  898. // Short-circuit PIs, XML-decls, whitespace and comments
  899. if ((apNodeInfo[0]->dwType == XML_PI) ||
  900. (apNodeInfo[0]->dwType == XML_XMLDECL) ||
  901. (apNodeInfo[0]->dwType == XML_COMMENT) ||
  902. (apNodeInfo[0]->dwType == XML_WHITESPACE))
  903. {
  904. hr = NOERROR;
  905. goto Exit;
  906. }
  907. IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnCreateNode(pSource, pNodeParent, NodeCount, apNodeInfo));
  908. IFALLOCFAILED_EXIT(pSXSNodeInfo = new SXS_NODE_INFO[NodeCount]);
  909. for (i=0; i<NodeCount; i++)
  910. IFCOMFAILED_EXIT(this->ConvertXMLNodeInfoToSXSNodeInfo(apNodeInfo[i], pSXSNodeInfo[i]));
  911. if (m_fFirstCreateNodeCall)
  912. {
  913. if ((apNodeInfo[0]->dwType == XML_COMMENT) ||
  914. (apNodeInfo[0]->dwType == XML_XMLDECL) ||
  915. (apNodeInfo[0]->dwType == XML_WHITESPACE))
  916. {
  917. hr = S_OK;
  918. goto Cont;
  919. }
  920. m_fFirstCreateNodeCall = FALSE;
  921. IFCOMFAILED_EXIT(this->FirstCreateNodeCall(pSource, pNodeParent, NodeCount, pSXSNodeInfo));
  922. }
  923. Cont:
  924. if (m_cUnknownChildDepth == 0)
  925. {
  926. for (i=0; i<NUMBER_OF(s_rgWorkers); i++)
  927. {
  928. bool fTemp = false;
  929. if ((s_rgWorkers[i].m_xpsOld == eNotParsing) ||
  930. (m_xpsParseState == s_rgWorkers[i].m_xpsOld))
  931. fTemp = true;
  932. const bool fParseStateMatches = fTemp;
  933. fTemp = false;
  934. if (fParseStateMatches)
  935. {
  936. if (s_rgWorkers[i].m_dwType == apNodeInfo[0]->dwType)
  937. fTemp = true;
  938. }
  939. const bool fTypeMatches = fTemp;
  940. fTemp = false;
  941. if (fTypeMatches)
  942. {
  943. if (s_rgWorkers[i].m_cchName == 0)
  944. fTemp = true;
  945. else
  946. {
  947. if (s_rgWorkers[i].m_cchNamespace == pSXSNodeInfo[0].NamespaceStringBuf.Cch())
  948. {
  949. if (s_rgWorkers[i].m_cchName == pSXSNodeInfo[0].cchText)
  950. {
  951. if (::FusionpCompareStrings(
  952. s_rgWorkers[i].m_pszNamespace,
  953. s_rgWorkers[i].m_cchNamespace,
  954. pSXSNodeInfo[0].NamespaceStringBuf,
  955. pSXSNodeInfo[0].NamespaceStringBuf.Cch(),
  956. false) == 0)
  957. {
  958. if (::FusionpCompareStrings(
  959. s_rgWorkers[i].m_pszName,
  960. s_rgWorkers[i].m_cchName,
  961. pSXSNodeInfo[0].pszText,
  962. pSXSNodeInfo[0].cchText,
  963. false) == 0)
  964. {
  965. fTemp = true;
  966. }
  967. }
  968. }
  969. }
  970. }
  971. }
  972. if (fTemp)
  973. {
  974. m_xpsParseState = s_rgWorkers[i].m_xpsNew;
  975. IFW32FALSE_EXIT(
  976. this->ValidateElementAttributes(
  977. pSXSNodeInfo,
  978. NodeCount,
  979. s_rgWorkers[i].m_prgLegalAttributes,
  980. s_rgWorkers[i].m_cLegalAttributes));
  981. if (s_rgWorkers[i].m_pfn != NULL)
  982. IFW32FALSE_EXIT((this->*s_rgWorkers[i].m_pfn)(NodeCount, pSXSNodeInfo));
  983. break;
  984. }
  985. }
  986. if (i == NUMBER_OF(s_rgWorkers))
  987. {
  988. bool fEquals;
  989. // If we hit an unrecognized element and its namespace is the one we own, error!
  990. IFW32FALSE_EXIT(
  991. pSXSNodeInfo[0].NamespaceStringBuf.Win32Equals(
  992. SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE,
  993. SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE_CCH,
  994. fEquals,
  995. false));
  996. if (fEquals)
  997. {
  998. this->LogParseError(
  999. MSG_SXS_MANIFEST_ELEMENT_USED_IN_INVALID_CONTEXT,
  1000. CUnicodeString(apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen),
  1001. CUnicodeString(m_ParseContext.ElementName, m_ParseContext.ElementNameCch));
  1002. ORIGINATE_WIN32_FAILURE_AND_EXIT(ElementInInvalidContext, ERROR_SXS_MANIFEST_PARSE_ERROR);
  1003. }
  1004. // For an unknown child element, the built-in XML parsing should start to ignore the subtree at this point.
  1005. if (apNodeInfo[0]->dwType == XML_ELEMENT)
  1006. m_cUnknownChildDepth = 1;
  1007. }
  1008. }
  1009. else
  1010. {
  1011. if ((NodeCount != 0) &&
  1012. (apNodeInfo[0]->dwType == XML_ELEMENT))
  1013. {
  1014. CUnicodeString s(apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen);
  1015. // We're handling an unknown series of elements; increment the depth.
  1016. m_cUnknownChildDepth++;
  1017. }
  1018. }
  1019. // Fire the right callbacks for XML_ELEMENT, XML_PCDATA and XML_CDATA nodes:
  1020. switch (apNodeInfo[0]->dwType)
  1021. {
  1022. case XML_ELEMENT:
  1023. #if defined(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_CHILDREN_NOT_ALLOWED)
  1024. if (m_cUnknownChildDepth != 0 && m_xpsParseState == eParsing_doc_assembly_noInherit)
  1025. {
  1026. hr = this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_CHILDREN_NOT_ALLOWED);
  1027. goto Exit;
  1028. }
  1029. #endif
  1030. if (m_buffElementPath.Cch() != 0)
  1031. IFW32FALSE_EXIT(m_buffElementPath.Win32Append(L"!", 1));
  1032. cchTemp = m_buffElementPath.Cch();
  1033. if (pSXSNodeInfo[0].NamespaceStringBuf.Cch() != 0)
  1034. {
  1035. IFW32FALSE_EXIT(m_buffElementPath.Win32Append(pSXSNodeInfo[0].NamespaceStringBuf));
  1036. IFW32FALSE_EXIT(m_buffElementPath.Win32Append(L"^", 1));
  1037. }
  1038. IFW32FALSE_EXIT(m_buffElementPath.Win32Append(pSXSNodeInfo[0].pszText, pSXSNodeInfo[0].cchText));
  1039. m_ParseContext.ElementPathCch = m_buffElementPath.Cch();
  1040. m_ParseContext.ElementPath = m_buffElementPath;
  1041. m_ParseContext.ElementName = static_cast<PCWSTR>(m_buffElementPath) + cchTemp;
  1042. m_ParseContext.ElementNameCch = m_buffElementPath.Cch() - cchTemp;
  1043. IFW32FALSE_EXIT(::SxspHashString(m_buffElementPath, m_buffElementPath.Cch(), &m_ParseContext.ElementHash, true));
  1044. m_ParseContext.XMLElementDepth++;
  1045. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1046. {
  1047. IFW32FALSE_EXIT(
  1048. m_ActCtxGenCtx->m_Contributors[i].Fire_ElementParsed(
  1049. m_ActCtxGenCtx,
  1050. m_AssemblyContext,
  1051. &m_ParseContext,
  1052. NodeCount,
  1053. pSXSNodeInfo));
  1054. }
  1055. break;
  1056. case XML_PCDATA:
  1057. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1058. {
  1059. IFW32FALSE_EXIT(
  1060. m_ActCtxGenCtx->m_Contributors[i].Fire_PCDATAParsed(
  1061. m_ActCtxGenCtx,
  1062. m_AssemblyContext,
  1063. &m_ParseContext,
  1064. apNodeInfo[0]->pwcText,
  1065. apNodeInfo[0]->ulLen));
  1066. }
  1067. break;
  1068. case XML_CDATA:
  1069. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1070. {
  1071. IFW32FALSE_EXIT(
  1072. m_ActCtxGenCtx->m_Contributors[i].Fire_CDATAParsed(
  1073. m_ActCtxGenCtx,
  1074. m_AssemblyContext,
  1075. &m_ParseContext,
  1076. apNodeInfo[0]->pwcText,
  1077. apNodeInfo[0]->ulLen));
  1078. }
  1079. break;
  1080. }
  1081. #if FUSION_XML_TREE
  1082. IFCOMFAILED_EXIT(this->CreateXmlNode(m_CurrentParent, NodeCount, apNodeInfo, pXmlNode));
  1083. // If we don't get a node back, just ignore it...
  1084. if (pXmlNode != NULL)
  1085. {
  1086. if (m_CurrentParent == NULL)
  1087. {
  1088. // Only XML Decls, PIs and the root document are at depth 0 or 1...
  1089. ASSERT(m_ParseContext.XMLElementDepth <= 1);
  1090. InsertTailList(&m_XmlDocument.ElementListHead, &pXmlNode->SiblingLink);
  1091. }
  1092. else
  1093. {
  1094. ASSERT(m_ParseContext.XMLElementDepth >= 1);
  1095. InsertTailList(&m_CurrentParent->Element.ChildListHead, &pXmlNode->SiblingLink);
  1096. }
  1097. if ((pXmlNode->Type != SXS_XML_NODE_TYPE_CDATA) &&
  1098. (pXmlNode->Type != SXS_XML_NODE_TYPE_PCDATA))
  1099. m_CurrentParent = pXmlNode;
  1100. pXmlNode = NULL;
  1101. }
  1102. #endif
  1103. hr = NOERROR;
  1104. Exit:
  1105. if (pSXSNodeInfo != NULL)
  1106. FUSION_DELETE_ARRAY(pSXSNodeInfo);
  1107. if (pXmlNode != NULL)
  1108. FUSION_DELETE_SINGLETON(pXmlNode);
  1109. return hr;
  1110. }
  1111. #if FUSION_XML_TREE
  1112. HRESULT
  1113. CNodeFactory::CreateXmlNode(
  1114. PSXS_XML_NODE pParent,
  1115. ULONG cNodes,
  1116. XML_NODE_INFO **prgpNodes,
  1117. PSXS_XML_NODE &rpNewNode
  1118. )
  1119. {
  1120. HRESULT hr = NOERROR;
  1121. FN_TRACE_HR(hr);
  1122. ULONG i;
  1123. ULONG cAttributes = 0;
  1124. ULONG iAttribute = 0;
  1125. PSXS_XML_NODE pNewNode = NULL;
  1126. PSXS_XML_ATTRIBUTE pAttribute = NULL;
  1127. CStringBuffer buffAttributeValue;
  1128. // Handle XML_ELEMENT vs. XML_CDATA vs. XML_PCDATA...
  1129. switch (prgpNodes[0]->dwType)
  1130. {
  1131. case XML_XMLDECL:
  1132. // <?xml version="1.0" ?> elements come through looking like normal XML_ELEMENT
  1133. // nodes with things broken into the XML_ATTRIBUTE followed by their value...
  1134. // First, let's count up the attributes...
  1135. for (i=0; i<cNodes; i++)
  1136. {
  1137. if (prgpNodes[i]->dwType == XML_ATTRIBUTE)
  1138. cAttributes++;
  1139. }
  1140. // Now let's allocate the SXS_XML_NODE plus the right number of SXS_XML_ATTRIBUTEs
  1141. IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast<PSXS_XML_NODE>(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE) + (cAttributes * sizeof(SXS_XML_ATTRIBUTE)), SXS_XML_NODE)));
  1142. pAttribute = reinterpret_cast<PSXS_XML_ATTRIBUTE>(pNewNode + 1);
  1143. pNewNode->Flags = 0;
  1144. pNewNode->Type = SXS_XML_NODE_TYPE_XML_DECL;
  1145. pNewNode->Parent = pParent;
  1146. pNewNode->XMLDecl.AttributeCount = cAttributes;
  1147. pNewNode->XMLDecl.Attributes = pAttribute;
  1148. for (i=0; i<cNodes; i++)
  1149. {
  1150. ULONG j;
  1151. const WCHAR *prgwch1;
  1152. const WCHAR *prgwch2;
  1153. ULONG ulPK1, ulPK2;
  1154. ULONG ulPos1, ulPos2;
  1155. ULONG cch;
  1156. switch (prgpNodes[i]->dwType)
  1157. {
  1158. case XML_XMLDECL:
  1159. INTERNAL_ERROR_CHECK(i == 0);
  1160. break;
  1161. case XML_ATTRIBUTE:
  1162. INTERNAL_ERROR_CHECK(iAttribute < cAttributes);
  1163. ulPKl = ::FusionpHashUnicodeStringCaseSensitive(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen);
  1164. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, ulPK1, ulPos1, prgwch1));
  1165. i++;
  1166. buffAttributeValue.Clear();
  1167. cch = 0;
  1168. while ((i < cNodes) && (prgpNodes[i]->dwType == XML_PCDATA))
  1169. {
  1170. IFCOMFAILED_EXIT(buffAttributeValue.Append(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen));
  1171. cch += prgpNodes[i]->ulLen;
  1172. i++;
  1173. }
  1174. // Gets incremented on the next iteration of the outer loop, so back up one...
  1175. i--;
  1176. IFW32FALSE_EXIT(::FusionpHashUnicodeString(buffAttributeValue, cch, &ulPK2, false));
  1177. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(buffAttributeValue, cch, ulPK2, ulPos2, prgwch2));
  1178. pAttribute[iAttribute].Flags = 0;
  1179. pAttribute[iAttribute].NamespaceString = 0;
  1180. pAttribute[iAttribute].NameString = ulPos1;
  1181. pAttribute[iAttribute].ValueString = ulPos2;
  1182. iAttribute++;
  1183. break;
  1184. }
  1185. }
  1186. ASSERT(iAttribute == cAttributes);
  1187. break;
  1188. case XML_ELEMENT:
  1189. // First, let's count up the attributes...
  1190. for (i=0; i<cNodes; i++)
  1191. {
  1192. if (prgpNodes[i]->dwType == XML_ATTRIBUTE)
  1193. cAttributes++;
  1194. }
  1195. // Now let's allocate the SXS_XML_NODE plus the right number of SXS_XML_ATTRIBUTEs
  1196. IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast<PSXS_XML_NODE>(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE) + (cAttributes * sizeof(SXS_XML_ATTRIBUTE)), SXS_XML_NODE)));
  1197. pAttribute = reinterpret_cast<PSXS_XML_ATTRIBUTE>(pNewNode + 1);
  1198. pNewNode->Flags = 0;
  1199. pNewNode->Type = SXS_XML_NODE_TYPE_ELEMENT;
  1200. pNewNode->Element.NamespaceString = 0;
  1201. pNewNode->Element.NameString = 0;
  1202. pNewNode->Parent = pParent;
  1203. pNewNode->Element.AttributeCount = cAttributes;
  1204. pNewNode->Element.Attributes = pAttribute;
  1205. InitializeListHead(&pNewNode->Element.ChildListHead);
  1206. for (i=0; i<cNodes; i++)
  1207. {
  1208. ULONG j;
  1209. const WCHAR *prgwch1;
  1210. const WCHAR *prgwch2;
  1211. ULONG ulPK1, ulPK2;
  1212. ULONG ulPos1, ulPos2;
  1213. ULONG cch;
  1214. switch (prgpNodes[i]->dwType)
  1215. {
  1216. case XML_ELEMENT:
  1217. INTERNAL_ERROR_CHECK(i == 0);
  1218. IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK1, false));
  1219. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK1, ulPos1, prgwch1));
  1220. pNewNode->Element.NamespaceString = 0;
  1221. pNewNode->Element.NameString = ulPos1;
  1222. break;
  1223. case XML_ATTRIBUTE:
  1224. INTERNAL_ERROR_CHECK(iAttribute < cAttributes);
  1225. IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, &ulPK1, false));
  1226. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, ulPK1, ulPos1, prgwch1));
  1227. i++;
  1228. buffAttributeValue.Clear();
  1229. cch = 0;
  1230. while ((i < cNodes) && (prgpNodes[i]->dwType == XML_PCDATA))
  1231. {
  1232. IFCOMFAILED_EXIT(buffAttributeValue.Append(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen));
  1233. cch += prgpNodes[i]->ulLen;
  1234. i++;
  1235. }
  1236. // Gets incremented on the next iteration of the outer loop, so back up one...
  1237. i--;
  1238. IFW32FALSE_EXIT(::FusionpHashUnicodeString(buffAttributeValue, cch, &ulPK2, false));
  1239. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(buffAttributeValue, cch, ulPK2, ulPos2, prgwch2));
  1240. pAttribute[iAttribute].Flags = 0;
  1241. pAttribute[iAttribute].NamespaceString = 0;
  1242. pAttribute[iAttribute].NameString = ulPos1;
  1243. pAttribute[iAttribute].ValueString = ulPos2;
  1244. iAttribute++;
  1245. break;
  1246. }
  1247. }
  1248. ASSERT(iAttribute == cAttributes);
  1249. break;
  1250. case XML_CDATA:
  1251. {
  1252. ULONG ulPK;
  1253. ULONG ulPos;
  1254. const WCHAR *prgwch;
  1255. IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK, false));
  1256. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK, ulPos, prgwch));
  1257. // Now let's allocate the SXS_XML_NODE
  1258. IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast<PSXS_XML_NODE>(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE), SXS_XML_NODE)));
  1259. pNewNode->Flags = 0;
  1260. pNewNode->Type = SXS_XML_NODE_TYPE_CDATA;
  1261. pNewNode->Parent = pParent;
  1262. pNewNode->CDataString = ulPos;
  1263. break;
  1264. }
  1265. case XML_PCDATA:
  1266. {
  1267. ULONG ulPK;
  1268. ULONG ulPos;
  1269. const WCHAR *prgwch;
  1270. IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK, false));
  1271. IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK, ulPos, prgwch));
  1272. // Now let's allocate the SXS_XML_NODE
  1273. IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast<PSXS_XML_NODE>(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE), SXS_XML_NODE)));
  1274. pNewNode->Flags = 0;
  1275. pNewNode->Type = SXS_XML_NODE_TYPE_PCDATA;
  1276. pNewNode->Parent = pParent;
  1277. pNewNode->PCDataString = ulPos;
  1278. break;
  1279. }
  1280. }
  1281. rpNewNode = pNewNode;
  1282. pNewNode = NULL;
  1283. hr = NOERROR;
  1284. Exit:
  1285. FUSION_RAW_DEALLOC(pNewNode);
  1286. return hr;
  1287. }
  1288. #endif // FUSION_XML_TREE
  1289. BOOL
  1290. CNodeFactory::SetParseType(
  1291. ULONG ParseType,
  1292. ULONG PathType,
  1293. const CBaseStringBuffer &Path,
  1294. const FILETIME &rftLastWriteTime
  1295. )
  1296. {
  1297. BOOL fSuccess = FALSE;
  1298. FN_TRACE_WIN32(fSuccess);
  1299. PARAMETER_CHECK(
  1300. (ParseType == XML_FILE_TYPE_MANIFEST) ||
  1301. (ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) ||
  1302. (ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION));
  1303. PARAMETER_CHECK(PathType == ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE);
  1304. IFW32FALSE_EXIT(m_buffCurrentFileName.Win32Assign(Path));
  1305. m_ParseContext.SourceFilePathType = PathType;
  1306. m_ParseContext.SourceFile = m_buffCurrentFileName;
  1307. m_ParseContext.SourceFileCch = m_buffCurrentFileName.Cch();
  1308. m_ParseContext.SourceFileLastWriteTime = rftLastWriteTime;
  1309. m_ParseType = ParseType;
  1310. fSuccess = TRUE;
  1311. Exit:
  1312. return fSuccess;
  1313. }
  1314. BOOL
  1315. CNodeFactory::XMLParser_Element_doc_assembly(
  1316. USHORT cNumRecs,
  1317. PCSXS_NODE_INFO prgNodeInfo
  1318. )
  1319. {
  1320. BOOL fSuccess = FALSE;
  1321. FN_TRACE_WIN32(fSuccess);
  1322. ULONG i;
  1323. ASSERT(cNumRecs != 0);
  1324. ASSERT(prgNodeInfo != NULL);
  1325. if (m_fAssemblyFound)
  1326. {
  1327. CUnicodeString s;
  1328. PCWSTR ManifestPath;
  1329. IFW32FALSE_EXIT(m_Assembly->GetManifestPath(&ManifestPath, NULL));
  1330. s = ManifestPath;
  1331. this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_TOP_ASSEMBLY, &s);
  1332. goto Exit;
  1333. }
  1334. m_fAssemblyFound = true;
  1335. m_fMetadataSatelliteAlreadyFound = false;
  1336. // Now let's tell all the contributors that we're about to begin a parsing session.
  1337. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1338. {
  1339. IFW32FALSE_EXIT(m_ActCtxGenCtx->m_Contributors[i].Fire_ParseBeginning(
  1340. m_ActCtxGenCtx,
  1341. m_AssemblyContext,
  1342. 0, // FileFlags
  1343. m_ParseType,
  1344. m_ParseContext.SourceFilePathType,
  1345. m_ParseContext.SourceFile,
  1346. m_ParseContext.SourceFileCch,
  1347. m_ParseContext.SourceFileLastWriteTime,
  1348. m_Assembly->m_ManifestVersionMajor,
  1349. m_Assembly->m_ManifestVersionMinor,
  1350. m_Assembly->m_MetadataSatelliteRosterIndex));
  1351. }
  1352. fSuccess = TRUE;
  1353. Exit:
  1354. return fSuccess;
  1355. }
  1356. BOOL
  1357. CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity(
  1358. USHORT cNumRecs,
  1359. PCSXS_NODE_INFO prgNodeInfo
  1360. )
  1361. {
  1362. BOOL fSuccess = FALSE;
  1363. FN_TRACE_WIN32(fSuccess);
  1364. PASSEMBLY_IDENTITY AssemblyIdentity = NULL;
  1365. const BOOL fGeneratingActCtx = (m_ActCtxGenCtx->m_ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  1366. ULONG i;
  1367. DWORD dwValidateFlags = 0;
  1368. if (m_fIdentityFound)
  1369. {
  1370. this->LogParseError(MSG_SXS_MULTIPLE_IDENTITY, CEventLogString(prgNodeInfo[0].pszText, prgNodeInfo[0].cchText));
  1371. ::FusionpDbgPrintEx(
  1372. FUSION_DBG_LEVEL_ERROR,
  1373. "SXS.DLL: Manifest %ls has multiple identities\n", static_cast<PCWSTR>(m_buffCurrentFileName));
  1374. ORIGINATE_WIN32_FAILURE_AND_EXIT(
  1375. MultipleIdentities,
  1376. ERROR_SXS_MANIFEST_PARSE_ERROR);
  1377. }
  1378. m_fIdentityFound = true;
  1379. IFW32FALSE_EXIT(
  1380. ::SxspCreateAssemblyIdentityFromIdentityElement(
  1381. 0, // DWORD Flags,
  1382. &m_ParseContext,
  1383. ASSEMBLY_IDENTITY_TYPE_DEFINITION, // ULONG Type,
  1384. &AssemblyIdentity, // PASSEMBLY_IDENTITY *AssemblyIdentityOut,
  1385. cNumRecs,
  1386. prgNodeInfo));
  1387. // If the identity that was created is a policy statement, then we
  1388. // set the internal parse type to our special 'intuited' parse type
  1389. // for later checks of missing attributes and whatnot. This does
  1390. // duplicate work in ValidateAssembly that does the same thing, but
  1391. // we need to preemptively set this parse type before we go validating.
  1392. // if (m_IntuitedParseType == eActualParseType_Undetermined)
  1393. {
  1394. BOOL fIsPolicy = FALSE;
  1395. IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy));
  1396. if (fIsPolicy)
  1397. m_IntuitedParseType = eActualParseType_PolicyManifest;
  1398. else
  1399. m_IntuitedParseType = eActualParseType_Manifest;
  1400. }
  1401. if ((m_IntuitedParseType == eActualParseType_Manifest) ||
  1402. (m_IntuitedParseType == eActualParseType_PolicyManifest) ||
  1403. (m_ParseType == XML_FILE_TYPE_MANIFEST) ||
  1404. (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION))
  1405. {
  1406. dwValidateFlags = eValidateIdentity_VersionRequired;
  1407. }
  1408. IFW32FALSE_EXIT(
  1409. this->ValidateIdentity(
  1410. dwValidateFlags,
  1411. ASSEMBLY_IDENTITY_TYPE_DEFINITION,
  1412. AssemblyIdentity));
  1413. if (fGeneratingActCtx)
  1414. {
  1415. if (m_Assembly->IsRoot())
  1416. {
  1417. // If we're generating the actctx and this is the root assembly, it's possible
  1418. // that we got to it by a filesystem path (e.g. private assembly) rather than
  1419. // an actual reference, so we need to fix up the assembly's identity information
  1420. // appropriately.
  1421. IFW32FALSE_EXIT(m_Assembly->m_Information.SetProbedIdentity(AssemblyIdentity));
  1422. }
  1423. else
  1424. {
  1425. // If we're generating the actctx and this isn't the root assembly, we need to verify
  1426. // that it's the right one.
  1427. BOOL fEqual;
  1428. IFW32FALSE_EXIT(
  1429. ::SxsAreAssemblyIdentitiesEqual(
  1430. SXS_ARE_ASSEMBLY_IDENTITIES_EQUAL_FLAG_ALLOW_REF_TO_MATCH_DEF,
  1431. m_Assembly->GetAssemblyIdentity(),
  1432. AssemblyIdentity,
  1433. &fEqual));
  1434. if (!fEqual)
  1435. {
  1436. this->LogParseError(MSG_SXS_COMPONENT_MANIFEST_PROBED_IDENTITY_MISMATCH);
  1437. // LogParseError sets the last error appropriate to the message logged
  1438. goto Exit;
  1439. }
  1440. }
  1441. }
  1442. if (m_IntuitedParseType == eActualParseType_PolicyManifest)
  1443. {
  1444. IFALLOCFAILED_EXIT(m_CurrentPolicyStatement = new CPolicyStatement);
  1445. IFW32FALSE_EXIT(m_CurrentPolicyStatement->Initialize());
  1446. }
  1447. // Tell everyone that we're sure who we are...
  1448. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1449. {
  1450. IFW32FALSE_EXIT(
  1451. m_ActCtxGenCtx->m_Contributors[i].Fire_IdentityDetermined(
  1452. m_ActCtxGenCtx,
  1453. m_AssemblyContext,
  1454. &m_ParseContext,
  1455. AssemblyIdentity));
  1456. }
  1457. // fix up assembly and assembly context so we know where to copy to
  1458. // also save the manifest
  1459. IFW32FALSE_EXIT(m_Assembly->m_Information.SetAssemblyIdentity(AssemblyIdentity));
  1460. if (m_AssemblyContext->AssemblyIdentity != NULL)
  1461. ::SxsDestroyAssemblyIdentity(const_cast<PASSEMBLY_IDENTITY>(m_AssemblyContext->AssemblyIdentity));
  1462. m_AssemblyContext->AssemblyIdentity = AssemblyIdentity;
  1463. AssemblyIdentity = NULL;
  1464. fSuccess = TRUE;
  1465. Exit:
  1466. if (AssemblyIdentity != NULL)
  1467. ::SxsDestroyAssemblyIdentity(AssemblyIdentity);
  1468. return fSuccess;
  1469. }
  1470. BOOL
  1471. CNodeFactory::XMLParser_Element_doc_assembly_noInherit(
  1472. USHORT cNumRecs,
  1473. PCSXS_NODE_INFO prgNodeInfo
  1474. )
  1475. {
  1476. BOOL fSuccess = FALSE;
  1477. FN_TRACE_WIN32(fSuccess);
  1478. INTERNAL_ERROR_CHECK(
  1479. (m_ParseType == XML_FILE_TYPE_MANIFEST) ||
  1480. (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) ||
  1481. (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION));
  1482. switch (m_ParseType)
  1483. {
  1484. case XML_FILE_TYPE_MANIFEST:
  1485. if (cNumRecs != 1)
  1486. {
  1487. this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_ATTRIBUTES_NOT_ALLOWED);
  1488. goto Exit;
  1489. }
  1490. if (m_ActCtxGenCtx->m_NoInherit)
  1491. {
  1492. this->LogParseError(MSG_SXS_MANIFEST_PARSE_MULTIPLE_NO_INHERIT);
  1493. goto Exit;
  1494. }
  1495. if (m_fIdentityFound)
  1496. {
  1497. this->LogParseError(
  1498. MSG_SXS_MANIFEST_ELEMENT_MUST_OCCUR_BEFORE,
  1499. CEventLogString(L"noInherit"),
  1500. CEventLogString(L"assemblyIdentity"));
  1501. goto Exit;
  1502. }
  1503. m_ActCtxGenCtx->m_NoInherit = true;
  1504. break;
  1505. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  1506. this->LogParseError(MSG_SXS_POLICY_PARSE_NO_INHERIT_NOT_ALLOWED);
  1507. goto Exit;
  1508. default:
  1509. ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR);
  1510. goto Exit;
  1511. }
  1512. fSuccess = TRUE;
  1513. Exit:
  1514. return fSuccess;
  1515. }
  1516. BOOL
  1517. CNodeFactory::XMLParser_Element_doc_assembly_noInheritable(
  1518. USHORT cNumRecs,
  1519. PCSXS_NODE_INFO prgNodeInfo
  1520. )
  1521. {
  1522. BOOL fSuccess = FALSE;
  1523. FN_TRACE_WIN32(fSuccess);
  1524. INTERNAL_ERROR_CHECK(
  1525. (m_ParseType == XML_FILE_TYPE_MANIFEST) ||
  1526. (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) ||
  1527. (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION));
  1528. switch (m_ParseType)
  1529. {
  1530. case XML_FILE_TYPE_MANIFEST:
  1531. if (cNumRecs != 1)
  1532. {
  1533. this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_ATTRIBUTES_NOT_ALLOWED);
  1534. goto Exit;
  1535. }
  1536. if (m_fNoInheritableFound)
  1537. {
  1538. this->LogParseError(MSG_SXS_MANIFEST_PARSE_MULTIPLE_NOINHERITABLE);
  1539. goto Exit;
  1540. }
  1541. if (m_fIdentityFound)
  1542. {
  1543. this->LogParseError(
  1544. MSG_SXS_MANIFEST_ELEMENT_MUST_OCCUR_BEFORE,
  1545. CEventLogString(L"noInheritable"),
  1546. CEventLogString(L"assemblyIdentity"));
  1547. goto Exit;
  1548. }
  1549. m_fNoInheritableFound = true;
  1550. break;
  1551. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  1552. case XML_FILE_TYPE_COMPONENT_CONFIGURATION:
  1553. this->LogParseError(MSG_SXS_POLICY_PARSE_NO_INHERIT_NOT_ALLOWED);
  1554. goto Exit;
  1555. default:
  1556. ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR);
  1557. goto Exit;
  1558. }
  1559. fSuccess = TRUE;
  1560. Exit:
  1561. return fSuccess;
  1562. }
  1563. BOOL
  1564. CNodeFactory::XMLParser_Element_doc_assembly_dependency(
  1565. USHORT cNumRecs,
  1566. PCSXS_NODE_INFO prgNodeInfo
  1567. )
  1568. {
  1569. BOOL fSuccess = FALSE;
  1570. FN_TRACE_WIN32(fSuccess);
  1571. bool fFound;
  1572. SIZE_T cb;
  1573. m_fIsDependencyOptional = false;
  1574. m_fDependencyChildHit = false;
  1575. m_fIsMetadataSatellite = false;
  1576. IFW32FALSE_EXIT(
  1577. ::SxspGetAttributeValue(
  1578. 0,
  1579. &s_AttributeName_optional,
  1580. prgNodeInfo,
  1581. cNumRecs,
  1582. &m_ParseContext,
  1583. fFound,
  1584. sizeof(m_fIsDependencyOptional),
  1585. &m_fIsDependencyOptional,
  1586. cb,
  1587. &::SxspValidateBoolAttribute,
  1588. 0));
  1589. if (!fFound)
  1590. m_fIsDependencyOptional = false;
  1591. fSuccess = TRUE;
  1592. Exit:
  1593. return fSuccess;
  1594. }
  1595. BOOL
  1596. CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly(
  1597. USHORT cNumRecs,
  1598. PCSXS_NODE_INFO prgNodeInfo
  1599. )
  1600. {
  1601. BOOL fSuccess = FALSE;
  1602. FN_TRACE_WIN32(fSuccess);
  1603. bool fFound;
  1604. SIZE_T cb;
  1605. if (m_fDependencyChildHit == false)
  1606. {
  1607. m_fDependencyChildHit = true;
  1608. }
  1609. else
  1610. {
  1611. this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_DEPENDENTASSEMBLY_IN_DEPENDENCY);
  1612. goto Exit;
  1613. }
  1614. m_fAssemblyIdentityChildOfDependenctAssemblyHit = false;
  1615. IFW32FALSE_EXIT(
  1616. ::SxspGetAttributeValue(
  1617. 0,
  1618. &s_AttributeName_metadataSatellite,
  1619. prgNodeInfo,
  1620. cNumRecs,
  1621. &m_ParseContext,
  1622. fFound,
  1623. sizeof(m_fIsMetadataSatellite),
  1624. &m_fIsMetadataSatellite,
  1625. cb,
  1626. &::SxspValidateBoolAttribute,
  1627. 0));
  1628. if (!fFound)
  1629. m_fIsMetadataSatellite = false;
  1630. fSuccess = TRUE;
  1631. Exit:
  1632. return fSuccess;
  1633. }
  1634. BOOL
  1635. CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly_bindingRedirect(
  1636. USHORT cNumRecs,
  1637. PCSXS_NODE_INFO prgNodeInfo
  1638. )
  1639. {
  1640. BOOL fSuccess = FALSE;
  1641. FN_TRACE_WIN32(fSuccess);
  1642. bool fFound;
  1643. bool fValid;
  1644. SIZE_T cb;
  1645. CSmallStringBuffer buffOldVersion;
  1646. CSmallStringBuffer buffNewVersion;
  1647. INTERNAL_ERROR_CHECK(m_CurrentPolicyStatement != NULL);
  1648. if (m_IntuitedParseType != eActualParseType_PolicyManifest)
  1649. {
  1650. this->LogParseError(MSG_SXS_BINDING_REDIRECTS_ONLY_IN_COMPONENT_CONFIGURATION);
  1651. goto Exit;
  1652. }
  1653. IFW32FALSE_EXIT(
  1654. ::SxspGetAttributeValue(
  1655. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  1656. &s_AttributeName_oldVersion,
  1657. prgNodeInfo,
  1658. cNumRecs,
  1659. &m_ParseContext,
  1660. fFound,
  1661. sizeof(buffOldVersion),
  1662. &buffOldVersion,
  1663. cb,
  1664. NULL,
  1665. 0));
  1666. INTERNAL_ERROR_CHECK(fFound);
  1667. IFW32FALSE_EXIT(
  1668. ::SxspGetAttributeValue(
  1669. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  1670. &s_AttributeName_newVersion,
  1671. prgNodeInfo,
  1672. cNumRecs,
  1673. &m_ParseContext,
  1674. fFound,
  1675. sizeof(buffNewVersion),
  1676. &buffNewVersion,
  1677. cb,
  1678. NULL,
  1679. 0));
  1680. INTERNAL_ERROR_CHECK(fFound);
  1681. IFW32FALSE_EXIT(m_CurrentPolicyStatement->AddRedirect(buffOldVersion, buffNewVersion, fValid));
  1682. if (!fValid)
  1683. {
  1684. this->LogParseError(MSG_SXS_BINDING_REDIRECT_MISSING_REQUIRED_ATTRIBUTES);
  1685. goto Exit;
  1686. }
  1687. fSuccess = TRUE;
  1688. Exit:
  1689. return fSuccess;
  1690. }
  1691. BOOL
  1692. CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly_assemblyIdentity(
  1693. USHORT cNumRecs,
  1694. PCSXS_NODE_INFO prgNodeInfo
  1695. )
  1696. {
  1697. BOOL fSuccess = FALSE;
  1698. FN_TRACE_WIN32(fSuccess);
  1699. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  1700. ULONG ParseType;
  1701. ASSERT(cNumRecs != 0);
  1702. ASSERT(prgNodeInfo != NULL);
  1703. // We're either parsing a manifest or a policy file; what else??
  1704. INTERNAL_ERROR_CHECK(
  1705. (m_ParseType == XML_FILE_TYPE_MANIFEST) ||
  1706. (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) ||
  1707. (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION));
  1708. if (m_fAssemblyIdentityChildOfDependenctAssemblyHit == false)
  1709. m_fAssemblyIdentityChildOfDependenctAssemblyHit = true;
  1710. else
  1711. {
  1712. this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_ASSEMBLYIDENTITY_IN_DEPENDENCYASSEMBLY);
  1713. goto Exit;
  1714. }
  1715. switch (m_IntuitedParseType)
  1716. {
  1717. case eActualParseType_Undetermined:
  1718. ParseType = m_ParseType;
  1719. break;
  1720. case eActualParseType_PolicyManifest:
  1721. ParseType = XML_FILE_TYPE_COMPONENT_CONFIGURATION;
  1722. break;
  1723. case eActualParseType_Manifest:
  1724. ParseType = XML_FILE_TYPE_MANIFEST;
  1725. break;
  1726. default:
  1727. INTERNAL_ERROR_CHECK(FALSE);
  1728. ParseType = m_ParseType;
  1729. break;
  1730. }
  1731. switch (ParseType)
  1732. {
  1733. case XML_FILE_TYPE_MANIFEST:
  1734. IFW32FALSE_EXIT(
  1735. ::SxspCreateAssemblyIdentityFromIdentityElement(
  1736. 0,
  1737. &m_ParseContext,
  1738. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1739. &pAssemblyIdentity,
  1740. cNumRecs,
  1741. prgNodeInfo));
  1742. IFW32FALSE_EXIT(
  1743. this->ValidateIdentity(
  1744. eValidateIdentity_VersionRequired | eValidateIdentity_PoliciesNotAllowed,
  1745. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1746. pAssemblyIdentity));
  1747. // If we're not installing, process the identity...
  1748. if (m_ActCtxGenCtx->m_ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  1749. IFW32FALSE_EXIT(::SxspEnqueueAssemblyReference(m_ActCtxGenCtx, m_Assembly, pAssemblyIdentity, m_fIsDependencyOptional, m_fIsMetadataSatellite));
  1750. break;
  1751. case XML_FILE_TYPE_COMPONENT_CONFIGURATION:
  1752. {
  1753. BOOL fValidDependencyAssemblyIdentity = FALSE;
  1754. PCWSTR pszName1 = NULL, pszName2 = NULL;
  1755. SIZE_T cchName1 = 0, cchName2 = 0;
  1756. if (m_CurrentPolicyDependentAssemblyIdentity != NULL)
  1757. {
  1758. this->LogParseError(MSG_SXS_COMPONENT_CONFIGURATION_MANIFESTS_MAY_ONLY_HAVE_ONE_DEPENDENCY);
  1759. goto Exit;
  1760. }
  1761. IFW32FALSE_EXIT(
  1762. ::SxspCreateAssemblyIdentityFromIdentityElement(
  1763. 0,
  1764. &m_ParseContext,
  1765. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1766. &pAssemblyIdentity,
  1767. cNumRecs,
  1768. prgNodeInfo));
  1769. // check the name in dependency-assemblyidentity match with the name in assembly-assemblyidentity
  1770. IFW32FALSE_EXIT(
  1771. ::SxspGetAssemblyIdentityAttributeValue(
  1772. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  1773. m_Assembly->GetAssemblyIdentity(),
  1774. &s_IdentityAttribute_name,
  1775. &pszName1, // something in a format of "Policy.1212.1221.assemblyname"
  1776. &cchName1));
  1777. IFW32FALSE_EXIT(
  1778. ::SxspGetAssemblyIdentityAttributeValue(
  1779. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  1780. pAssemblyIdentity,
  1781. &s_IdentityAttribute_name,
  1782. &pszName2, // would be something as "assemblyname"
  1783. &cchName2));
  1784. if ((cchName1 > cchName2) && (cchName2 !=0))
  1785. {
  1786. if ( (*(pszName1 + (cchName1 - cchName2 -1)) == L'.') && (::FusionpCompareStrings(
  1787. pszName1 + (cchName1 - cchName2), cchName2,
  1788. pszName2, cchName2, FALSE // must be case-sensitive for values
  1789. ) == 0 ))
  1790. {
  1791. fValidDependencyAssemblyIdentity = TRUE;
  1792. }
  1793. }
  1794. if (fValidDependencyAssemblyIdentity)
  1795. {
  1796. IFW32FALSE_EXIT(
  1797. this->ValidateIdentity(
  1798. eValidateIdentity_VersionNotAllowed | eValidateIdentity_PoliciesNotAllowed,
  1799. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1800. pAssemblyIdentity));
  1801. // We'll keep track of this so that we can recognize multiple dependentAssembly elements on installation
  1802. // of policies.
  1803. m_CurrentPolicyDependentAssemblyIdentity = pAssemblyIdentity;
  1804. pAssemblyIdentity = NULL;
  1805. }
  1806. else // print a message and ignore this entry
  1807. {
  1808. ::FusionpDbgPrintEx(
  1809. FUSION_DBG_LEVEL_POLICY | FUSION_DBG_LEVEL_INFO,
  1810. "SXS.DLL: unexpected assemblyidentity within dependency tag in component policy \"%ls\"\n",
  1811. m_buffCurrentFileName
  1812. );
  1813. }
  1814. } // end of this case
  1815. break;
  1816. #if 0
  1817. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  1818. IFW32FALSE_EXIT(this->ParseElementAttributes(cNumRecs, prgpNodeInfo, NUMBER_OF(rgPolicyAttributes), rgPolicyAttributes));
  1819. if (!(m_fAssemblyNamePresent && m_fOldVersionPresent && m_fNewVersionPresent))
  1820. {
  1821. ::FusionpDbgPrintEx(
  1822. FUSION_DBG_LEVEL_ERROR,
  1823. "SXS.DLL: Policy dependency tag found and either assemblyname, oldversion or newversion attributes are missing\n");
  1824. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  1825. goto Exit;
  1826. }
  1827. break;
  1828. #endif // 0
  1829. default:
  1830. // Internal error!
  1831. INTERNAL_ERROR_CHECK(FALSE);
  1832. }
  1833. fSuccess = TRUE;
  1834. Exit:
  1835. if (pAssemblyIdentity != NULL)
  1836. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  1837. return fSuccess;
  1838. }
  1839. BOOL
  1840. CNodeFactory::XMLParser_Element_doc_configuration(
  1841. USHORT cNumRecs,
  1842. PCSXS_NODE_INFO prgNodeInfo
  1843. )
  1844. {
  1845. BOOL fSuccess = FALSE;
  1846. FN_TRACE_WIN32(fSuccess);
  1847. ULONG i;
  1848. ASSERT(cNumRecs != 0);
  1849. ASSERT(prgNodeInfo != NULL);
  1850. if (m_fAssemblyFound)
  1851. {
  1852. CUnicodeString s;
  1853. PCWSTR ManifestPath;
  1854. IFW32FALSE_EXIT(m_Assembly->GetManifestPath(&ManifestPath, NULL));
  1855. s = ManifestPath;
  1856. this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_TOP_ASSEMBLY, &s);
  1857. goto Exit;
  1858. }
  1859. m_fAssemblyFound = true;
  1860. m_fMetadataSatelliteAlreadyFound = false;
  1861. // Now let's tell all the contributors that we're about to begin a parsing session.
  1862. for (i=0; i<m_ActCtxGenCtx->m_ContributorCount; i++)
  1863. {
  1864. IFW32FALSE_EXIT(
  1865. m_ActCtxGenCtx->m_Contributors[i].Fire_ParseBeginning(
  1866. m_ActCtxGenCtx,
  1867. m_AssemblyContext,
  1868. 0, // FileFlags
  1869. m_ParseType,
  1870. m_ParseContext.SourceFilePathType,
  1871. m_ParseContext.SourceFile,
  1872. m_ParseContext.SourceFileCch,
  1873. m_ParseContext.SourceFileLastWriteTime,
  1874. m_Assembly->m_ManifestVersionMajor,
  1875. m_Assembly->m_ManifestVersionMinor,
  1876. m_Assembly->m_MetadataSatelliteRosterIndex));
  1877. }
  1878. fSuccess = TRUE;
  1879. Exit:
  1880. return fSuccess;
  1881. }
  1882. BOOL
  1883. CNodeFactory::XMLParser_Element_doc_configuration_windows(
  1884. USHORT cNumRecs,
  1885. PCSXS_NODE_INFO prgNodeInfo
  1886. )
  1887. {
  1888. BOOL fSuccess = FALSE;
  1889. FN_TRACE_WIN32(fSuccess);
  1890. fSuccess = TRUE;
  1891. // Exit:
  1892. return fSuccess;
  1893. }
  1894. BOOL
  1895. CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding(
  1896. USHORT cNumRecs,
  1897. PCSXS_NODE_INFO prgNodeInfo
  1898. )
  1899. {
  1900. BOOL fSuccess = FALSE;
  1901. FN_TRACE_WIN32(fSuccess);
  1902. fSuccess = TRUE;
  1903. // Exit:
  1904. return fSuccess;
  1905. }
  1906. BOOL
  1907. CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_assemblyIdentity(
  1908. USHORT cNumRecs,
  1909. PCSXS_NODE_INFO prgNodeInfo
  1910. )
  1911. {
  1912. BOOL fSuccess = FALSE;
  1913. FN_TRACE_WIN32(fSuccess);
  1914. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  1915. IFW32FALSE_EXIT(
  1916. ::SxspCreateAssemblyIdentityFromIdentityElement(
  1917. 0,
  1918. &m_ParseContext,
  1919. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1920. &pAssemblyIdentity,
  1921. cNumRecs,
  1922. prgNodeInfo));
  1923. IFW32FALSE_EXIT(
  1924. this->ValidateIdentity(
  1925. eValidateIdentity_VersionRequired | eValidateIdentity_PoliciesNotAllowed,
  1926. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1927. pAssemblyIdentity));
  1928. fSuccess = TRUE;
  1929. Exit:
  1930. if (pAssemblyIdentity != NULL)
  1931. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  1932. return fSuccess;
  1933. }
  1934. BOOL
  1935. CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly(
  1936. USHORT cNumRecs,
  1937. PCSXS_NODE_INFO prgNodeInfo
  1938. )
  1939. {
  1940. BOOL fSuccess = FALSE;
  1941. FN_TRACE_WIN32(fSuccess);
  1942. fSuccess = TRUE;
  1943. // Exit:
  1944. return fSuccess;
  1945. }
  1946. BOOL
  1947. CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity(
  1948. USHORT cNumRecs,
  1949. PCSXS_NODE_INFO prgNodeInfo
  1950. )
  1951. {
  1952. BOOL fSuccess = FALSE;
  1953. FN_TRACE_WIN32(fSuccess);
  1954. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  1955. CPolicyStatement *pPolicyStatement = NULL;
  1956. IFW32FALSE_EXIT(
  1957. ::SxspCreateAssemblyIdentityFromIdentityElement(
  1958. 0,
  1959. &m_ParseContext,
  1960. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1961. &pAssemblyIdentity,
  1962. cNumRecs,
  1963. prgNodeInfo));
  1964. IFW32FALSE_EXIT(
  1965. this->ValidateIdentity(
  1966. eValidateIdentity_VersionNotAllowed | eValidateIdentity_PoliciesNotAllowed,
  1967. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  1968. pAssemblyIdentity));
  1969. IFW32FALSE_EXIT(
  1970. ::SxspGenerateTextuallyEncodedPolicyIdentityFromAssemblyIdentity(
  1971. SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION,
  1972. pAssemblyIdentity,
  1973. m_buffCurrentApplicationPolicyIdentityKey,
  1974. NULL));
  1975. IFW32FALSE_EXIT(m_ActCtxGenCtx->m_ApplicationPolicyTable.Find(m_buffCurrentApplicationPolicyIdentityKey, pPolicyStatement));
  1976. if (pPolicyStatement != NULL)
  1977. {
  1978. pPolicyStatement = NULL;
  1979. this->LogParseError(MSG_SXS_APPLICATION_CONFIGURATION_MANIFEST_MAY_ONLY_HAVE_ONE_DEPENDENTASSEMBLY_PER_IDENTITY);
  1980. goto Exit;
  1981. }
  1982. IFALLOCFAILED_EXIT(pPolicyStatement = new CPolicyStatement);
  1983. IFW32FALSE_EXIT(pPolicyStatement->Initialize());
  1984. IFW32FALSE_EXIT(m_ActCtxGenCtx->m_ApplicationPolicyTable.Insert(m_buffCurrentApplicationPolicyIdentityKey, pPolicyStatement));
  1985. m_CurrentPolicyStatement = pPolicyStatement;
  1986. pPolicyStatement = NULL;
  1987. if (m_CurrentPolicyDependentAssemblyIdentity != NULL)
  1988. {
  1989. ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity);
  1990. m_CurrentPolicyDependentAssemblyIdentity = NULL;
  1991. }
  1992. m_CurrentPolicyDependentAssemblyIdentity = pAssemblyIdentity;
  1993. pAssemblyIdentity = NULL;
  1994. fSuccess = TRUE;
  1995. Exit:
  1996. if (pAssemblyIdentity != NULL)
  1997. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  1998. if (pPolicyStatement != NULL)
  1999. FUSION_DELETE_SINGLETON(pPolicyStatement);
  2000. return fSuccess;
  2001. }
  2002. BOOL
  2003. CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect(
  2004. USHORT cNumRecs,
  2005. PCSXS_NODE_INFO prgNodeInfo
  2006. )
  2007. {
  2008. BOOL fSuccess = FALSE;
  2009. FN_TRACE_WIN32(fSuccess);
  2010. CSmallStringBuffer buffOldVersion;
  2011. CSmallStringBuffer buffNewVersion;
  2012. bool fFound;
  2013. bool fValid;
  2014. SIZE_T cb;
  2015. if (m_CurrentPolicyStatement == NULL)
  2016. {
  2017. this->LogParseError(MSG_SXS_APPLICATION_CONFIGURATION_MANIFEST_DEPENDENTASSEMBLY_MISSING_IDENTITY);
  2018. goto Exit;
  2019. }
  2020. IFW32FALSE_EXIT(
  2021. ::SxspGetAttributeValue(
  2022. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  2023. &s_AttributeName_oldVersion,
  2024. prgNodeInfo,
  2025. cNumRecs,
  2026. &m_ParseContext,
  2027. fFound,
  2028. sizeof(buffOldVersion),
  2029. &buffOldVersion,
  2030. cb,
  2031. NULL,
  2032. 0));
  2033. INTERNAL_ERROR_CHECK(fFound);
  2034. IFW32FALSE_EXIT(
  2035. ::SxspGetAttributeValue(
  2036. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  2037. &s_AttributeName_newVersion,
  2038. prgNodeInfo,
  2039. cNumRecs,
  2040. &m_ParseContext,
  2041. fFound,
  2042. sizeof(buffNewVersion),
  2043. &buffNewVersion,
  2044. cb,
  2045. NULL,
  2046. 0));
  2047. INTERNAL_ERROR_CHECK(fFound);
  2048. // If either are not found, log an error
  2049. if (!fFound)
  2050. {
  2051. this->LogParseError(MSG_SXS_BINDING_REDIRECT_MISSING_REQUIRED_ATTRIBUTES);
  2052. goto Exit;
  2053. }
  2054. IFW32FALSE_EXIT(m_CurrentPolicyStatement->AddRedirect(buffOldVersion, buffNewVersion, fValid));
  2055. if (! fValid)
  2056. {
  2057. // log an error
  2058. ::FusionpLogError(
  2059. MSG_SXS_POLICY_VERSION_OVERLAP,
  2060. CEventLogString(m_AssemblyContext->PolicyPath),
  2061. CEventLogString(buffOldVersion),
  2062. CEventLogString(buffNewVersion));
  2063. ORIGINATE_WIN32_FAILURE_AND_EXIT(PolicyVersionOverlap, ERROR_SXS_MANIFEST_PARSE_ERROR);
  2064. }
  2065. fSuccess = TRUE;
  2066. Exit:
  2067. return fSuccess;
  2068. }
  2069. BOOL
  2070. CNodeFactory::XMLParser_Parse_PartialAssemblyVersion(
  2071. PVOID pvDatum,
  2072. BOOL fAlreadyFound,
  2073. CBaseStringBuffer &rbuff
  2074. )
  2075. {
  2076. return reinterpret_cast<CPartialAssemblyVersion *>(pvDatum)->Parse(rbuff, rbuff.Cch());
  2077. }
  2078. BOOL
  2079. CNodeFactory::XMLParser_Parse_String(
  2080. LPVOID pvDatum,
  2081. BOOL fAlreadyFound,
  2082. CBaseStringBuffer &rbuff)
  2083. {
  2084. return ((CBaseStringBuffer *) pvDatum)->Win32Assign(rbuff);
  2085. }
  2086. BOOL
  2087. CNodeFactory::ParseElementAttributes(
  2088. USHORT cNumRecs,
  2089. XML_NODE_INFO **prgpNodeInfo,
  2090. SIZE_T cEntries,
  2091. const AttributeMapEntry *prgEntries
  2092. )
  2093. {
  2094. BOOL fSuccess = FALSE;
  2095. ULONG i, j;
  2096. for (i=1; i<cNumRecs; i++)
  2097. {
  2098. // Skip things we don't understand.
  2099. if (prgpNodeInfo[i]->dwType != XML_ATTRIBUTE)
  2100. continue;
  2101. for (j=0; j<cEntries; j++)
  2102. {
  2103. if (::FusionpCompareStrings(
  2104. prgEntries[j].m_pszAttributeName,
  2105. prgEntries[j].m_cchAttributeName,
  2106. prgpNodeInfo[i]->pwcText,
  2107. prgpNodeInfo[i]->ulLen,
  2108. false) == 0)
  2109. {
  2110. // Because attribute values may be multipart due to entity references,
  2111. // we accumulate the attibute value into buffTemp to start, and then do
  2112. // the parsing/whatever afterwards.
  2113. CStringBuffer buffTemp;
  2114. BOOL *pfIndicator = (BOOL *) (((ULONG_PTR) this) + prgEntries[j].m_offsetIndicator);
  2115. while ((++i < cNumRecs) &&
  2116. (prgpNodeInfo[i]->dwType == XML_PCDATA))
  2117. {
  2118. if (!buffTemp.Win32Append(prgpNodeInfo[i]->pwcText, prgpNodeInfo[i]->ulLen))
  2119. goto Exit;
  2120. }
  2121. // The outer for(;;) loop is going to increment i, so we need to back it up one
  2122. // place...
  2123. i--;
  2124. // Call the appropriate value type handler function...
  2125. if (prgEntries[j].m_pfn != NULL)
  2126. {
  2127. if (!((this->*(prgEntries[j].m_pfn))(((LPBYTE) this) + prgEntries[j].m_offsetData, *pfIndicator, buffTemp)))
  2128. goto Exit;
  2129. }
  2130. *pfIndicator = TRUE;
  2131. break;
  2132. }
  2133. }
  2134. }
  2135. fSuccess = TRUE;
  2136. Exit:
  2137. return fSuccess;
  2138. }
  2139. HRESULT
  2140. CNodeFactory::LogParseError(
  2141. DWORD dwLastParseError,
  2142. const UNICODE_STRING *p1,
  2143. const UNICODE_STRING *p2,
  2144. const UNICODE_STRING *p3,
  2145. const UNICODE_STRING *p4,
  2146. const UNICODE_STRING *p5,
  2147. const UNICODE_STRING *p6,
  2148. const UNICODE_STRING *p7,
  2149. const UNICODE_STRING *p8,
  2150. const UNICODE_STRING *p9,
  2151. const UNICODE_STRING *p10,
  2152. const UNICODE_STRING *p11,
  2153. const UNICODE_STRING *p12,
  2154. const UNICODE_STRING *p13,
  2155. const UNICODE_STRING *p14,
  2156. const UNICODE_STRING *p15,
  2157. const UNICODE_STRING *p16,
  2158. const UNICODE_STRING *p17,
  2159. const UNICODE_STRING *p18,
  2160. const UNICODE_STRING *p19,
  2161. const UNICODE_STRING *p20
  2162. )
  2163. {
  2164. return
  2165. ::FusionpLogParseError(
  2166. m_ParseContext.SourceFile,
  2167. m_ParseContext.SourceFileCch,
  2168. m_ParseContext.LineNumber,
  2169. dwLastParseError,
  2170. p1, p2, p3, p4, p5,
  2171. p6, p7, p8, p9, p10,
  2172. p11, p12, p13, p14, p15,
  2173. p16, p17, p18, p19, p20);
  2174. }
  2175. VOID
  2176. CNodeFactory::ParseErrorCallback_MissingRequiredAttribute(
  2177. PCACTCTXCTB_PARSE_CONTEXT ParseContext,
  2178. IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName
  2179. )
  2180. {
  2181. // CNodeFactory *pThis = (CNodeFactory *) ErrorContext;
  2182. ::FusionpLogRequiredAttributeMissingParseError(
  2183. ParseContext->SourceFile,
  2184. ParseContext->SourceFileCch,
  2185. ParseContext->LineNumber,
  2186. ParseContext->ElementName,
  2187. ParseContext->ElementNameCch,
  2188. AttributeName->Name,
  2189. AttributeName->NameCch);
  2190. }
  2191. VOID
  2192. CNodeFactory::ParseErrorCallback_InvalidAttributeValue(
  2193. PCACTCTXCTB_PARSE_CONTEXT ParseContext,
  2194. IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName
  2195. )
  2196. {
  2197. // CNodeFactory *pThis = (CNodeFactory *) ErrorContext;
  2198. ::FusionpLogInvalidAttributeValueParseError(
  2199. ParseContext->SourceFile,
  2200. ParseContext->SourceFileCch,
  2201. ParseContext->LineNumber,
  2202. ParseContext->ElementName,
  2203. ParseContext->ElementNameCch,
  2204. AttributeName->Name,
  2205. AttributeName->NameCch);
  2206. }
  2207. VOID
  2208. CNodeFactory::ParseErrorCallback_AttributeNotAllowed(
  2209. PCACTCTXCTB_PARSE_CONTEXT ParseContext,
  2210. IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName
  2211. )
  2212. {
  2213. // CNodeFactory *pThis = (CNodeFactory *) ErrorContext;
  2214. ::FusionpLogAttributeNotAllowedParseError(
  2215. ParseContext->SourceFile,
  2216. ParseContext->SourceFileCch,
  2217. ParseContext->LineNumber,
  2218. ParseContext->ElementName,
  2219. ParseContext->ElementNameCch,
  2220. AttributeName->Name,
  2221. AttributeName->NameCch);
  2222. }
  2223. static
  2224. VOID
  2225. SxspDbgPrintXmlNodeInfo(
  2226. ULONG Level,
  2227. XML_NODE_INFO *pNode
  2228. )
  2229. {
  2230. CUnicodeString s(pNode->pwcText, pNode->ulLen);
  2231. #if DBG_SXS
  2232. ::FusionpDbgPrintEx(Level, "SXS.DLL: XML_NODE_INFO at %p\n", pNode);
  2233. ::FusionpDbgPrintEx(Level, " dwSize = %d\n", pNode->dwSize);
  2234. ::FusionpDbgPrintEx(Level, " dwType = %d (%s)\n", pNode->dwType, SxspFormatXmlNodeType(pNode->dwType));
  2235. ::FusionpDbgPrintEx(Level, " dwSubType = %d\n", pNode->dwSubType);
  2236. ::FusionpDbgPrintEx(Level, " fTerminal = %d\n", pNode->fTerminal);
  2237. ::FusionpDbgPrintEx(Level, " pwcText = %p (\"%wZ\")\n", pNode->pwcText, &s);
  2238. ::FusionpDbgPrintEx(Level, " ulLen = %d\n", pNode->ulLen);
  2239. ::FusionpDbgPrintEx(Level, " ulNsPrefixLen = %d\n", pNode->ulNsPrefixLen);
  2240. ::FusionpDbgPrintEx(Level, " pNode = %p\n", pNode->pNode);
  2241. ::FusionpDbgPrintEx(Level, " pReserved = %p\n", pNode->pReserved);
  2242. #else
  2243. ::FusionpDbgPrintEx(Level, "SXS.DLL: XML_NODE_INFO at %p: \"%wZ\"\n", pNode, &s);
  2244. #endif
  2245. }
  2246. static
  2247. PCSTR
  2248. SxspFormatXmlNodeType(
  2249. DWORD dwType
  2250. )
  2251. {
  2252. PCSTR Result = "Unknown";
  2253. #define HANDLE_NODE_TYPE(x) case static_cast<DWORD>(x): Result = #x; break;
  2254. switch (dwType)
  2255. {
  2256. HANDLE_NODE_TYPE(XML_ELEMENT)
  2257. HANDLE_NODE_TYPE(XML_ATTRIBUTE)
  2258. HANDLE_NODE_TYPE(XML_PI)
  2259. HANDLE_NODE_TYPE(XML_XMLDECL)
  2260. HANDLE_NODE_TYPE(XML_DOCTYPE)
  2261. HANDLE_NODE_TYPE(XML_DTDATTRIBUTE)
  2262. HANDLE_NODE_TYPE(XML_ENTITYDECL)
  2263. HANDLE_NODE_TYPE(XML_ELEMENTDECL)
  2264. HANDLE_NODE_TYPE(XML_ATTLISTDECL)
  2265. HANDLE_NODE_TYPE(XML_NOTATION)
  2266. HANDLE_NODE_TYPE(XML_GROUP)
  2267. HANDLE_NODE_TYPE(XML_INCLUDESECT)
  2268. HANDLE_NODE_TYPE(XML_PCDATA)
  2269. HANDLE_NODE_TYPE(XML_CDATA)
  2270. HANDLE_NODE_TYPE(XML_IGNORESECT)
  2271. HANDLE_NODE_TYPE(XML_COMMENT)
  2272. HANDLE_NODE_TYPE(XML_ENTITYREF)
  2273. HANDLE_NODE_TYPE(XML_WHITESPACE)
  2274. HANDLE_NODE_TYPE(XML_NAME)
  2275. HANDLE_NODE_TYPE(XML_NMTOKEN)
  2276. HANDLE_NODE_TYPE(XML_STRING)
  2277. HANDLE_NODE_TYPE(XML_PEREF)
  2278. HANDLE_NODE_TYPE(XML_MODEL)
  2279. HANDLE_NODE_TYPE(XML_ATTDEF)
  2280. HANDLE_NODE_TYPE(XML_ATTTYPE)
  2281. HANDLE_NODE_TYPE(XML_ATTPRESENCE)
  2282. HANDLE_NODE_TYPE(XML_DTDSUBSET)
  2283. }
  2284. return Result;
  2285. }
  2286. BOOL
  2287. CNodeFactory::ValidateIdentity(
  2288. DWORD Flags,
  2289. ULONG Type,
  2290. PCASSEMBLY_IDENTITY AssemblyIdentity
  2291. )
  2292. {
  2293. BOOL fSuccess = FALSE;
  2294. FN_TRACE_WIN32(fSuccess);
  2295. PCWSTR pszTemp = NULL;
  2296. SIZE_T cchTemp = 0;
  2297. bool fSyntaxValid = false;
  2298. bool fError = false;
  2299. BOOL fIsPolicy;
  2300. PARAMETER_CHECK((Flags & ~(
  2301. eValidateIdentity_VersionRequired |
  2302. eValidateIdentity_PoliciesNotAllowed |
  2303. eValidateIdentity_VersionNotAllowed)) == 0);
  2304. PARAMETER_CHECK((Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) || (Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE));
  2305. PARAMETER_CHECK(AssemblyIdentity != NULL);
  2306. //
  2307. // only one of these flags is allowed
  2308. //
  2309. IFINVALID_FLAGS_EXIT_WIN32(Flags,
  2310. eValidateIdentity_PoliciesNotAllowed |
  2311. eValidateIdentity_VersionNotAllowed |
  2312. eValidateIdentity_VersionRequired);
  2313. //
  2314. // Get the type of this assembly
  2315. //
  2316. IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy));
  2317. //
  2318. // If it's policy, then make sure that policies are allowed. Otherwise, fail out.
  2319. //
  2320. if (fIsPolicy)
  2321. {
  2322. if (Flags & eValidateIdentity_PoliciesNotAllowed)
  2323. {
  2324. FusionpDbgPrintEx(
  2325. FUSION_DBG_LEVEL_ERROR,
  2326. "SXS.DLL: Manifest \"%ls\" (line %d) contains a type=\"win32-policy\" where it shouldn't\n",
  2327. m_ParseContext.SourceFile,
  2328. m_ParseContext.LineNumber);
  2329. fError = true;
  2330. }
  2331. else
  2332. {
  2333. m_AssemblyContext->Flags |= ACTCTXCTB_ASSEMBLY_CONTEXT_IS_SYSTEM_POLICY_INSTALLATION;
  2334. }
  2335. }
  2336. IFW32FALSE_EXIT(
  2337. ::SxspGetAssemblyIdentityAttributeValue(
  2338. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  2339. AssemblyIdentity,
  2340. &s_IdentityAttribute_name,
  2341. &pszTemp,
  2342. &cchTemp));
  2343. if (cchTemp == 0)
  2344. {
  2345. ::FusionpDbgPrintEx(
  2346. FUSION_DBG_LEVEL_ERROR,
  2347. "SXS.DLL: Manifest \"%ls\" (line %d) is missing name attribute; report to owner of \"%ls\"\n",
  2348. m_ParseContext.SourceFile,
  2349. m_ParseContext.LineNumber,
  2350. m_ParseContext.SourceFile);
  2351. fError = true;
  2352. }
  2353. IFW32FALSE_EXIT(
  2354. ::SxspGetAssemblyIdentityAttributeValue(
  2355. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  2356. AssemblyIdentity,
  2357. &s_IdentityAttribute_processorArchitecture,
  2358. &pszTemp,
  2359. &cchTemp));
  2360. IFW32FALSE_EXIT(
  2361. ::SxspGetAssemblyIdentityAttributeValue(
  2362. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  2363. AssemblyIdentity,
  2364. &s_IdentityAttribute_version,
  2365. &pszTemp,
  2366. &cchTemp));
  2367. if (cchTemp != 0)
  2368. {
  2369. ASSEMBLY_VERSION av;
  2370. IFW32FALSE_EXIT(CFusionParser::ParseVersion(av, pszTemp, cchTemp, fSyntaxValid));
  2371. if (!fSyntaxValid)
  2372. {
  2373. ::FusionpLogInvalidAttributeValueParseError(
  2374. m_ParseContext.SourceFile,
  2375. m_ParseContext.SourceFileCch,
  2376. m_ParseContext.LineNumber,
  2377. m_ParseContext.ElementName,
  2378. m_ParseContext.ElementNameCch,
  2379. s_IdentityAttribute_version);
  2380. ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidVersionNumber, ERROR_SXS_MANIFEST_PARSE_ERROR);
  2381. }
  2382. }
  2383. if ((Flags & (eValidateIdentity_VersionNotAllowed | eValidateIdentity_VersionRequired)) != 0)
  2384. {
  2385. if ((Flags & eValidateIdentity_VersionNotAllowed) != 0 && cchTemp != 0)
  2386. {
  2387. fError = true;
  2388. ::FusionpDbgPrintEx(
  2389. FUSION_DBG_LEVEL_ERROR,
  2390. "SXS.DLL: Manifest \"%ls\" (line %d) has a version attribute where it may not appear; report to owner of \"%ls\"\n",
  2391. m_ParseContext.SourceFile,
  2392. m_ParseContext.LineNumber,
  2393. m_ParseContext.SourceFile);
  2394. }
  2395. else if ((Flags & eValidateIdentity_VersionRequired) != 0 && cchTemp == 0)
  2396. {
  2397. fError = true;
  2398. ::FusionpDbgPrintEx(
  2399. FUSION_DBG_LEVEL_ERROR,
  2400. "SXS.DLL: Manifest \"%ls\" (line %d) is missing version attribute; report to owner of \"%ls\"\n",
  2401. m_ParseContext.SourceFile,
  2402. m_ParseContext.LineNumber,
  2403. m_ParseContext.SourceFile);
  2404. }
  2405. }
  2406. if (fError)
  2407. {
  2408. ::FusionpDbgPrintEx(
  2409. FUSION_DBG_LEVEL_ERROR,
  2410. "SXS.DLL: Manifest \"%ls\" is missing required attribute or contains disallowed attribute; report to owner of \"%ls\"\n",
  2411. m_ParseContext.SourceFile,
  2412. m_ParseContext.SourceFile);
  2413. ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidIdentity, ERROR_SXS_MANIFEST_PARSE_ERROR);
  2414. }
  2415. fSuccess = TRUE;
  2416. Exit:
  2417. return fSuccess;
  2418. }
  2419. BOOL
  2420. CNodeFactory::ValidateElementAttributes(
  2421. PCSXS_NODE_INFO prgNodes,
  2422. SIZE_T cNodes,
  2423. PCELEMENT_LEGAL_ATTRIBUTE prgAttributes,
  2424. UCHAR cAttributes
  2425. )
  2426. {
  2427. FN_PROLOG_WIN32
  2428. SIZE_T i;
  2429. UCHAR j;
  2430. UCHAR cRequiredAttributes, cRequiredAttributesFound;
  2431. UCHAR rgRequiredAttributeFoundBitMask[8]; // 8 * 32 = 256
  2432. BOOL fParseFailed = FALSE;
  2433. PARAMETER_CHECK((cNodes == 0) || (prgNodes != NULL));
  2434. PARAMETER_CHECK((cAttributes == 0) || (prgAttributes != NULL));
  2435. cRequiredAttributes = 0;
  2436. cRequiredAttributesFound = 0;
  2437. for (i=0; i<cAttributes; i++)
  2438. if (prgAttributes[i].m_dwFlags & ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED)
  2439. cRequiredAttributes++;
  2440. rgRequiredAttributeFoundBitMask[0] = 0;
  2441. rgRequiredAttributeFoundBitMask[1] = 0;
  2442. rgRequiredAttributeFoundBitMask[2] = 0;
  2443. rgRequiredAttributeFoundBitMask[3] = 0;
  2444. rgRequiredAttributeFoundBitMask[4] = 0;
  2445. rgRequiredAttributeFoundBitMask[5] = 0;
  2446. rgRequiredAttributeFoundBitMask[6] = 0;
  2447. rgRequiredAttributeFoundBitMask[7] = 0;
  2448. for (i=0; i<cNodes; i++)
  2449. {
  2450. if (prgNodes[i].Type == SXS_ATTRIBUTE)
  2451. {
  2452. const SIZE_T cchText = prgNodes[i].cchText;
  2453. const SIZE_T cchNamespace = prgNodes[i].NamespaceStringBuf.Cch();
  2454. const PCWSTR pszText = prgNodes[i].pszText;
  2455. // Ignore any attributes that start with xml
  2456. if ((cchText >= 3) &&
  2457. ((pszText[0] == L'x') || (pszText[0] == L'X')) &&
  2458. ((pszText[1] == L'm') || (pszText[1] == L'M')) &&
  2459. ((pszText[2] == L'l') || (pszText[2] == L'L')))
  2460. {
  2461. continue;
  2462. }
  2463. if (cchNamespace != 0 )
  2464. {
  2465. continue;
  2466. }
  2467. for (j=0; j<cAttributes; j++)
  2468. {
  2469. if ((prgAttributes[j].m_pName != NULL) &&
  2470. (cchText == prgAttributes[j].m_pName->NameCch) &&
  2471. (cchNamespace == prgAttributes[j].m_pName->NamespaceCch) &&
  2472. (::FusionpCompareStrings(prgNodes[i].NamespaceStringBuf, cchNamespace, prgAttributes[j].m_pName->Namespace, cchNamespace, false) == 0) &&
  2473. (::FusionpCompareStrings(pszText, cchText, prgAttributes[j].m_pName->Name, cchText, false) == 0))
  2474. {
  2475. if (prgAttributes[j].m_pfnValidator != NULL)
  2476. {
  2477. CSmallStringBuffer buffValue;
  2478. bool fValid = false;
  2479. SIZE_T cb;
  2480. SIZE_T i2;
  2481. for (i2=i+1; i2<cNodes; i2++)
  2482. {
  2483. if (prgNodes[i2].Type == SXS_PCDATA)
  2484. IFW32FALSE_EXIT(buffValue.Win32Append(prgNodes[i2].pszText, prgNodes[i2].cchText));
  2485. else
  2486. break;
  2487. }
  2488. IFW32FALSE_EXIT(
  2489. (*prgAttributes[j].m_pfnValidator)(
  2490. prgAttributes[j].m_dwValidatorFlags,
  2491. buffValue,
  2492. fValid,
  2493. 0,
  2494. NULL,
  2495. cb));
  2496. if (!fValid)
  2497. {
  2498. ::FusionpLogInvalidAttributeValueParseError(
  2499. m_ParseContext.SourceFile,
  2500. m_ParseContext.SourceFileCch,
  2501. m_ParseContext.LineNumber,
  2502. m_ParseContext.ElementName,
  2503. m_ParseContext.ElementNameCch,
  2504. prgAttributes[j].m_pName->Name,
  2505. prgAttributes[j].m_pName->NameCch);
  2506. ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidAttributeValue, ERROR_SXS_MANIFEST_PARSE_ERROR);
  2507. }
  2508. }
  2509. if (prgAttributes[j].m_dwFlags & ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED)
  2510. {
  2511. rgRequiredAttributeFoundBitMask[(j / 32)] |= (1 << (j % 32));
  2512. cRequiredAttributesFound++;
  2513. }
  2514. break;
  2515. }
  2516. }
  2517. if (j == cAttributes)
  2518. {
  2519. // We found an illegal attribute!!
  2520. ::FusionpLogAttributeNotAllowedParseError(
  2521. m_ParseContext.SourceFile,
  2522. m_ParseContext.SourceFileCch,
  2523. m_ParseContext.LineNumber,
  2524. prgNodes[0].pszText,
  2525. prgNodes[0].cchText,
  2526. prgNodes[i].pszText,
  2527. prgNodes[i].cchText);
  2528. // We don't just go to exit here because we want to report all the bad attributes and missing attributes...
  2529. fParseFailed = TRUE;
  2530. }
  2531. }
  2532. }
  2533. if (cRequiredAttributesFound != cRequiredAttributes)
  2534. {
  2535. for (j=0; j<cAttributes; j++)
  2536. {
  2537. if (prgAttributes[j].m_dwFlags & ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED)
  2538. {
  2539. if ((rgRequiredAttributeFoundBitMask[(j / 32)] & (1 << (j % 32))) == 0)
  2540. {
  2541. ::FusionpLogRequiredAttributeMissingParseError(
  2542. m_ParseContext.SourceFile,
  2543. m_ParseContext.SourceFileCch,
  2544. m_ParseContext.LineNumber,
  2545. prgNodes[0].pszText,
  2546. prgNodes[0].cchText,
  2547. prgAttributes[j].m_pName->Name,
  2548. prgAttributes[j].m_pName->NameCch);
  2549. fParseFailed = TRUE;
  2550. }
  2551. }
  2552. }
  2553. }
  2554. if (fParseFailed)
  2555. ORIGINATE_WIN32_FAILURE_AND_EXIT(ParseError, ERROR_SXS_MANIFEST_PARSE_ERROR);
  2556. FN_EPILOG
  2557. }