interface ICLRPrivAssembly;
typedef DPTR(ICLRPrivAssembly) PTR_ICLRPrivAssembly;
typedef DPTR(ICLRPrivBinder) PTR_ICLRPrivBinder;
-class PEAssembly;
-class AssemblySpec;
//=====================================================================================================================
#define VALIDATE_CONDITION(condition, fail_op) \
//=====================================================================================================================
namespace CLRPrivBinderUtil
{
- //=================================================================================================================
- enum BindFlags
- {
- BF_BindIL = 1,
- BF_BindNI = 2,
- BF_Default = BF_BindIL | BF_BindNI,
- };
-
- //=================================================================================================================
- template <typename ItfT, typename ObjT>
- inline ItfT * ToInterface(
- ObjT * && pObj)
- {
- STATIC_CONTRACT_THROWS;
-
- ItfT * pItf = nullptr;
- IfFailThrow(pObj->QueryInterface(__uuidof(ItfT), (void **)&pItf));
- return pItf;
- }
-
- //=================================================================================================================
- template <typename ItfT, typename ObjT>
- inline ItfT * ToInterface_NoThrow(
- ObjT * && pObj)
- {
- LIMITED_METHOD_CONTRACT;
-
- ItfT * pItf = nullptr;
- if (FAILED(pObj->QueryInterface(__uuidof(ItfT), (void **)&pItf)))
- {
- return nullptr;
- }
- return pItf;
- }
-
- //=====================================================================================================================
-
- //=================================================================================================================
- // Used to create an identity-only ICLRPrivAssembly from an ICLRPrivBinder. This is currently used when
- // creating dynamic assemblies as these use the parent assembly's ICLRPrivBinder object to provide binding
- // functionaltiy.
-
- class CLRPrivBinderAsAssemblyWrapper :
- public IUnknownCommon<ICLRPrivAssembly>
- {
- public:
- //-----------------------------------------------------------------------------------------------------------------
- CLRPrivBinderAsAssemblyWrapper(
- ICLRPrivBinder *pWrapped)
- : _pWrapped(clr::SafeAddRef(pWrapped))
- {
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW(pWrapped);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // Forwards to wrapped binder.
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
- {
- WRAPPER_NO_CONTRACT;
- return _pWrapped->BindAssemblyByName(pAssemblyName, ppAssembly);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // Forwards to wrapped binder.
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId)
- {
- WRAPPER_NO_CONTRACT;
- return _pWrapped->GetBinderID(pBinderId);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // Forwards to wrapped binder.
- STDMETHOD(GetLoaderAllocator)(
- LPVOID * pLoaderAllocator)
- {
- WRAPPER_NO_CONTRACT;
- return _pWrapped->GetLoaderAllocator(pLoaderAllocator);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // ICLRPrivAssembly method is unsupported.
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!");
- VALIDATE_ARG_RET(pbIsShareable);
- *pbIsShareable = FALSE;
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // ICLRPrivAssembly method is unsupported.
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!");
- VALIDATE_ARG_RET(pdwImageTypes);
- *pdwImageTypes = 0;
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- // ICLRPrivAssembly method is unsupported.
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD* pdwImageType,
- ICLRPrivResource ** ppIResource)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!");
- VALIDATE_ARG_RET(pdwImageType);
- *pdwImageType = 0;
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
-
- private:
- ReleaseHolder<ICLRPrivBinder> _pWrapped;
- };
-
- //=================================================================================================================
- // Provides a struct that can be accessed at the QWORD, DWORD, or WORD level, and is structured
-
- struct AssemblyVersion
- {
-#if BIGENDIAN
- union
- {
- UINT64 qwMajorMinorBuildRevision;
- struct
- {
- union
- {
- DWORD dwMajorMinor;
- struct
- {
- WORD wMajor;
- WORD wMinor;
- };
- };
- union
- {
- DWORD dwBuildRevision;
- struct
- {
- WORD wBuild;
- WORD wRevision;
- };
- };
- };
- };
-#else
- union
- {
- UINT64 qwMajorMinorBuildRevision;
- struct
- {
- union
- {
- DWORD dwBuildRevision;
- struct
- {
- WORD wRevision;
- WORD wBuild;
- };
- };
- union
- {
- DWORD dwMajorMinor;
- struct
- {
- WORD wMinor;
- WORD wMajor;
- };
- };
- };
- };
-#endif
-
- // Default value is 0.0.0.0
- AssemblyVersion()
- : qwMajorMinorBuildRevision(static_cast<UINT64>(0))
- { LIMITED_METHOD_CONTRACT; }
-
- // Copy constructor
- AssemblyVersion(AssemblyVersion const & other)
- : qwMajorMinorBuildRevision(other.qwMajorMinorBuildRevision)
- { LIMITED_METHOD_CONTRACT; }
-
- // Initialize version using an IAssemblyName object.
- HRESULT Initialize(IAssemblyName * pName);
-
- // Initialize version using an ICLRPrivAssemblyInfo object.
- HRESULT Initialize(ICLRPrivAssemblyInfo * pInfo);
-
- // Relative ordering of versions.
- static inline int Compare(
- AssemblyVersion const & left,
- AssemblyVersion const & right)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (left.qwMajorMinorBuildRevision < right.qwMajorMinorBuildRevision)
- return -1;
- else if (left.qwMajorMinorBuildRevision == right.qwMajorMinorBuildRevision)
- return 0;
- else
- return 1;
- }
- }; // struct AssemblyVersion
-
- inline bool operator ==(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision == rhs.qwMajorMinorBuildRevision; }
-
- inline bool operator !=(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision != rhs.qwMajorMinorBuildRevision; }
-
- inline bool operator <(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision < rhs.qwMajorMinorBuildRevision; }
-
- inline bool operator <=(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision <= rhs.qwMajorMinorBuildRevision; }
-
- inline bool operator >(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision > rhs.qwMajorMinorBuildRevision; }
-
- inline bool operator >=(AssemblyVersion const & lhs, AssemblyVersion const & rhs)
- { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision >= rhs.qwMajorMinorBuildRevision; }
-
- //=================================================================================================================
- // Encapsulates PublicKey value, can be initialized using a variety of data sources.
-
- struct PublicKey
- {
- // Defaults to empty value.
- PublicKey()
- : m_key(nullptr)
- , m_key_owned(false)
- , m_size((DWORD)-1)
- { LIMITED_METHOD_CONTRACT; }
-
- // Construct directly from existing public key data.
- PublicKey(PBYTE pbKey, DWORD cbKey)
- : m_key(pbKey)
- , m_key_owned(false)
- , m_size(cbKey)
- { LIMITED_METHOD_CONTRACT; }
-
- ~PublicKey()
- { WRAPPER_NO_CONTRACT; Uninitialize(); }
-
- // Frees any public key data and resets to default value.
- void Uninitialize()
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_key_owned)
- {
- delete [] m_key;
- m_key_owned = false;
- }
- m_key = nullptr;
- m_size = 0;
- }
-
- // Initialize PK data form an ICLRPrivAssemblyInfo object.
- HRESULT Initialize(ICLRPrivAssemblyInfo * pAssemblyInfo);
-
- // Returns PK data pointer.
- inline BYTE const * GetKey() const
- { LIMITED_METHOD_CONTRACT; return m_key; }
-
- // Returns size in bytes of the PK data.
- inline DWORD GetSize() const
- { LIMITED_METHOD_CONTRACT; return m_size; }
-
- private:
- PBYTE m_key;
- bool m_key_owned;
- DWORD m_size;
- };
-
- //=================================================================================================================
- // Encapsulates PublicKeyToken value, can be initialized using a variety of data sources.
- //
- // Constraints: assumes that non-empty PKT data will always be 8 bytes long.
- //
-
- struct PublicKeyToken
- {
- PublicKeyToken()
- : m_cbKeyToken(0)
- { LIMITED_METHOD_CONTRACT; ZeroMemory(&m_rbKeyToken, sizeof(m_rbKeyToken)); }
-
- PublicKeyToken(PublicKeyToken const & other)
- : m_cbKeyToken(other.m_cbKeyToken)
- { LIMITED_METHOD_CONTRACT; CopyMemory(m_rbKeyToken, other.m_rbKeyToken, sizeof(m_rbKeyToken)); }
-
- // Initialize directly from PKT data.
- HRESULT Initialize(BYTE * pbKeyToken, DWORD cbKeyToken);
-
- // Converts PK data to PKT data.
- HRESULT Initialize(PublicKey const & pk);
-
- // Initialize using the PKT value contained by pName; returns S_FALSE if there is no associated PKT.
- HRESULT Initialize(IAssemblyName * pName);
-
- // Initialize using the PK data contained by pInfo; returns S_FALSE if there is no associated PK.
- HRESULT Initialize(ICLRPrivAssemblyInfo * pInfo);
-
- // PKT data.
- BYTE const * GetToken() const
- { LIMITED_METHOD_CONTRACT; return m_rbKeyToken; }
-
- // Size in bytes of the PKT (should always be 0 or 8).
- DWORD GetSize() const
- { LIMITED_METHOD_CONTRACT; return m_cbKeyToken; }
-
- private:
- static const DWORD PUBLIC_KEY_TOKEN_LEN1 = 8;
- BYTE m_rbKeyToken[PUBLIC_KEY_TOKEN_LEN1];
- DWORD m_cbKeyToken;
- };
-
- bool operator==(PublicKeyToken const & lhs, PublicKeyToken const & rhs);
-
- inline bool operator!=(PublicKeyToken const & lhs, PublicKeyToken const & rhs)
- { WRAPPER_NO_CONTRACT; return !(lhs == rhs); }
-
- //=================================================================================================================
- // Encapsulates data required for packaged assembly identity: simple name, version, and public key token.
- //
- // Constraints: assumes that the assembly simple name is no longer than _MAX_PATH
- //
-
- struct AssemblyIdentity
- {
- AssemblyIdentity()
- { LIMITED_METHOD_CONTRACT; Name[0] = W('\0'); }
-
- AssemblyIdentity(AssemblyIdentity const & other)
- : Version(other.Version)
- , KeyToken(other.KeyToken)
- { LIMITED_METHOD_CONTRACT; CopyMemory(Name, other.Name, sizeof(Name)); }
-
- // Initialize from assembly simple name; default version and empty PKT values are used.
- HRESULT Initialize(LPCWSTR wzName);
-
- // Initialize from an ICLRPrivAssemblyInfo object.
- HRESULT Initialize(ICLRPrivAssemblyInfo * pAssemblyInfo);
-
- // Initialize from an IAssemblyName object.
- HRESULT Initialize(IAssemblyName * pAssemblyName);
-
- // Initialize from an AssemblySpec object.
- HRESULT Initialize(AssemblySpec * pSpec);
-
- // Assembly simple name
- WCHAR Name[_MAX_PATH];
-
- // Assembly version; defaults to 0.0.0.0.
- CLRPrivBinderUtil::AssemblyVersion Version;
-
- // Assembly public key token; defaults to none.
- CLRPrivBinderUtil::PublicKeyToken KeyToken;
- };
-
//=================================================================================================
template <typename ItfT>
struct CLRPrivResourceBase :
//---------------------------------------------------------------------------------------------
ReleaseHolder<IStream> m_pStream;
};
-
- //=================================================================================================================
- // Helper to prioritize binder errors. This class will ensure that all other errors have priority over
- // CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT. This class should be used just like an HRESULT variable.
- class BinderHRESULT
- {
- public:
- BinderHRESULT()
- : m_hr(S_OK)
- {}
-
- BinderHRESULT(HRESULT hr)
- : m_hr(hr)
- {}
-
- operator HRESULT() const
- { return m_hr; }
-
- BinderHRESULT & operator=(HRESULT hr)
- {
- // Always record change in success/failure status.
- if (FAILED(hr) != FAILED(m_hr))
- m_hr = hr;
-
- if (FAILED(hr))
- {
- if (SUCCEEDED(m_hr))
- m_hr = hr;
- else if (m_hr == CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT)
- m_hr = hr;
- }
- else
- {
- m_hr = hr;
- }
- return *this;
- }
-
- private:
- HRESULT m_hr;
- }; // class BinderHRESULT
//=================================================================================================================
// Types for WStringList (used in WinRT binders)
}; // class HSTRINGArrayHolder
#endif // FEATURE_COMINTEROP
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- ///// ----------------------------- Questionable stuff -------------------------------------------
- ////////////////////////////////////////////////////////////////////////////////////////////////////
-
- /** probably should be exposed on an instance (of something) method rather that magically calling GetAppDomain() **/
- ICLRPrivAssembly* RaiseAssemblyResolveEvent(IAssemblyName *pAssemblyName, ICLRPrivAssembly* pRequestingAssembly);
-
- /** Ultimately, only the binder can do ref-def matching, and it should be opaque to CLR.
- This is not trivial to do, however, since we cannot do data conversion as the function is nofault **/
- BOOL CompareHostBinderSpecs(AssemblySpec* a1, AssemblySpec* a2);
-
- /** PLACEHOLDER - the same issue as CompareHostBinderSpecs applies to hashing assemblyspecs **/
} // namespace CLRPrivBinderUtil
#endif // __CLRPRIVBINDERUTIL_H__
return m_pStream->QueryInterface(riid, ppvStream);
}
- //---------------------------------------------------------------------------------------------
- HRESULT AssemblyVersion::Initialize(
- IAssemblyName * pAssemblyName)
- {
- WRAPPER_NO_CONTRACT;
- HRESULT hr = pAssemblyName->GetVersion(&dwMajorMinor, &dwBuildRevision);
- if (hr == FUSION_E_INVALID_NAME)
- {
- hr = S_FALSE;
- }
- return hr;
- }
-
- //---------------------------------------------------------------------------------------------
- HRESULT AssemblyVersion::Initialize(
- ICLRPrivAssemblyInfo * pAssemblyInfo)
- {
- WRAPPER_NO_CONTRACT;
- return pAssemblyInfo->GetAssemblyVersion(&wMajor, &wMinor, &wBuild, &wRevision);
- }
-
- //---------------------------------------------------------------------------------------------
- HRESULT PublicKey::Initialize(
- ICLRPrivAssemblyInfo * pAssemblyInfo)
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pAssemblyInfo);
-
- Uninitialize();
-
- DWORD cbKeyDef = 0;
- hr = pAssemblyInfo->GetAssemblyPublicKey(cbKeyDef, &cbKeyDef, nullptr);
-
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (cbKeyDef != 0)
- {
- NewArrayHolder<BYTE> pbKeyDef = new (nothrow) BYTE[cbKeyDef];
- IfNullRet(pbKeyDef);
-
- if (SUCCEEDED(hr = pAssemblyInfo->GetAssemblyPublicKey(cbKeyDef, &cbKeyDef, pbKeyDef)))
- {
- m_key = pbKeyDef.Extract();
- m_key_owned = true;
- m_size = cbKeyDef;
- }
- }
- }
-
- return hr;
- }
-
- //---------------------------------------------------------------------------------------------
- HRESULT PublicKeyToken::Initialize(
- BYTE * pbKeyToken,
- DWORD cbKeyToken)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_CONDITION((pbKeyToken == nullptr) == (cbKeyToken == 0), return E_INVALIDARG);
- VALIDATE_ARG_RET(cbKeyToken == 0 || cbKeyToken == PUBLIC_KEY_TOKEN_LEN1);
-
- m_cbKeyToken = cbKeyToken;
-
- if (pbKeyToken != nullptr)
- {
- memcpy(m_rbKeyToken, pbKeyToken, PUBLIC_KEY_TOKEN_LEN1);
- }
- else
- {
- memset(m_rbKeyToken, 0, PUBLIC_KEY_TOKEN_LEN1);
- }
-
- return S_OK;
- }
-
- //---------------------------------------------------------------------------------------------
- HRESULT PublicKeyToken::Initialize(
- PublicKey const & pk)
- {
- LIMITED_METHOD_CONTRACT;
-
- StrongNameBufferHolder<BYTE> pbKeyToken;
- DWORD cbKeyToken;
-
- if (!StrongNameTokenFromPublicKey(const_cast<BYTE*>(pk.GetKey()), pk.GetSize(), &pbKeyToken, &cbKeyToken))
- {
- return static_cast<HRESULT>(StrongNameErrorInfo());
- }
-
- return Initialize(pbKeyToken, cbKeyToken);
- }
-
- //=====================================================================================================================
- HRESULT PublicKeyToken::Initialize(
- IAssemblyName * pName)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- DWORD cbKeyToken = sizeof(m_rbKeyToken);
- hr = pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_rbKeyToken, &cbKeyToken);
- if (SUCCEEDED(hr))
- {
- m_cbKeyToken = cbKeyToken;
- }
-
- if (hr == FUSION_E_INVALID_NAME)
- {
- hr = S_FALSE;
- }
-
- return hr;
- }
-
- //=====================================================================================================================
- HRESULT PublicKeyToken::Initialize(
- ICLRPrivAssemblyInfo * pName)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- PublicKey pk;
- IfFailRet(pk.Initialize(pName));
-
- if (hr == S_OK) // Can return S_FALSE if no public key/token defined.
- {
- hr = Initialize(pk);
- }
-
- return hr;
- }
-
- //=====================================================================================================================
- bool operator==(
- PublicKeyToken const & lhs,
- PublicKeyToken const & rhs)
- {
- LIMITED_METHOD_CONTRACT;
-
- // Sizes must match
- if (lhs.GetSize() != rhs.GetSize())
- {
- return false;
- }
-
- // Empty PKT values are considered to be equal.
- if (lhs.GetSize() == 0)
- {
- return true;
- }
-
- // Compare values.
- return memcmp(lhs.GetToken(), rhs.GetToken(), lhs.GetSize()) == 0;
- }
-
- //=====================================================================================================================
- HRESULT AssemblyIdentity::Initialize(
- LPCWSTR wzName)
- {
- LIMITED_METHOD_CONTRACT;
- return StringCchCopy(Name, sizeof(Name) / sizeof(Name[0]), wzName);
- }
-
- //=====================================================================================================================
- HRESULT AssemblyIdentity::Initialize(
- ICLRPrivAssemblyInfo * pAssemblyInfo)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- DWORD cchName = sizeof(Name) / sizeof(Name[0]);
- IfFailRet(pAssemblyInfo->GetAssemblyName(cchName, &cchName, Name));
- IfFailRet(Version.Initialize(pAssemblyInfo));
- IfFailRet(KeyToken.Initialize(pAssemblyInfo));
-
- return hr;
- }
-
- //=====================================================================================================================
- HRESULT AssemblyIdentity::Initialize(
- IAssemblyName * pAssemblyName)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- DWORD cchName = sizeof(Name) / sizeof(Name[0]);
- IfFailRet(pAssemblyName->GetName(&cchName, Name));
- IfFailRet(Version.Initialize(pAssemblyName));
- IfFailRet(KeyToken.Initialize(pAssemblyName));
-
- return hr;
- }
-
-
-
//=====================================================================================================================
// Destroys list of strings (code:WStringList).
void