diff options
Diffstat (limited to 'src/binder/inc')
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 ¤tString, 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 ¤tString, + BOOL fPermitUnescapeQuotes); + + void TrimTrailingWhiteSpaces(SString ¤tString); + + 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 |