summaryrefslogtreecommitdiff
path: root/src/vm/assemblynamesconfigfactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/assemblynamesconfigfactory.cpp')
-rw-r--r--src/vm/assemblynamesconfigfactory.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/vm/assemblynamesconfigfactory.cpp b/src/vm/assemblynamesconfigfactory.cpp
new file mode 100644
index 0000000000..ed5da9679b
--- /dev/null
+++ b/src/vm/assemblynamesconfigfactory.cpp
@@ -0,0 +1,264 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+// AssemblyNamesConfigFactory.cpp
+//
+
+//
+//
+// Parses XML files and adding runtime entries to assembly list
+// Abstract, derived classes need to override AddAssemblyName
+#include "common.h"
+#include "common.h"
+#include <xmlparser.h>
+#include <objbase.h>
+#include "parse.h"
+#include "assemblynamesconfigfactory.h"
+
+
+#define ISWHITE(ch) ((ch) >= 0x09 && (ch) <= 0x0D || (ch) == 0x20)
+
+#define CONST_STRING_AND_LEN(str) str, NumItems(str)-1
+
+extern int EEXMLStringCompare(const WCHAR *pStr1,
+ DWORD cchStr1,
+ const WCHAR *pStr2,
+ DWORD cchStr2);
+extern HRESULT VersionFromString(LPCWSTR wzVersion, WORD *pwVerMajor, WORD *pwVerMinor,
+ WORD *pwVerBld, WORD *pwVerRev);
+extern HRESULT MapProcessorArchitectureToPEKIND(LPCWSTR pwzProcArch, PEKIND *pe);
+
+AssemblyNamesConfigFactory::AssemblyNamesConfigFactory()
+{
+ LIMITED_METHOD_CONTRACT;
+ m_pAssemblyName = NULL;
+ m_bCurrentEntryInvalid = TRUE;
+ m_dwCurrentElementDepth = 0;
+ m_dwProperty = ASM_NAME_MAX_PARAMS;
+}
+
+AssemblyNamesConfigFactory::~AssemblyNamesConfigFactory()
+{
+ LIMITED_METHOD_CONTRACT;
+}
+
+
+HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::NotifyEvent(
+ /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
+ /* [in] */ XML_NODEFACTORY_EVENT iEvt)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::BeginChildren(
+ /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
+ /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
+{
+ LIMITED_METHOD_CONTRACT;
+ m_dwCurrentElementDepth ++;
+
+ return S_OK;
+}
+
+//---------------------------------------------------------------------------
+HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::EndChildren(
+ /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
+ /* [in] */ BOOL fEmptyNode,
+ /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ INJECT_FAULT(return E_OUTOFMEMORY;);
+ }
+ CONTRACTL_END;
+
+ HRESULT hr = S_OK;
+ EX_TRY
+ {
+ if (m_dwCurrentElementDepth == 1 && m_pAssemblyName != NULL)
+ {
+ if (!m_bCurrentEntryInvalid)
+ {
+ // publish
+ AddAssemblyName(m_pAssemblyName);
+ };
+ m_pAssemblyName->Release();
+ m_pAssemblyName = NULL;
+ }
+
+ if (!fEmptyNode)
+ m_dwCurrentElementDepth --;
+ }
+ EX_CATCH_HRESULT(hr);
+ return hr;
+}
+
+
+
+HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::CreateNode(
+ /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
+ /* [in] */ PVOID pNode,
+ /* [in] */ USHORT cNumRecs,
+ /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ INJECT_FAULT(return E_OUTOFMEMORY;);
+ }
+ CONTRACTL_END;
+
+ if(m_dwCurrentElementDepth > 1)
+ return S_OK;
+
+ HRESULT hr = S_OK;
+
+ for(DWORD i = 0; i < cNumRecs; i++) {
+ CONTRACT_VIOLATION(ThrowsViolation); // Lots of stuff in here throws!
+
+ if(apNodeInfo[i]->dwType == XML_ELEMENT ||
+ apNodeInfo[i]->dwType == XML_ATTRIBUTE ||
+ apNodeInfo[i]->dwType == XML_PCDATA)
+ {
+
+ DWORD dwStringSize = apNodeInfo[i]->ulLen;
+ LPWSTR pszString = (WCHAR*) apNodeInfo[i]->pwcText;
+ // Trim the value
+
+ // we should never decrement lgth if it's 0, because it's unsigned
+
+ for(;*pszString && ISWHITE(*pszString) && dwStringSize>0; pszString++, dwStringSize--);
+ while( dwStringSize > 0 && ISWHITE(pszString[dwStringSize-1]))
+ dwStringSize--;
+ switch(apNodeInfo[i]->dwType)
+ {
+ case XML_ELEMENT :
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("assemblyIdentity"))) == 0)
+ {
+ // new entry
+ _ASSERTE(m_pAssemblyName == NULL);
+ IfFailRet(CreateAssemblyNameObject(&m_pAssemblyName, NULL,0,NULL));
+ m_bCurrentEntryInvalid = FALSE;
+ }
+ else
+ {
+ m_bCurrentEntryInvalid = TRUE;
+ }
+
+ break;
+
+
+ case XML_ATTRIBUTE :
+ if(m_bCurrentEntryInvalid)
+ break;
+
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("name"))) == 0)
+ {
+ m_dwProperty = ASM_NAME_NAME;
+ }
+ else
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("version"))) == 0)
+ {
+ m_dwProperty = ASM_NAME_MAJOR_VERSION;
+ }
+ else
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("publicKeyToken"))) == 0)
+ {
+ m_dwProperty = ASM_NAME_PUBLIC_KEY_TOKEN;
+ }
+ else
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("processorArchitecture"))) == 0)
+ {
+ m_dwProperty = ASM_NAME_ARCHITECTURE;
+ }
+ else
+ {
+ m_bCurrentEntryInvalid = TRUE;
+ }
+ break;
+
+
+ case XML_PCDATA :
+ if(m_bCurrentEntryInvalid)
+ break;
+
+ _ASSERTE(m_pAssemblyName!= NULL); // can only be null if m_bCurrentEntryInvalid
+ switch(m_dwProperty)
+ {
+ case ASM_NAME_NAME:
+ {
+ StackSString s(pszString,dwStringSize);
+ // takes number of bytes, thus *2
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_NAME, LPCWSTR(s), (dwStringSize+1)*sizeof(WCHAR)));
+ }
+ break;
+ case ASM_NAME_MAJOR_VERSION:
+ {
+ StackSString s(pszString,dwStringSize);
+ WORD wVerMajor = 0;
+ WORD wVerMinor = 0;
+ WORD wVerBld = 0;
+ WORD wVerRev = 0;
+ if (SUCCEEDED(VersionFromString(s, &wVerMajor, &wVerMinor, &wVerBld, &wVerRev)))
+ {
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_MAJOR_VERSION, &wVerMajor, sizeof(WORD)));
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_MINOR_VERSION, &wVerMinor, sizeof(WORD)));
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_BUILD_NUMBER, &wVerBld, sizeof(WORD)));
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_REVISION_NUMBER, &wVerRev, sizeof(WORD)));
+ }
+ else
+ m_bCurrentEntryInvalid = TRUE;
+
+ }
+ break;
+ case ASM_NAME_ARCHITECTURE:
+ {
+ StackSString s(pszString,dwStringSize);
+ PEKIND PeKind = peNone;
+ if(SUCCEEDED(MapProcessorArchitectureToPEKIND(s, &PeKind)))
+ {
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_ARCHITECTURE, (LPBYTE) &PeKind, sizeof(PeKind)));
+ }
+ else
+ {
+ m_bCurrentEntryInvalid = TRUE;
+ }
+
+ }
+ break;
+ case ASM_NAME_PUBLIC_KEY_TOKEN:
+ {
+ if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("null"))) == 0)
+ {
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, 0));
+ }
+ else
+ {
+ if (dwStringSize % 2 != 0)
+ return FUSION_E_INVALID_NAME;
+
+ DWORD cbProp = dwStringSize / 2;
+ NewHolder<BYTE> pbProp = new BYTE[cbProp];
+ CParseUtils::UnicodeHexToBin(pszString, dwStringSize, pbProp); //????
+ IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, pbProp, cbProp));
+ }
+ break;
+ }
+
+ default:
+ _ASSERTE(!"Invalid format");
+ m_bCurrentEntryInvalid = TRUE;
+ break;
+ }
+ break;
+ }
+
+ }
+ }
+ return S_OK;
+}