summaryrefslogtreecommitdiff
path: root/src/binder/inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/binder/inc')
-rw-r--r--src/binder/inc/.gitmirror1
-rw-r--r--src/binder/inc/applicationcontext.hpp197
-rw-r--r--src/binder/inc/applicationcontext.inl110
-rw-r--r--src/binder/inc/assembly.hpp222
-rw-r--r--src/binder/inc/assembly.inl218
-rw-r--r--src/binder/inc/assemblybinder.hpp178
-rw-r--r--src/binder/inc/assemblyentry.hpp62
-rw-r--r--src/binder/inc/assemblyhashtraits.hpp59
-rw-r--r--src/binder/inc/assemblyidentity.hpp149
-rw-r--r--src/binder/inc/assemblyidentitycache.hpp116
-rw-r--r--src/binder/inc/assemblyname.hpp112
-rw-r--r--src/binder/inc/assemblyname.inl144
-rw-r--r--src/binder/inc/assemblyversion.hpp60
-rw-r--r--src/binder/inc/assemblyversion.inl183
-rw-r--r--src/binder/inc/binderinterface.hpp69
-rw-r--r--src/binder/inc/bindertypes.hpp132
-rw-r--r--src/binder/inc/bindinglog.hpp82
-rw-r--r--src/binder/inc/bindinglog.inl46
-rw-r--r--src/binder/inc/bindresult.hpp64
-rw-r--r--src/binder/inc/bindresult.inl229
-rw-r--r--src/binder/inc/cdebuglog.hpp67
-rw-r--r--src/binder/inc/clrprivbinderassemblyloadcontext.h86
-rw-r--r--src/binder/inc/clrprivbindercoreclr.h100
-rw-r--r--src/binder/inc/contextentry.hpp146
-rw-r--r--src/binder/inc/coreclrbindercommon.h58
-rw-r--r--src/binder/inc/debuglog.hpp118
-rw-r--r--src/binder/inc/failurecache.hpp38
-rw-r--r--src/binder/inc/failurecachehashtraits.hpp88
-rw-r--r--src/binder/inc/fusionassemblyname.hpp217
-rw-r--r--src/binder/inc/fusionhelpers.hpp95
-rw-r--r--src/binder/inc/list.hpp358
-rw-r--r--src/binder/inc/loadcontext.hpp49
-rw-r--r--src/binder/inc/loadcontext.inl90
-rw-r--r--src/binder/inc/propertyhashtraits.hpp95
-rw-r--r--src/binder/inc/propertymap.hpp35
-rw-r--r--src/binder/inc/stringlexer.hpp100
-rw-r--r--src/binder/inc/stringlexer.inl266
-rw-r--r--src/binder/inc/textualidentityparser.hpp70
-rw-r--r--src/binder/inc/utils.hpp57
-rw-r--r--src/binder/inc/variables.hpp66
40 files changed, 4632 insertions, 0 deletions
diff --git a/src/binder/inc/.gitmirror b/src/binder/inc/.gitmirror
new file mode 100644
index 0000000000..f507630f94
--- /dev/null
+++ b/src/binder/inc/.gitmirror
@@ -0,0 +1 @@
+Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror. \ No newline at end of file
diff --git a/src/binder/inc/applicationcontext.hpp b/src/binder/inc/applicationcontext.hpp
new file mode 100644
index 0000000000..4c256771eb
--- /dev/null
+++ b/src/binder/inc/applicationcontext.hpp
@@ -0,0 +1,197 @@
+// 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.
+// ============================================================
+//
+// ApplicationContext.hpp
+//
+
+
+//
+// Defines the ApplicationContext class
+//
+// ============================================================
+
+#ifndef __BINDER__APPLICATION_CONTEXT_HPP__
+#define __BINDER__APPLICATION_CONTEXT_HPP__
+
+#include "bindertypes.hpp"
+#include "failurecache.hpp"
+#include "assemblyidentitycache.hpp"
+#ifdef FEATURE_VERSIONING_LOG
+#include "bindinglog.hpp"
+#endif // FEATURE_VERSIONING_LOG
+#include "stringarraylist.h"
+
+namespace BINDER_SPACE
+{
+ //=============================================================================================
+ // Data structures for Simple Name -> File Name hash
+ struct FileNameMapEntry
+ {
+ LPWSTR m_wszFileName;
+ };
+
+ class FileNameHashTraits : public NoRemoveSHashTraits< DefaultSHashTraits< FileNameMapEntry > >
+ {
+ public:
+ typedef PCWSTR key_t;
+ static const FileNameMapEntry Null() { FileNameMapEntry e; e.m_wszFileName = nullptr; return e; }
+ static bool IsNull(const FileNameMapEntry & e) { return e.m_wszFileName == nullptr; }
+ static const key_t GetKey(const FileNameMapEntry & e)
+ {
+ key_t key;
+ key = e.m_wszFileName;
+ return key;
+ }
+ static count_t Hash(const key_t &str) { return HashiString(str); }
+ static BOOL Equals(const key_t &lhs, const key_t &rhs) { LIMITED_METHOD_CONTRACT; return (_wcsicmp(lhs, rhs) == 0); }
+ };
+
+ typedef SHash<FileNameHashTraits> TpaFileNameHash;
+
+ // Entry in SHash table that maps namespace to list of files
+ struct SimpleNameToFileNameMapEntry
+ {
+ LPWSTR m_wszSimpleName;
+ LPWSTR m_wszILFileName;
+ LPWSTR m_wszNIFileName;
+ };
+
+ // SHash traits for Namespace -> FileNameList hash
+ class SimpleNameToFileNameMapTraits : public NoRemoveSHashTraits< DefaultSHashTraits< SimpleNameToFileNameMapEntry > >
+ {
+ public:
+ typedef PCWSTR key_t;
+ static const SimpleNameToFileNameMapEntry Null() { SimpleNameToFileNameMapEntry e; e.m_wszSimpleName = nullptr; return e; }
+ static bool IsNull(const SimpleNameToFileNameMapEntry & e) { return e.m_wszSimpleName == nullptr; }
+ static const key_t GetKey(const SimpleNameToFileNameMapEntry & e)
+ {
+ key_t key;
+ key = e.m_wszSimpleName;
+ return key;
+ }
+ static count_t Hash(const key_t &str) { return HashiString(str); }
+ static BOOL Equals(const key_t &lhs, const key_t &rhs) { LIMITED_METHOD_CONTRACT; return (_wcsicmp(lhs, rhs) == 0); }
+
+ void OnDestructPerEntryCleanupAction(const SimpleNameToFileNameMapEntry & e)
+ {
+ if (e.m_wszILFileName == nullptr && e.m_wszNIFileName == nullptr)
+ {
+ // Don't delete simple name here since it's a filename only entry and will be cleaned up
+ // by the SimpleName -> FileName entry which reuses the same filename pointer.
+ return;
+ }
+
+ if (e.m_wszSimpleName != nullptr)
+ {
+ delete [] e.m_wszSimpleName;
+ }
+ if (e.m_wszILFileName != nullptr)
+ {
+ delete [] e.m_wszILFileName;
+ }
+ if (e.m_wszNIFileName != nullptr)
+ {
+ delete [] e.m_wszNIFileName;
+ }
+ }
+ static const bool s_DestructPerEntryCleanupAction = true;
+ };
+
+ typedef SHash<SimpleNameToFileNameMapTraits> SimpleNameToFileNameMap;
+
+ class ApplicationContext
+ : public IUnknown
+ {
+ public:
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid,
+ void **ppv);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+
+ // ApplicationContext methods
+ ApplicationContext();
+ virtual ~ApplicationContext();
+ HRESULT Init();
+
+ inline SString &GetApplicationName();
+ inline DWORD GetAppDomainId();
+ inline void SetAppDomainId(DWORD dwAppDomainId);
+
+ HRESULT SetupBindingPaths(/* in */ SString &sTrustedPlatformAssemblies,
+ /* in */ SString &sPlatformResourceRoots,
+ /* in */ SString &sAppPaths,
+ /* in */ SString &sAppNiPaths,
+ /* in */ BOOL fAcquireLock);
+
+ HRESULT GetAssemblyIdentity(/* in */ LPCSTR szTextualIdentity,
+ /* in */ AssemblyIdentityUTF8 **ppAssemblyIdentity);
+
+ // Getters/Setter
+ inline ExecutionContext *GetExecutionContext();
+ inline InspectionContext *GetInspectionContext();
+ inline FailureCache *GetFailureCache();
+ inline HRESULT AddToFailureCache(SString &assemblyNameOrPath,
+ HRESULT hrBindResult);
+ inline StringArrayList *GetAppPaths();
+ inline SimpleNameToFileNameMap *GetTpaList();
+ inline TpaFileNameHash *GetTpaFileNameList();
+ inline StringArrayList *GetPlatformResourceRoots();
+ inline StringArrayList *GetAppNiPaths();
+
+ // Using a host-configured Trusted Platform Assembly list
+ bool IsTpaListProvided();
+ inline CRITSEC_COOKIE GetCriticalSectionCookie();
+ inline LONG GetVersion();
+ inline void IncrementVersion();
+
+#ifdef FEATURE_VERSIONING_LOG
+ inline BindingLog *GetBindingLog();
+ inline void ClearBindingLog();
+#endif // FEATURE_VERSIONING_LOG
+
+ protected:
+ LONG m_cRef;
+ Volatile<LONG> m_cVersion;
+ SString m_applicationName;
+ DWORD m_dwAppDomainId;
+ ExecutionContext *m_pExecutionContext;
+ InspectionContext *m_pInspectionContext;
+ FailureCache *m_pFailureCache;
+ CRITSEC_COOKIE m_contextCS;
+#ifdef FEATURE_VERSIONING_LOG
+ BindingLog m_bindingLog;
+#endif // FEATURE_VERSIONING_LOG
+
+ AssemblyIdentityCache m_assemblyIdentityCache;
+
+ StringArrayList m_platformResourceRoots;
+ StringArrayList m_appPaths;
+ StringArrayList m_appNiPaths;
+
+ SimpleNameToFileNameMap * m_pTrustedPlatformAssemblyMap;
+ TpaFileNameHash * m_pFileNameHash;
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
+ bool m_fCanExplicitlyBindToNativeImages;
+public:
+ inline void SetExplicitBindToNativeImages(bool fCanExplicitlyBindToNativeImages)
+ {
+ m_fCanExplicitlyBindToNativeImages = fCanExplicitlyBindToNativeImages;
+ }
+
+ inline bool CanExplicitlyBindToNativeImages()
+ {
+ return m_fCanExplicitlyBindToNativeImages;
+ }
+protected:
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
+ };
+
+#include "applicationcontext.inl"
+
+};
+
+#endif
diff --git a/src/binder/inc/applicationcontext.inl b/src/binder/inc/applicationcontext.inl
new file mode 100644
index 0000000000..b57562f4d5
--- /dev/null
+++ b/src/binder/inc/applicationcontext.inl
@@ -0,0 +1,110 @@
+// 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.
+// ============================================================
+//
+// ApplicationContext.inl
+//
+
+
+//
+// Implements inlined methods of ApplicationContext
+//
+// ============================================================
+
+#ifndef __BINDER__APPLICATION_CONTEXT_INL__
+#define __BINDER__APPLICATION_CONTEXT_INL__
+
+LONG ApplicationContext::GetVersion()
+{
+ return m_cVersion;
+}
+
+void ApplicationContext::IncrementVersion()
+{
+ InterlockedIncrement(&m_cVersion);
+}
+
+SString &ApplicationContext::GetApplicationName()
+{
+ return m_applicationName;
+}
+
+DWORD ApplicationContext::GetAppDomainId()
+{
+ return m_dwAppDomainId;
+}
+
+void ApplicationContext::SetAppDomainId(DWORD dwAppDomainId)
+{
+ m_dwAppDomainId = dwAppDomainId;
+}
+
+ExecutionContext *ApplicationContext::GetExecutionContext()
+{
+ return m_pExecutionContext;
+}
+
+InspectionContext *ApplicationContext::GetInspectionContext()
+{
+ return m_pInspectionContext;
+}
+
+FailureCache *ApplicationContext::GetFailureCache()
+{
+ _ASSERTE(m_pFailureCache != NULL);
+ return m_pFailureCache;
+}
+
+HRESULT ApplicationContext::AddToFailureCache(SString &assemblyNameOrPath,
+ HRESULT hrBindResult)
+{
+ HRESULT hr = GetFailureCache()->Add(assemblyNameOrPath, hrBindResult);
+ IncrementVersion();
+ return hr;
+}
+
+StringArrayList *ApplicationContext::GetAppPaths()
+{
+ return &m_appPaths;
+}
+
+SimpleNameToFileNameMap * ApplicationContext::GetTpaList()
+{
+ return m_pTrustedPlatformAssemblyMap;
+}
+
+TpaFileNameHash * ApplicationContext::GetTpaFileNameList()
+{
+ return m_pFileNameHash;
+}
+
+StringArrayList * ApplicationContext::GetPlatformResourceRoots()
+{
+ return &m_platformResourceRoots;
+}
+
+StringArrayList * ApplicationContext::GetAppNiPaths()
+{
+ return &m_appNiPaths;
+}
+
+CRITSEC_COOKIE ApplicationContext::GetCriticalSectionCookie()
+{
+ return m_contextCS;
+}
+
+#ifdef FEATURE_VERSIONING_LOG
+BindingLog *ApplicationContext::GetBindingLog()
+{
+ return &m_bindingLog;
+}
+
+void ApplicationContext::ClearBindingLog()
+{
+ m_bindingLog.SetDebugLog(NULL);
+}
+#endif // FEATURE_VERSIONING_LOG
+
+
+#endif
diff --git a/src/binder/inc/assembly.hpp b/src/binder/inc/assembly.hpp
new file mode 100644
index 0000000000..5b8425a3d1
--- /dev/null
+++ b/src/binder/inc/assembly.hpp
@@ -0,0 +1,222 @@
+// 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.
+// ============================================================
+//
+// Assembly.hpp
+//
+
+
+//
+// Defines the Assembly class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_HPP__
+#define __BINDER__ASSEMBLY_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyname.hpp"
+
+#include "corpriv.h"
+#include "clrprivbinding.h"
+
+#if !defined(FEATURE_FUSION)
+#include "clrprivbindercoreclr.h"
+#endif // !defined(FEATURE_FUSION)
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#include "clrprivbinderassemblyloadcontext.h"
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
+STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath,
+ PEImage **ppPEImage,
+ PEImage **ppNativeImage,
+ BOOL fExplicitBindToNativeImage);
+
+STDAPI BinderAcquireImport(PEImage *pPEImage,
+ IMDInternalImport **pIMetaDataAssemblyImport,
+ DWORD *pdwPAFlags,
+ BOOL bNativeImage);
+
+STDAPI BinderHasNativeHeader(PEImage *pPEImage,
+ BOOL *result);
+
+STDAPI BinderGetImagePath(PEImage *pPEImage,
+ SString &imagePath);
+
+STDAPI BinderReleasePEImage(PEImage *pPEImage);
+
+STDAPI BinderAddRefPEImage(PEImage *pPEImage);
+
+namespace BINDER_SPACE
+{
+
+ // An assembly represents a particular set of bits. However we extend this to
+ // also include whether those bits have precompiled information (NGEN). Thus
+ // and assembly knows whether it has an NGEN image or not.
+ //
+ // This allows us to preferentially use the NGEN image if it is available.
+ class Assembly
+ : public ICLRPrivAssembly
+ {
+ public:
+ // --------------------------------------------------------------------
+ // IUnknown methods
+ // --------------------------------------------------------------------
+ STDMETHOD(QueryInterface)(REFIID riid,
+ void ** ppv);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+
+ // --------------------------------------------------------------------
+ // ICLRPrivAssembly methods
+ // --------------------------------------------------------------------
+ LPCWSTR GetSimpleName();
+
+ STDMETHOD(BindAssemblyByName)(
+ IAssemblyName * pIAssemblyName,
+ ICLRPrivAssembly ** ppAssembly);
+
+ STDMETHOD(IsShareable)(BOOL * pbIsShareable);
+
+ STDMETHOD(GetAvailableImageTypes)(PDWORD pdwImageTypes);
+
+ STDMETHOD(GetImageResource)(
+ DWORD dwImageType,
+ DWORD *pdwImageType,
+ ICLRPrivResource ** ppIResource);
+
+ STDMETHOD(VerifyBind)(
+ IAssemblyName * pIAssemblyName,
+ ICLRPrivAssembly *pAssembly,
+ ICLRPrivAssemblyInfo *pAssemblyInfo);
+
+ STDMETHOD(GetBinderID)(UINT_PTR *pBinderId);
+
+ STDMETHOD(FindAssemblyBySpec)(
+ LPVOID pvAppDomain,
+ LPVOID pvAssemblySpec,
+ HRESULT * pResult,
+ ICLRPrivAssembly ** ppAssembly);
+
+ STDMETHOD(GetBinderFlags)(DWORD *pBinderFlags);
+
+ // --------------------------------------------------------------------
+ // Assembly methods
+ // --------------------------------------------------------------------
+ Assembly();
+ virtual ~Assembly();
+
+ HRESULT Init(/* in */ IMDInternalImport *pIMetaDataAssemblyImport,
+ /* in */ PEKIND PeKind,
+ /* in */ PEImage *pPEImage,
+ /* in */ PEImage *pPENativeImage,
+ /* in */ SString &assemblyPath,
+ /* in */ BOOL fInspectionOnly,
+ /* in */ BOOL fIsInGAC);
+
+ // Enumerates dependent assemblies
+ HRESULT GetNextAssemblyNameRef(/* in */ DWORD nIndex,
+ /* out */ AssemblyName **ppAssemblyName);
+
+ inline AssemblyName *GetAssemblyName(BOOL fAddRef = FALSE);
+ inline BOOL GetIsInGAC();
+ inline BOOL GetIsDynamicBind();
+ inline void SetIsDynamicBind(BOOL fIsDynamicBind);
+ inline BOOL GetIsByteArray();
+ inline void SetIsByteArray(BOOL fIsByteArray);
+ inline BOOL GetIsSharable();
+ inline void SetIsSharable(BOOL fIsSharable);
+ inline SString &GetPath();
+
+ inline PEImage *GetPEImage(BOOL fAddRef = FALSE);
+ inline PEImage *GetNativePEImage(BOOL fAddRef = FALSE);
+ inline PEImage *GetNativeOrILPEImage(BOOL fAddRef = FALSE);
+
+ HRESULT GetMVID(GUID *pMVID);
+
+ static PEKIND GetSystemArchitecture();
+ static BOOL IsValidArchitecture(PEKIND kArchitecture);
+
+#ifndef CROSSGEN_COMPILE
+ protected:
+#endif
+ // Asssembly Flags
+ enum
+ {
+ FLAG_NONE = 0x00,
+ FLAG_INSPECTION_ONLY = 0x01,
+ FLAG_IS_IN_GAC = 0x02,
+ FLAG_IS_DYNAMIC_BIND = 0x04,
+ FLAG_IS_BYTE_ARRAY = 0x08,
+ FLAG_IS_SHARABLE = 0x10
+ };
+
+ inline void SetPEImage(PEImage *pPEImage);
+ inline void SetNativePEImage(PEImage *pNativePEImage);
+
+ inline void SetAssemblyName(AssemblyName *pAssemblyName,
+ BOOL fAddRef = TRUE);
+ inline BOOL GetInspectionOnly();
+ inline void SetInspectionOnly(BOOL fInspectionOnly);
+ inline void SetIsInGAC(BOOL fIsInGAC);
+
+ inline IMDInternalImport *GetMDImport();
+ inline void SetMDImport(IMDInternalImport *pMDImport);
+ inline mdAssembly *GetAssemblyRefTokens();
+
+ inline DWORD GetNbAssemblyRefTokens();
+ inline void SetNbAsssemblyRefTokens(DWORD dwCAssemblyRefTokens);
+
+ LONG m_cRef;
+ PEImage *m_pPEImage;
+ PEImage *m_pNativePEImage;
+ IMDInternalImport *m_pMDImport;
+ mdAssembly *m_pAssemblyRefTokens;
+ DWORD m_dwCAssemblyRefTokens;
+ AssemblyName *m_pAssemblyName;
+ SString m_assemblyPath;
+ DWORD m_dwAssemblyFlags;
+ ICLRPrivBinder *m_pBinder;
+
+ // Nested class used to implement ICLRPriv binder related interfaces
+ class CLRPrivResourceAssembly :
+ public ICLRPrivResource, public ICLRPrivResourceAssembly
+ {
+public:
+ STDMETHOD(QueryInterface)(REFIID riid, void ** ppv);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+ STDMETHOD(GetResourceType)(IID *pIID);
+ STDMETHOD(GetAssembly)(LPVOID *ppAssembly);
+ } m_clrPrivRes;
+
+ inline void SetBinder(ICLRPrivBinder *pBinder)
+ {
+ _ASSERTE(m_pBinder == NULL || m_pBinder == pBinder);
+ m_pBinder = pBinder;
+ }
+
+ inline ICLRPrivBinder* GetBinder()
+ {
+ return m_pBinder;
+ }
+
+#if !defined(FEATURE_FUSION)
+ friend class ::CLRPrivBinderCoreCLR;
+#endif // !defined(FEATURE_FUSION)
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ friend class ::CLRPrivBinderAssemblyLoadContext;
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ };
+
+ // This is a fast version which goes around the COM interfaces and directly
+ // casts the interfaces and does't AddRef
+ inline BINDER_SPACE::Assembly * GetAssemblyFromPrivAssemblyFast(ICLRPrivAssembly *pPrivAssembly);
+
+#include "assembly.inl"
+};
+
+#endif
diff --git a/src/binder/inc/assembly.inl b/src/binder/inc/assembly.inl
new file mode 100644
index 0000000000..92f9c72e6d
--- /dev/null
+++ b/src/binder/inc/assembly.inl
@@ -0,0 +1,218 @@
+// 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.
+// ============================================================
+//
+// Assembly.inl
+//
+
+
+//
+// Implements the inline methods of Assembly
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_INL__
+#define __BINDER__ASSEMBLY_INL__
+
+PEImage *Assembly::GetPEImage(BOOL fAddRef /* = FALSE */)
+{
+ PEImage *pPEImage = m_pPEImage;
+
+ if (fAddRef)
+ {
+ BinderAddRefPEImage(pPEImage);
+ }
+
+ return pPEImage;
+}
+
+PEImage *Assembly::GetNativePEImage(BOOL fAddRef /* = FALSE */)
+{
+ PEImage *pNativePEImage = m_pNativePEImage;
+
+ if (fAddRef)
+ {
+ BinderAddRefPEImage(pNativePEImage);
+ }
+
+ return pNativePEImage;
+}
+
+PEImage *Assembly::GetNativeOrILPEImage(BOOL fAddRef /* = FALSE */)
+{
+ PEImage* pPEImage = GetNativePEImage(fAddRef);
+ if (pPEImage == NULL)
+ pPEImage = GetPEImage(fAddRef);
+ return pPEImage;
+}
+
+void Assembly::SetPEImage(PEImage *pPEImage)
+{
+ BinderAddRefPEImage(pPEImage);
+ m_pPEImage = pPEImage;
+}
+
+void Assembly::SetNativePEImage(PEImage *pNativePEImage)
+{
+ BinderAddRefPEImage(pNativePEImage);
+ m_pNativePEImage = pNativePEImage;
+}
+
+AssemblyName *Assembly::GetAssemblyName(BOOL fAddRef /* = FALSE */)
+{
+ AssemblyName *pAssemblyName = m_pAssemblyName;
+
+ if (fAddRef && (pAssemblyName != NULL))
+ {
+ pAssemblyName->AddRef();
+ }
+ return pAssemblyName;
+}
+
+void Assembly::SetAssemblyName(AssemblyName *pAssemblyName,
+ BOOL fAddRef /* = TRUE */)
+{
+ SAFE_RELEASE(m_pAssemblyName);
+
+ m_pAssemblyName = pAssemblyName;
+
+ if (fAddRef && (pAssemblyName != NULL))
+ {
+ pAssemblyName->AddRef();
+ }
+}
+
+BOOL Assembly::GetInspectionOnly()
+{
+ return ((m_dwAssemblyFlags & FLAG_INSPECTION_ONLY) != 0);
+}
+
+void Assembly::SetInspectionOnly(BOOL fInspectionOnly)
+{
+ if (fInspectionOnly)
+ {
+ m_dwAssemblyFlags |= FLAG_INSPECTION_ONLY;
+ }
+ else
+ {
+ m_dwAssemblyFlags &= ~FLAG_INSPECTION_ONLY;
+ }
+}
+
+BOOL Assembly::GetIsInGAC()
+{
+ return ((m_dwAssemblyFlags & FLAG_IS_IN_GAC) != 0);
+}
+
+void Assembly::SetIsInGAC(BOOL fIsInGAC)
+{
+ if (fIsInGAC)
+ {
+ m_dwAssemblyFlags |= FLAG_IS_IN_GAC;
+ }
+ else
+ {
+ m_dwAssemblyFlags &= ~FLAG_IS_IN_GAC;
+ }
+}
+
+BOOL Assembly::GetIsDynamicBind()
+{
+ return ((m_dwAssemblyFlags & FLAG_IS_DYNAMIC_BIND) != 0);
+}
+
+void Assembly::SetIsDynamicBind(BOOL fIsDynamicBind)
+{
+ if (fIsDynamicBind)
+ {
+ m_dwAssemblyFlags |= FLAG_IS_DYNAMIC_BIND;
+ }
+ else
+ {
+ m_dwAssemblyFlags &= ~FLAG_IS_DYNAMIC_BIND;
+ }
+}
+
+BOOL Assembly::GetIsByteArray()
+{
+ return ((m_dwAssemblyFlags & FLAG_IS_BYTE_ARRAY) != 0);
+}
+
+void Assembly::SetIsByteArray(BOOL fIsByteArray)
+{
+ if (fIsByteArray)
+ {
+ m_dwAssemblyFlags |= FLAG_IS_BYTE_ARRAY;
+ }
+ else
+ {
+ m_dwAssemblyFlags &= ~FLAG_IS_BYTE_ARRAY;
+ }
+}
+
+BOOL Assembly::GetIsSharable()
+{
+ return ((m_dwAssemblyFlags & FLAG_IS_SHARABLE) != 0);
+}
+
+void Assembly::SetIsSharable(BOOL fIsSharable)
+{
+ if (fIsSharable)
+ {
+ m_dwAssemblyFlags |= FLAG_IS_SHARABLE;
+ }
+ else
+ {
+ m_dwAssemblyFlags &= ~FLAG_IS_SHARABLE;
+ }
+}
+
+SString &Assembly::GetPath()
+{
+ return m_assemblyPath;
+}
+
+IMDInternalImport *Assembly::GetMDImport()
+{
+ return m_pMDImport;
+}
+
+void Assembly::SetMDImport(IMDInternalImport *pMDImport)
+{
+ SAFE_RELEASE(m_pMDImport);
+
+ m_pMDImport = pMDImport;
+ m_pMDImport->AddRef();
+}
+
+mdAssembly *Assembly::GetAssemblyRefTokens()
+{
+ return m_pAssemblyRefTokens;
+}
+
+DWORD Assembly::GetNbAssemblyRefTokens()
+{
+ return m_dwCAssemblyRefTokens;
+}
+
+void Assembly::SetNbAsssemblyRefTokens(DWORD dwCAssemblyRefTokens)
+{
+ m_dwCAssemblyRefTokens = dwCAssemblyRefTokens;
+}
+
+BINDER_SPACE::Assembly* GetAssemblyFromPrivAssemblyFast(ICLRPrivAssembly *pPrivAssembly)
+{
+#ifdef _DEBUG
+ if(pPrivAssembly != nullptr)
+ {
+ // Ensure the pPrivAssembly we are about to cast is indeed a valid Assembly
+ DWORD dwImageType = 0;
+ pPrivAssembly->GetAvailableImageTypes(&dwImageType);
+ _ASSERTE((dwImageType & ASSEMBLY_IMAGE_TYPE_ASSEMBLY) == ASSEMBLY_IMAGE_TYPE_ASSEMBLY);
+ }
+#endif
+ return (BINDER_SPACE::Assembly *)pPrivAssembly;
+}
+
+#endif
diff --git a/src/binder/inc/assemblybinder.hpp b/src/binder/inc/assemblybinder.hpp
new file mode 100644
index 0000000000..3a1f1e45fd
--- /dev/null
+++ b/src/binder/inc/assemblybinder.hpp
@@ -0,0 +1,178 @@
+// 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.
+// ============================================================
+//
+// AssemblyBinder.hpp
+//
+
+
+//
+// Defines the AssemblyBinder class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_BINDER_HPP__
+#define __BINDER__ASSEMBLY_BINDER_HPP__
+
+#include "bindertypes.hpp"
+#include "bindresult.hpp"
+#include "coreclrbindercommon.h"
+
+class CLRPrivBinderAssemblyLoadContext;
+class CLRPrivBinderCoreCLR;
+
+namespace BINDER_SPACE
+{
+ typedef enum
+ {
+ kBindingStoreGAC = 0x01,
+ kBindingStoreManifest = 0x02,
+ kBindingStoreHost = 0x04,
+ kBindingStoreContext = 0x08
+ } BindingStore;
+
+ class AssemblyBinder
+ {
+ public:
+ static HRESULT Startup();
+
+ // See code:BINDER_SPACE::AssemblyBinder::GetAssembly for info on fNgenExplicitBind
+ // and fExplicitBindToNativeImage, and see code:CEECompileInfo::LoadAssemblyByPath
+ // for an example of how they're used.
+ static HRESULT BindAssembly(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ LPCWSTR szCodeBase,
+ /* in */ PEAssembly *pParentAssembly,
+ /* in */ BOOL fNgenExplicitBind,
+ /* in */ BOOL fExplicitBindToNativeImage,
+ /* in */ bool excludeAppPaths,
+ /* out */ Assembly **ppAssembly);
+
+ static HRESULT BindToSystem(/* in */ SString &systemDirectory,
+ /* out */ Assembly **ppSystemAssembly,
+ /* in */ bool fBindToNativeImage);
+
+ static HRESULT BindToSystemSatellite(/* in */ SString &systemDirectory,
+ /* in */ SString &simpleName,
+ /* in */ SString &cultureName,
+ /* out */ Assembly **ppSystemAssembly);
+
+ static HRESULT GetAssemblyFromImage(/* in */ PEImage *pPEImage,
+ /* in */ PEImage *pNativePEImage,
+ /* out */ Assembly **ppAssembly);
+
+ // Special assembly binder entry point for byte arrays
+ static HRESULT PreBindByteArray(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ PEImage *pPEImage,
+ /* in */ BOOL fInspectionOnly);
+
+ static HRESULT GetAssembly(/* in */ SString &assemblyPath,
+ /* in */ BOOL fInspectionOnly,
+ /* in */ BOOL fIsInGAC,
+ /* in */ BOOL fExplicitBindToNativeImage,
+ /* out */ Assembly **ppAssembly,
+ /* in */ LPCTSTR szMDAssemblyPath = NULL);
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ IAssemblyName *pIAssemblyName,
+ /* in */ CLRPrivBinderCoreCLR *pTPABinder,
+ /* out */ Assembly **ppAssembly);
+
+ static HRESULT BindUsingPEImage(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ BINDER_SPACE::AssemblyName *pAssemblyName,
+ /* in */ PEImage *pPEImage,
+ /* in */ PEKIND peKind,
+ /* in */ IMDInternalImport *pIMetaDataAssemblyImport,
+ /* [retval] [out] */ Assembly **ppAssembly);
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
+ static HRESULT TranslatePEToArchitectureType(DWORD *pdwPAFlags, PEKIND *PeKind);
+
+ protected:
+ enum
+ {
+ BIND_NONE = 0x00,
+ BIND_CACHE_FAILURES = 0x01,
+ BIND_CACHE_RERUN_BIND = 0x02,
+ BIND_IGNORE_DYNAMIC_BINDS = 0x04
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ ,
+ BIND_IGNORE_REFDEF_MATCH = 0x8
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ };
+
+ static BOOL IgnoreDynamicBinds(DWORD dwBindFlags)
+ {
+ return ((dwBindFlags & BIND_IGNORE_DYNAMIC_BINDS) != 0);
+ }
+
+ static BOOL CacheBindFailures(DWORD dwBindFlags)
+ {
+ return ((dwBindFlags & BIND_CACHE_FAILURES) != 0);
+ }
+
+ static BOOL RerunBind(DWORD dwBindFlags)
+ {
+ return ((dwBindFlags & BIND_CACHE_RERUN_BIND) != 0);
+ }
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ static BOOL IgnoreRefDefMatch(DWORD dwBindFlags)
+ {
+ return ((dwBindFlags & BIND_IGNORE_REFDEF_MATCH) != 0);
+ }
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
+ static HRESULT BindByName(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ DWORD dwBindFlags,
+ /* in */ bool excludeAppPaths,
+ /* out */ BindResult *pBindResult);
+
+ // See code:BINDER_SPACE::AssemblyBinder::GetAssembly for info on fNgenExplicitBind
+ // and fExplicitBindToNativeImage, and see code:CEECompileInfo::LoadAssemblyByPath
+ // for an example of how they're used.
+ static HRESULT BindWhereRef(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ PathString &assemblyPath,
+ /* in */ BOOL fNgenExplicitBind,
+ /* in */ BOOL fExplicitBindToNativeImage,
+ /* in */ bool excludeAppPaths,
+ /* out */ BindResult *pBindResult);
+
+ static HRESULT BindLocked(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ DWORD dwBindFlags,
+ /* in */ bool excludeAppPaths,
+ /* out */ BindResult *pBindResult);
+ static HRESULT BindLockedOrService(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ bool excludeAppPaths,
+ /* out */ BindResult *pBindResult);
+
+ static HRESULT FindInExecutionContext(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* out */ ContextEntry **ppContextEntry);
+
+ static HRESULT BindByTpaList(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pRequestedAssemblyName,
+ /* in */ BOOL fInspectionOnly,
+ /* in */ bool excludeAppPaths,
+ /* out */ BindResult *pBindResult);
+
+ static HRESULT Register(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ BOOL fInspectionOnly,
+ /* in */ BindResult *pBindResult);
+ static HRESULT RegisterAndGetHostChosen(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ LONG kContextVersion,
+ /* in */ BindResult *pBindResult,
+ /* out */ BindResult *pHostBindResult);
+
+ static HRESULT OtherBindInterfered(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ BindResult *pBindResult);
+ };
+};
+
+#endif
diff --git a/src/binder/inc/assemblyentry.hpp b/src/binder/inc/assemblyentry.hpp
new file mode 100644
index 0000000000..d0bf27b2d5
--- /dev/null
+++ b/src/binder/inc/assemblyentry.hpp
@@ -0,0 +1,62 @@
+// 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.
+// ============================================================
+//
+// AssemblyEntry.hpp
+//
+
+
+//
+// Defines the AssemblyEntry class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_ENTRY_HPP__
+#define __BINDER__ASSEMBLY_ENTRY_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyname.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyEntry
+ {
+ public:
+ AssemblyEntry()
+ {
+ m_pAssemblyName = NULL;
+ }
+ virtual ~AssemblyEntry()
+ {
+ SAFE_RELEASE(m_pAssemblyName);
+ }
+
+ AssemblyName *GetAssemblyName(BOOL fAddRef = FALSE)
+ {
+ AssemblyName *pAssemblyName = m_pAssemblyName;
+
+ if (fAddRef && (pAssemblyName != NULL))
+ {
+ pAssemblyName->AddRef();
+ }
+ return pAssemblyName;
+ }
+
+ void SetAssemblyName(AssemblyName *pAssemblyName, BOOL fAddRef = TRUE)
+ {
+ SAFE_RELEASE(m_pAssemblyName);
+
+ if (fAddRef && (pAssemblyName != NULL))
+ {
+ pAssemblyName->AddRef();
+ }
+
+ m_pAssemblyName = pAssemblyName;
+ }
+ protected:
+ AssemblyName *m_pAssemblyName;
+ };
+};
+
+#endif
diff --git a/src/binder/inc/assemblyhashtraits.hpp b/src/binder/inc/assemblyhashtraits.hpp
new file mode 100644
index 0000000000..285368f687
--- /dev/null
+++ b/src/binder/inc/assemblyhashtraits.hpp
@@ -0,0 +1,59 @@
+// 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.
+// ============================================================
+//
+// AssemblyHashTraits.hpp
+//
+
+
+//
+// Defines the AssemblyHashTraits template class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_HASH_TRAITS_HPP__
+#define __BINDER__ASSEMBLY_HASH_TRAITS_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyentry.hpp"
+#include "shash.h"
+
+namespace BINDER_SPACE
+{
+ template<typename HashEntry, DWORD dwAssemblyNameFlags>
+ class AssemblyHashTraits : public NoRemoveSHashTraits<DefaultSHashTraits<HashEntry> >
+ {
+ public:
+ typedef typename NoRemoveSHashTraits<DefaultSHashTraits<HashEntry> >::element_t element_t;
+ typedef typename NoRemoveSHashTraits<DefaultSHashTraits<HashEntry> >::count_t count_t;
+
+ typedef AssemblyName* key_t;
+
+ // GetKey, Equals and Hash can throw due to SString
+ static const bool s_NoThrow = false;
+
+ static key_t GetKey(element_t pAssemblyEntry)
+ {
+ return pAssemblyEntry->GetAssemblyName();
+ }
+ static BOOL Equals(key_t pAssemblyName1, key_t pAssemblyName2)
+ {
+ return pAssemblyName1->Equals(pAssemblyName2, dwAssemblyNameFlags);
+ }
+ static count_t Hash(key_t pAssemblyName)
+ {
+ return pAssemblyName->Hash(dwAssemblyNameFlags);
+ }
+ static const element_t Null()
+ {
+ return NULL;
+ }
+ static bool IsNull(const element_t &assemblyEntry)
+ {
+ return (assemblyEntry == NULL);
+ }
+ };
+};
+
+#endif
diff --git a/src/binder/inc/assemblyidentity.hpp b/src/binder/inc/assemblyidentity.hpp
new file mode 100644
index 0000000000..4d7c7f1bac
--- /dev/null
+++ b/src/binder/inc/assemblyidentity.hpp
@@ -0,0 +1,149 @@
+// 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.
+// ============================================================
+//
+// AssemblyIdentity.hpp
+//
+
+
+//
+// Defines the AssemblyIdentity class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_IDENTITY_HPP__
+#define __BINDER__ASSEMBLY_IDENTITY_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyversion.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyIdentity
+ {
+ public:
+ enum
+ {
+ IDENTITY_FLAG_EMPTY = 0x000,
+ IDENTITY_FLAG_SIMPLE_NAME = 0x001,
+ IDENTITY_FLAG_VERSION = 0x002,
+ IDENTITY_FLAG_PUBLIC_KEY_TOKEN = 0x004,
+ IDENTITY_FLAG_PUBLIC_KEY = 0x008,
+ IDENTITY_FLAG_CULTURE = 0x010,
+ IDENTITY_FLAG_LANGUAGE = 0x020,
+ IDENTITY_FLAG_PROCESSOR_ARCHITECTURE = 0x040,
+ IDENTITY_FLAG_RETARGETABLE = 0x080,
+ IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL = 0x100,
+ IDENTITY_FLAG_CUSTOM = 0x200,
+ IDENTITY_FLAG_CUSTOM_NULL = 0x400,
+ IDENTITY_FLAG_CONTENT_TYPE = 0x800,
+ IDENTITY_FLAG_FULL_NAME = (IDENTITY_FLAG_SIMPLE_NAME |
+ IDENTITY_FLAG_VERSION)
+ } IdentityFlags;
+
+ AssemblyIdentity()
+ {
+ m_dwIdentityFlags = IDENTITY_FLAG_EMPTY;
+ m_kProcessorArchitecture = peNone;
+ m_kContentType = AssemblyContentType_Default;
+
+ // Need to pre-populate SBuffers because of bogus asserts
+ static const BYTE byteArr[] = { 0 };
+ m_publicKeyOrTokenBLOB.SetImmutable(byteArr, sizeof(byteArr));
+ m_customBLOB.SetImmutable(byteArr, sizeof(byteArr));
+ }
+ ~AssemblyIdentity()
+ {
+ // Nothing to do here
+ }
+
+ static BOOL Have(DWORD dwUseIdentityFlags, DWORD dwIdentityFlags)
+ {
+ return ((dwUseIdentityFlags & dwIdentityFlags) != 0);
+ }
+
+ BOOL Have(DWORD dwIdentityFlags)
+ {
+ return Have(m_dwIdentityFlags, dwIdentityFlags);
+ }
+
+ void SetHave(DWORD dwIdentityFlags)
+ {
+ m_dwIdentityFlags |= dwIdentityFlags;
+ }
+
+ void SetClear(DWORD dwIdentityFlags)
+ {
+ m_dwIdentityFlags &= ~dwIdentityFlags;
+ }
+
+ void CloneInto(AssemblyIdentity *pAssemblyIdentity)
+ {
+ pAssemblyIdentity->m_simpleName.Set(m_simpleName);
+ pAssemblyIdentity->m_simpleName.Normalize();
+ pAssemblyIdentity->m_version.SetVersion(&m_version);
+ pAssemblyIdentity->m_cultureOrLanguage.Set(m_cultureOrLanguage);
+ pAssemblyIdentity->m_cultureOrLanguage.Normalize();
+ pAssemblyIdentity->m_publicKeyOrTokenBLOB.Set(m_publicKeyOrTokenBLOB);
+ pAssemblyIdentity->m_kProcessorArchitecture = m_kProcessorArchitecture;
+ pAssemblyIdentity->m_kContentType = m_kContentType;
+ pAssemblyIdentity->m_customBLOB.Set(m_customBLOB);
+ pAssemblyIdentity->m_dwIdentityFlags = m_dwIdentityFlags;
+ }
+
+ SString m_simpleName;
+ AssemblyVersion m_version;
+ SString m_cultureOrLanguage;
+ SBuffer m_publicKeyOrTokenBLOB;
+ PEKIND m_kProcessorArchitecture;
+ AssemblyContentType m_kContentType;
+ SBuffer m_customBLOB;
+ DWORD m_dwIdentityFlags;
+ };
+
+ class AssemblyIdentityUTF8 : public AssemblyIdentity
+ {
+ public:
+ AssemblyIdentityUTF8()
+ {
+ m_szSimpleNameUTF8 = NULL;
+ m_szCultureOrLanguageUTF8 = NULL;
+ }
+
+ void PopulateUTF8Fields()
+ {
+ m_szSimpleNameUTF8 = m_simpleName.GetUTF8(sSimpleNameBuffer);
+
+ if (Have(IDENTITY_FLAG_CULTURE) && !m_cultureOrLanguage.IsEmpty())
+ {
+ m_szCultureOrLanguageUTF8 = m_cultureOrLanguage.GetUTF8(sCultureBuffer);
+ }
+ }
+
+ inline LPCSTR GetSimpleNameUTF8()
+ {
+ return m_szSimpleNameUTF8;
+ }
+
+ inline LPCSTR GetCultureOrLanguageUTF8()
+ {
+ return m_szCultureOrLanguageUTF8;
+ }
+
+ inline const BYTE *GetPublicKeyOrTokenArray()
+ {
+ const BYTE *pPublicKeyOrToken = m_publicKeyOrTokenBLOB;
+
+ return pPublicKeyOrToken;
+ }
+
+ protected:
+ StackScratchBuffer sSimpleNameBuffer;
+ StackScratchBuffer sCultureBuffer;
+ LPCSTR m_szSimpleNameUTF8;
+ LPCSTR m_szCultureOrLanguageUTF8;
+ };
+};
+
+#endif
diff --git a/src/binder/inc/assemblyidentitycache.hpp b/src/binder/inc/assemblyidentitycache.hpp
new file mode 100644
index 0000000000..39ad283175
--- /dev/null
+++ b/src/binder/inc/assemblyidentitycache.hpp
@@ -0,0 +1,116 @@
+// 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.
+// ============================================================
+//
+// AssemblyIdentityCache.hpp
+//
+
+
+//
+// Defines the AssemblyIdentityCache class and its helpers
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_IDENTITY_CACHE_HPP__
+#define __BINDER__ASSEMBLY_IDENTITY_CACHE_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyidentity.hpp"
+#include "utils.hpp"
+#include "sstring.h"
+#include "shash.h"
+
+namespace BINDER_SPACE
+{
+ class AssemblyIdentityCacheEntry
+ {
+ public:
+ inline AssemblyIdentityCacheEntry()
+ {
+ m_szTextualIdentity = NULL;
+ m_pAssemblyIdentity = NULL;
+ }
+ inline ~AssemblyIdentityCacheEntry()
+ {
+ SAFE_DELETE_ARRAY(m_szTextualIdentity);
+ SAFE_DELETE(m_pAssemblyIdentity);
+ }
+
+ // Getters/Setters
+ inline LPCSTR GetTextualIdentity()
+ {
+ return m_szTextualIdentity;
+ }
+ inline void SetTextualIdentity(LPCSTR szTextualIdentity)
+ {
+ size_t len = strlen(szTextualIdentity) + 1;
+
+ m_szTextualIdentity = new char[len];
+ strcpy_s((LPSTR) m_szTextualIdentity, len, szTextualIdentity);
+ }
+ inline AssemblyIdentityUTF8 *GetAssemblyIdentity()
+ {
+ return m_pAssemblyIdentity;
+ }
+ inline void SetAssemblyIdentity(AssemblyIdentityUTF8 *pAssemblyIdentity)
+ {
+ m_pAssemblyIdentity = pAssemblyIdentity;
+ }
+
+ protected:
+ LPCSTR m_szTextualIdentity;
+ AssemblyIdentityUTF8 *m_pAssemblyIdentity;
+ };
+
+ class AssemblyIdentityHashTraits : public DefaultSHashTraits<AssemblyIdentityCacheEntry *>
+ {
+ public:
+ typedef LPCSTR key_t;
+
+ static key_t GetKey(element_t pAssemblyIdentityCacheEntry)
+ {
+ return pAssemblyIdentityCacheEntry->GetTextualIdentity();
+ }
+ static BOOL Equals(key_t textualIdentity1, key_t textualIdentity2)
+ {
+ if ((textualIdentity1 == NULL) && (textualIdentity2 == NULL))
+ return TRUE;
+ if ((textualIdentity1 == NULL) || (textualIdentity2 == NULL))
+ return FALSE;
+
+ return (strcmp(textualIdentity1, textualIdentity2) == 0);
+ }
+ static count_t Hash(key_t textualIdentity)
+ {
+ if (textualIdentity == NULL)
+ return 0;
+ else
+ return HashStringA(textualIdentity);
+ }
+ static const element_t Null()
+ {
+ return NULL;
+ }
+ static bool IsNull(const element_t &assemblyIdentityCacheEntry)
+ {
+ return (assemblyIdentityCacheEntry == NULL);
+ }
+
+ };
+
+ class AssemblyIdentityCache : protected SHash<AssemblyIdentityHashTraits>
+ {
+ private:
+ typedef SHash<AssemblyIdentityHashTraits> Hash;
+ public:
+ AssemblyIdentityCache();
+ ~AssemblyIdentityCache();
+
+ HRESULT Add(/* in */ LPCSTR szTextualIdentity,
+ /* in */ AssemblyIdentityUTF8 *pAssemblyIdentity);
+ AssemblyIdentityUTF8 *Lookup(/* in */ LPCSTR szTextualIdentity);
+ };
+};
+
+#endif
diff --git a/src/binder/inc/assemblyname.hpp b/src/binder/inc/assemblyname.hpp
new file mode 100644
index 0000000000..1ce84d1902
--- /dev/null
+++ b/src/binder/inc/assemblyname.hpp
@@ -0,0 +1,112 @@
+// 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.
+// ============================================================
+//
+// AssemblyName.hpp
+//
+
+
+//
+// Defines the AssemblyName class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_NAME_HPP__
+#define __BINDER__ASSEMBLY_NAME_HPP__
+
+#include "bindertypes.hpp"
+#include "assemblyidentity.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyName : protected AssemblyIdentity
+ {
+ public:
+ typedef enum
+ {
+ INCLUDE_DEFAULT = 0x00,
+ INCLUDE_VERSION = 0x01,
+ INCLUDE_ARCHITECTURE = 0x02,
+ INCLUDE_RETARGETABLE = 0x04,
+ INCLUDE_CONTENT_TYPE = 0x08,
+ INCLUDE_PUBLIC_KEY_TOKEN = 0x10,
+ EXCLUDE_CULTURE = 0x20
+ } INCLUDE_FLAGS;
+
+ AssemblyName();
+ ~AssemblyName();
+
+ HRESULT Init(/* in */ IMDInternalImport *pIMetaDataAssemblyImport,
+ /* in */ PEKIND PeKind,
+ /* in */ mdAssemblyRef mda = 0,
+ /* in */ BOOL fIsDefinition = TRUE);
+ HRESULT Init(/* in */ SString &assemblyDisplayName);
+ HRESULT Init(/* in */ IAssemblyName *pIAssemblyName);
+ HRESULT CreateFusionName(/* out */ IAssemblyName **ppIAssemblyName);
+
+ ULONG AddRef();
+ ULONG Release();
+
+ // Getters/Setters
+ inline SString &GetSimpleName();
+ inline void SetSimpleName(SString &simpleName);
+ inline AssemblyVersion *GetVersion();
+ inline void SetVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline SString &GetCulture();
+ inline void SetCulture(SString &culture);
+ inline SBuffer &GetPublicKeyTokenBLOB();
+ inline PEKIND GetArchitecture();
+ inline void SetArchitecture(PEKIND kArchitecture);
+ inline AssemblyContentType GetContentType();
+ inline void SetContentType(AssemblyContentType kContentType);
+ inline BOOL GetIsRetargetable();
+ inline void SetIsRetargetable(BOOL fIsRetargetable);
+ inline BOOL GetIsDefinition();
+ inline void SetIsDefinition(BOOL fIsDefinition);
+
+ inline void SetHave(DWORD dwIdentityFlags);
+
+ inline BOOL HaveAssemblyVersion();
+ inline BOOL HaveNeutralCulture();
+
+ SString &GetDeNormalizedCulture();
+ BOOL IsStronglyNamed();
+
+ BOOL IsMscorlib();
+
+ // Translate textual identity into appropriate PEKIND
+ HRESULT SetArchitecture(SString &architecture);
+
+ ULONG Hash(/* in */ DWORD dwIncludeFlags);
+ BOOL Equals(/* in */ AssemblyName *pAssemblyName,
+ /* in */ DWORD dwIncludeFlags);
+
+ // Compare assembly ref with assembly def ignoring assembly version
+ BOOL RefEqualsDef(/* in */ AssemblyName *pAssemblyNameDef,
+ /* in */ BOOL fInspectionOnly);
+
+ HRESULT Clone(/* out */ AssemblyName **ppAssemblyName);
+
+ void GetDisplayName(/* out */ PathString &displayName,
+ /* in */ DWORD dwIncludeFlags);
+
+ static SString &ArchitectureToString(PEKIND kArchitecture);
+ protected:
+ enum
+ {
+ NAME_FLAG_NONE = 0x00,
+ NAME_FLAG_RETARGETABLE = 0x01,
+ NAME_FLAG_DEFINITION = 0x02,
+ };
+
+ SString &GetNormalizedCulture();
+
+ LONG m_cRef;
+ DWORD m_dwNameFlags;
+ };
+
+#include "assemblyname.inl"
+};
+
+#endif
diff --git a/src/binder/inc/assemblyname.inl b/src/binder/inc/assemblyname.inl
new file mode 100644
index 0000000000..3acd39ce0a
--- /dev/null
+++ b/src/binder/inc/assemblyname.inl
@@ -0,0 +1,144 @@
+// 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.
+// ============================================================
+//
+// AssemblyName.inl
+//
+
+
+//
+// Implements the inlined methods of AssemblyName class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_NAME_INL__
+#define __BINDER__ASSEMBLY_NAME_INL__
+
+SString &AssemblyName::GetSimpleName()
+{
+ return m_simpleName;
+}
+
+void AssemblyName::SetSimpleName(SString &simpleName)
+{
+ m_simpleName.Set(simpleName);
+ SetHave(AssemblyIdentity::IDENTITY_FLAG_SIMPLE_NAME);
+}
+
+AssemblyVersion *AssemblyName::GetVersion()
+{
+ return &m_version;
+}
+
+void AssemblyName::SetVersion(AssemblyVersion *pAssemblyVersion)
+{
+ m_version.SetVersion(pAssemblyVersion);
+}
+
+SString &AssemblyName::GetCulture()
+{
+ return m_cultureOrLanguage;
+}
+
+void AssemblyName::SetCulture(SString &culture)
+{
+ m_cultureOrLanguage.Set(culture);
+ SetHave(AssemblyIdentity::IDENTITY_FLAG_CULTURE);
+}
+
+SBuffer &AssemblyName::GetPublicKeyTokenBLOB()
+{
+ return m_publicKeyOrTokenBLOB;
+}
+
+PEKIND AssemblyName::GetArchitecture()
+{
+ return m_kProcessorArchitecture;
+}
+
+void AssemblyName::SetArchitecture(PEKIND kArchitecture)
+{
+ m_kProcessorArchitecture = kArchitecture;
+
+ if (kArchitecture != peNone)
+ {
+ SetHave(AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE);
+ }
+ else
+ {
+ SetClear(AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE);
+ }
+}
+
+AssemblyContentType AssemblyName::GetContentType()
+{
+ return m_kContentType;
+}
+
+void AssemblyName::SetContentType(AssemblyContentType kContentType)
+{
+ m_kContentType = kContentType;
+
+ if (kContentType != AssemblyContentType_Default)
+ {
+ SetHave(AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE);
+ }
+ else
+ {
+ SetClear(AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE);
+ }
+}
+
+BOOL AssemblyName::GetIsRetargetable()
+{
+ return m_dwIdentityFlags & AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE;
+}
+
+void AssemblyName::SetIsRetargetable(BOOL fIsRetargetable)
+{
+ if (fIsRetargetable)
+ {
+ m_dwNameFlags |= NAME_FLAG_RETARGETABLE;
+ SetHave(AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE);
+ }
+ else
+ {
+ m_dwNameFlags &= ~NAME_FLAG_RETARGETABLE;
+ SetClear(AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE);
+ }
+}
+
+BOOL AssemblyName::GetIsDefinition()
+{
+ return ((m_dwNameFlags & NAME_FLAG_DEFINITION) != 0);
+}
+
+void AssemblyName::SetIsDefinition(BOOL fIsDefinition)
+{
+ if (fIsDefinition)
+ {
+ m_dwNameFlags |= NAME_FLAG_DEFINITION;
+ }
+ else
+ {
+ m_dwNameFlags &= ~NAME_FLAG_DEFINITION;
+ }
+}
+
+void AssemblyName::SetHave(DWORD dwIdentityFlags)
+{
+ AssemblyIdentity::SetHave(dwIdentityFlags);
+}
+
+BOOL AssemblyName::HaveAssemblyVersion()
+{
+ return (m_version.GetMajor() != static_cast<DWORD>(-1));
+}
+
+BOOL AssemblyName::HaveNeutralCulture()
+{
+ return GetDeNormalizedCulture().IsEmpty();
+}
+
+#endif
diff --git a/src/binder/inc/assemblyversion.hpp b/src/binder/inc/assemblyversion.hpp
new file mode 100644
index 0000000000..20ef4ee48c
--- /dev/null
+++ b/src/binder/inc/assemblyversion.hpp
@@ -0,0 +1,60 @@
+// 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.
+// ============================================================
+//
+// AssemblyVersion.hpp
+//
+
+
+//
+// Defines the AssemblyVersion class
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_VERSION_HPP__
+#define __BINDER__ASSEMBLY_VERSION_HPP__
+
+#include "bindertypes.hpp"
+#include "textualidentityparser.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyVersion
+ {
+ public:
+ inline AssemblyVersion();
+ inline ~AssemblyVersion();
+
+ inline DWORD GetMajor();
+ inline DWORD GetMinor();
+ inline DWORD GetBuild();
+ inline DWORD GetRevision();
+
+ inline void SetFeatureVersion(/* in */ DWORD dwMajor,
+ /* in */ DWORD dwMinor);
+ inline void SetServiceVersion(/* in */ DWORD dwBuild,
+ /* in */ DWORD dwRevision);
+ inline BOOL SetServiceVersion(/* in */ LPCWSTR pwzVersionStr);
+ inline BOOL SetVersion(/* in */ LPCWSTR pwzVersionStr);
+ inline void SetVersion(AssemblyVersion *pAssemblyVersion);
+
+ inline BOOL IsLargerFeatureVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsEqualFeatureVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsSmallerFeatureVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsEqualServiceVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsLargerServiceVersion(/* in */ AssemblyVersion *pAssemblyVersion);
+ inline BOOL Equals(AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsSmallerOrEqual(AssemblyVersion *pAssemblyVersion);
+ inline BOOL IsLargerOrEqual(AssemblyVersion *pAssemblyVersion);
+ protected:
+ DWORD m_dwMajor;
+ DWORD m_dwMinor;
+ DWORD m_dwBuild;
+ DWORD m_dwRevision;
+ };
+
+#include "assemblyversion.inl"
+};
+
+#endif
diff --git a/src/binder/inc/assemblyversion.inl b/src/binder/inc/assemblyversion.inl
new file mode 100644
index 0000000000..795f8c1765
--- /dev/null
+++ b/src/binder/inc/assemblyversion.inl
@@ -0,0 +1,183 @@
+// 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.
+// ============================================================
+//
+// AssemblyVersion.inl
+//
+
+
+//
+// Implements the inline methods of AssemblyVersion
+//
+// ============================================================
+
+#ifndef __BINDER__ASSEMBLY_VERSION_INL__
+#define __BINDER__ASSEMBLY_VERSION_INL__
+
+AssemblyVersion::AssemblyVersion()
+{
+ m_dwMajor = m_dwMinor = m_dwBuild = m_dwRevision = static_cast<DWORD>(-1);
+}
+
+AssemblyVersion::~AssemblyVersion()
+{
+ // Noting to do here
+}
+
+DWORD AssemblyVersion::GetMajor()
+{
+ return m_dwMajor;
+}
+
+DWORD AssemblyVersion::GetMinor()
+{
+ return m_dwMinor;
+}
+
+DWORD AssemblyVersion::GetBuild()
+{
+ return m_dwBuild;
+}
+
+DWORD AssemblyVersion::GetRevision()
+{
+ return m_dwRevision;
+}
+
+void AssemblyVersion::SetFeatureVersion(DWORD dwMajor,
+ DWORD dwMinor)
+{
+ m_dwMajor = dwMajor;
+ m_dwMinor = dwMinor;
+}
+
+void AssemblyVersion::SetServiceVersion(DWORD dwBuild,
+ DWORD dwRevision)
+{
+ m_dwBuild = dwBuild;
+ m_dwRevision = dwRevision;
+}
+
+BOOL AssemblyVersion::SetVersion(LPCWSTR pwzVersionStr)
+{
+ SmallStackSString versionString(pwzVersionStr);
+
+ return TextualIdentityParser::ParseVersion(versionString, this);
+}
+
+void AssemblyVersion::SetVersion(AssemblyVersion *pAssemblyVersion)
+{
+ m_dwMajor = pAssemblyVersion->GetMajor();
+ m_dwMinor = pAssemblyVersion->GetMinor();
+ m_dwBuild = pAssemblyVersion->GetBuild();
+ m_dwRevision = pAssemblyVersion->GetRevision();
+}
+
+BOOL AssemblyVersion::IsLargerFeatureVersion(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+
+ if (GetMajor() > pAssemblyVersion->GetMajor())
+ {
+ result = TRUE;
+ }
+ else if ((GetMajor() == pAssemblyVersion->GetMajor()) &&
+ (GetMinor() > pAssemblyVersion->GetMinor()))
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+BOOL AssemblyVersion::IsEqualFeatureVersion(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+
+ if ((GetMajor() == pAssemblyVersion->GetMajor()) &&
+ (GetMinor() == pAssemblyVersion->GetMinor()))
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+BOOL AssemblyVersion::IsSmallerFeatureVersion(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+
+ if (GetMajor() < pAssemblyVersion->GetMajor())
+ {
+ result = TRUE;
+ }
+ else if ((GetMajor() == pAssemblyVersion->GetMajor()) &&
+ (GetMinor() < pAssemblyVersion->GetMinor()))
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+BOOL AssemblyVersion::IsEqualServiceVersion(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+
+ if ((GetBuild() == pAssemblyVersion->GetBuild()) &&
+ (GetRevision() == pAssemblyVersion->GetRevision()))
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+BOOL AssemblyVersion::IsLargerServiceVersion(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+
+ if (GetBuild() > pAssemblyVersion->GetBuild())
+ {
+ result = TRUE;
+ }
+ else if ((GetBuild() == pAssemblyVersion->GetBuild()) &&
+ (GetRevision() > pAssemblyVersion->GetRevision()))
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+BOOL AssemblyVersion::Equals(AssemblyVersion *pAssemblyVersion)
+{
+ BOOL result = FALSE;
+ if ((GetMajor() == pAssemblyVersion->GetMajor()) &&
+ (GetMinor() == pAssemblyVersion->GetMinor()) &&
+ (GetBuild() == pAssemblyVersion->GetBuild()) &&
+ (GetRevision() == pAssemblyVersion->GetRevision()))
+ {
+ result = TRUE;
+ }
+ return result;
+}
+
+BOOL AssemblyVersion::IsSmallerOrEqual(AssemblyVersion *pAssemblyVersion)
+{
+ return (Equals(pAssemblyVersion) ||
+ IsSmallerFeatureVersion(pAssemblyVersion) ||
+ (IsEqualFeatureVersion(pAssemblyVersion) &&
+ !IsLargerServiceVersion(pAssemblyVersion)));
+}
+
+BOOL AssemblyVersion::IsLargerOrEqual(AssemblyVersion *pAssemblyVersion)
+{
+ return (Equals(pAssemblyVersion) ||
+ IsLargerFeatureVersion(pAssemblyVersion) ||
+ (IsEqualFeatureVersion(pAssemblyVersion) &&
+ IsLargerServiceVersion(pAssemblyVersion)));
+}
+
+#endif
diff --git a/src/binder/inc/binderinterface.hpp b/src/binder/inc/binderinterface.hpp
new file mode 100644
index 0000000000..a9f0c210ff
--- /dev/null
+++ b/src/binder/inc/binderinterface.hpp
@@ -0,0 +1,69 @@
+// 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.
+// ============================================================
+//
+// BinderInterface.hpp
+//
+
+
+//
+// Defines the public AssemblyBinder interface
+//
+// ============================================================
+
+#ifndef __BINDER_INTERFACE_HPP__
+#define __BINDER_INTERFACE_HPP__
+
+class PEImage;
+class PEAssembly;
+class StringArrayList;
+
+namespace BINDER_SPACE
+{
+ class Assembly;
+ class AssemblyIdentityUTF8;
+};
+
+namespace BinderInterface
+{
+ HRESULT Init();
+
+ HRESULT SetupContext(/* in */ LPCWSTR wszApplicationBase,
+ /* in */ DWORD dwAppDomainId,
+ /* out */ IUnknown **ppIApplicationContext);
+
+ // See code:BINDER_SPACE::AssemblyBinder::GetAssembly for info on fNgenExplicitBind
+ // and fExplicitBindToNativeImage, and see code:CEECompileInfo::LoadAssemblyByPath
+ // for an example of how they're used.
+ HRESULT Bind(/* in */ IUnknown *pIApplicationContext,
+ /* in */ SString &assemblyDisplayName,
+ /* in */ LPCWSTR wszCodeBase,
+ /* in */ PEAssembly *pParentAssembly,
+ /* in */ BOOL fNgenExplicitBind,
+ /* in */ BOOL fExplicitBindToNativeImage,
+ /*out */ BINDER_SPACE::Assembly **ppAssembly);
+
+ //
+ // Called via managed AppDomain.ExecuteAssembly variants and during binding host setup
+ //
+ HRESULT SetupBindingPaths(/* in */ IUnknown *pIApplicationContext,
+ /* in */ SString &sTrustedPlatformAssemblies,
+ /* in */ SString &sPlatformResourceRoots,
+ /* in */ SString &sAppPaths,
+ /* in */ SString &sAppNiPaths);
+
+ //
+ // Called via CoreAssemblySpec::BindToSystem
+ //
+ HRESULT BindToSystem(/* in */ SString &sSystemDirectory,
+ /* out */ BINDER_SPACE::Assembly **ppSystemAssembly,
+ /* in */ bool fBindToNativeImage);
+
+#ifdef BINDER_DEBUG_LOG
+ HRESULT Log(/* in */ LPCWSTR wszMessage);
+#endif // BINDER_DEBUG_LOG
+
+};
+
+#endif
diff --git a/src/binder/inc/bindertypes.hpp b/src/binder/inc/bindertypes.hpp
new file mode 100644
index 0000000000..7d7e822871
--- /dev/null
+++ b/src/binder/inc/bindertypes.hpp
@@ -0,0 +1,132 @@
+// 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.
+// ============================================================
+//
+// BinderTypes.hpp
+//
+
+
+//
+// Declares a bunch of binder classes, types and macros
+//
+// ============================================================
+
+#ifndef __BINDER_TYPES_HPP__
+#define __BINDER_TYPES_HPP__
+
+#include "clrtypes.h"
+#include "sstring.h"
+
+#include "fusionhelpers.hpp"
+
+extern void DECLSPEC_NORETURN ThrowOutOfMemory();
+
+#ifndef S_TRUE
+#define S_TRUE S_OK
+#endif
+
+class PEImage;
+class PEAssembly;
+
+namespace BINDER_SPACE
+{
+ class AssemblyVersion;
+ class AssemblyName;
+ class Assembly;
+
+ class GACEntry;
+ class GACVersionIterator;
+ class GAC;
+
+ class ContextEntry;
+ class ExecutionContext;
+ class InspectionContext;
+
+ class PropertyMap;
+ class ApplicationContext;
+
+ class BindResult;
+ class FailureCache;
+ class AssemblyBinder;
+
+#if defined(BINDER_DEBUG_LOG)
+ class DebugLog;
+#endif
+
+#if defined(FEATURE_VERSIONING_LOG)
+ class BindingLog;
+ class CDebugLog;
+#endif // FEATURE_VERSIONING_LOG
+
+ namespace Tests
+ {
+ HRESULT Run();
+ };
+};
+
+#define IF_FAIL_GO(expr) \
+ hr = (expr); \
+ if (FAILED(hr)) \
+ { \
+ goto Exit; \
+ }
+
+#define IF_FALSE_GO(expr) \
+ if (!(expr)) { \
+ hr = E_FAIL; \
+ goto Exit; \
+ }
+
+#define GO_WITH_HRESULT(hrValue) \
+ hr = hrValue; \
+ goto Exit;
+
+#define IF_WIN32_ERROR_GO(expr) \
+ if (!(expr)) \
+ { \
+ hr = HRESULT_FROM_GetLastError(); \
+ goto Exit; \
+ }
+
+#define NEW_CONSTR(Object, Constr) \
+ (Object) = new (nothrow) Constr;
+
+#define SAFE_NEW_CONSTR(Object, Constr) \
+ (Object) = new (nothrow) Constr; \
+ if ((Object) == NULL) \
+ { \
+ hr = E_OUTOFMEMORY; \
+ goto Exit; \
+ }
+
+#define SAFE_NEW(Object, Class) \
+ SAFE_NEW_CONSTR(Object, Class());
+
+#define SAFE_RELEASE(objectPtr) \
+ if ((objectPtr) != NULL) \
+ { \
+ (objectPtr)->Release(); \
+ (objectPtr) = NULL; \
+ }
+
+#define SAFE_DELETE(objectPtr) \
+ if ((objectPtr) != NULL) \
+ { \
+ delete (objectPtr); \
+ (objectPtr) = NULL; \
+ }
+
+#define SAFE_DELETE_ARRAY(objectPtr) \
+ if ((objectPtr) != NULL) \
+ { \
+ delete[] (objectPtr); \
+ (objectPtr) = NULL; \
+ }
+
+#define LENGTH_OF(x) \
+ (sizeof(x) / sizeof(x[0]))
+
+#include "debuglog.hpp"
+
+#endif
diff --git a/src/binder/inc/bindinglog.hpp b/src/binder/inc/bindinglog.hpp
new file mode 100644
index 0000000000..d1467ed5c4
--- /dev/null
+++ b/src/binder/inc/bindinglog.hpp
@@ -0,0 +1,82 @@
+// 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.
+// ============================================================
+//
+// BindingLog.hpp
+//
+
+
+//
+// Defines the BindingLog class
+//
+// ============================================================
+
+#ifndef __BINDER__BINDING_LOG_HPP__
+#define __BINDER__BINDING_LOG_HPP__
+
+#include "bindertypes.hpp"
+
+namespace BINDER_SPACE
+{
+ class BindingLog
+ {
+ public:
+ BindingLog();
+ ~BindingLog();
+
+ //
+ // These functions will create a new log together with pre-bind state
+ // information if needed and store it into the application context.
+ // This is to avoid endlessly passing around the debug log.
+ //
+ static HRESULT CreateInContext(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ SString &assemblyPath,
+ /* in */ PEAssembly *pParentAssembly);
+ static HRESULT CreateInContext(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ PEAssembly *pParentAssembly);
+
+ HRESULT Log(SString &info);
+
+ inline HRESULT Log(LPCWSTR pwzInfo);
+ inline HRESULT Log(/* in */ LPCWSTR pwzPrefix,
+ /* in */ SString &info);
+
+ HRESULT LogAssemblyName(/* in */ LPCWSTR pwzPrefix,
+ /* in */ AssemblyName *pAssemblyName);
+
+ HRESULT LogHR(/* in */ HRESULT logHR);
+ HRESULT LogResult(/* in */ BindResult *pBindResult);
+
+ HRESULT Flush();
+
+ inline BOOL CanLog();
+
+ void SetDebugLog(CDebugLog *pCDebugLog);
+
+ protected:
+ static BOOL IsLoggingNeeded();
+
+ static HRESULT CreateInContext(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ SString &assemblyPath,
+ /* in */ PEAssembly *pParentAssembly);
+
+ HRESULT LogPreBindState(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ SString &assemblyPath,
+ /* in */ PEAssembly *pParentAssembly);
+
+
+ inline CDebugLog *GetDebugLog();
+
+ HRESULT LogUser();
+
+ CDebugLog *m_pCDebugLog;
+ };
+
+#include "bindinglog.inl"
+};
+
+#endif
diff --git a/src/binder/inc/bindinglog.inl b/src/binder/inc/bindinglog.inl
new file mode 100644
index 0000000000..f342f618ea
--- /dev/null
+++ b/src/binder/inc/bindinglog.inl
@@ -0,0 +1,46 @@
+// 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.
+// ============================================================
+//
+// BindingLog.inl
+//
+
+
+//
+// Implements inlined methods of BindingLog
+//
+// ============================================================
+
+#ifndef __BINDER__BINDING_LOG_INL__
+#define __BINDER__BINDING_LOG_INL__
+
+BOOL BindingLog::CanLog()
+{
+ return (m_pCDebugLog != NULL);
+}
+
+CDebugLog *BindingLog::GetDebugLog()
+{
+ _ASSERTE(m_pCDebugLog != NULL);
+ return m_pCDebugLog;
+}
+
+HRESULT BindingLog::Log(LPCWSTR pwzInfo)
+{
+ PathString info(pwzInfo);
+ return BindingLog::Log(info);
+}
+
+HRESULT BindingLog::Log(LPCWSTR pwzPrefix,
+ SString &info)
+{
+ PathString message;
+
+ message.Append(pwzPrefix);
+ message.Append(info);
+
+ return Log(message);
+}
+
+#endif
diff --git a/src/binder/inc/bindresult.hpp b/src/binder/inc/bindresult.hpp
new file mode 100644
index 0000000000..54d154a009
--- /dev/null
+++ b/src/binder/inc/bindresult.hpp
@@ -0,0 +1,64 @@
+// 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.
+// ============================================================
+//
+// BindResult.hpp
+//
+
+
+//
+// Defines the BindResult class
+//
+// ============================================================
+
+#ifndef __BINDER__BIND_RESULT_HPP__
+#define __BINDER__BIND_RESULT_HPP__
+
+#include "bindertypes.hpp"
+
+namespace BINDER_SPACE
+{
+ class BindResult
+ {
+ public:
+ inline BindResult();
+ inline ~BindResult();
+
+ inline AssemblyName *GetAssemblyName(BOOL fAddRef = FALSE);
+ inline IUnknown *GetAssembly(BOOL fAddRef = FALSE);
+ inline Assembly *GetAsAssembly(BOOL fAddRef = FALSE);
+
+ inline AssemblyName *GetRetargetedAssemblyName();
+ inline void SetRetargetedAssemblyName(AssemblyName *pRetargetedAssemblyName);
+
+ inline BOOL GetIsDynamicBind();
+ inline void SetIsDynamicBind(BOOL fIsDynamicBind);
+ inline BOOL GetIsInGAC();
+ inline void SetIsInGAC(BOOL fIsInGAC);
+ inline BOOL GetIsContextBound();
+ inline void SetIsContextBound(BOOL fIsContextBound);
+ inline BOOL GetIsFirstRequest();
+ inline void SetIsFirstRequest(BOOL fIsFirstRequest);
+ inline BOOL GetIsSharable();
+ inline void SetIsSharable(BOOL fIsSharable);
+
+ inline void SetResult(ContextEntry *pContextEntry, BOOL fIsContextBound = TRUE);
+ inline void SetResult(Assembly *pAssembly);
+ inline void SetResult(BindResult *pBindResult);
+
+ inline void SetNoResult();
+ inline BOOL HaveResult();
+
+ inline IUnknown *ExtractAssembly();
+ inline void Reset();
+
+ protected:
+ DWORD m_dwResultFlags;
+ AssemblyName *m_pAssemblyName;
+ AssemblyName *m_pRetargetedAssemblyName;
+ ReleaseHolder<IUnknown> m_pIUnknownAssembly;
+ };
+};
+
+#endif
diff --git a/src/binder/inc/bindresult.inl b/src/binder/inc/bindresult.inl
new file mode 100644
index 0000000000..8e94e85c4f
--- /dev/null
+++ b/src/binder/inc/bindresult.inl
@@ -0,0 +1,229 @@
+// 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.
+// ============================================================
+//
+// BindResult.inl
+//
+
+
+//
+// Implements the inline methods of BindResult
+//
+// ============================================================
+
+#ifndef __BINDER__BIND_RESULT_INL__
+#define __BINDER__BIND_RESULT_INL__
+
+#include "contextentry.hpp"
+#include "assembly.hpp"
+
+namespace BINDER_SPACE
+{
+BindResult::BindResult()
+{
+ m_dwResultFlags = ContextEntry::RESULT_FLAG_NONE;
+ m_pAssemblyName = NULL;
+ m_pRetargetedAssemblyName = NULL;
+ m_pIUnknownAssembly = NULL;
+}
+
+BindResult::~BindResult()
+{
+ SAFE_RELEASE(m_pAssemblyName);
+ SAFE_RELEASE(m_pRetargetedAssemblyName);
+}
+
+AssemblyName *BindResult::GetAssemblyName(BOOL fAddRef /* = FALSE */)
+{
+ AssemblyName *pAssemblyName = m_pAssemblyName;
+
+ if (fAddRef && (pAssemblyName != NULL))
+ {
+ pAssemblyName->AddRef();
+ }
+
+ return pAssemblyName;
+}
+
+AssemblyName *BindResult::GetRetargetedAssemblyName()
+{
+ return m_pRetargetedAssemblyName;
+}
+
+void BindResult::SetRetargetedAssemblyName(AssemblyName *pRetargetedAssemblyName)
+{
+ SAFE_RELEASE(m_pRetargetedAssemblyName);
+
+ if (pRetargetedAssemblyName)
+ {
+ pRetargetedAssemblyName->AddRef();
+ }
+
+ m_pRetargetedAssemblyName = pRetargetedAssemblyName;
+}
+
+IUnknown *BindResult::GetAssembly(BOOL fAddRef /* = FALSE */)
+{
+ IUnknown *pIUnknownAssembly = m_pIUnknownAssembly;
+
+ if (fAddRef && (pIUnknownAssembly != NULL))
+ {
+ pIUnknownAssembly->AddRef();
+ }
+
+ return pIUnknownAssembly;
+}
+
+Assembly *BindResult::GetAsAssembly(BOOL fAddRef /* = FALSE */)
+{
+ return static_cast<Assembly *>(GetAssembly(fAddRef));
+}
+
+BOOL BindResult::GetIsDynamicBind()
+{
+ return ((m_dwResultFlags & ContextEntry::RESULT_FLAG_IS_DYNAMIC_BIND) != 0);
+}
+
+void BindResult::SetIsDynamicBind(BOOL fIsDynamicBind)
+{
+ if (fIsDynamicBind)
+ {
+ m_dwResultFlags |= ContextEntry::RESULT_FLAG_IS_DYNAMIC_BIND;
+ }
+ else
+ {
+ m_dwResultFlags &= ~ContextEntry::RESULT_FLAG_IS_DYNAMIC_BIND;
+ }
+}
+
+BOOL BindResult::GetIsInGAC()
+{
+ return ((m_dwResultFlags & ContextEntry::RESULT_FLAG_IS_IN_GAC) != 0);
+}
+
+void BindResult::SetIsInGAC(BOOL fIsInGAC)
+{
+ if (fIsInGAC)
+ {
+ m_dwResultFlags |= ContextEntry::RESULT_FLAG_IS_IN_GAC;
+ }
+ else
+ {
+ m_dwResultFlags &= ~ContextEntry::RESULT_FLAG_IS_IN_GAC;
+ }
+}
+
+BOOL BindResult::GetIsContextBound()
+{
+ return ((m_dwResultFlags & ContextEntry::RESULT_FLAG_CONTEXT_BOUND) != 0);
+}
+
+void BindResult::SetIsContextBound(BOOL fIsContextBound)
+{
+ if (fIsContextBound)
+ {
+ m_dwResultFlags |= ContextEntry::RESULT_FLAG_CONTEXT_BOUND;
+ }
+ else
+ {
+ m_dwResultFlags &= ~ContextEntry::RESULT_FLAG_CONTEXT_BOUND;
+ }
+}
+
+BOOL BindResult::GetIsFirstRequest()
+{
+ return ((m_dwResultFlags & ContextEntry::RESULT_FLAG_FIRST_REQUEST) != 0);
+}
+
+void BindResult::SetIsFirstRequest(BOOL fIsFirstRequest)
+{
+ if (fIsFirstRequest)
+ {
+ m_dwResultFlags |= ContextEntry::RESULT_FLAG_FIRST_REQUEST;
+ }
+ else
+ {
+ m_dwResultFlags &= ~ContextEntry::RESULT_FLAG_FIRST_REQUEST;
+ }
+}
+
+BOOL BindResult::GetIsSharable()
+{
+ return ((m_dwResultFlags & ContextEntry::RESULT_FLAG_IS_SHARABLE) != 0);
+}
+
+void BindResult::SetIsSharable(BOOL fIsSharable)
+{
+ if (fIsSharable)
+ {
+ m_dwResultFlags |= ContextEntry::RESULT_FLAG_IS_SHARABLE;
+ }
+ else
+ {
+ m_dwResultFlags &= ~ContextEntry::RESULT_FLAG_IS_SHARABLE;
+ }
+}
+
+void BindResult::SetResult(ContextEntry *pContextEntry, BOOL fIsContextBound /* = TRUE */)
+{
+ _ASSERTE(pContextEntry != NULL);
+
+ SetIsDynamicBind(pContextEntry->GetIsDynamicBind());
+ SetIsInGAC(pContextEntry->GetIsInGAC());
+ SetIsContextBound(fIsContextBound);
+ SetIsSharable(pContextEntry->GetIsSharable());
+ SAFE_RELEASE(m_pAssemblyName);
+ m_pAssemblyName = pContextEntry->GetAssemblyName(TRUE /* fAddRef */);
+ m_pIUnknownAssembly = pContextEntry->GetAssembly(TRUE /* fAddRef */);
+}
+
+void BindResult::SetResult(Assembly *pAssembly)
+{
+ _ASSERTE(pAssembly != NULL);
+
+ SetIsDynamicBind(pAssembly->GetIsDynamicBind());
+ SetIsInGAC(pAssembly->GetIsInGAC());
+ SetIsSharable(pAssembly->GetIsSharable());
+ SAFE_RELEASE(m_pAssemblyName);
+ m_pAssemblyName = pAssembly->GetAssemblyName(TRUE /* fAddRef */);
+ pAssembly->AddRef();
+ m_pIUnknownAssembly = static_cast<IUnknown *>(pAssembly);
+}
+
+void BindResult::SetResult(BindResult *pBindResult)
+{
+ _ASSERTE(pBindResult != NULL);
+
+ m_dwResultFlags = pBindResult->m_dwResultFlags;
+ SAFE_RELEASE(m_pAssemblyName);
+ m_pAssemblyName = pBindResult->GetAssemblyName(TRUE /* fAddRef */);
+ m_pIUnknownAssembly = pBindResult->GetAssembly(TRUE /* fAddRef */);
+}
+
+void BindResult::SetNoResult()
+{
+ m_pAssemblyName = NULL;
+}
+
+BOOL BindResult::HaveResult()
+{
+ return (GetAssemblyName() != NULL);
+}
+
+IUnknown *BindResult::ExtractAssembly()
+{
+ return m_pIUnknownAssembly.Extract();
+}
+
+void BindResult::Reset()
+{
+ SAFE_RELEASE(m_pAssemblyName);
+ SAFE_RELEASE(m_pRetargetedAssemblyName);
+ m_pIUnknownAssembly = NULL;
+ m_dwResultFlags = ContextEntry::RESULT_FLAG_NONE;
+}
+
+}
+
+#endif
diff --git a/src/binder/inc/cdebuglog.hpp b/src/binder/inc/cdebuglog.hpp
new file mode 100644
index 0000000000..37e1bc65b9
--- /dev/null
+++ b/src/binder/inc/cdebuglog.hpp
@@ -0,0 +1,67 @@
+// 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.
+// ============================================================
+//
+// CDebugLog.hpp
+//
+
+
+//
+// Defines the CDebugLog class
+//
+// ============================================================
+
+#ifndef __BINDER__C_DEBUG_LOG_HPP__
+#define __BINDER__C_DEBUG_LOG_HPP__
+
+#include "bindertypes.hpp"
+#include "list.hpp"
+
+#define FUSION_BIND_LOG_CATEGORY_DEFAULT 0
+#define FUSION_BIND_LOG_CATEGORY_NGEN 1
+#define FUSION_BIND_LOG_CATEGORY_MAX 2
+
+namespace BINDER_SPACE
+{
+ class CDebugLog
+ {
+ public:
+ CDebugLog();
+ ~CDebugLog();
+
+ static HRESULT Create(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ SString &sCodeBase,
+ /* out */ CDebugLog **ppCDebugLog);
+
+ ULONG AddRef();
+ ULONG Release();
+
+ HRESULT SetResultCode(/* in */ DWORD dwLogCategory,
+ /* in */ HRESULT hrResult);
+
+ HRESULT LogMessage(/* in */ DWORD dwDetailLevel,
+ /* in */ DWORD dwLogCategory,
+ /* in */ SString &sDebugString);
+
+ HRESULT Flush(/* in */ DWORD dwDetailLevel,
+ /* in */ DWORD dwLogCategory);
+ protected:
+ HRESULT Init(/* in */ ApplicationContext *pApplicationContext,
+ /* in */ AssemblyName *pAssemblyName,
+ /* in */ SString &sCodeBase);
+
+ HRESULT LogHeader(/* in */ DWORD dwLogCategory);
+ HRESULT LogFooter(/* in */ DWORD dwLogCategory);
+
+ LONG m_cRef;
+ FileHandleHolder m_hLogFile;
+ List<SString> m_content[FUSION_BIND_LOG_CATEGORY_MAX];
+ SString m_applicationName;
+ SString m_logFileName;
+ HRESULT m_HrResult[FUSION_BIND_LOG_CATEGORY_MAX];
+ };
+};
+
+#endif
diff --git a/src/binder/inc/clrprivbinderassemblyloadcontext.h b/src/binder/inc/clrprivbinderassemblyloadcontext.h
new file mode 100644
index 0000000000..83113f4633
--- /dev/null
+++ b/src/binder/inc/clrprivbinderassemblyloadcontext.h
@@ -0,0 +1,86 @@
+// 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.
+
+
+#ifndef __CLRPRIVBINDERASSEMBLYLOADCONTEXT_H__
+#define __CLRPRIVBINDERASSEMBLYLOADCONTEXT_H__
+
+#include "coreclrbindercommon.h"
+#include "applicationcontext.hpp"
+#include "clrprivbindercoreclr.h"
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
+namespace BINDER_SPACE
+{
+ class AssemblyIdentityUTF8;
+};
+
+class CLRPrivBinderAssemblyLoadContext : public IUnknownCommon<ICLRPrivBinder>
+{
+public:
+
+ //=========================================================================
+ // ICLRPrivBinder functions
+ //-------------------------------------------------------------------------
+ STDMETHOD(BindAssemblyByName)(
+ /* [in] */ IAssemblyName *pIAssemblyName,
+ /* [retval][out] */ ICLRPrivAssembly **ppAssembly);
+
+ STDMETHOD(VerifyBind)(
+ /* [in] */ IAssemblyName *pIAssemblyName,
+ /* [in] */ ICLRPrivAssembly *pAssembly,
+ /* [in] */ ICLRPrivAssemblyInfo *pAssemblyInfo);
+
+ STDMETHOD(GetBinderFlags)(
+ /* [retval][out] */ DWORD *pBinderFlags);
+
+ STDMETHOD(GetBinderID)(
+ /* [retval][out] */ UINT_PTR *pBinderId);
+
+ STDMETHOD(FindAssemblyBySpec)(
+ /* [in] */ LPVOID pvAppDomain,
+ /* [in] */ LPVOID pvAssemblySpec,
+ /* [out] */ HRESULT *pResult,
+ /* [out] */ ICLRPrivAssembly **ppAssembly);
+
+public:
+ //=========================================================================
+ // Class functions
+ //-------------------------------------------------------------------------
+
+ static HRESULT SetupContext(DWORD dwAppDomainId, CLRPrivBinderCoreCLR *pTPABinder,
+ UINT_PTR ptrAssemblyLoadContext, CLRPrivBinderAssemblyLoadContext **ppBindContext);
+
+ CLRPrivBinderAssemblyLoadContext();
+
+ inline BINDER_SPACE::ApplicationContext *GetAppContext()
+ {
+ return &m_appContext;
+ }
+
+ inline INT_PTR GetManagedAssemblyLoadContext()
+ {
+ return m_ptrManagedAssemblyLoadContext;
+ }
+
+ HRESULT BindUsingPEImage( /* in */ PEImage *pPEImage,
+ /* in */ BOOL fIsNativeImage,
+ /* [retval][out] */ ICLRPrivAssembly **ppAssembly);
+
+ //=========================================================================
+ // Internal implementation details
+ //-------------------------------------------------------------------------
+private:
+ HRESULT BindAssemblyByNameWorker(BINDER_SPACE::AssemblyName *pAssemblyName, BINDER_SPACE::Assembly **ppCoreCLRFoundAssembly);
+
+ BINDER_SPACE::ApplicationContext m_appContext;
+
+ CLRPrivBinderCoreCLR *m_pTPABinder;
+
+ INT_PTR m_ptrManagedAssemblyLoadContext;
+};
+
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // __CLRPRIVBINDERASSEMBLYLOADCONTEXT_H__
diff --git a/src/binder/inc/clrprivbindercoreclr.h b/src/binder/inc/clrprivbindercoreclr.h
new file mode 100644
index 0000000000..e906e01b12
--- /dev/null
+++ b/src/binder/inc/clrprivbindercoreclr.h
@@ -0,0 +1,100 @@
+// 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.
+
+
+#ifndef __CLR_PRIV_BINDER_CORECLR_H__
+#define __CLR_PRIV_BINDER_CORECLR_H__
+
+#include "coreclrbindercommon.h"
+#include "applicationcontext.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyIdentityUTF8;
+};
+
+class CLRPrivBinderCoreCLR : public IUnknownCommon<ICLRPrivBinder>
+{
+public:
+
+ //=========================================================================
+ // ICLRPrivBinder functions
+ //-------------------------------------------------------------------------
+ STDMETHOD(BindAssemblyByName)(
+ /* [in] */ IAssemblyName *pIAssemblyName,
+ /* [retval][out] */ ICLRPrivAssembly **ppAssembly);
+
+ STDMETHOD(VerifyBind)(
+ /* [in] */ IAssemblyName *pIAssemblyName,
+ /* [in] */ ICLRPrivAssembly *pAssembly,
+ /* [in] */ ICLRPrivAssemblyInfo *pAssemblyInfo);
+
+ STDMETHOD(GetBinderFlags)(
+ /* [retval][out] */ DWORD *pBinderFlags);
+
+ STDMETHOD(GetBinderID)(
+ /* [retval][out] */ UINT_PTR *pBinderId);
+
+ STDMETHOD(FindAssemblyBySpec)(
+ /* [in] */ LPVOID pvAppDomain,
+ /* [in] */ LPVOID pvAssemblySpec,
+ /* [out] */ HRESULT *pResult,
+ /* [out] */ ICLRPrivAssembly **ppAssembly);
+
+public:
+
+ HRESULT SetupBindingPaths(SString &sTrustedPlatformAssemblies,
+ SString &sPlatformResourceRoots,
+ SString &sAppPaths,
+ SString &sAppNiPaths);
+
+ bool IsInTpaList(const SString &sFileName);
+
+ inline BINDER_SPACE::ApplicationContext *GetAppContext()
+ {
+ return &m_appContext;
+ }
+
+ HRESULT Bind(SString &assemblyDisplayName,
+ LPCWSTR wszCodeBase,
+ PEAssembly *pParentAssembly,
+ BOOL fNgenExplicitBind,
+ BOOL fExplicitBindToNativeImage,
+ ICLRPrivAssembly **ppAssembly);
+
+#ifndef CROSSGEN_COMPILE
+ HRESULT PreBindByteArray(PEImage *pPEImage, BOOL fInspectionOnly);
+#endif // CROSSGEN_COMPILE
+
+#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ HRESULT BindUsingPEImage( /* in */ PEImage *pPEImage,
+ /* in */ BOOL fIsNativeImage,
+ /* [retval][out] */ ICLRPrivAssembly **ppAssembly);
+#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
+ HRESULT BindAssemblyByNameWorker(
+ BINDER_SPACE::AssemblyName *pAssemblyName,
+ BINDER_SPACE::Assembly **ppCoreCLRFoundAssembly,
+ bool excludeAppPaths);
+
+ INT_PTR GetManagedAssemblyLoadContext()
+ {
+ return m_ptrManagedAssemblyLoadContext;
+ }
+
+ void SetManagedAssemblyLoadContext(INT_PTR ptrManagedTPABinderInstance)
+ {
+ m_ptrManagedAssemblyLoadContext = ptrManagedTPABinderInstance;
+ }
+
+ //=========================================================================
+ // Internal implementation details
+ //-------------------------------------------------------------------------
+private:
+ BINDER_SPACE::ApplicationContext m_appContext;
+
+ INT_PTR m_ptrManagedAssemblyLoadContext;
+};
+
+#endif // __CLR_PRIV_BINDER_CORECLR_H__
diff --git a/src/binder/inc/contextentry.hpp b/src/binder/inc/contextentry.hpp
new file mode 100644
index 0000000000..d35f57b0ca
--- /dev/null
+++ b/src/binder/inc/contextentry.hpp
@@ -0,0 +1,146 @@
+// 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.
+// ============================================================
+//
+// ContextEntry.hpp
+//
+
+
+//
+// Defines the ContextEntry class
+//
+// ============================================================
+
+#ifndef __BINDER__CONTEXT_ENTRY_HPP__
+#define __BINDER__CONTEXT_ENTRY_HPP__
+
+#include "assemblyentry.hpp"
+#include "assembly.hpp"
+
+namespace BINDER_SPACE
+{
+ class ContextEntry : public AssemblyEntry
+ {
+ public:
+ typedef enum
+ {
+ RESULT_FLAG_NONE = 0x00,
+ RESULT_FLAG_IS_DYNAMIC_BIND = 0x01,
+ RESULT_FLAG_IS_IN_GAC = 0x02,
+ //RESULT_FLAG_FROM_MANIFEST = 0x04,
+ RESULT_FLAG_CONTEXT_BOUND = 0x08,
+ RESULT_FLAG_FIRST_REQUEST = 0x10,
+ RESULT_FLAG_IS_SHARABLE = 0x20
+ } ResultFlags;
+
+ ContextEntry() : AssemblyEntry()
+ {
+ m_dwResultFlags = RESULT_FLAG_NONE;
+ m_pIUnknownAssembly = NULL;
+ }
+
+ ~ContextEntry()
+ {
+ SAFE_RELEASE(m_pIUnknownAssembly);
+ }
+
+ BOOL GetIsDynamicBind()
+ {
+ return ((m_dwResultFlags & RESULT_FLAG_IS_DYNAMIC_BIND) != 0);
+ }
+
+ void SetIsDynamicBind(BOOL fIsDynamicBind)
+ {
+ if (fIsDynamicBind)
+ {
+ m_dwResultFlags |= RESULT_FLAG_IS_DYNAMIC_BIND;
+ }
+ else
+ {
+ m_dwResultFlags &= ~RESULT_FLAG_IS_DYNAMIC_BIND;
+ }
+ }
+
+ BOOL GetIsInGAC()
+ {
+ return ((m_dwResultFlags & RESULT_FLAG_IS_IN_GAC) != 0);
+ }
+
+ void SetIsInGAC(BOOL fIsInGAC)
+ {
+ if (fIsInGAC)
+ {
+ m_dwResultFlags |= RESULT_FLAG_IS_IN_GAC;
+ }
+ else
+ {
+ m_dwResultFlags &= ~RESULT_FLAG_IS_IN_GAC;
+ }
+ }
+
+ BOOL GetIsFirstRequest()
+ {
+ return ((m_dwResultFlags & RESULT_FLAG_FIRST_REQUEST) != 0);
+ }
+
+ void SetIsFirstRequest(BOOL fIsFirstRequest)
+ {
+ if (fIsFirstRequest)
+ {
+ m_dwResultFlags |= RESULT_FLAG_FIRST_REQUEST;
+ }
+ else
+ {
+ m_dwResultFlags &= ~RESULT_FLAG_FIRST_REQUEST;
+ }
+ }
+
+ BOOL GetIsSharable()
+ {
+ return ((m_dwResultFlags & RESULT_FLAG_IS_SHARABLE) != 0);
+ }
+
+ void SetIsSharable(BOOL fIsSharable)
+ {
+ if (fIsSharable)
+ {
+ m_dwResultFlags |= RESULT_FLAG_IS_SHARABLE;
+ }
+ else
+ {
+ m_dwResultFlags &= ~RESULT_FLAG_IS_SHARABLE;
+ }
+ }
+
+ IUnknown *GetAssembly(BOOL fAddRef = FALSE)
+ {
+ IUnknown *pIUnknownAssembly = m_pIUnknownAssembly;
+
+ if (fAddRef && (pIUnknownAssembly != NULL))
+ {
+ pIUnknownAssembly->AddRef();
+ }
+
+ return pIUnknownAssembly;
+ }
+
+ void SetAssembly(IUnknown *pIUnknownAssembly)
+ {
+ SAFE_RELEASE(m_pIUnknownAssembly);
+
+ if (pIUnknownAssembly != NULL)
+ {
+ pIUnknownAssembly->AddRef();
+ }
+
+ m_pIUnknownAssembly = pIUnknownAssembly;
+ }
+
+ protected:
+ DWORD m_dwResultFlags;
+ IUnknown *m_pIUnknownAssembly;
+ };
+};
+
+#endif
diff --git a/src/binder/inc/coreclrbindercommon.h b/src/binder/inc/coreclrbindercommon.h
new file mode 100644
index 0000000000..66166d6fd2
--- /dev/null
+++ b/src/binder/inc/coreclrbindercommon.h
@@ -0,0 +1,58 @@
+// 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.
+
+
+#ifndef __CORECLR_BINDER_COMMON_H__
+#define __CORECLR_BINDER_COMMON_H__
+
+#include "clrprivbinding.h"
+#include "internalunknownimpl.h"
+#include "applicationcontext.hpp"
+
+
+namespace BINDER_SPACE
+{
+ class AssemblyIdentityUTF8;
+};
+
+class CLRPrivBinderCoreCLR;
+
+// General purpose AssemblyBinder helper class
+class CCoreCLRBinderHelper
+{
+public:
+ static HRESULT Init();
+
+ static HRESULT DefaultBinderSetupContext(DWORD dwAppDomainId,
+ CLRPrivBinderCoreCLR **ppTPABinder);
+
+ // ABHI-TODO: The call indicates that this can come from a case where
+ // pDomain->GetFusionContext() is null, hence this is static function
+ // which handles a null binder. See if this actually happens
+ static HRESULT GetAssemblyIdentity(LPCSTR szTextualIdentity,
+ BINDER_SPACE::ApplicationContext *pApplicationContext,
+ NewHolder<BINDER_SPACE::AssemblyIdentityUTF8> &assemblyIdentityHolder);
+
+ //=============================================================================
+ // Class functions that provides binding services beyond the ICLRPrivInterface
+ //-----------------------------------------------------------------------------
+ static HRESULT BindToSystem(ICLRPrivAssembly **ppSystemAssembly, bool fBindToNativeImage);
+
+ static HRESULT BindToSystemSatellite(SString &systemPath,
+ SString &sSimpleName,
+ SString &sCultureName,
+ ICLRPrivAssembly **ppSystemAssembly);
+
+ static HRESULT GetAssemblyFromImage(PEImage *pPEImage,
+ PEImage *pNativePEImage,
+ ICLRPrivAssembly **ppAssembly);
+
+ static HRESULT GetAssembly(/* in */ SString &assemblyPath,
+ /* in */ BOOL fInspectionOnly,
+ /* in */ BOOL fIsInGAC,
+ /* in */ BOOL fExplicitBindToNativeImage,
+ /* out */ BINDER_SPACE::Assembly **ppAssembly);
+};
+
+#endif // __CORECLR_BINDER_COMMON_H__
diff --git a/src/binder/inc/debuglog.hpp b/src/binder/inc/debuglog.hpp
new file mode 100644
index 0000000000..28de7f3267
--- /dev/null
+++ b/src/binder/inc/debuglog.hpp
@@ -0,0 +1,118 @@
+// 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.
+// ============================================================
+//
+// DebugLog.hpp
+//
+
+
+//
+// Defines the DebugLog class
+//
+// ============================================================
+
+#ifndef __BINDER__DEBUG_LOG_HPP__
+#define __BINDER__DEBUG_LOG_HPP__
+
+#include "bindertypes.hpp"
+#include "variables.hpp"
+
+namespace BINDER_SPACE
+{
+
+// When defined at the top of a source file, DISABLE_BINDER_DEBUG_LOGGING will cause
+// binder debug logging to be disabled only in the scope of that file by defining all the
+// binder logging macros as NOPs.
+
+#if defined(BINDER_DEBUG_LOG) && !defined(DISABLE_BINDER_DEBUG_LOGGING)
+
+#define BINDER_LOG_STARTUP() \
+ IF_FAIL_GO(DebugLog::Startup());
+
+#define BINDER_LOG_LOCK() \
+ CRITSEC_Holder logLock(g_BinderVariables->m_logCS);
+
+#define BINDER_LOG_ENTER(scope) \
+ DebugLog::Enter(scope);
+
+#define BINDER_LOG_LEAVE(scope) \
+ DebugLog::Leave(scope);
+
+#define BINDER_LOG_LEAVE_HR(scope, hr) \
+ DebugLog::LeaveHR(scope, hr);
+
+#define BINDER_LOG_LEAVE_BOOL(scope, fResult) \
+ DebugLog::LeaveBool(scope, fResult);
+
+#define BINDER_LOG(comment) \
+ DebugLog::Log(comment);
+
+#define BINDER_LOG_STRING(comment, value) \
+ DebugLog::Log(comment, value);
+
+#define BINDER_LOG_HRESULT(comment, hr) \
+ DebugLog::Log(comment, hr);
+
+#define BINDER_LOG_ASSEMBLY_NAME(comment, assemblyName) \
+ DebugLog::Log(comment, assemblyName);
+
+#define BINDER_LOG_I_ASSEMBLY_NAME(comment, assemblyName) \
+ DebugLog::Log(comment, assemblyName);
+
+#define BINDER_LOG_POINTER(comment, pData) \
+ DebugLog::Log(comment, (void *) (pData));
+
+ class DebugLog
+ {
+ public:
+ static HRESULT Startup();
+
+ static void Enter(/* in */ WCHAR *pwzScope);
+ static void Leave(/* in */ WCHAR *pwzScope);
+ static void LeaveHR(/* in */ WCHAR *pwzScope,
+ /* in */ HRESULT hrLog);
+ static void LeaveBool(/* in */ WCHAR *pwzScope,
+ /* in */ BOOL fResult);
+
+ static void Log(/* in */ WCHAR *pwzComment);
+ static void Log(/* in */ WCHAR *pwzComment,
+ /* in */ SString &value);
+ static void Log(/* in */ WCHAR *pwzComment,
+ /* in */ const WCHAR *value);
+ static void Log(/* in */ WCHAR *pwzComment,
+ /* in */ HRESULT hrLog);
+ static void Log(/* in */ WCHAR *pwzComment,
+ /* in */ AssemblyName *pAssemblyName);
+ static void Log(/* in */ WCHAR *pwzComment,
+ /* in */ void *pData);
+ protected:
+ static void Log(/* in */ SString &info);
+ };
+#else
+ class DebugLog
+ {
+ public:
+ static void Empty() {};
+ };
+
+#define BINDER_LOG_STARTUP() DebugLog::Empty();
+
+#define BINDER_LOG_LOCK() DebugLog::Empty();
+
+#define BINDER_LOG_ENTER(scope) DebugLog::Empty();
+#define BINDER_LOG_LEAVE(scope) DebugLog::Empty();
+#define BINDER_LOG_LEAVE_HR(scope, hr) DebugLog::Empty();
+#define BINDER_LOG_LEAVE_BOOL(scope, fResult) DebugLog::Empty();
+
+#define BINDER_LOG(comment) DebugLog::Empty();
+#define BINDER_LOG_STRING(comment, value) DebugLog::Empty();
+#define BINDER_LOG_HRESULT(comment, hr) DebugLog::Empty();
+#define BINDER_LOG_ASSEMBLY_NAME(comment, assemblyName) DebugLog::Empty();
+#define BINDER_LOG_I_ASSEMBLY_NAME(comment, assemblyName) DebugLog::Empty();
+#define BINDER_LOG_POINTER(comment, pData) DebugLog::Empty();
+
+#endif
+};
+
+#endif
diff --git a/src/binder/inc/failurecache.hpp b/src/binder/inc/failurecache.hpp
new file mode 100644
index 0000000000..3dbc3f611e
--- /dev/null
+++ b/src/binder/inc/failurecache.hpp
@@ -0,0 +1,38 @@
+// 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.
+// ============================================================
+//
+// FailureCache.hpp
+//
+
+
+//
+// Defines the FailureCache class
+//
+// ============================================================
+
+
+#ifndef __BINDER__FAILURE_CACHE_HPP__
+#define __BINDER__FAILURE_CACHE_HPP__
+
+#include "failurecachehashtraits.hpp"
+
+namespace BINDER_SPACE
+{
+ class FailureCache : protected SHash<FailureCacheHashTraits>
+ {
+ private:
+ typedef SHash<FailureCacheHashTraits> Hash;
+ public:
+ FailureCache();
+ ~FailureCache();
+
+ HRESULT Add(/* in */ SString &assemblyNameorPath,
+ /* in */ HRESULT hrBindResult);
+ HRESULT Lookup(/* in */ SString &assemblyNameorPath);
+ void Remove(/* in */ SString &assemblyName);
+ };
+};
+
+#endif
diff --git a/src/binder/inc/failurecachehashtraits.hpp b/src/binder/inc/failurecachehashtraits.hpp
new file mode 100644
index 0000000000..7d65544ecc
--- /dev/null
+++ b/src/binder/inc/failurecachehashtraits.hpp
@@ -0,0 +1,88 @@
+// 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.
+// ============================================================
+//
+// FailureCache.hpp
+//
+
+
+//
+// Defines the FailureCache class
+//
+// ============================================================
+
+#ifndef __BINDER__FAILURE_CACHE_HASH_TRAITS_HPP__
+#define __BINDER__FAILURE_CACHE_HASH_TRAITS_HPP__
+
+#include "bindertypes.hpp"
+#include "utils.hpp"
+#include "sstring.h"
+#include "shash.h"
+
+namespace BINDER_SPACE
+{
+ class FailureCacheEntry
+ {
+ public:
+ inline FailureCacheEntry()
+ {
+ m_hrBindingResult = S_OK;
+ }
+ inline ~FailureCacheEntry()
+ {
+ // Nothing to do here
+ }
+
+ // Getters/Setters
+ inline SString &GetAssemblyNameOrPath()
+ {
+ return m_assemblyNameOrPath;
+ }
+ inline HRESULT GetBindingResult()
+ {
+ return m_hrBindingResult;
+ }
+ inline void SetBindingResult(HRESULT hrBindingResult)
+ {
+ m_hrBindingResult = hrBindingResult;
+ }
+
+ protected:
+ SString m_assemblyNameOrPath;
+ HRESULT m_hrBindingResult;
+ };
+
+ class FailureCacheHashTraits : public DefaultSHashTraits<FailureCacheEntry *>
+ {
+ public:
+ typedef SString& key_t;
+
+ // GetKey, Equals, and Hash can throw due to SString
+ static const bool s_NoThrow = false;
+
+ static key_t GetKey(element_t pFailureCacheEntry)
+ {
+ return pFailureCacheEntry->GetAssemblyNameOrPath();
+ }
+ static BOOL Equals(key_t pAssemblyNameOrPath1, key_t pAssemblyNameOrPath2)
+ {
+ return EqualsCaseInsensitive(pAssemblyNameOrPath1, pAssemblyNameOrPath2);
+ }
+ static count_t Hash(key_t pAssemblyNameOrPath)
+ {
+ return HashCaseInsensitive(pAssemblyNameOrPath);
+ }
+ static const element_t Null()
+ {
+ return NULL;
+ }
+ static bool IsNull(const element_t &propertyEntry)
+ {
+ return (propertyEntry == NULL);
+ }
+
+ };
+};
+
+#endif
diff --git a/src/binder/inc/fusionassemblyname.hpp b/src/binder/inc/fusionassemblyname.hpp
new file mode 100644
index 0000000000..f0f69d3274
--- /dev/null
+++ b/src/binder/inc/fusionassemblyname.hpp
@@ -0,0 +1,217 @@
+// 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.
+// ============================================================
+//
+// FusionAssemblyName.hpp
+//
+// Defines the CAssemblyName class
+//
+// ============================================================
+
+#ifndef __FUSION_ASSEMBLY_NAME_HPP__
+#define __FUSION_ASSEMBLY_NAME_HPP__
+
+#include "fusionhelpers.hpp"
+
+struct FusionProperty
+{
+ union {
+ LPVOID pv;
+ wchar_t* asStr; // For debugging.
+ };
+ DWORD cb;
+};
+
+class CPropertyArray
+{
+ friend class CAssemblyName;
+private:
+ DWORD _dwSig;
+ FusionProperty _rProp[ASM_NAME_MAX_PARAMS];
+
+public:
+ CPropertyArray();
+ ~CPropertyArray();
+
+ inline HRESULT Set(DWORD PropertyId, LPCVOID pvProperty, DWORD cbProperty);
+ inline HRESULT Get(DWORD PropertyId, LPVOID pvProperty, LPDWORD pcbProperty);
+ inline FusionProperty operator [] (DWORD dwPropId);
+};
+
+class CAssemblyName : public IAssemblyName
+{
+private:
+ DWORD _dwSig;
+ Volatile<LONG> _cRef;
+ CPropertyArray _rProp;
+ BOOL _fIsFinalized;
+ BOOL _fPublicKeyToken;
+ BOOL _fCustom;
+ LPWSTR _pwzPathModifier;
+ LPWSTR _pwzTextualIdentity;
+ LPWSTR _pwzTextualIdentityILFull;
+
+ DWORD _dw;
+
+public:
+ // IUnknown methods
+ STDMETHODIMP QueryInterface(REFIID riid,void ** ppv);
+ STDMETHODIMP_(ULONG) AddRef();
+ STDMETHODIMP_(ULONG) Release();
+
+ // IAssemblyName methods
+ STDMETHOD(SetProperty)(
+ /* in */ DWORD PropertyId,
+ /* in */ LPCVOID pvProperty,
+ /* in */ DWORD cbProperty);
+
+ STDMETHOD(GetProperty)(
+ /* in */ DWORD PropertyId,
+ /* out */ LPVOID pvProperty,
+ /* in out */ LPDWORD pcbProperty);
+
+ STDMETHOD(Finalize)();
+
+ STDMETHOD(GetDisplayName)(
+ __out_ecount_opt(*pccDisplayName) LPOLESTR szDisplayName,
+ __inout LPDWORD pccDisplayName,
+ __in DWORD dwDisplayFlags);
+
+ STDMETHOD(GetName)(
+ __inout LPDWORD lpcwBuffer,
+ __out_ecount_opt(*lpcwBuffer) LPOLESTR pwzBuffer);
+
+ STDMETHOD(GetVersion)(
+ /* [out] */ LPDWORD pwVersionHi,
+ /* [out] */ LPDWORD pwVersionLow);
+
+ STDMETHOD (IsEqual)(
+ /* [in] */ LPASSEMBLYNAME pName,
+ /* [in] */ DWORD dwCmpFlags);
+
+ STDMETHOD(Reserved)(
+ /* in */ REFIID refIID,
+ /* in */ IUnknown *pUnkBindSink,
+ /* in */ IUnknown *pUnkAppCtx,
+ /* in */ LPCOLESTR szCodebase,
+ /* in */ LONGLONG llFlags,
+ /* in */ LPVOID pvReserved,
+ /* in */ DWORD cbReserved,
+ /* out */ VOID **ppv);
+
+ STDMETHODIMP Clone(IAssemblyName **ppName);
+
+ HRESULT SetPropertyInternal(/* in */ DWORD PropertyId,
+ /* in */ LPCVOID pvProperty,
+ /* in */ DWORD cbProperty);
+
+ CAssemblyName();
+ virtual ~CAssemblyName();
+
+ HRESULT Init(LPCTSTR pszAssemblyName, ASSEMBLYMETADATA *pamd);
+ HRESULT Parse(LPCWSTR szDisplayName);
+
+ static BOOL IsStronglyNamed(IAssemblyName *pName);
+ static BOOL IsPartial(IAssemblyName *pName,
+ LPDWORD pdwCmpMask = NULL);
+
+protected:
+ HRESULT GetVersion(DWORD dwMajorVersionEnumValue,
+ LPDWORD pwVersionHi,
+ LPDWORD pwVersionLow);
+
+ HRESULT CopyProperties(CAssemblyName *pSource,
+ CAssemblyName *pTarget,
+ const DWORD properties[],
+ DWORD dwSize);
+};
+
+STDAPI
+CreateAssemblyNameObject(
+ LPASSEMBLYNAME *ppAssemblyName,
+ LPCOLESTR szAssemblyName,
+ DWORD dwFlags,
+ LPVOID pvReserved);
+
+STDAPI
+CreateAssemblyNameObjectFromMetaData(
+ LPASSEMBLYNAME *ppAssemblyName,
+ LPCOLESTR szAssemblyName,
+ ASSEMBLYMETADATA *pamd,
+ LPVOID pvReserved);
+
+namespace LegacyFusion
+{
+ HRESULT SetStringProperty(IAssemblyName *pIAssemblyName,
+ DWORD dwPropertyId,
+ SString &value);
+ HRESULT SetBufferProperty(IAssemblyName *pIAssemblyName,
+ DWORD dwPropertyId,
+ SBuffer &value);
+ HRESULT SetWordProperty(IAssemblyName *pIAssemblyName,
+ DWORD dwPropertyId,
+ DWORD dwValue);
+ HRESULT SetDwordProperty(IAssemblyName *pIAssemblyName,
+ DWORD dwPropertyId,
+ DWORD dwValue);
+};
+
+namespace fusion
+{
+ namespace util
+ {
+ // Fills the provided buffer with the contents of the property. pcbBuf is
+ // set to be either the required buffer space when insufficient buffer is
+ // provided, or the number of bytes written.
+ //
+ // Returns S_FALSE if the property has not been set, regardless of the values of pBuf and pcbBuf.
+ HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, PVOID pBuf, DWORD *pcbBuf);
+
+ // Fills the provided buffer with the contents of the property. If no buffer is provided
+ // (*ppBuf == nullptr), then a buffer is allocated for the caller and ppBuf is set to point
+ // at the allocated buffer on return. pcbBuf is set to be either the required buffer space
+ // when insufficient buffer is provided, or the number of bytes written.
+ //
+ // Returns S_FALSE if the property has not been set, regardless of the values of pBuf and pcbBuf.
+ HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, PBYTE * ppBuf, DWORD *pcbBuf);
+
+ // Fills the provided SString with the contents of the property.
+ //
+ // Returns S_FALSE if the property has not been set.
+ HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, SString & ssVal);
+
+ // Returns an allocated buffer with the contents of the property.
+ //
+ // Returns S_FALSE if the property has not been set.
+ HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, __deref_out LPWSTR * pwzVal);
+
+ inline HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, LPCWSTR *pwzOut)
+ { return GetProperty(pName, dwProperty, const_cast<LPWSTR*>(pwzOut)); }
+
+ // Returns an allocated buffer with the contents of the property.
+ //
+ // Returns S_FALSE if the property has not been set.
+ HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, __deref_out LPSTR *pwzOut);
+
+ inline HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, LPCSTR *pwzOut)
+ { return GetProperty(pName, dwProperty, const_cast<LPSTR*>(pwzOut)); }
+
+ template <typename T> inline
+ typename std::enable_if<!std::is_pointer< typename std::remove_cv< T >::type >::value, HRESULT>::type
+ GetProperty(IAssemblyName * pName, DWORD dwProperty, T * pVal)
+ {
+ DWORD cbBuf = sizeof(T);
+ HRESULT hr = GetProperty(pName, dwProperty, pVal, &cbBuf);
+ if (hr == S_OK && cbBuf != sizeof(T))
+ hr = E_UNEXPECTED;
+ return hr;
+ }
+
+ inline HRESULT GetSimpleName(IAssemblyName * pName, SString & ssName)
+ { return GetProperty(pName, ASM_NAME_NAME, ssName); }
+ } // namespace fusion.util
+} // namespace fusion
+
+
+#endif
diff --git a/src/binder/inc/fusionhelpers.hpp b/src/binder/inc/fusionhelpers.hpp
new file mode 100644
index 0000000000..229ebe6c4e
--- /dev/null
+++ b/src/binder/inc/fusionhelpers.hpp
@@ -0,0 +1,95 @@
+// 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.
+// ============================================================
+//
+// FusionHelpers.hpp
+//
+// Defines various legacy fusion types
+//
+// ============================================================
+
+#ifndef __FUSION_HELPERS_HPP__
+#define __FUSION_HELPERS_HPP__
+
+#include "clrtypes.h"
+#include "sstring.h"
+
+#include "clrhost.h"
+#include "shlwapi.h"
+#include "winwrap.h"
+#include "ex.h"
+#include "fusion.h"
+
+#ifndef FEATURE_VERSIONING
+// Rename the fusion bind result to avoid collision with core bind result
+#define IBindResult IBindResult_Fusion
+#include "binderngen.h"
+#undef IBindResult
+#endif
+
+#include "peinformation.h"
+
+#define FUSION_NEW_SINGLETON(_type) new (nothrow) _type
+#define FUSION_NEW_ARRAY(_type, _n) new (nothrow) _type[_n]
+#define FUSION_DELETE_ARRAY(_ptr) if((_ptr)) delete [] (_ptr)
+#define FUSION_DELETE_SINGLETON(_ptr) if((_ptr)) delete (_ptr)
+
+#define SAFEDELETE(p) if ((p) != NULL) { FUSION_DELETE_SINGLETON((p)); (p) = NULL; };
+#define SAFEDELETEARRAY(p) if ((p) != NULL) { FUSION_DELETE_ARRAY((p)); (p) = NULL; };
+#define SAFERELEASE(p) if ((p) != NULL) { (p)->Release(); (p) = NULL; };
+
+#ifndef NEW
+#define NEW(_type) FUSION_NEW_SINGLETON(_type)
+#endif // !NEW
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif // !ARRAYSIZE
+
+#define MAX_VERSION_DISPLAY_SIZE sizeof("65535.65535.65535.65535")
+
+#define ASM_DISPLAYF_DEFAULT (ASM_DISPLAYF_VERSION \
+ |ASM_DISPLAYF_CULTURE \
+ |ASM_DISPLAYF_PUBLIC_KEY_TOKEN \
+ |ASM_DISPLAYF_RETARGET)
+
+#define SIGNATURE_BLOB_LENGTH 0x80
+#define SIGNATURE_BLOB_LENGTH_HASH 0x14
+#define MVID_LENGTH sizeof(GUID)
+
+#define PUBLIC_KEY_TOKEN_LEN 8
+
+inline
+WCHAR*
+WSTRDupDynamic(LPCWSTR pwszSrc)
+{
+ LPWSTR pwszDest = NULL;
+ if (pwszSrc != NULL)
+ {
+ const size_t dwLen = wcslen(pwszSrc) + 1;
+ pwszDest = FUSION_NEW_ARRAY(WCHAR, dwLen);
+
+ if( pwszDest )
+ memcpy(pwszDest, pwszSrc, dwLen * sizeof(WCHAR));
+ }
+
+ return pwszDest;
+}
+
+#define MAX_URL_LENGTH 2084 // same as INTERNET_MAX_URL_LENGTH
+
+// bit mask macro helpers
+#define MAX_ID_FROM_MASK(size) ((size) << 3)
+#define MASK_SIZE_FROM_ID(id) ((id) >> 3)
+#define IS_IN_RANGE(id, size) ((id) <= ((size) << 3))
+#define IS_BIT_SET(id, mask) (mask[((id)-1)>>3] & (0x1 << (((id)-1)&0x7)))
+#define SET_BIT(id, mask) (mask[((id)-1)>>3] |= (0x1<< (((id)-1)&0x7)))
+#define UNSET_BIT(id, mask) (mask[((id)-1)>>3] &= (0xFF - (0x1<<(((id)-1)&0x7))))
+
+int FusionCompareStringI(LPCWSTR pwz1, LPCWSTR pwz2);
+
+// CLR lobal culture ID
+extern LocaleID g_lcid;
+
+#endif
diff --git a/src/binder/inc/list.hpp b/src/binder/inc/list.hpp
new file mode 100644
index 0000000000..91ecd1752b
--- /dev/null
+++ b/src/binder/inc/list.hpp
@@ -0,0 +1,358 @@
+// 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.
+// ============================================================
+//
+// List.hpp
+//
+
+
+//
+// Defines the List class
+//
+// ============================================================
+
+#ifndef __BINDER__LIST_HPP__
+#define __BINDER__LIST_HPP__
+
+#include "bindertypes.hpp"
+#include "ex.h"
+
+namespace BINDER_SPACE
+{
+ // Ripped from Fusion
+
+ //
+ // ListNode
+ //
+
+ typedef void *LISTNODE;
+
+ template <class Type> class ListNode
+ {
+ public:
+ ListNode(Type item);
+ virtual ~ListNode();
+
+ void SetNext(ListNode *pNode);
+ void SetPrev(ListNode *pNode);
+ Type GetItem();
+ ListNode *GetNext();
+ ListNode *GetPrev();
+
+ private:
+ Type _type;
+ ListNode *_pNext;
+ ListNode *_pPrev;
+ };
+
+ //
+ // List
+ //
+
+ template <class Type> class List
+ {
+ public:
+ List();
+ ~List();
+
+ LISTNODE AddHead(const Type &item);
+ LISTNODE AddTail(const Type &item);
+
+ LISTNODE GetHeadPosition();
+ LISTNODE GetTailPosition();
+ void RemoveAt(LISTNODE pNode);
+ void RemoveAll();
+ LISTNODE Find(const Type &item);
+ int GetCount();
+ Type GetNext(LISTNODE &pNode);
+ Type GetAt(LISTNODE pNode);
+ LISTNODE AddSorted(const Type &item, LPVOID pfn);
+
+ public:
+ DWORD _dwSig;
+
+ private:
+ ListNode<Type> *_pHead;
+ ListNode<Type> *_pTail;
+ int _iCount;
+ };
+
+ //
+ // ListNode Implementation
+ //
+
+ template <class Type> ListNode<Type>::ListNode(Type item)
+ : _type(item)
+ , _pNext(NULL)
+ , _pPrev(NULL)
+ {
+ }
+
+ template <class Type> ListNode<Type>::~ListNode()
+ {
+ }
+
+ template <class Type> void ListNode<Type>::SetNext(ListNode *pNode)
+ {
+ _pNext = pNode;
+ }
+
+ template <class Type> void ListNode<Type>::SetPrev(ListNode *pNode)
+ {
+ _pPrev = pNode;
+ }
+
+ template <class Type> Type ListNode<Type>::GetItem()
+ {
+ return _type;
+ }
+
+ template <class Type> ListNode<Type> *ListNode<Type>::GetNext()
+ {
+ return _pNext;
+ }
+
+ template <class Type> ListNode<Type> *ListNode<Type>::GetPrev()
+ {
+ return _pPrev;
+ }
+
+
+ //
+ // List Implementation
+ //
+
+ template <class Type> List<Type>::List()
+ : _pHead(NULL)
+ , _pTail(NULL)
+ , _iCount(0)
+ {
+ _dwSig = 0x5453494c; /* 'TSIL' */
+ }
+
+ template <class Type> List<Type>::~List()
+ {
+ HRESULT hr = S_OK;
+
+ EX_TRY
+ {
+ RemoveAll();
+ }
+ EX_CATCH_HRESULT(hr);
+ }
+
+ template <class Type> LISTNODE List<Type>::AddHead(const Type &item)
+ {
+ ListNode<Type> *pNode = NULL;
+
+ NEW_CONSTR(pNode, ListNode<Type>(item));
+ if (pNode) {
+ _iCount++;
+ pNode->SetNext(_pHead);
+ pNode->SetPrev(NULL);
+ if (_pHead == NULL) {
+ _pTail = pNode;
+ }
+ else {
+ _pHead->SetPrev(pNode);
+ }
+ _pHead = pNode;
+ }
+
+ return (LISTNODE)pNode;
+ }
+
+ template <class Type> LISTNODE List<Type>::AddSorted(const Type &item,
+ LPVOID pfn)
+ {
+ ListNode<Type> *pNode = NULL;
+ LISTNODE pCurrNode = NULL;
+ LISTNODE pPrevNode = NULL;
+ int i;
+ Type curItem;
+
+ LONG (*pFN) (const Type item1, const Type item2);
+
+ pFN = (LONG (*) (const Type item1, const Type item2))pfn;
+
+ if(_pHead == NULL) {
+ return AddHead(item);
+ }
+ else {
+ pCurrNode = GetHeadPosition();
+ curItem = ((ListNode<Type> *) pCurrNode)->GetItem();
+ for (i = 0; i < _iCount; i++) {
+ if (pFN(item, curItem) < 1) {
+ NEW_CONSTR(pNode, ListNode<Type>(item));
+ if (pNode) {
+ pNode->SetPrev((ListNode<Type> *)pPrevNode);
+ pNode->SetNext((ListNode<Type> *)pCurrNode);
+ // update pPrevNode
+ if(pPrevNode) {
+ ((ListNode<Type> *)pPrevNode)->SetNext(pNode);
+ }
+ else {
+ _pHead = pNode;
+ }
+ // update pCurrNode
+ ((ListNode<Type> *)pCurrNode)->SetPrev(pNode);
+ _iCount++;
+ }
+ break;
+ }
+ pPrevNode = pCurrNode;
+ GetNext(pCurrNode);
+ if(i+1 == _iCount) {
+ return AddTail(item);
+ }
+ else {
+ _ASSERTE(pCurrNode);
+ curItem = GetAt(pCurrNode);
+ }
+ }
+ }
+
+ return (LISTNODE)pNode;
+ }
+
+ template <class Type> LISTNODE List<Type>::AddTail(const Type &item)
+ {
+ ListNode<Type> *pNode = NULL;
+
+ NEW_CONSTR(pNode, ListNode<Type>(item));
+ if (pNode) {
+ _iCount++;
+ if (_pTail) {
+ pNode->SetPrev(_pTail);
+ _pTail->SetNext(pNode);
+ _pTail = pNode;
+ }
+ else {
+ _pHead = _pTail = pNode;
+ }
+ }
+
+ return (LISTNODE)pNode;
+ }
+
+ template <class Type> int List<Type>::GetCount()
+ {
+ return _iCount;
+ }
+
+ template <class Type> LISTNODE List<Type>::GetHeadPosition()
+ {
+ return (LISTNODE)_pHead;
+ }
+
+ template <class Type> LISTNODE List<Type>::GetTailPosition()
+ {
+ return (LISTNODE)_pTail;
+ }
+
+ template <class Type> Type List<Type>::GetNext(LISTNODE &pNode)
+ {
+ ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
+
+ // Faults if you pass NULL
+ _ASSERTE(pNode);
+
+ Type item = pListNode->GetItem();
+ pNode = (LISTNODE)(pListNode->GetNext());
+
+ return item;
+ }
+
+ template <class Type> void List<Type>::RemoveAll()
+ {
+ int i;
+ LISTNODE listNode = NULL;
+ ListNode<Type> *pDelNode = NULL;
+
+ listNode = GetHeadPosition();
+
+ for (i = 0; i < _iCount; i++) {
+ pDelNode = (ListNode<Type> *)listNode;
+ GetNext(listNode);
+ SAFE_DELETE(pDelNode);
+ }
+
+ _iCount = 0;
+ _pHead = NULL;
+ _pTail = NULL;
+ }
+
+ template <class Type> void List<Type>::RemoveAt(LISTNODE pNode)
+ {
+ ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
+ ListNode<Type> *pPrevNode = NULL;
+ ListNode<Type> *pNextNode = NULL;
+
+ if (pNode) {
+ pPrevNode = pListNode->GetPrev();
+ pNextNode = pListNode->GetNext();
+
+ if (pPrevNode) {
+ pPrevNode->SetNext(pNextNode);
+ if (pNextNode) {
+ pNextNode->SetPrev(pPrevNode);
+ }
+ else {
+ // We're removing the last node, so we have a new tail
+ _pTail = pPrevNode;
+ }
+ SAFE_DELETE(pListNode);
+ }
+ else {
+ // No previous, so we are the head of the list
+ _pHead = pNextNode;
+ if (pNextNode) {
+ pNextNode->SetPrev(NULL);
+ }
+ else {
+ // No previous, or next. There was only one node.
+ _pHead = NULL;
+ _pTail = NULL;
+ }
+ SAFE_DELETE(pListNode);
+ }
+
+ _iCount--;
+ }
+ }
+
+
+ template <class Type> LISTNODE List<Type>::Find(const Type &item)
+ {
+ int i;
+ Type curItem;
+ LISTNODE pNode = NULL;
+ LISTNODE pMatchNode = NULL;
+ ListNode<Type> * pListNode = NULL;
+
+ pNode = GetHeadPosition();
+ for (i = 0; i < _iCount; i++) {
+ pListNode = (ListNode<Type> *)pNode;
+ curItem = GetNext(pNode);
+ if (curItem == item) {
+ pMatchNode = (LISTNODE)pListNode;
+ break;
+ }
+ }
+
+ return pMatchNode;
+ }
+
+ template <class Type> Type List<Type>::GetAt(LISTNODE pNode)
+ {
+ ListNode<Type> *pListNode = (ListNode<Type> *)pNode;
+
+ // Faults if you pass NULL
+ _ASSERTE(pNode);
+
+ return pListNode->GetItem();
+ }
+};
+
+#endif
diff --git a/src/binder/inc/loadcontext.hpp b/src/binder/inc/loadcontext.hpp
new file mode 100644
index 0000000000..5a403a7542
--- /dev/null
+++ b/src/binder/inc/loadcontext.hpp
@@ -0,0 +1,49 @@
+// 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.
+// ============================================================
+//
+// LoadContext.hpp
+//
+
+
+//
+// Defines the LoadContext template class
+//
+// ============================================================
+
+#ifndef __BINDER__LOAD_CONTEXT_HPP__
+#define __BINDER__LOAD_CONTEXT_HPP__
+
+#include "assemblyhashtraits.hpp"
+#include "contextentry.hpp"
+#include "bindresult.hpp"
+
+namespace BINDER_SPACE
+{
+ template <DWORD dwIncludeFlags>
+ class LoadContext : protected SHash<AssemblyHashTraits<ContextEntry *, dwIncludeFlags> >
+ {
+ private:
+ typedef SHash<AssemblyHashTraits<ContextEntry *, dwIncludeFlags> > Hash;
+ public:
+ LoadContext();
+ ~LoadContext();
+
+ ULONG AddRef();
+ ULONG Release();
+ ContextEntry *Lookup(/* in */ AssemblyName *pAssemblyName);
+ HRESULT Register(BindResult *pBindResult);
+
+ protected:
+ LONG m_cRef;
+ };
+
+#include "loadcontext.inl"
+
+ class InspectionContext :
+ public LoadContext<AssemblyName::INCLUDE_VERSION | AssemblyName::INCLUDE_ARCHITECTURE> {};
+ class ExecutionContext : public LoadContext<AssemblyName::INCLUDE_DEFAULT> {};
+};
+
+#endif
diff --git a/src/binder/inc/loadcontext.inl b/src/binder/inc/loadcontext.inl
new file mode 100644
index 0000000000..c584f8d6ef
--- /dev/null
+++ b/src/binder/inc/loadcontext.inl
@@ -0,0 +1,90 @@
+// 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.
+// ============================================================
+//
+// LoadContext.inl
+//
+
+
+//
+// Implements the inlined methods of LoadContext template class
+//
+// ============================================================
+
+#ifndef __BINDER__LOAD_CONTEXT_INL__
+#define __BINDER__LOAD_CONTEXT_INL__
+
+template <DWORD dwIncludeFlags>
+LoadContext<dwIncludeFlags>::LoadContext() :
+ SHash<AssemblyHashTraits<ContextEntry *, dwIncludeFlags> >::SHash()
+{
+ m_cRef = 1;
+}
+
+template <DWORD dwIncludeFlags>
+LoadContext<dwIncludeFlags>::~LoadContext()
+{
+ // Delete context entries and contents array
+ for (typename Hash::Iterator i = Hash::Begin(), end = Hash::End(); i != end; i++)
+ {
+ const ContextEntry *pContextEntry = *i;
+ delete pContextEntry;
+ }
+ this->RemoveAll();
+}
+
+template <DWORD dwIncludeFlags>
+ULONG LoadContext<dwIncludeFlags>::AddRef()
+{
+ return InterlockedIncrement(&m_cRef);
+}
+
+template <DWORD dwIncludeFlags>
+ULONG LoadContext<dwIncludeFlags>::Release()
+{
+ ULONG ulRef = InterlockedDecrement(&m_cRef);
+
+ if (ulRef == 0)
+ {
+ delete this;
+ }
+
+ return ulRef;
+}
+
+template <DWORD dwIncludeFlags>
+ContextEntry *LoadContext<dwIncludeFlags>::Lookup(AssemblyName *pAssemblyName)
+{
+ ContextEntry *pContextEntry =
+ SHash<AssemblyHashTraits<ContextEntry *, dwIncludeFlags> >::Lookup(pAssemblyName);
+
+ return pContextEntry;
+}
+
+template <DWORD dwIncludeFlags>
+HRESULT LoadContext<dwIncludeFlags>::Register(BindResult *pBindResult)
+{
+ HRESULT hr = S_OK;
+ ContextEntry *pContextEntry = NULL;
+
+ SAFE_NEW(pContextEntry, ContextEntry);
+
+ pContextEntry->SetIsDynamicBind(pBindResult->GetIsDynamicBind());
+ pContextEntry->SetIsInGAC(pBindResult->GetIsInGAC());
+ pContextEntry->SetIsSharable(pBindResult->GetIsSharable());
+ pContextEntry->SetAssemblyName(pBindResult->GetAssemblyName(), TRUE /* fAddRef */);
+ pContextEntry->SetAssembly(pBindResult->GetAssembly());
+
+ if (pBindResult->GetIsFirstRequest())
+ {
+ pContextEntry->SetIsFirstRequest(TRUE);
+ }
+
+ SHash<AssemblyHashTraits<ContextEntry *, dwIncludeFlags> >::Add(pContextEntry);
+
+ Exit:
+ return hr;
+}
+
+#endif
diff --git a/src/binder/inc/propertyhashtraits.hpp b/src/binder/inc/propertyhashtraits.hpp
new file mode 100644
index 0000000000..c35d5f0dfe
--- /dev/null
+++ b/src/binder/inc/propertyhashtraits.hpp
@@ -0,0 +1,95 @@
+// 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.
+// ============================================================
+//
+// PropertyMap.hpp
+//
+
+
+//
+// Defines the PropertyMap class
+//
+// ============================================================
+
+#ifndef __BINDER__PROPERTY_HASH_TRAITS_HPP__
+#define __BINDER__PROPERTY_HASH_TRAITS_HPP__
+
+#include "bindertypes.hpp"
+#include "sstring.h"
+#include "shash.h"
+
+namespace BINDER_SPACE
+{
+ class PropertyEntry
+ {
+ public:
+ inline PropertyEntry()
+ {
+ m_pPropertyName = NULL;
+ m_pPropertyValue = NULL;
+ }
+ inline ~PropertyEntry()
+ {
+ SAFE_DELETE(m_pPropertyName);
+ SAFE_DELETE(m_pPropertyValue);
+ }
+
+ // Getters/Setters
+ inline SString *GetPropertyName()
+ {
+ return m_pPropertyName;
+ }
+ inline void SetPropertyName(SString *pPropertyName)
+ {
+ SAFE_DELETE(m_pPropertyName);
+ m_pPropertyName = pPropertyName;
+ }
+ inline SBuffer *GetPropertyValue()
+ {
+ return m_pPropertyValue;
+ }
+ inline void SetPropertyValue(SBuffer *pPropertyValue)
+ {
+ SAFE_DELETE(m_pPropertyValue);
+ m_pPropertyValue = pPropertyValue;
+ }
+
+ protected:
+ SString *m_pPropertyName;
+ SBuffer *m_pPropertyValue;
+ };
+
+ class PropertyHashTraits : public DefaultSHashTraits<PropertyEntry *>
+ {
+ public:
+ typedef SString* key_t;
+
+ // GetKey, Equals, and Hash can throw due to SString
+ static const bool s_NoThrow = false;
+
+ static key_t GetKey(element_t pPropertyEntry)
+ {
+ return pPropertyEntry->GetPropertyName();
+ }
+ static BOOL Equals(key_t pPropertyName1, key_t pPropertyName2)
+ {
+ return pPropertyName1->Equals(*pPropertyName2);
+ }
+ static count_t Hash(key_t pPropertyName)
+ {
+ return pPropertyName->Hash();
+ }
+ static const element_t Null()
+ {
+ return NULL;
+ }
+ static bool IsNull(const element_t &propertyEntry)
+ {
+ return (propertyEntry == NULL);
+ }
+
+ };
+};
+
+#endif
diff --git a/src/binder/inc/propertymap.hpp b/src/binder/inc/propertymap.hpp
new file mode 100644
index 0000000000..38a8890dcc
--- /dev/null
+++ b/src/binder/inc/propertymap.hpp
@@ -0,0 +1,35 @@
+// 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.
+// ============================================================
+//
+// PropertyMap.hpp
+//
+
+
+//
+// Defines the PropertyMap class
+//
+// ============================================================
+
+
+#ifndef __BINDER__PROPERTY_MAP_HPP__
+#define __BINDER__PROPERTY_MAP_HPP__
+
+#include "propertyhashtraits.hpp"
+
+namespace BINDER_SPACE
+{
+ class PropertyMap : protected SHash<PropertyHashTraits>
+ {
+ public:
+ PropertyMap();
+ ~PropertyMap();
+
+ HRESULT Add(/* in */ SString *pPropertyName,
+ /* in */ SBuffer *pPropertyValue);
+ SBuffer *Lookup(/* in */ SString *pPropertyName);
+ };
+};
+
+#endif
diff --git a/src/binder/inc/stringlexer.hpp b/src/binder/inc/stringlexer.hpp
new file mode 100644
index 0000000000..257b883c51
--- /dev/null
+++ b/src/binder/inc/stringlexer.hpp
@@ -0,0 +1,100 @@
+// 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.
+// ============================================================
+//
+// StringLexer.hpp
+//
+
+
+//
+// Defines the StringLexer class
+//
+// ============================================================
+
+#ifndef __BINDER__STRING_LEXER_HPP__
+#define __BINDER__STRING_LEXER_HPP__
+
+#include "bindertypes.hpp"
+
+#define GO_IF_NOT_EXPECTED(expr, kRequiredLexemeType) \
+ if ((expr) != kRequiredLexemeType) \
+ { \
+ fIsValid = FALSE; \
+ goto Exit; \
+ }
+
+#define GO_IF_END_OR_NOT_EXPECTED(expr, kRequiredLexemeType) \
+ { \
+ LEXEME_TYPE kGotLexemeType = (expr); \
+ if (kGotLexemeType == LEXEME_TYPE_END_OF_STREAM) \
+ { \
+ goto Exit; \
+ } \
+ else \
+ { \
+ GO_IF_NOT_EXPECTED(kGotLexemeType, kRequiredLexemeType); \
+ } \
+ }
+
+namespace BINDER_SPACE
+{
+ class StringLexer
+ {
+ public:
+ typedef enum
+ {
+ LEXEME_TYPE_INVALID,
+ LEXEME_TYPE_EQUALS,
+ LEXEME_TYPE_COMMA,
+ LEXEME_TYPE_COLON,
+ LEXEME_TYPE_SEMICOLON,
+ LEXEME_TYPE_STRING,
+ LEXEME_TYPE_END_OF_STREAM
+ } LEXEME_TYPE;
+
+ inline StringLexer();
+ inline ~StringLexer();
+
+ inline void Init(SString &inputString, BOOL fSupportEscaping);
+
+ static inline BOOL IsWhitespace(WCHAR wcChar);
+ static inline BOOL IsEOS(WCHAR wcChar);
+ static inline BOOL IsQuoteCharacter(WCHAR wcChar);
+
+ virtual BOOL IsSeparatorChar(WCHAR wcChar) = NULL;
+ virtual LEXEME_TYPE GetLexemeType(WCHAR wcChar) = NULL;
+
+ protected:
+ static const WCHAR INVALID_CHARACTER = -1;
+
+ LEXEME_TYPE GetNextLexeme(SString &currentString, BOOL fPermitUnescapedQuotes = FALSE);
+
+ inline WCHAR PopCharacter(BOOL *pfIsEscaped);
+ inline void PushCharacter(WCHAR wcCurrentChar,
+ BOOL fIsEscaped);
+
+ inline WCHAR GetRawCharacter();
+ inline void PushRawCharacter();
+ inline WCHAR DecodeUTF16Character();
+ inline WCHAR GetNextCharacter(BOOL *pfIsEscaped);
+
+ inline WCHAR ParseUnicode();
+ LEXEME_TYPE ParseString(SString &currentString,
+ BOOL fPermitUnescapeQuotes);
+
+ void TrimTrailingWhiteSpaces(SString &currentString);
+
+ SString::Iterator m_cursor;
+ SString::Iterator m_end;
+
+ WCHAR m_wcCurrentChar;
+ BOOL m_fCurrentCharIsEscaped;
+ BOOL m_fSupportEscaping;
+ BOOL m_fReadRawCharacter;
+ };
+
+#include "stringlexer.inl"
+};
+
+#endif
diff --git a/src/binder/inc/stringlexer.inl b/src/binder/inc/stringlexer.inl
new file mode 100644
index 0000000000..f8bc3816a4
--- /dev/null
+++ b/src/binder/inc/stringlexer.inl
@@ -0,0 +1,266 @@
+// 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.
+// ============================================================
+//
+// StringLexer.inl
+//
+
+
+//
+// Implements the inlined methods of StringLexer class
+//
+// ============================================================
+
+#ifndef __BINDER__STRING_LEXER_INL__
+#define __BINDER__STRING_LEXER_INL__
+
+StringLexer::StringLexer()
+{
+ m_wcCurrentChar = INVALID_CHARACTER;
+ m_fCurrentCharIsEscaped = FALSE;
+}
+
+StringLexer::~StringLexer()
+{
+ // Nothing to do here
+}
+
+void StringLexer::Init(SString &inputString, BOOL fSupportEscaping)
+{
+ m_cursor = inputString.Begin();
+ m_end = inputString.End();
+ m_fSupportEscaping = fSupportEscaping;
+ m_fReadRawCharacter = FALSE;
+}
+
+BOOL StringLexer::IsWhitespace(WCHAR wcChar)
+{
+ return ((wcChar == L'\n') || (wcChar == L'\r') || (wcChar == L' ') || (wcChar == L'\t'));
+}
+
+BOOL StringLexer::IsEOS(WCHAR wcChar)
+{
+ return (wcChar == 0);
+}
+
+BOOL StringLexer::IsQuoteCharacter(WCHAR wcChar)
+{
+ return ((wcChar == L'\'') || (wcChar == L'"'));
+}
+
+WCHAR StringLexer::PopCharacter(BOOL *pfIsEscaped)
+{
+ WCHAR wcCurrentChar = m_wcCurrentChar;
+ BINDER_LOG_ENTER(L"StringLexer::PopCharacter");
+
+ if (wcCurrentChar != INVALID_CHARACTER)
+ {
+ BINDER_LOG(L"HAVE wcCurrentChar");
+ m_wcCurrentChar = INVALID_CHARACTER;
+ *pfIsEscaped = m_fCurrentCharIsEscaped;
+ }
+ else
+ {
+ BINDER_LOG(L"GET wcCurrentChar");
+ wcCurrentChar = GetNextCharacter(pfIsEscaped);
+ }
+
+#ifdef BINDER_DEBUG_LOG
+ PathString info;
+
+ info.Printf(L"wcCurrentChar=%p", (void *) wcCurrentChar);
+ BINDER_LOG((WCHAR *) info.GetUnicode());
+#endif
+
+ BINDER_LOG_LEAVE(L"StringLexer::PopCharacter");
+ return wcCurrentChar;
+}
+
+void StringLexer::PushCharacter(WCHAR wcCurrentChar,
+ BOOL fIsEscaped)
+{
+ BINDER_LOG_ENTER(L"StringLexer::PushCharacter");
+
+#ifdef BINDER_DEBUG_LOG
+ PathString info;
+
+ info.Printf(L"wcCurrentChar=%p, fIsEscaped=%d", (void *) wcCurrentChar, fIsEscaped);
+ BINDER_LOG((WCHAR *) info.GetUnicode());
+#endif
+
+ _ASSERTE(m_wcCurrentChar == INVALID_CHARACTER);
+
+ m_wcCurrentChar = wcCurrentChar;
+ m_fCurrentCharIsEscaped = fIsEscaped;
+
+ BINDER_LOG_LEAVE(L"StringLexer::PushCharacter");
+}
+
+WCHAR StringLexer::GetRawCharacter()
+{
+ WCHAR wcCurrentChar = 0;
+
+ if (m_cursor <= m_end)
+ {
+ wcCurrentChar = m_cursor[0];
+ m_fReadRawCharacter = TRUE;
+ m_cursor++;
+ }
+ else
+ {
+ m_fReadRawCharacter = FALSE;
+ }
+
+ return wcCurrentChar;
+}
+
+void StringLexer::PushRawCharacter()
+{
+ if (m_fReadRawCharacter)
+ {
+ m_cursor--;
+ m_fReadRawCharacter = FALSE;
+ }
+}
+
+WCHAR StringLexer::DecodeUTF16Character()
+{
+ // See http://www.ietf.org/rfc/rfc2781.txt for details on UTF-16 encoding.
+
+ WCHAR wcCurrentChar = 0;
+ SIZE_T nCharacters = m_end - m_cursor + 1;
+ WCHAR wcChar1 = GetRawCharacter();
+
+ if (wcChar1 < 0xd800)
+ {
+ wcCurrentChar = wcChar1;
+ }
+ else
+ {
+ // StringLexer is not designed to handle UTF-16 characters beyond the Basic Multilingual Plane,
+ // since it stores all characters in 16-bit WCHARs.
+ // However, since the vast majority of the time, we (Microsoft) produce the manifests,
+ // this is likely a non-scenario, as the other Unicode planes would never be used in practice.
+
+ if (wcChar1 <= 0xdbff) // 0xd800 - 0xdbff indicates the first WCHAR of a surrogate pair
+ {
+ if (nCharacters >= 2)
+ {
+ GetRawCharacter(); // Skip the second WCHAR of the surrogate pair
+ }
+ }
+ // Otherwise, the character is either in the 0xdc00 - 0xdfff range, indicating the second WCHAR of a surrogate pair,
+ // or in the 0xE000 - 0xFFFF range, which has within it ranges of invalid characters, and which we conservatively treat
+ // as invalid.
+
+ wcCurrentChar = INVALID_CHARACTER;
+ }
+
+ return wcCurrentChar;
+}
+
+
+WCHAR StringLexer::GetNextCharacter(BOOL *pfIsEscaped)
+{
+ *pfIsEscaped = FALSE;
+
+ WCHAR wcCurrentChar = GetRawCharacter(); // DecodeUTF16Character()
+ if (wcCurrentChar == L'\\')
+ {
+ WCHAR wcTempChar = GetRawCharacter(); // DecodeUTF16Character()
+
+ if (m_fSupportEscaping)
+ {
+ // Handle standard escapes
+ switch (wcTempChar)
+ {
+ case L'"':
+ case L'\'':
+ case L',':
+ case L'\\':
+ case L'/':
+ case L'=':
+ break;
+ case L't':
+ wcTempChar = 9;
+ break;
+ case L'n':
+ wcTempChar = 10;
+ break;
+ case L'r':
+ wcTempChar = 13;
+ break;
+ case L'u':
+ wcTempChar = ParseUnicode();
+ break;
+ default:
+ return INVALID_CHARACTER;
+ }
+
+ *pfIsEscaped = TRUE;
+ wcCurrentChar = wcTempChar;
+ }
+ else
+ {
+ // Do not handle escapes except for quotes
+ switch (wcTempChar)
+ {
+ case L'"':
+ case L'\'':
+ *pfIsEscaped = TRUE;
+ wcCurrentChar = wcTempChar;
+ break;
+ default:
+ PushRawCharacter();
+ break;
+ }
+ }
+ }
+
+ return wcCurrentChar;
+}
+
+WCHAR StringLexer::ParseUnicode()
+{
+ int nCharacters = 0;
+ WCHAR wcUnicodeChar = 0;
+
+ for(;;)
+ {
+ WCHAR wcCurrentChar = DecodeUTF16Character();
+ nCharacters++;
+
+ if (wcCurrentChar == L';')
+ {
+ break;
+ }
+ else if ((wcCurrentChar == INVALID_CHARACTER) || (nCharacters >= 9))
+ {
+ return INVALID_CHARACTER;
+ }
+
+ wcUnicodeChar <<= 4;
+
+ if ((wcCurrentChar >= L'0') && (wcCurrentChar <= L'9'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'0');
+ }
+ else if ((wcCurrentChar >= L'a') && (wcCurrentChar <= L'f'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'a') + 10;
+ }
+ else if ((wcCurrentChar >= L'A') && (wcCurrentChar <= L'F'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'A') + 10;
+ }
+ else
+ {
+ return INVALID_CHARACTER;
+ }
+ }
+
+ return wcUnicodeChar;
+}
+
+#endif
diff --git a/src/binder/inc/textualidentityparser.hpp b/src/binder/inc/textualidentityparser.hpp
new file mode 100644
index 0000000000..02af033cfb
--- /dev/null
+++ b/src/binder/inc/textualidentityparser.hpp
@@ -0,0 +1,70 @@
+// 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.
+// ============================================================
+//
+// TextualIdentityParser.hpp
+//
+
+
+//
+// Defines the TextualIdentityParser class
+//
+// ============================================================
+
+#ifndef __BINDER__TEXTUAL_IDENTITY_PARSER_HPP__
+#define __BINDER__TEXTUAL_IDENTITY_PARSER_HPP__
+
+#include "bindertypes.hpp"
+#include "stringlexer.hpp"
+
+namespace BINDER_SPACE
+{
+ class AssemblyVersion;
+ class AssemblyIdentity;
+
+ class TextualIdentityParser : public StringLexer
+ {
+ public:
+ TextualIdentityParser(AssemblyIdentity *pAssemblyIdentity);
+ ~TextualIdentityParser();
+
+ virtual BOOL IsSeparatorChar(WCHAR wcChar);
+ virtual StringLexer::LEXEME_TYPE GetLexemeType(WCHAR wcChar);
+
+ static HRESULT Parse(/* in */ SString &textualIdentity,
+ /* out */ AssemblyIdentity *pAssemblyIdentity,
+ /* in */ BOOL fPermitUnescapedQuotes = FALSE);
+ static HRESULT ToString(/* in */ AssemblyIdentity *pAssemblyIdentity,
+ /* in */ DWORD dwIdentityFlags,
+ /* out */ SString &textualIdentity);
+
+ static BOOL ParseVersion(/* in */ SString &versionString,
+ /* out */ AssemblyVersion *pAssemblyVersion);
+
+ static BOOL HexToBlob(/* in */ SString &publicKeyOrToken,
+ /* in */ BOOL fValidateHex,
+ /* in */ BOOL fIsToken,
+ /* out */ SBuffer &publicKeyOrTokenBLOB);
+ static void BlobToHex(/* in */ SBuffer &publicKeyOrTokenBLOB,
+ /* out */ SString &publicKeyOrToken);
+
+ BOOL ParseString(/* in */ SString &textualString,
+ /* out */ SString &contentString);
+
+ protected:
+ BOOL Parse(/* in */ SString &textualIdentity,
+ /* in */ BOOL fPermitUnescapedQuotes = FALSE);
+
+ BOOL PopulateAssemblyIdentity(/* in */ SString &attributeString,
+ /* in */ SString &valueString);
+
+ static void EscapeString(/* in */ SString &input,
+ /* out*/ SString &result);
+
+ AssemblyIdentity *m_pAssemblyIdentity;
+ DWORD m_dwAttributesSeen;
+ };
+};
+
+#endif
diff --git a/src/binder/inc/utils.hpp b/src/binder/inc/utils.hpp
new file mode 100644
index 0000000000..8b65fd8c12
--- /dev/null
+++ b/src/binder/inc/utils.hpp
@@ -0,0 +1,57 @@
+// 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.
+// ============================================================
+//
+// Utils.hpp
+//
+
+
+//
+// Declares a bunch of binder auxilary functions
+//
+// ============================================================
+
+#ifndef __BINDER_UTILS_HPP__
+#define __BINDER_UTILS_HPP__
+
+#include "bindertypes.hpp"
+
+extern LocaleID g_lcid;
+
+namespace BINDER_SPACE
+{
+ inline BOOL EqualsCaseInsensitive(SString &a, SString &b)
+ {
+ return a.EqualsCaseInsensitive(b, g_lcid);
+ }
+
+ inline ULONG HashCaseInsensitive(SString &string)
+ {
+ return string.HashCaseInsensitive(g_lcid);
+ }
+
+ HRESULT FileOrDirectoryExists(PathString &path);
+ HRESULT FileOrDirectoryExistsLog(PathString &path);
+
+ BOOL IsURL(SString &urlOrPath);
+
+ void MutateUrlToPath(SString &urlOrPath);
+ void MutatePathToUrl(SString &pathOrUrl);
+
+ // Mutates path
+ void PlatformPath(SString &path);
+ void CanonicalizePath(SString &path, BOOL fAppendPathSeparator = FALSE);
+
+ // It is safe to use either A or B as CombinedPath.
+ void CombinePath(SString &pathA,
+ SString &pathB,
+ SString &combinedPath);
+
+ HRESULT GetTokenFromPublicKey(SBuffer &publicKeyBLOB,
+ SBuffer &publicKeyTokenBLOB);
+
+ BOOL IsFileNotFound(HRESULT hr);
+};
+
+#endif
diff --git a/src/binder/inc/variables.hpp b/src/binder/inc/variables.hpp
new file mode 100644
index 0000000000..d2cf742a23
--- /dev/null
+++ b/src/binder/inc/variables.hpp
@@ -0,0 +1,66 @@
+// 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.
+// ============================================================
+//
+// Variables.hpp
+//
+
+
+//
+// Defines the Variables class
+//
+// ============================================================
+
+#ifndef __BINDER__VARIABLES_HPP__
+#define __BINDER__VARIABLES_HPP__
+
+#include "bindertypes.hpp"
+
+namespace BINDER_SPACE
+{
+ class Variables
+ {
+ public:
+ Variables();
+ ~Variables();
+
+ HRESULT Init();
+
+ // ApplicationContext string constants
+ SString AppBaseURL;
+ SString DynamicDirectory;
+ SString DynamicBaseDirectory;
+ SString AppName;
+ SString AppConfigFile;
+ SString AppDomainId;
+
+ // AssemblyBinder string constants
+ SString httpURLPrefix;
+
+ // AssemblyName string constants
+ SString architectureMSIL;
+ SString architectureX86;
+ SString architectureAMD64;
+ SString architectureARM;
+ SString architectureARM64;
+ SString cultureNeutral;
+ SString emptyString;
+ SString mscorlib;
+
+#ifdef FEATURE_VERSIONING_LOG
+ BOOL fLoggingNeeded;
+ SString logPath;
+#endif // FEATURE_VERSIONING_LOG
+#ifndef DACCESS_COMPILE
+#ifdef BINDER_DEBUG_LOG
+ CRITSEC_COOKIE m_logCS;
+ HandleHolder m_hDebugLogFile;
+#endif // BINDER_DEBUG_LOG
+#endif
+ };
+
+ extern Variables *g_BinderVariables;
+};
+
+#endif