#include "stdinc.h" #include "actctxgenctx.h" #define DEFINE_ATTRIBUTE(attributeName, attributeType, typePrefix) \ { \ L ## #attributeName, \ offsetof(CNodeFactory, m_ ## typePrefix ## _ ## attributeName), \ offsetof(CNodeFactory, m_f ## attributeName ## _ ## Present), \ &CNodeFactory::XMLParser_Parse_ ## attributeType \ }, const static ASSEMBLY_VERSION assemblyVersion0 = {0,0,0,0}; typedef enum _in_xml_tag_when_identity_generated_{ SXS_IN_INVALID_XML_TAG_WHEN_ASSEMBLY_IDENTITY_GENERATED, SXS_IN_ASSEMBLY_TAG, SXS_IN_DEPENDENCY_TAG }SXS_IN_XML_TAG_WHEN_IDENTITY_GENERATED; static VOID SxspDbgPrintXmlNodeInfo( ULONG Level, XML_NODE_INFO *pNode ); static PCSTR SxspFormatXmlNodeType( DWORD dwType ); struct EventIdErrorPair { DWORD dwEventId; LONG nError; }; const static EventIdErrorPair eventIdToErrorMap[] = { #include "Messages.hi" // generated from .x file, like .mc }; // deliberately no extra paranetheses here #define NODEFACTORY_STRING_AND_LENGTH(x) x, NUMBER_OF(x) - 1 const static SXS_NAME_LENGTH_PAIR IgnoredAttributesInDependencyTagForIdentity[]={ //maybe more later { NODEFACTORY_STRING_AND_LENGTH(L"Description") } }; const DWORD IGNORED_ATTRIBUTE_NUM_IN_DEPENDENCY_TAG = NUMBER_OF(IgnoredAttributesInDependencyTagForIdentity); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(baseInterface); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(clsid); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(description); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(flags); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(hash); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(hashalg); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(helpdir); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(iid); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(language); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(loadFrom); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(manifestVersion); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(metadataSatellite); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(newVersion); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(numMethods); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(oldVersion); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(optional); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(processorArchitecture); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(progid); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(proxyStubClsid32); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(publicKeyToken); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(publicKey); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(resourceid); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(runtimeVersion); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(size); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(threadingModel); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(tlbid); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(type); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(version); DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(versioned); // How to interpret the parser worker rules here: // // First, the state of the parser must match m_xps for the rule to be considered. // If the value eNotParsing is in the table, it matches any current parser // state. Use this to globally ignore some particular tag type when // combined with a NULL m_pszTag and NULL m_pfn. // Second, the type of the tag from the XML parser must match m_dwType. // If m_pszTag is not NULL, a case-insensitive comparison is done between the // string m_pszTag points to and the tag from the XML parser. An m_pszTag // value of NULL matches any tag. // If the three criteria match, the worker function is called. The worker function // pointer may be NULL, in which case no action is taken. (This is useful for // callbacks from the parser about XML_WHITESPACE where we don't really have to do // anything at all.) // #define DEFINE_TAG_WORKER_IGNOREALLOFTYPE(dwType) { CNodeFactory::eNotParsing, (dwType), NULL, NULL, NULL, 0, 0, 0, NULL } // // Notes on use of the DEFINE_TAG_WORKER_ELEMENT() macro: // // The first parameter, sourceState, is part of the name of a XMLParseState // enumeration value. It is concatenated onto "eParsing" to form the name of // the state which the rule will match. // // The second parameter is both the text of the tag to match and is used to // form the name of the function to invoke if the rule matches. The tag is // compared case-insensitively, and the name of the member function invoked // is XMLParser_Element_ followed by the sourceState string followed by another // underscore, followed by the tagName string. So, for example, the following // rule: // // DEFINE_TAG_WORKER_ELEMENT(DepAssy, Version) // // says that when the parser is in the eParsingDepAssy state and a "Version" // tag is found, call the function CNodeFactory::XMLParser_Element_DepAssy_Version(). // #define DEFINE_TAG_WORKER_ELEMENT(sourceState, tagName) \ { \ CNodeFactory::eParsing_ ## sourceState, \ XML_ELEMENT, \ SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, \ L ## #tagName, \ s_rg_ ## sourceState ## _ ## tagName ## _attributes, \ NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1, \ NUMBER_OF(L ## #tagName) - 1, \ NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \ &CNodeFactory::XMLParser_Element_ ## sourceState ## _ ## tagName, \ CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \ } #define DEFINE_TAG_WORKER_ELEMENT_NOCB(sourceState, tagName) \ { \ CNodeFactory::eParsing_ ## sourceState, \ XML_ELEMENT, \ SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, \ L ## #tagName, \ s_rg_ ## sourceState ## _ ## tagName ## _attributes, \ NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1, \ NUMBER_OF(L ## #tagName) - 1, \ NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \ NULL, \ CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \ } #define DEFINE_TAG_WORKER_ELEMENT_NONS(sourceState, tagName) \ { \ CNodeFactory::eParsing_ ## sourceState, \ XML_ELEMENT, \ NULL, \ L ## #tagName, \ s_rg_ ## sourceState ## _ ## tagName ## _attributes, \ 0, \ NUMBER_OF(L ## #tagName) - 1, \ NUMBER_OF(s_rg_ ## sourceState ## _ ## tagName ## _attributes), \ &CNodeFactory::XMLParser_Element_ ## sourceState ## _ ## tagName, \ CNodeFactory::eParsing_ ## sourceState ## _ ## tagName \ } #define BEGIN_ELEMENT_LEGAL_ATTRIBUTES(_element) \ const static ELEMENT_LEGAL_ATTRIBUTE s_rg_ ## _element ## _attributes[] = { \ { ELEMENT_LEGAL_ATTRIBUTE_FLAG_IGNORE, NULL, NULL }, #define DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(attributeName, validatorFlags, validator) { ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED, &s_AttributeName_ ## attributeName, validator, validatorFlags }, #define DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(attributeName, validatorFlags, validator) { 0, &s_AttributeName_ ## attributeName, validator, validatorFlags }, #define END_ELEMENT_LEGAL_ATTRIBUTES(_element) }; BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(manifestVersion, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_description) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_description) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInherit) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInherit) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInheritable) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_noInheritable) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_assemblyIdentity) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, SXSP_VALIDATE_PROCESSOR_ARCHITECTURE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateProcessorArchitectureAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKey, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_assemblyIdentity) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(optional, 0, &::SxspValidateBoolAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_assemblyIdentity) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(version, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, SXSP_VALIDATE_PROCESSOR_ARCHITECTURE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateProcessorArchitectureAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, SXSP_VALIDATE_LANGUAGE_ATTRIBUTE_FLAG_WILDCARD_ALLOWED, &::SxspValidateLanguageAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_assemblyIdentity) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_bindingRedirect) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(oldVersion, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(newVersion, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_dependency_dependentAssembly_bindingRedirect) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(hash, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(hashalg, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(loadFrom, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(size, 0, &::SxspValidateUnsigned64Attribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(progid, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(description, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass_progid) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comClass_progid) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(progid, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(description, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(runtimeVersion, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrSurrogate) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(clsid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(runtimeVersion, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_clrSurrogate) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass_progid) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_clrClass_progid) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comInterfaceProxyStub) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(iid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(numMethods, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(baseInterface, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(proxyStubClsid32, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(threadingModel, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_comInterfaceProxyStub) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_typelib) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(helpdir, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(resourceid, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(flags, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_typelib) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_windowClass) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(versioned, 0, &::SxspValidateBoolAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_file_windowClass) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_comInterfaceExternalProxyStub) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(iid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(proxyStubClsid32, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(tlbid, 0, &::SxspValidateGuidAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(numMethods, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(baseInterface, 0, &::SxspValidateGuidAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_assembly_comInterfaceExternalProxyStub) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_assemblyIdentity) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(version, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(processorArchitecture, 0, &::SxspValidateProcessorArchitectureAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_assemblyIdentity) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(name, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(processorArchitecture, 0, &::SxspValidateProcessorArchitectureAttribute) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(type, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(publicKeyToken, 0, NULL) DEFINE_ELEMENT_NONS_OPTIONAL_ATTRIBUTE(language, 0, &::SxspValidateLanguageAttribute) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity) BEGIN_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(oldVersion, 0, NULL) DEFINE_ELEMENT_NONS_REQUIRED_ATTRIBUTE(newVersion, 0, NULL) END_ELEMENT_LEGAL_ATTRIBUTES(doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect) static const struct { CNodeFactory::XMLParseState m_xpsOld; DWORD m_dwType; PCWSTR m_pszNamespace; PCWSTR m_pszName; PCELEMENT_LEGAL_ATTRIBUTE m_prgLegalAttributes; UCHAR m_cchNamespace; // We use UCHAR here just for greater data density. Changing this and rebuilding UCHAR m_cchName; // this module should work fine if you really need namespaces or names longer than // 255 characters. UCHAR m_cLegalAttributes; CNodeFactory::XMLParserWorkerFunctionPtr m_pfn; CNodeFactory::XMLParseState m_xpsNew; } s_rgWorkers[] = { DEFINE_TAG_WORKER_IGNOREALLOFTYPE(XML_WHITESPACE), DEFINE_TAG_WORKER_IGNOREALLOFTYPE(XML_COMMENT), DEFINE_TAG_WORKER_ELEMENT(doc, assembly), DEFINE_TAG_WORKER_ELEMENT(doc_assembly, assemblyIdentity), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, description), DEFINE_TAG_WORKER_ELEMENT(doc_assembly, noInherit), DEFINE_TAG_WORKER_ELEMENT(doc_assembly, noInheritable), DEFINE_TAG_WORKER_ELEMENT(doc_assembly, dependency), DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency, dependentAssembly), DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency_dependentAssembly, assemblyIdentity), DEFINE_TAG_WORKER_ELEMENT(doc_assembly_dependency_dependentAssembly, bindingRedirect), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, file), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, comClass), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file_comClass, progid), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, clrClass), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_clrClass, progid), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, comInterfaceProxyStub), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, typelib), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly_file, windowClass), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, clrSurrogate), DEFINE_TAG_WORKER_ELEMENT_NOCB(doc_assembly, comInterfaceExternalProxyStub), // All app config productions go here, just for neatness DEFINE_TAG_WORKER_ELEMENT_NONS(doc, configuration), DEFINE_TAG_WORKER_ELEMENT_NONS(doc_configuration, windows), DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows, assemblyBinding), DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding, assemblyIdentity), DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding, dependentAssembly), DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding_dependentAssembly, assemblyIdentity), DEFINE_TAG_WORKER_ELEMENT(doc_configuration_windows_assemblyBinding_dependentAssembly, bindingRedirect), }; BOOL SxspIsNamespaceDeclaration(XML_NODE_INFO *pNodeInfo) { FN_TRACE(); ASSERT(pNodeInfo->dwType == XML_ATTRIBUTE); if (pNodeInfo->ulLen >= 5) { // "xmlns" : prefix for namespace declaration, default ns or non-default ns if ((pNodeInfo->pwcText[0] == L'x') && (pNodeInfo->pwcText[1] == L'm') && (pNodeInfo->pwcText[2] == L'l') && (pNodeInfo->pwcText[3] == L'n') && (pNodeInfo->pwcText[4] == L's')) { if (pNodeInfo->ulLen == 5) // like xmlns="", default ns declaration return TRUE; else if (pNodeInfo->pwcText[5] == L':') return TRUE; } } return FALSE; } //In this function, two tasks: // 1) verify PublicKey and StrongName // 2) create AssemblyIdentity based on xmlnode array // 3) for (name, processorArchitecure, version. langid) they would be unique with SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE // 4) if there are dup triples {nsURL, name, value), only one is count, this is done with SxsCreateAssemblyIdentity BOOL SxspCreateAssemblyIdentityFromIdentityElement( DWORD Flags, PCACTCTXCTB_PARSE_CONTEXT ParseContext, ULONG Type, PASSEMBLY_IDENTITY *AssemblyIdentityOut, DWORD cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); DWORD i; PASSEMBLY_IDENTITY AssemblyIdentity = NULL; CStringBuffer buffValue; if (AssemblyIdentityOut != NULL) *AssemblyIdentityOut = NULL; PARAMETER_CHECK((Flags & ~(SXSP_CREATE_ASSEMBLY_IDENTITY_FROM_IDENTITY_TAG_FLAG_VERIFY_PUBLIC_KEY_IF_PRESENT)) == 0); PARAMETER_CHECK((Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) || (Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE)); PARAMETER_CHECK(AssemblyIdentityOut != NULL); PARAMETER_CHECK(prgNodeInfo != NULL); PARAMETER_CHECK(prgNodeInfo[0].Type == XML_ELEMENT); IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, Type, &AssemblyIdentity, 0, NULL)); i = 1; while (iFind(m_buffCurrentApplicationPolicyIdentityKey, m_CurrentPolicyStatement)) m_CurrentPolicyStatement = NULL; } FUSION_DELETE_SINGLETON(m_CurrentPolicyStatement); if (m_CurrentPolicyDependentAssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity); if (m_Assembly != NULL) { m_Assembly->Release(); m_Assembly = NULL; } ple.Restore(); } BOOL CNodeFactory::Initialize( PACTCTXGENCTX ActCtxGenCtx, PASSEMBLY Assembly, PACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PARAMETER_CHECK(Assembly != NULL); #if FUSION_XML_TREE IFW32FALSE_EXIT(m_ParseTreeStringPool.Initialize()); #endif // FUSION_XML_TREE IFW32FALSE_EXIT(m_XMLNamespaceManager.Initialize()); m_ActCtxGenCtx = ActCtxGenCtx; Assembly->AddRef(); if (m_Assembly != NULL) m_Assembly->Release(); m_Assembly = Assembly; m_AssemblyContext = AssemblyContext; m_ParseContext.AssemblyContext = AssemblyContext; m_ParseContext.ErrorCallbacks.MissingRequiredAttribute = &CNodeFactory::ParseErrorCallback_MissingRequiredAttribute; m_ParseContext.ErrorCallbacks.AttributeNotAllowed = &CNodeFactory::ParseErrorCallback_AttributeNotAllowed; m_ParseContext.ErrorCallbacks.InvalidAttributeValue = &CNodeFactory::ParseErrorCallback_InvalidAttributeValue; m_ParseContext.SourceFilePathType = AssemblyContext->ManifestPathType; m_ParseContext.SourceFile = AssemblyContext->ManifestPath; m_ParseContext.SourceFileCch = AssemblyContext->ManifestPathCch; m_ParseContext.LineNumber = 0; #if FUSION_XML_TREE m_XmlDocument.Flags = 0; m_XmlDocument.StringCount = 0; m_XmlDocument.Strings = NULL; InitializeListHead(&m_XmlDocument.ElementListHead); m_CurrentNode = NULL; m_CurrentParent = NULL; #endif // FUSION_XML_TREE fSuccess = TRUE; Exit: return fSuccess; } VOID CNodeFactory::ResetParseState() { m_fFirstCreateNodeCall = true; m_fAssemblyFound = false; m_fIdentityFound = false; m_fNoInheritableFound = false; FUSION_DELETE_SINGLETON(m_CurrentPolicyStatement); m_CurrentPolicyStatement = NULL; ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity); m_CurrentPolicyDependentAssemblyIdentity = NULL; } HRESULT CNodeFactory::QueryInterface( REFIID riid, LPVOID *ppvObj ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); IUnknown *pIUnknown = NULL; if (ppvObj != NULL) *ppvObj = NULL; if (ppvObj == NULL) { hr = E_POINTER; goto Exit; } if (riid == __uuidof(this)) pIUnknown = this; else if ((riid == IID_IUnknown) || (riid == IID_IXMLNodeFactory)) pIUnknown = static_cast(this); else { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Node factory asked for unknown interface\n"); hr = E_NOINTERFACE; goto Exit; } pIUnknown->AddRef(); *ppvObj = pIUnknown; hr = NOERROR; Exit: return hr; } HRESULT CNodeFactory::NotifyEvent( IXMLNodeSource *pSource, XML_NODEFACTORY_EVENT iEvt ) { return NOERROR; } HRESULT CNodeFactory::ConvertXMLNodeInfoToSXSNodeInfo( const XML_NODE_INFO *pNodeInfo, SXS_NODE_INFO &rSXSNodeInfo ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); INTERNAL_ERROR_CHECK(pNodeInfo != NULL); rSXSNodeInfo.Size = pNodeInfo->dwSize; rSXSNodeInfo.Type = pNodeInfo->dwType; switch (pNodeInfo->dwType) { case XML_ELEMENT: { SIZE_T cchNamespacePrefix; IFCOMFAILED_EXIT( m_XMLNamespaceManager.Map( 0, pNodeInfo, &rSXSNodeInfo.NamespaceStringBuf, &cchNamespacePrefix)); // +1 to skip colon rSXSNodeInfo.pszText = pNodeInfo->pwcText + ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0); rSXSNodeInfo.cchText = pNodeInfo->ulLen - ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0); break; } case XML_ATTRIBUTE: { SIZE_T cchNamespacePrefix; // if this is a namespace definition, ignore const PCWSTR pwcText = pNodeInfo->pwcText; if ((pwcText[0] == L'x') && (pwcText[1] == L'm') && (pwcText[2] == L'l') && (pwcText[3] == L'n') && (pwcText[4] == L's') && ((pwcText[5] == L':') || (pwcText[5] == L'='))) { rSXSNodeInfo.pszText = pNodeInfo->pwcText; rSXSNodeInfo.cchText = pNodeInfo->ulLen; } else { IFCOMFAILED_EXIT( m_XMLNamespaceManager.Map( CXMLNamespaceManager::eMapFlag_DoNotApplyDefaultNamespace, pNodeInfo, &rSXSNodeInfo.NamespaceStringBuf, &cchNamespacePrefix)); // +1 to skip colon rSXSNodeInfo.pszText = pNodeInfo->pwcText + ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0); rSXSNodeInfo.cchText = pNodeInfo->ulLen - ((cchNamespacePrefix != 0) ? (cchNamespacePrefix + 1) : 0); } break; } default: // Otherwise we'll assume there's no namespace processing to do... rSXSNodeInfo.NamespaceStringBuf.Clear(); rSXSNodeInfo.pszText = pNodeInfo->pwcText; rSXSNodeInfo.cchText = pNodeInfo->ulLen; break; } FN_EPILOG } HRESULT CNodeFactory::BeginChildren( IXMLNodeSource *pSource, XML_NODE_INFO *pNodeInfo ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); ULONG i; SXS_NODE_INFO SXSNodeInfo; IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnBeginChildren(pSource, pNodeInfo)); IFCOMFAILED_EXIT(this->ConvertXMLNodeInfoToSXSNodeInfo(pNodeInfo, SXSNodeInfo)); for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_BeginChildren( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, &SXSNodeInfo)); } FN_EPILOG } HRESULT CNodeFactory::EndChildren( IXMLNodeSource *pSource, BOOL Empty, XML_NODE_INFO *pNodeInfo ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); ULONG i; PWSTR Bang; SXS_NODE_INFO SXSNodeInfo; // Short-circuit PIs, XML-decls, whitespace and comments if ((pNodeInfo->dwType == XML_PI) || (pNodeInfo->dwType == XML_XMLDECL) || (pNodeInfo->dwType == XML_COMMENT) || (pNodeInfo->dwType == XML_WHITESPACE)) { hr = NOERROR; goto Exit; } IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnEndChildren(pSource, Empty, pNodeInfo)); // We hit the end of something; if we're skipping stuff, we're one level back towards // paying attention. if (m_cUnknownChildDepth != 0) { m_cUnknownChildDepth--; } else { ULONG j; for (j=0; jFlags & ACTCTXCTB_ASSEMBLY_CONTEXT_IS_ROOT_ASSEMBLY) == 0) && m_ActCtxGenCtx->m_NoInherit && !m_fNoInheritableFound) { this->LogParseError(MSG_SXS_NOINHERIT_REQUIRES_NOINHERITABLE); ORIGINATE_WIN32_FAILURE_AND_EXIT(NoInheritRequiresNoInheritable, ERROR_SXS_MANIFEST_PARSE_ERROR); } break; } } } #if FUSION_XML_TREE m_CurrentParent = const_cast(m_CurrentParent->Parent); #endif // FUSION_XML_TREE if (pNodeInfo->dwType != XML_XMLDECL) { IFCOMFAILED_EXIT(this->ConvertXMLNodeInfoToSXSNodeInfo(pNodeInfo, SXSNodeInfo)); for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_EndChildren( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, Empty, &SXSNodeInfo)); } INTERNAL_ERROR_CHECK(m_ParseContext.XMLElementDepth != 0); m_ParseContext.XMLElementDepth--; Bang = wcsrchr(m_buffElementPath, L'!'); INTERNAL_ERROR_CHECK(((Bang == NULL) == (m_ParseContext.XMLElementDepth == 0))); if (Bang != NULL) { m_buffElementPath.Left(Bang - m_buffElementPath); m_ParseContext.ElementPathCch = m_buffElementPath.Cch(); m_ParseContext.ElementPath = m_buffElementPath; m_ParseContext.ElementName = wcsrchr(m_buffElementPath, L'!'); if (m_ParseContext.ElementName == NULL) { m_ParseContext.ElementName = m_buffElementPath; m_ParseContext.ElementNameCch = m_buffElementPath.Cch(); } else { m_ParseContext.ElementName++; m_ParseContext.ElementNameCch = m_buffElementPath.Cch() - (m_ParseContext.ElementName - m_buffElementPath); } IFW32FALSE_ORIGINATE_AND_EXIT( ::SxspHashString( m_buffElementPath, m_ParseContext.ElementPathCch, &m_ParseContext.ElementHash, false)); } else { m_buffElementPath.Clear(); m_ParseContext.ElementPath = NULL; m_ParseContext.ElementPathCch = 0; m_ParseContext.ElementName = NULL; m_ParseContext.ElementNameCch = 0; m_ParseContext.ElementHash = 0; m_ParseContext.XMLElementDepth = 0; } } hr = NOERROR; Exit: return hr; } HRESULT CNodeFactory::Error( IXMLNodeSource *pSource, HRESULT hrErrorCode, USHORT cNumRecs, XML_NODE_INFO **apNodeInfo ) { CSxsPreserveLastError ple; ::FusionpConvertCOMFailure(hrErrorCode); ::FusionpSetLastErrorFromHRESULT(hrErrorCode); this->LogParseError(MSG_SXS_WIN32_ERROR_MSG_WHEN_PARSING_MANIFEST, CEventLogLastError()); ple.Restore(); return NOERROR; } HRESULT CNodeFactory::FirstCreateNodeCall( IXMLNodeSource *pSource, PVOID pNodeParent, USHORT NodeCount, const SXS_NODE_INFO *prgNodeInfo ) { HRESULT hr = S_OK; FN_TRACE_HR(hr); ULONG i; const static WCHAR rgch1_0[] = L"1.0"; const static UNICODE_STRING ustr1_0 = CONSTANT_UNICODE_STRING(rgch1_0); bool fGotGoodManifestVersion = false; bool fGotAnyManifestVersion = false; // It's our first IXMLNodeFactory::CreateNode() call. This had better // be an deal. for (i=0; iLogParseError(MSG_SXS_MANIFEST_INCORRECT_ROOT_ELEMENT)); } break; case XML_FILE_TYPE_APPLICATION_CONFIGURATION: if ((prgNodeInfo[i].cchText != SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION_CCH) || (prgNodeInfo[i].NamespaceStringBuf.Cch() != 0) || (memcmp(prgNodeInfo[i].pszText, SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION, SXS_APPLICATION_CONFIGURATION_MANIFEST_STD_ELEMENT_NAME_CONFIGURATION_CCH * sizeof(WCHAR)) != 0)) { IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_INCORRECT_ROOT_ELEMENT)); } break; } } else if (prgNodeInfo[i].Type == XML_ATTRIBUTE) { if ((prgNodeInfo[i].cchText == (NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_ATTRIBUTE_NAME_MANIFEST_VERSION) - 1)) && (prgNodeInfo[i].NamespaceStringBuf.Cch() == 0) && (memcmp(prgNodeInfo[i].pszText, SXS_ASSEMBLY_MANIFEST_STD_ATTRIBUTE_NAME_MANIFEST_VERSION, prgNodeInfo[i].cchText * sizeof(WCHAR)) == 0)) { fGotAnyManifestVersion = true; ULONG j = i + 1; if (j < NodeCount) { if (prgNodeInfo[j].Type == XML_PCDATA) { if (prgNodeInfo[j].cchText == 3) { if (memcmp(prgNodeInfo[j].pszText, L"1.0", prgNodeInfo[j].cchText * sizeof(WCHAR)) == 0) { fGotGoodManifestVersion = true; } } } } } } } if ((m_ParseType == XML_FILE_TYPE_MANIFEST) || (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)) { if (fGotAnyManifestVersion) { if (!fGotGoodManifestVersion) IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_VERSION_ERROR)); } else IFCOMFAILED_EXIT(this->LogParseError(MSG_SXS_MANIFEST_VERSION_MISSING)); } m_Assembly->m_ManifestVersionMajor = 1; m_Assembly->m_ManifestVersionMinor = 0; hr = NOERROR; Exit: return hr; } HRESULT CNodeFactory::CreateNode( IXMLNodeSource *pSource, PVOID pNodeParent, USHORT NodeCount, XML_NODE_INFO **apNodeInfo ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); ULONG i; PSXS_XML_NODE pXmlNode = NULL; PSXS_NODE_INFO pSXSNodeInfo = NULL; SIZE_T cchTemp; m_ParseContext.LineNumber = pSource->GetLineNumber(); INTERNAL_ERROR_CHECK(NodeCount != 0); #if DBG ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_NODEFACTORY, "SXS.DLL: " __FUNCTION__ "() entered\n" " m_ParseContext.XMLElementDepth = %lu\n", m_ParseContext.XMLElementDepth); for (i=0; idwType == XML_PI) || (apNodeInfo[0]->dwType == XML_XMLDECL) || (apNodeInfo[0]->dwType == XML_COMMENT) || (apNodeInfo[0]->dwType == XML_WHITESPACE)) { hr = NOERROR; goto Exit; } IFCOMFAILED_EXIT(m_XMLNamespaceManager.OnCreateNode(pSource, pNodeParent, NodeCount, apNodeInfo)); IFALLOCFAILED_EXIT(pSXSNodeInfo = new SXS_NODE_INFO[NodeCount]); for (i=0; iConvertXMLNodeInfoToSXSNodeInfo(apNodeInfo[i], pSXSNodeInfo[i])); if (m_fFirstCreateNodeCall) { if ((apNodeInfo[0]->dwType == XML_COMMENT) || (apNodeInfo[0]->dwType == XML_XMLDECL) || (apNodeInfo[0]->dwType == XML_WHITESPACE)) { hr = S_OK; goto Cont; } m_fFirstCreateNodeCall = FALSE; IFCOMFAILED_EXIT(this->FirstCreateNodeCall(pSource, pNodeParent, NodeCount, pSXSNodeInfo)); } Cont: if (m_cUnknownChildDepth == 0) { for (i=0; idwType) fTemp = true; } const bool fTypeMatches = fTemp; fTemp = false; if (fTypeMatches) { if (s_rgWorkers[i].m_cchName == 0) fTemp = true; else { if (s_rgWorkers[i].m_cchNamespace == pSXSNodeInfo[0].NamespaceStringBuf.Cch()) { if (s_rgWorkers[i].m_cchName == pSXSNodeInfo[0].cchText) { if (::FusionpCompareStrings( s_rgWorkers[i].m_pszNamespace, s_rgWorkers[i].m_cchNamespace, pSXSNodeInfo[0].NamespaceStringBuf, pSXSNodeInfo[0].NamespaceStringBuf.Cch(), false) == 0) { if (::FusionpCompareStrings( s_rgWorkers[i].m_pszName, s_rgWorkers[i].m_cchName, pSXSNodeInfo[0].pszText, pSXSNodeInfo[0].cchText, false) == 0) { fTemp = true; } } } } } } if (fTemp) { m_xpsParseState = s_rgWorkers[i].m_xpsNew; IFW32FALSE_EXIT( this->ValidateElementAttributes( pSXSNodeInfo, NodeCount, s_rgWorkers[i].m_prgLegalAttributes, s_rgWorkers[i].m_cLegalAttributes)); if (s_rgWorkers[i].m_pfn != NULL) IFW32FALSE_EXIT((this->*s_rgWorkers[i].m_pfn)(NodeCount, pSXSNodeInfo)); break; } } if (i == NUMBER_OF(s_rgWorkers)) { bool fEquals; // If we hit an unrecognized element and its namespace is the one we own, error! IFW32FALSE_EXIT( pSXSNodeInfo[0].NamespaceStringBuf.Win32Equals( SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE, SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE_CCH, fEquals, false)); if (fEquals) { this->LogParseError( MSG_SXS_MANIFEST_ELEMENT_USED_IN_INVALID_CONTEXT, CUnicodeString(apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen), CUnicodeString(m_ParseContext.ElementName, m_ParseContext.ElementNameCch)); ORIGINATE_WIN32_FAILURE_AND_EXIT(ElementInInvalidContext, ERROR_SXS_MANIFEST_PARSE_ERROR); } // For an unknown child element, the built-in XML parsing should start to ignore the subtree at this point. if (apNodeInfo[0]->dwType == XML_ELEMENT) m_cUnknownChildDepth = 1; } } else { if ((NodeCount != 0) && (apNodeInfo[0]->dwType == XML_ELEMENT)) { CUnicodeString s(apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen); // We're handling an unknown series of elements; increment the depth. m_cUnknownChildDepth++; } } // Fire the right callbacks for XML_ELEMENT, XML_PCDATA and XML_CDATA nodes: switch (apNodeInfo[0]->dwType) { case XML_ELEMENT: #if defined(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_CHILDREN_NOT_ALLOWED) if (m_cUnknownChildDepth != 0 && m_xpsParseState == eParsing_doc_assembly_noInherit) { hr = this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_CHILDREN_NOT_ALLOWED); goto Exit; } #endif if (m_buffElementPath.Cch() != 0) IFW32FALSE_EXIT(m_buffElementPath.Win32Append(L"!", 1)); cchTemp = m_buffElementPath.Cch(); if (pSXSNodeInfo[0].NamespaceStringBuf.Cch() != 0) { IFW32FALSE_EXIT(m_buffElementPath.Win32Append(pSXSNodeInfo[0].NamespaceStringBuf)); IFW32FALSE_EXIT(m_buffElementPath.Win32Append(L"^", 1)); } IFW32FALSE_EXIT(m_buffElementPath.Win32Append(pSXSNodeInfo[0].pszText, pSXSNodeInfo[0].cchText)); m_ParseContext.ElementPathCch = m_buffElementPath.Cch(); m_ParseContext.ElementPath = m_buffElementPath; m_ParseContext.ElementName = static_cast(m_buffElementPath) + cchTemp; m_ParseContext.ElementNameCch = m_buffElementPath.Cch() - cchTemp; IFW32FALSE_EXIT(::SxspHashString(m_buffElementPath, m_buffElementPath.Cch(), &m_ParseContext.ElementHash, true)); m_ParseContext.XMLElementDepth++; for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_ElementParsed( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, NodeCount, pSXSNodeInfo)); } break; case XML_PCDATA: for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_PCDATAParsed( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen)); } break; case XML_CDATA: for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_CDATAParsed( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen)); } break; } #if FUSION_XML_TREE IFCOMFAILED_EXIT(this->CreateXmlNode(m_CurrentParent, NodeCount, apNodeInfo, pXmlNode)); // If we don't get a node back, just ignore it... if (pXmlNode != NULL) { if (m_CurrentParent == NULL) { // Only XML Decls, PIs and the root document are at depth 0 or 1... ASSERT(m_ParseContext.XMLElementDepth <= 1); InsertTailList(&m_XmlDocument.ElementListHead, &pXmlNode->SiblingLink); } else { ASSERT(m_ParseContext.XMLElementDepth >= 1); InsertTailList(&m_CurrentParent->Element.ChildListHead, &pXmlNode->SiblingLink); } if ((pXmlNode->Type != SXS_XML_NODE_TYPE_CDATA) && (pXmlNode->Type != SXS_XML_NODE_TYPE_PCDATA)) m_CurrentParent = pXmlNode; pXmlNode = NULL; } #endif hr = NOERROR; Exit: if (pSXSNodeInfo != NULL) FUSION_DELETE_ARRAY(pSXSNodeInfo); if (pXmlNode != NULL) FUSION_DELETE_SINGLETON(pXmlNode); return hr; } #if FUSION_XML_TREE HRESULT CNodeFactory::CreateXmlNode( PSXS_XML_NODE pParent, ULONG cNodes, XML_NODE_INFO **prgpNodes, PSXS_XML_NODE &rpNewNode ) { HRESULT hr = NOERROR; FN_TRACE_HR(hr); ULONG i; ULONG cAttributes = 0; ULONG iAttribute = 0; PSXS_XML_NODE pNewNode = NULL; PSXS_XML_ATTRIBUTE pAttribute = NULL; CStringBuffer buffAttributeValue; // Handle XML_ELEMENT vs. XML_CDATA vs. XML_PCDATA... switch (prgpNodes[0]->dwType) { case XML_XMLDECL: // elements come through looking like normal XML_ELEMENT // nodes with things broken into the XML_ATTRIBUTE followed by their value... // First, let's count up the attributes... for (i=0; idwType == XML_ATTRIBUTE) cAttributes++; } // Now let's allocate the SXS_XML_NODE plus the right number of SXS_XML_ATTRIBUTEs IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE) + (cAttributes * sizeof(SXS_XML_ATTRIBUTE)), SXS_XML_NODE))); pAttribute = reinterpret_cast(pNewNode + 1); pNewNode->Flags = 0; pNewNode->Type = SXS_XML_NODE_TYPE_XML_DECL; pNewNode->Parent = pParent; pNewNode->XMLDecl.AttributeCount = cAttributes; pNewNode->XMLDecl.Attributes = pAttribute; for (i=0; idwType) { case XML_XMLDECL: INTERNAL_ERROR_CHECK(i == 0); break; case XML_ATTRIBUTE: INTERNAL_ERROR_CHECK(iAttribute < cAttributes); ulPKl = ::FusionpHashUnicodeStringCaseSensitive(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, ulPK1, ulPos1, prgwch1)); i++; buffAttributeValue.Clear(); cch = 0; while ((i < cNodes) && (prgpNodes[i]->dwType == XML_PCDATA)) { IFCOMFAILED_EXIT(buffAttributeValue.Append(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen)); cch += prgpNodes[i]->ulLen; i++; } // Gets incremented on the next iteration of the outer loop, so back up one... i--; IFW32FALSE_EXIT(::FusionpHashUnicodeString(buffAttributeValue, cch, &ulPK2, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(buffAttributeValue, cch, ulPK2, ulPos2, prgwch2)); pAttribute[iAttribute].Flags = 0; pAttribute[iAttribute].NamespaceString = 0; pAttribute[iAttribute].NameString = ulPos1; pAttribute[iAttribute].ValueString = ulPos2; iAttribute++; break; } } ASSERT(iAttribute == cAttributes); break; case XML_ELEMENT: // First, let's count up the attributes... for (i=0; idwType == XML_ATTRIBUTE) cAttributes++; } // Now let's allocate the SXS_XML_NODE plus the right number of SXS_XML_ATTRIBUTEs IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE) + (cAttributes * sizeof(SXS_XML_ATTRIBUTE)), SXS_XML_NODE))); pAttribute = reinterpret_cast(pNewNode + 1); pNewNode->Flags = 0; pNewNode->Type = SXS_XML_NODE_TYPE_ELEMENT; pNewNode->Element.NamespaceString = 0; pNewNode->Element.NameString = 0; pNewNode->Parent = pParent; pNewNode->Element.AttributeCount = cAttributes; pNewNode->Element.Attributes = pAttribute; InitializeListHead(&pNewNode->Element.ChildListHead); for (i=0; idwType) { case XML_ELEMENT: INTERNAL_ERROR_CHECK(i == 0); IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK1, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK1, ulPos1, prgwch1)); pNewNode->Element.NamespaceString = 0; pNewNode->Element.NameString = ulPos1; break; case XML_ATTRIBUTE: INTERNAL_ERROR_CHECK(iAttribute < cAttributes); IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, &ulPK1, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen, ulPK1, ulPos1, prgwch1)); i++; buffAttributeValue.Clear(); cch = 0; while ((i < cNodes) && (prgpNodes[i]->dwType == XML_PCDATA)) { IFCOMFAILED_EXIT(buffAttributeValue.Append(prgpNodes[i]->pwcText, prgpNodes[i]->ulLen)); cch += prgpNodes[i]->ulLen; i++; } // Gets incremented on the next iteration of the outer loop, so back up one... i--; IFW32FALSE_EXIT(::FusionpHashUnicodeString(buffAttributeValue, cch, &ulPK2, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(buffAttributeValue, cch, ulPK2, ulPos2, prgwch2)); pAttribute[iAttribute].Flags = 0; pAttribute[iAttribute].NamespaceString = 0; pAttribute[iAttribute].NameString = ulPos1; pAttribute[iAttribute].ValueString = ulPos2; iAttribute++; break; } } ASSERT(iAttribute == cAttributes); break; case XML_CDATA: { ULONG ulPK; ULONG ulPos; const WCHAR *prgwch; IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK, ulPos, prgwch)); // Now let's allocate the SXS_XML_NODE IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE), SXS_XML_NODE))); pNewNode->Flags = 0; pNewNode->Type = SXS_XML_NODE_TYPE_CDATA; pNewNode->Parent = pParent; pNewNode->CDataString = ulPos; break; } case XML_PCDATA: { ULONG ulPK; ULONG ulPos; const WCHAR *prgwch; IFW32FALSE_EXIT(::FusionpHashUnicodeString(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, &ulPK, false)); IFW32FALSE_EXIT(m_ParseTreeStringPool.Canonicalize(prgpNodes[0]->pwcText, prgpNodes[0]->ulLen, ulPK, ulPos, prgwch)); // Now let's allocate the SXS_XML_NODE IFALLOCFAILED_EXIT(hr, pNewNode = reinterpret_cast(FUSION_RAW_ALLOC(sizeof(SXS_XML_NODE), SXS_XML_NODE))); pNewNode->Flags = 0; pNewNode->Type = SXS_XML_NODE_TYPE_PCDATA; pNewNode->Parent = pParent; pNewNode->PCDataString = ulPos; break; } } rpNewNode = pNewNode; pNewNode = NULL; hr = NOERROR; Exit: FUSION_RAW_DEALLOC(pNewNode); return hr; } #endif // FUSION_XML_TREE BOOL CNodeFactory::SetParseType( ULONG ParseType, ULONG PathType, const CBaseStringBuffer &Path, const FILETIME &rftLastWriteTime ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PARAMETER_CHECK( (ParseType == XML_FILE_TYPE_MANIFEST) || (ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) || (ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)); PARAMETER_CHECK(PathType == ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE); IFW32FALSE_EXIT(m_buffCurrentFileName.Win32Assign(Path)); m_ParseContext.SourceFilePathType = PathType; m_ParseContext.SourceFile = m_buffCurrentFileName; m_ParseContext.SourceFileCch = m_buffCurrentFileName.Cch(); m_ParseContext.SourceFileLastWriteTime = rftLastWriteTime; m_ParseType = ParseType; fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ULONG i; ASSERT(cNumRecs != 0); ASSERT(prgNodeInfo != NULL); if (m_fAssemblyFound) { CUnicodeString s; PCWSTR ManifestPath; IFW32FALSE_EXIT(m_Assembly->GetManifestPath(&ManifestPath, NULL)); s = ManifestPath; this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_TOP_ASSEMBLY, &s); goto Exit; } m_fAssemblyFound = true; m_fMetadataSatelliteAlreadyFound = false; // Now let's tell all the contributors that we're about to begin a parsing session. for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT(m_ActCtxGenCtx->m_Contributors[i].Fire_ParseBeginning( m_ActCtxGenCtx, m_AssemblyContext, 0, // FileFlags m_ParseType, m_ParseContext.SourceFilePathType, m_ParseContext.SourceFile, m_ParseContext.SourceFileCch, m_ParseContext.SourceFileLastWriteTime, m_Assembly->m_ManifestVersionMajor, m_Assembly->m_ManifestVersionMinor, m_Assembly->m_MetadataSatelliteRosterIndex)); } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY AssemblyIdentity = NULL; const BOOL fGeneratingActCtx = (m_ActCtxGenCtx->m_ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT); ULONG i; DWORD dwValidateFlags = 0; if (m_fIdentityFound) { this->LogParseError(MSG_SXS_MULTIPLE_IDENTITY, CEventLogString(prgNodeInfo[0].pszText, prgNodeInfo[0].cchText)); ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest %ls has multiple identities\n", static_cast(m_buffCurrentFileName)); ORIGINATE_WIN32_FAILURE_AND_EXIT( MultipleIdentities, ERROR_SXS_MANIFEST_PARSE_ERROR); } m_fIdentityFound = true; IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromIdentityElement( 0, // DWORD Flags, &m_ParseContext, ASSEMBLY_IDENTITY_TYPE_DEFINITION, // ULONG Type, &AssemblyIdentity, // PASSEMBLY_IDENTITY *AssemblyIdentityOut, cNumRecs, prgNodeInfo)); // If the identity that was created is a policy statement, then we // set the internal parse type to our special 'intuited' parse type // for later checks of missing attributes and whatnot. This does // duplicate work in ValidateAssembly that does the same thing, but // we need to preemptively set this parse type before we go validating. // if (m_IntuitedParseType == eActualParseType_Undetermined) { BOOL fIsPolicy = FALSE; IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy)); if (fIsPolicy) m_IntuitedParseType = eActualParseType_PolicyManifest; else m_IntuitedParseType = eActualParseType_Manifest; } if ((m_IntuitedParseType == eActualParseType_Manifest) || (m_IntuitedParseType == eActualParseType_PolicyManifest) || (m_ParseType == XML_FILE_TYPE_MANIFEST) || (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)) { dwValidateFlags = eValidateIdentity_VersionRequired; } IFW32FALSE_EXIT( this->ValidateIdentity( dwValidateFlags, ASSEMBLY_IDENTITY_TYPE_DEFINITION, AssemblyIdentity)); if (fGeneratingActCtx) { if (m_Assembly->IsRoot()) { // If we're generating the actctx and this is the root assembly, it's possible // that we got to it by a filesystem path (e.g. private assembly) rather than // an actual reference, so we need to fix up the assembly's identity information // appropriately. IFW32FALSE_EXIT(m_Assembly->m_Information.SetProbedIdentity(AssemblyIdentity)); } else { // If we're generating the actctx and this isn't the root assembly, we need to verify // that it's the right one. BOOL fEqual; IFW32FALSE_EXIT( ::SxsAreAssemblyIdentitiesEqual( SXS_ARE_ASSEMBLY_IDENTITIES_EQUAL_FLAG_ALLOW_REF_TO_MATCH_DEF, m_Assembly->GetAssemblyIdentity(), AssemblyIdentity, &fEqual)); if (!fEqual) { this->LogParseError(MSG_SXS_COMPONENT_MANIFEST_PROBED_IDENTITY_MISMATCH); // LogParseError sets the last error appropriate to the message logged goto Exit; } } } if (m_IntuitedParseType == eActualParseType_PolicyManifest) { IFALLOCFAILED_EXIT(m_CurrentPolicyStatement = new CPolicyStatement); IFW32FALSE_EXIT(m_CurrentPolicyStatement->Initialize()); } // Tell everyone that we're sure who we are... for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_IdentityDetermined( m_ActCtxGenCtx, m_AssemblyContext, &m_ParseContext, AssemblyIdentity)); } // fix up assembly and assembly context so we know where to copy to // also save the manifest IFW32FALSE_EXIT(m_Assembly->m_Information.SetAssemblyIdentity(AssemblyIdentity)); if (m_AssemblyContext->AssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(const_cast(m_AssemblyContext->AssemblyIdentity)); m_AssemblyContext->AssemblyIdentity = AssemblyIdentity; AssemblyIdentity = NULL; fSuccess = TRUE; Exit: if (AssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(AssemblyIdentity); return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_noInherit( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); INTERNAL_ERROR_CHECK( (m_ParseType == XML_FILE_TYPE_MANIFEST) || (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) || (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)); switch (m_ParseType) { case XML_FILE_TYPE_MANIFEST: if (cNumRecs != 1) { this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_ATTRIBUTES_NOT_ALLOWED); goto Exit; } if (m_ActCtxGenCtx->m_NoInherit) { this->LogParseError(MSG_SXS_MANIFEST_PARSE_MULTIPLE_NO_INHERIT); goto Exit; } if (m_fIdentityFound) { this->LogParseError( MSG_SXS_MANIFEST_ELEMENT_MUST_OCCUR_BEFORE, CEventLogString(L"noInherit"), CEventLogString(L"assemblyIdentity")); goto Exit; } m_ActCtxGenCtx->m_NoInherit = true; break; case XML_FILE_TYPE_APPLICATION_CONFIGURATION: this->LogParseError(MSG_SXS_POLICY_PARSE_NO_INHERIT_NOT_ALLOWED); goto Exit; default: ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR); goto Exit; } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_noInheritable( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); INTERNAL_ERROR_CHECK( (m_ParseType == XML_FILE_TYPE_MANIFEST) || (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) || (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)); switch (m_ParseType) { case XML_FILE_TYPE_MANIFEST: if (cNumRecs != 1) { this->LogParseError(MSG_SXS_MANIFEST_PARSE_NO_INHERIT_ATTRIBUTES_NOT_ALLOWED); goto Exit; } if (m_fNoInheritableFound) { this->LogParseError(MSG_SXS_MANIFEST_PARSE_MULTIPLE_NOINHERITABLE); goto Exit; } if (m_fIdentityFound) { this->LogParseError( MSG_SXS_MANIFEST_ELEMENT_MUST_OCCUR_BEFORE, CEventLogString(L"noInheritable"), CEventLogString(L"assemblyIdentity")); goto Exit; } m_fNoInheritableFound = true; break; case XML_FILE_TYPE_APPLICATION_CONFIGURATION: case XML_FILE_TYPE_COMPONENT_CONFIGURATION: this->LogParseError(MSG_SXS_POLICY_PARSE_NO_INHERIT_NOT_ALLOWED); goto Exit; default: ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR); goto Exit; } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_dependency( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); bool fFound; SIZE_T cb; m_fIsDependencyOptional = false; m_fDependencyChildHit = false; m_fIsMetadataSatellite = false; IFW32FALSE_EXIT( ::SxspGetAttributeValue( 0, &s_AttributeName_optional, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(m_fIsDependencyOptional), &m_fIsDependencyOptional, cb, &::SxspValidateBoolAttribute, 0)); if (!fFound) m_fIsDependencyOptional = false; fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); bool fFound; SIZE_T cb; if (m_fDependencyChildHit == false) { m_fDependencyChildHit = true; } else { this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_DEPENDENTASSEMBLY_IN_DEPENDENCY); goto Exit; } m_fAssemblyIdentityChildOfDependenctAssemblyHit = false; IFW32FALSE_EXIT( ::SxspGetAttributeValue( 0, &s_AttributeName_metadataSatellite, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(m_fIsMetadataSatellite), &m_fIsMetadataSatellite, cb, &::SxspValidateBoolAttribute, 0)); if (!fFound) m_fIsMetadataSatellite = false; fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly_bindingRedirect( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); bool fFound; bool fValid; SIZE_T cb; CSmallStringBuffer buffOldVersion; CSmallStringBuffer buffNewVersion; INTERNAL_ERROR_CHECK(m_CurrentPolicyStatement != NULL); if (m_IntuitedParseType != eActualParseType_PolicyManifest) { this->LogParseError(MSG_SXS_BINDING_REDIRECTS_ONLY_IN_COMPONENT_CONFIGURATION); goto Exit; } IFW32FALSE_EXIT( ::SxspGetAttributeValue( SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE, &s_AttributeName_oldVersion, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(buffOldVersion), &buffOldVersion, cb, NULL, 0)); INTERNAL_ERROR_CHECK(fFound); IFW32FALSE_EXIT( ::SxspGetAttributeValue( SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE, &s_AttributeName_newVersion, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(buffNewVersion), &buffNewVersion, cb, NULL, 0)); INTERNAL_ERROR_CHECK(fFound); IFW32FALSE_EXIT(m_CurrentPolicyStatement->AddRedirect(buffOldVersion, buffNewVersion, fValid)); if (!fValid) { this->LogParseError(MSG_SXS_BINDING_REDIRECT_MISSING_REQUIRED_ATTRIBUTES); goto Exit; } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly_assemblyIdentity( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; ULONG ParseType; ASSERT(cNumRecs != 0); ASSERT(prgNodeInfo != NULL); // We're either parsing a manifest or a policy file; what else?? INTERNAL_ERROR_CHECK( (m_ParseType == XML_FILE_TYPE_MANIFEST) || (m_ParseType == XML_FILE_TYPE_APPLICATION_CONFIGURATION) || (m_ParseType == XML_FILE_TYPE_COMPONENT_CONFIGURATION)); if (m_fAssemblyIdentityChildOfDependenctAssemblyHit == false) m_fAssemblyIdentityChildOfDependenctAssemblyHit = true; else { this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_ASSEMBLYIDENTITY_IN_DEPENDENCYASSEMBLY); goto Exit; } switch (m_IntuitedParseType) { case eActualParseType_Undetermined: ParseType = m_ParseType; break; case eActualParseType_PolicyManifest: ParseType = XML_FILE_TYPE_COMPONENT_CONFIGURATION; break; case eActualParseType_Manifest: ParseType = XML_FILE_TYPE_MANIFEST; break; default: INTERNAL_ERROR_CHECK(FALSE); ParseType = m_ParseType; break; } switch (ParseType) { case XML_FILE_TYPE_MANIFEST: IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromIdentityElement( 0, &m_ParseContext, ASSEMBLY_IDENTITY_TYPE_REFERENCE, &pAssemblyIdentity, cNumRecs, prgNodeInfo)); IFW32FALSE_EXIT( this->ValidateIdentity( eValidateIdentity_VersionRequired | eValidateIdentity_PoliciesNotAllowed, ASSEMBLY_IDENTITY_TYPE_REFERENCE, pAssemblyIdentity)); // If we're not installing, process the identity... if (m_ActCtxGenCtx->m_ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT) IFW32FALSE_EXIT(::SxspEnqueueAssemblyReference(m_ActCtxGenCtx, m_Assembly, pAssemblyIdentity, m_fIsDependencyOptional, m_fIsMetadataSatellite)); break; case XML_FILE_TYPE_COMPONENT_CONFIGURATION: { BOOL fValidDependencyAssemblyIdentity = FALSE; PCWSTR pszName1 = NULL, pszName2 = NULL; SIZE_T cchName1 = 0, cchName2 = 0; if (m_CurrentPolicyDependentAssemblyIdentity != NULL) { this->LogParseError(MSG_SXS_COMPONENT_CONFIGURATION_MANIFESTS_MAY_ONLY_HAVE_ONE_DEPENDENCY); goto Exit; } IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromIdentityElement( 0, &m_ParseContext, ASSEMBLY_IDENTITY_TYPE_REFERENCE, &pAssemblyIdentity, cNumRecs, prgNodeInfo)); // check the name in dependency-assemblyidentity match with the name in assembly-assemblyidentity IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, m_Assembly->GetAssemblyIdentity(), &s_IdentityAttribute_name, &pszName1, // something in a format of "Policy.1212.1221.assemblyname" &cchName1)); IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, pAssemblyIdentity, &s_IdentityAttribute_name, &pszName2, // would be something as "assemblyname" &cchName2)); if ((cchName1 > cchName2) && (cchName2 !=0)) { if ( (*(pszName1 + (cchName1 - cchName2 -1)) == L'.') && (::FusionpCompareStrings( pszName1 + (cchName1 - cchName2), cchName2, pszName2, cchName2, FALSE // must be case-sensitive for values ) == 0 )) { fValidDependencyAssemblyIdentity = TRUE; } } if (fValidDependencyAssemblyIdentity) { IFW32FALSE_EXIT( this->ValidateIdentity( eValidateIdentity_VersionNotAllowed | eValidateIdentity_PoliciesNotAllowed, ASSEMBLY_IDENTITY_TYPE_REFERENCE, pAssemblyIdentity)); // We'll keep track of this so that we can recognize multiple dependentAssembly elements on installation // of policies. m_CurrentPolicyDependentAssemblyIdentity = pAssemblyIdentity; pAssemblyIdentity = NULL; } else // print a message and ignore this entry { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_POLICY | FUSION_DBG_LEVEL_INFO, "SXS.DLL: unexpected assemblyidentity within dependency tag in component policy \"%ls\"\n", m_buffCurrentFileName ); } } // end of this case break; #if 0 case XML_FILE_TYPE_APPLICATION_CONFIGURATION: IFW32FALSE_EXIT(this->ParseElementAttributes(cNumRecs, prgpNodeInfo, NUMBER_OF(rgPolicyAttributes), rgPolicyAttributes)); if (!(m_fAssemblyNamePresent && m_fOldVersionPresent && m_fNewVersionPresent)) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Policy dependency tag found and either assemblyname, oldversion or newversion attributes are missing\n"); ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR); goto Exit; } break; #endif // 0 default: // Internal error! INTERNAL_ERROR_CHECK(FALSE); } fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ULONG i; ASSERT(cNumRecs != 0); ASSERT(prgNodeInfo != NULL); if (m_fAssemblyFound) { CUnicodeString s; PCWSTR ManifestPath; IFW32FALSE_EXIT(m_Assembly->GetManifestPath(&ManifestPath, NULL)); s = ManifestPath; this->LogParseError(MSG_SXS_MANIFEST_MULTIPLE_TOP_ASSEMBLY, &s); goto Exit; } m_fAssemblyFound = true; m_fMetadataSatelliteAlreadyFound = false; // Now let's tell all the contributors that we're about to begin a parsing session. for (i=0; im_ContributorCount; i++) { IFW32FALSE_EXIT( m_ActCtxGenCtx->m_Contributors[i].Fire_ParseBeginning( m_ActCtxGenCtx, m_AssemblyContext, 0, // FileFlags m_ParseType, m_ParseContext.SourceFilePathType, m_ParseContext.SourceFile, m_ParseContext.SourceFileCch, m_ParseContext.SourceFileLastWriteTime, m_Assembly->m_ManifestVersionMajor, m_Assembly->m_ManifestVersionMinor, m_Assembly->m_MetadataSatelliteRosterIndex)); } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); fSuccess = TRUE; // Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); fSuccess = TRUE; // Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_assemblyIdentity( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromIdentityElement( 0, &m_ParseContext, ASSEMBLY_IDENTITY_TYPE_REFERENCE, &pAssemblyIdentity, cNumRecs, prgNodeInfo)); IFW32FALSE_EXIT( this->ValidateIdentity( eValidateIdentity_VersionRequired | eValidateIdentity_PoliciesNotAllowed, ASSEMBLY_IDENTITY_TYPE_REFERENCE, pAssemblyIdentity)); fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); fSuccess = TRUE; // Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly_assemblyIdentity( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY pAssemblyIdentity = NULL; CPolicyStatement *pPolicyStatement = NULL; IFW32FALSE_EXIT( ::SxspCreateAssemblyIdentityFromIdentityElement( 0, &m_ParseContext, ASSEMBLY_IDENTITY_TYPE_REFERENCE, &pAssemblyIdentity, cNumRecs, prgNodeInfo)); IFW32FALSE_EXIT( this->ValidateIdentity( eValidateIdentity_VersionNotAllowed | eValidateIdentity_PoliciesNotAllowed, ASSEMBLY_IDENTITY_TYPE_REFERENCE, pAssemblyIdentity)); IFW32FALSE_EXIT( ::SxspGenerateTextuallyEncodedPolicyIdentityFromAssemblyIdentity( SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION, pAssemblyIdentity, m_buffCurrentApplicationPolicyIdentityKey, NULL)); IFW32FALSE_EXIT(m_ActCtxGenCtx->m_ApplicationPolicyTable.Find(m_buffCurrentApplicationPolicyIdentityKey, pPolicyStatement)); if (pPolicyStatement != NULL) { pPolicyStatement = NULL; this->LogParseError(MSG_SXS_APPLICATION_CONFIGURATION_MANIFEST_MAY_ONLY_HAVE_ONE_DEPENDENTASSEMBLY_PER_IDENTITY); goto Exit; } IFALLOCFAILED_EXIT(pPolicyStatement = new CPolicyStatement); IFW32FALSE_EXIT(pPolicyStatement->Initialize()); IFW32FALSE_EXIT(m_ActCtxGenCtx->m_ApplicationPolicyTable.Insert(m_buffCurrentApplicationPolicyIdentityKey, pPolicyStatement)); m_CurrentPolicyStatement = pPolicyStatement; pPolicyStatement = NULL; if (m_CurrentPolicyDependentAssemblyIdentity != NULL) { ::SxsDestroyAssemblyIdentity(m_CurrentPolicyDependentAssemblyIdentity); m_CurrentPolicyDependentAssemblyIdentity = NULL; } m_CurrentPolicyDependentAssemblyIdentity = pAssemblyIdentity; pAssemblyIdentity = NULL; fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); if (pPolicyStatement != NULL) FUSION_DELETE_SINGLETON(pPolicyStatement); return fSuccess; } BOOL CNodeFactory::XMLParser_Element_doc_configuration_windows_assemblyBinding_dependentAssembly_bindingRedirect( USHORT cNumRecs, PCSXS_NODE_INFO prgNodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); CSmallStringBuffer buffOldVersion; CSmallStringBuffer buffNewVersion; bool fFound; bool fValid; SIZE_T cb; if (m_CurrentPolicyStatement == NULL) { this->LogParseError(MSG_SXS_APPLICATION_CONFIGURATION_MANIFEST_DEPENDENTASSEMBLY_MISSING_IDENTITY); goto Exit; } IFW32FALSE_EXIT( ::SxspGetAttributeValue( SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE, &s_AttributeName_oldVersion, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(buffOldVersion), &buffOldVersion, cb, NULL, 0)); INTERNAL_ERROR_CHECK(fFound); IFW32FALSE_EXIT( ::SxspGetAttributeValue( SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE, &s_AttributeName_newVersion, prgNodeInfo, cNumRecs, &m_ParseContext, fFound, sizeof(buffNewVersion), &buffNewVersion, cb, NULL, 0)); INTERNAL_ERROR_CHECK(fFound); // If either are not found, log an error if (!fFound) { this->LogParseError(MSG_SXS_BINDING_REDIRECT_MISSING_REQUIRED_ATTRIBUTES); goto Exit; } IFW32FALSE_EXIT(m_CurrentPolicyStatement->AddRedirect(buffOldVersion, buffNewVersion, fValid)); if (! fValid) { // log an error ::FusionpLogError( MSG_SXS_POLICY_VERSION_OVERLAP, CEventLogString(m_AssemblyContext->PolicyPath), CEventLogString(buffOldVersion), CEventLogString(buffNewVersion)); ORIGINATE_WIN32_FAILURE_AND_EXIT(PolicyVersionOverlap, ERROR_SXS_MANIFEST_PARSE_ERROR); } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::XMLParser_Parse_PartialAssemblyVersion( PVOID pvDatum, BOOL fAlreadyFound, CBaseStringBuffer &rbuff ) { return reinterpret_cast(pvDatum)->Parse(rbuff, rbuff.Cch()); } BOOL CNodeFactory::XMLParser_Parse_String( LPVOID pvDatum, BOOL fAlreadyFound, CBaseStringBuffer &rbuff) { return ((CBaseStringBuffer *) pvDatum)->Win32Assign(rbuff); } BOOL CNodeFactory::ParseElementAttributes( USHORT cNumRecs, XML_NODE_INFO **prgpNodeInfo, SIZE_T cEntries, const AttributeMapEntry *prgEntries ) { BOOL fSuccess = FALSE; ULONG i, j; for (i=1; idwType != XML_ATTRIBUTE) continue; for (j=0; jpwcText, prgpNodeInfo[i]->ulLen, false) == 0) { // Because attribute values may be multipart due to entity references, // we accumulate the attibute value into buffTemp to start, and then do // the parsing/whatever afterwards. CStringBuffer buffTemp; BOOL *pfIndicator = (BOOL *) (((ULONG_PTR) this) + prgEntries[j].m_offsetIndicator); while ((++i < cNumRecs) && (prgpNodeInfo[i]->dwType == XML_PCDATA)) { if (!buffTemp.Win32Append(prgpNodeInfo[i]->pwcText, prgpNodeInfo[i]->ulLen)) goto Exit; } // The outer for(;;) loop is going to increment i, so we need to back it up one // place... i--; // Call the appropriate value type handler function... if (prgEntries[j].m_pfn != NULL) { if (!((this->*(prgEntries[j].m_pfn))(((LPBYTE) this) + prgEntries[j].m_offsetData, *pfIndicator, buffTemp))) goto Exit; } *pfIndicator = TRUE; break; } } } fSuccess = TRUE; Exit: return fSuccess; } HRESULT CNodeFactory::LogParseError( DWORD dwLastParseError, const UNICODE_STRING *p1, const UNICODE_STRING *p2, const UNICODE_STRING *p3, const UNICODE_STRING *p4, const UNICODE_STRING *p5, const UNICODE_STRING *p6, const UNICODE_STRING *p7, const UNICODE_STRING *p8, const UNICODE_STRING *p9, const UNICODE_STRING *p10, const UNICODE_STRING *p11, const UNICODE_STRING *p12, const UNICODE_STRING *p13, const UNICODE_STRING *p14, const UNICODE_STRING *p15, const UNICODE_STRING *p16, const UNICODE_STRING *p17, const UNICODE_STRING *p18, const UNICODE_STRING *p19, const UNICODE_STRING *p20 ) { return ::FusionpLogParseError( m_ParseContext.SourceFile, m_ParseContext.SourceFileCch, m_ParseContext.LineNumber, dwLastParseError, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); } VOID CNodeFactory::ParseErrorCallback_MissingRequiredAttribute( PCACTCTXCTB_PARSE_CONTEXT ParseContext, IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName ) { // CNodeFactory *pThis = (CNodeFactory *) ErrorContext; ::FusionpLogRequiredAttributeMissingParseError( ParseContext->SourceFile, ParseContext->SourceFileCch, ParseContext->LineNumber, ParseContext->ElementName, ParseContext->ElementNameCch, AttributeName->Name, AttributeName->NameCch); } VOID CNodeFactory::ParseErrorCallback_InvalidAttributeValue( PCACTCTXCTB_PARSE_CONTEXT ParseContext, IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName ) { // CNodeFactory *pThis = (CNodeFactory *) ErrorContext; ::FusionpLogInvalidAttributeValueParseError( ParseContext->SourceFile, ParseContext->SourceFileCch, ParseContext->LineNumber, ParseContext->ElementName, ParseContext->ElementNameCch, AttributeName->Name, AttributeName->NameCch); } VOID CNodeFactory::ParseErrorCallback_AttributeNotAllowed( PCACTCTXCTB_PARSE_CONTEXT ParseContext, IN PCATTRIBUTE_NAME_DESCRIPTOR AttributeName ) { // CNodeFactory *pThis = (CNodeFactory *) ErrorContext; ::FusionpLogAttributeNotAllowedParseError( ParseContext->SourceFile, ParseContext->SourceFileCch, ParseContext->LineNumber, ParseContext->ElementName, ParseContext->ElementNameCch, AttributeName->Name, AttributeName->NameCch); } static VOID SxspDbgPrintXmlNodeInfo( ULONG Level, XML_NODE_INFO *pNode ) { CUnicodeString s(pNode->pwcText, pNode->ulLen); #if DBG_SXS ::FusionpDbgPrintEx(Level, "SXS.DLL: XML_NODE_INFO at %p\n", pNode); ::FusionpDbgPrintEx(Level, " dwSize = %d\n", pNode->dwSize); ::FusionpDbgPrintEx(Level, " dwType = %d (%s)\n", pNode->dwType, SxspFormatXmlNodeType(pNode->dwType)); ::FusionpDbgPrintEx(Level, " dwSubType = %d\n", pNode->dwSubType); ::FusionpDbgPrintEx(Level, " fTerminal = %d\n", pNode->fTerminal); ::FusionpDbgPrintEx(Level, " pwcText = %p (\"%wZ\")\n", pNode->pwcText, &s); ::FusionpDbgPrintEx(Level, " ulLen = %d\n", pNode->ulLen); ::FusionpDbgPrintEx(Level, " ulNsPrefixLen = %d\n", pNode->ulNsPrefixLen); ::FusionpDbgPrintEx(Level, " pNode = %p\n", pNode->pNode); ::FusionpDbgPrintEx(Level, " pReserved = %p\n", pNode->pReserved); #else ::FusionpDbgPrintEx(Level, "SXS.DLL: XML_NODE_INFO at %p: \"%wZ\"\n", pNode, &s); #endif } static PCSTR SxspFormatXmlNodeType( DWORD dwType ) { PCSTR Result = "Unknown"; #define HANDLE_NODE_TYPE(x) case static_cast(x): Result = #x; break; switch (dwType) { HANDLE_NODE_TYPE(XML_ELEMENT) HANDLE_NODE_TYPE(XML_ATTRIBUTE) HANDLE_NODE_TYPE(XML_PI) HANDLE_NODE_TYPE(XML_XMLDECL) HANDLE_NODE_TYPE(XML_DOCTYPE) HANDLE_NODE_TYPE(XML_DTDATTRIBUTE) HANDLE_NODE_TYPE(XML_ENTITYDECL) HANDLE_NODE_TYPE(XML_ELEMENTDECL) HANDLE_NODE_TYPE(XML_ATTLISTDECL) HANDLE_NODE_TYPE(XML_NOTATION) HANDLE_NODE_TYPE(XML_GROUP) HANDLE_NODE_TYPE(XML_INCLUDESECT) HANDLE_NODE_TYPE(XML_PCDATA) HANDLE_NODE_TYPE(XML_CDATA) HANDLE_NODE_TYPE(XML_IGNORESECT) HANDLE_NODE_TYPE(XML_COMMENT) HANDLE_NODE_TYPE(XML_ENTITYREF) HANDLE_NODE_TYPE(XML_WHITESPACE) HANDLE_NODE_TYPE(XML_NAME) HANDLE_NODE_TYPE(XML_NMTOKEN) HANDLE_NODE_TYPE(XML_STRING) HANDLE_NODE_TYPE(XML_PEREF) HANDLE_NODE_TYPE(XML_MODEL) HANDLE_NODE_TYPE(XML_ATTDEF) HANDLE_NODE_TYPE(XML_ATTTYPE) HANDLE_NODE_TYPE(XML_ATTPRESENCE) HANDLE_NODE_TYPE(XML_DTDSUBSET) } return Result; } BOOL CNodeFactory::ValidateIdentity( DWORD Flags, ULONG Type, PCASSEMBLY_IDENTITY AssemblyIdentity ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PCWSTR pszTemp = NULL; SIZE_T cchTemp = 0; bool fSyntaxValid = false; bool fError = false; BOOL fIsPolicy; PARAMETER_CHECK((Flags & ~( eValidateIdentity_VersionRequired | eValidateIdentity_PoliciesNotAllowed | eValidateIdentity_VersionNotAllowed)) == 0); PARAMETER_CHECK((Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) || (Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE)); PARAMETER_CHECK(AssemblyIdentity != NULL); // // only one of these flags is allowed // IFINVALID_FLAGS_EXIT_WIN32(Flags, eValidateIdentity_PoliciesNotAllowed | eValidateIdentity_VersionNotAllowed | eValidateIdentity_VersionRequired); // // Get the type of this assembly // IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy)); // // If it's policy, then make sure that policies are allowed. Otherwise, fail out. // if (fIsPolicy) { if (Flags & eValidateIdentity_PoliciesNotAllowed) { FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest \"%ls\" (line %d) contains a type=\"win32-policy\" where it shouldn't\n", m_ParseContext.SourceFile, m_ParseContext.LineNumber); fError = true; } else { m_AssemblyContext->Flags |= ACTCTXCTB_ASSEMBLY_CONTEXT_IS_SYSTEM_POLICY_INSTALLATION; } } IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, AssemblyIdentity, &s_IdentityAttribute_name, &pszTemp, &cchTemp)); if (cchTemp == 0) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest \"%ls\" (line %d) is missing name attribute; report to owner of \"%ls\"\n", m_ParseContext.SourceFile, m_ParseContext.LineNumber, m_ParseContext.SourceFile); fError = true; } IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, AssemblyIdentity, &s_IdentityAttribute_processorArchitecture, &pszTemp, &cchTemp)); IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, AssemblyIdentity, &s_IdentityAttribute_version, &pszTemp, &cchTemp)); if (cchTemp != 0) { ASSEMBLY_VERSION av; IFW32FALSE_EXIT(CFusionParser::ParseVersion(av, pszTemp, cchTemp, fSyntaxValid)); if (!fSyntaxValid) { ::FusionpLogInvalidAttributeValueParseError( m_ParseContext.SourceFile, m_ParseContext.SourceFileCch, m_ParseContext.LineNumber, m_ParseContext.ElementName, m_ParseContext.ElementNameCch, s_IdentityAttribute_version); ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidVersionNumber, ERROR_SXS_MANIFEST_PARSE_ERROR); } } if ((Flags & (eValidateIdentity_VersionNotAllowed | eValidateIdentity_VersionRequired)) != 0) { if ((Flags & eValidateIdentity_VersionNotAllowed) != 0 && cchTemp != 0) { fError = true; ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest \"%ls\" (line %d) has a version attribute where it may not appear; report to owner of \"%ls\"\n", m_ParseContext.SourceFile, m_ParseContext.LineNumber, m_ParseContext.SourceFile); } else if ((Flags & eValidateIdentity_VersionRequired) != 0 && cchTemp == 0) { fError = true; ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest \"%ls\" (line %d) is missing version attribute; report to owner of \"%ls\"\n", m_ParseContext.SourceFile, m_ParseContext.LineNumber, m_ParseContext.SourceFile); } } if (fError) { ::FusionpDbgPrintEx( FUSION_DBG_LEVEL_ERROR, "SXS.DLL: Manifest \"%ls\" is missing required attribute or contains disallowed attribute; report to owner of \"%ls\"\n", m_ParseContext.SourceFile, m_ParseContext.SourceFile); ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidIdentity, ERROR_SXS_MANIFEST_PARSE_ERROR); } fSuccess = TRUE; Exit: return fSuccess; } BOOL CNodeFactory::ValidateElementAttributes( PCSXS_NODE_INFO prgNodes, SIZE_T cNodes, PCELEMENT_LEGAL_ATTRIBUTE prgAttributes, UCHAR cAttributes ) { FN_PROLOG_WIN32 SIZE_T i; UCHAR j; UCHAR cRequiredAttributes, cRequiredAttributesFound; UCHAR rgRequiredAttributeFoundBitMask[8]; // 8 * 32 = 256 BOOL fParseFailed = FALSE; PARAMETER_CHECK((cNodes == 0) || (prgNodes != NULL)); PARAMETER_CHECK((cAttributes == 0) || (prgAttributes != NULL)); cRequiredAttributes = 0; cRequiredAttributesFound = 0; for (i=0; i= 3) && ((pszText[0] == L'x') || (pszText[0] == L'X')) && ((pszText[1] == L'm') || (pszText[1] == L'M')) && ((pszText[2] == L'l') || (pszText[2] == L'L'))) { continue; } if (cchNamespace != 0 ) { continue; } for (j=0; jNameCch) && (cchNamespace == prgAttributes[j].m_pName->NamespaceCch) && (::FusionpCompareStrings(prgNodes[i].NamespaceStringBuf, cchNamespace, prgAttributes[j].m_pName->Namespace, cchNamespace, false) == 0) && (::FusionpCompareStrings(pszText, cchText, prgAttributes[j].m_pName->Name, cchText, false) == 0)) { if (prgAttributes[j].m_pfnValidator != NULL) { CSmallStringBuffer buffValue; bool fValid = false; SIZE_T cb; SIZE_T i2; for (i2=i+1; i2Name, prgAttributes[j].m_pName->NameCch); ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidAttributeValue, ERROR_SXS_MANIFEST_PARSE_ERROR); } } if (prgAttributes[j].m_dwFlags & ELEMENT_LEGAL_ATTRIBUTE_FLAG_REQUIRED) { rgRequiredAttributeFoundBitMask[(j / 32)] |= (1 << (j % 32)); cRequiredAttributesFound++; } break; } } if (j == cAttributes) { // We found an illegal attribute!! ::FusionpLogAttributeNotAllowedParseError( m_ParseContext.SourceFile, m_ParseContext.SourceFileCch, m_ParseContext.LineNumber, prgNodes[0].pszText, prgNodes[0].cchText, prgNodes[i].pszText, prgNodes[i].cchText); // We don't just go to exit here because we want to report all the bad attributes and missing attributes... fParseFailed = TRUE; } } } if (cRequiredAttributesFound != cRequiredAttributes) { for (j=0; jName, prgAttributes[j].m_pName->NameCch); fParseFailed = TRUE; } } } } if (fParseFailed) ORIGINATE_WIN32_FAILURE_AND_EXIT(ParseError, ERROR_SXS_MANIFEST_PARSE_ERROR); FN_EPILOG }