| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | // ============================================================ |
| 5 | // |
| 6 | // FusionAssemblyName.hpp |
| 7 | // |
| 8 | // Defines the CAssemblyName class |
| 9 | // |
| 10 | // ============================================================ |
| 11 | |
| 12 | #ifndef __FUSION_ASSEMBLY_NAME_HPP__ |
| 13 | #define __FUSION_ASSEMBLY_NAME_HPP__ |
| 14 | |
| 15 | #include "fusionhelpers.hpp" |
| 16 | |
| 17 | struct FusionProperty |
| 18 | { |
| 19 | union { |
| 20 | LPVOID pv; |
| 21 | wchar_t* asStr; // For debugging. |
| 22 | }; |
| 23 | DWORD cb; |
| 24 | }; |
| 25 | |
| 26 | class CPropertyArray |
| 27 | { |
| 28 | friend class CAssemblyName; |
| 29 | private: |
| 30 | DWORD _dwSig; |
| 31 | FusionProperty _rProp[ASM_NAME_MAX_PARAMS]; |
| 32 | |
| 33 | public: |
| 34 | CPropertyArray(); |
| 35 | ~CPropertyArray(); |
| 36 | |
| 37 | inline HRESULT Set(DWORD PropertyId, LPCVOID pvProperty, DWORD cbProperty); |
| 38 | inline HRESULT Get(DWORD PropertyId, LPVOID pvProperty, LPDWORD pcbProperty); |
| 39 | inline FusionProperty operator [] (DWORD dwPropId); |
| 40 | }; |
| 41 | |
| 42 | class CAssemblyName : public IAssemblyName |
| 43 | { |
| 44 | private: |
| 45 | DWORD _dwSig; |
| 46 | Volatile<LONG> _cRef; |
| 47 | CPropertyArray _rProp; |
| 48 | BOOL _fIsFinalized; |
| 49 | BOOL _fPublicKeyToken; |
| 50 | BOOL _fCustom; |
| 51 | LPWSTR _pwzPathModifier; |
| 52 | LPWSTR _pwzTextualIdentity; |
| 53 | LPWSTR _pwzTextualIdentityILFull; |
| 54 | |
| 55 | DWORD _dw; |
| 56 | |
| 57 | public: |
| 58 | // IUnknown methods |
| 59 | STDMETHODIMP QueryInterface(REFIID riid,void ** ppv); |
| 60 | STDMETHODIMP_(ULONG) AddRef(); |
| 61 | STDMETHODIMP_(ULONG) Release(); |
| 62 | |
| 63 | // IAssemblyName methods |
| 64 | STDMETHOD(SetProperty)( |
| 65 | /* in */ DWORD PropertyId, |
| 66 | /* in */ LPCVOID pvProperty, |
| 67 | /* in */ DWORD cbProperty); |
| 68 | |
| 69 | STDMETHOD(GetProperty)( |
| 70 | /* in */ DWORD PropertyId, |
| 71 | /* out */ LPVOID pvProperty, |
| 72 | /* in out */ LPDWORD pcbProperty); |
| 73 | |
| 74 | STDMETHOD(Finalize)(); |
| 75 | |
| 76 | STDMETHOD(GetDisplayName)( |
| 77 | __out_ecount_opt(*pccDisplayName) LPOLESTR szDisplayName, |
| 78 | __inout LPDWORD pccDisplayName, |
| 79 | __in DWORD dwDisplayFlags); |
| 80 | |
| 81 | STDMETHOD(GetName)( |
| 82 | __inout LPDWORD lpcwBuffer, |
| 83 | __out_ecount_opt(*lpcwBuffer) LPOLESTR pwzBuffer); |
| 84 | |
| 85 | STDMETHOD(GetVersion)( |
| 86 | /* [out] */ LPDWORD pwVersionHi, |
| 87 | /* [out] */ LPDWORD pwVersionLow); |
| 88 | |
| 89 | STDMETHOD (IsEqual)( |
| 90 | /* [in] */ LPASSEMBLYNAME pName, |
| 91 | /* [in] */ DWORD dwCmpFlags); |
| 92 | |
| 93 | STDMETHOD(Reserved)( |
| 94 | /* in */ REFIID refIID, |
| 95 | /* in */ IUnknown *pUnkBindSink, |
| 96 | /* in */ IUnknown *pUnkAppCtx, |
| 97 | /* in */ LPCOLESTR szCodebase, |
| 98 | /* in */ LONGLONG llFlags, |
| 99 | /* in */ LPVOID pvReserved, |
| 100 | /* in */ DWORD cbReserved, |
| 101 | /* out */ VOID **ppv); |
| 102 | |
| 103 | STDMETHODIMP Clone(IAssemblyName **ppName); |
| 104 | |
| 105 | HRESULT SetPropertyInternal(/* in */ DWORD PropertyId, |
| 106 | /* in */ LPCVOID pvProperty, |
| 107 | /* in */ DWORD cbProperty); |
| 108 | |
| 109 | CAssemblyName(); |
| 110 | virtual ~CAssemblyName(); |
| 111 | |
| 112 | HRESULT Init(LPCTSTR pszAssemblyName, ASSEMBLYMETADATA *pamd); |
| 113 | HRESULT Parse(LPCWSTR szDisplayName); |
| 114 | |
| 115 | static BOOL IsStronglyNamed(IAssemblyName *pName); |
| 116 | static BOOL IsPartial(IAssemblyName *pName, |
| 117 | LPDWORD pdwCmpMask = NULL); |
| 118 | |
| 119 | protected: |
| 120 | HRESULT GetVersion(DWORD dwMajorVersionEnumValue, |
| 121 | LPDWORD pwVersionHi, |
| 122 | LPDWORD pwVersionLow); |
| 123 | |
| 124 | HRESULT CopyProperties(CAssemblyName *pSource, |
| 125 | CAssemblyName *pTarget, |
| 126 | const DWORD properties[], |
| 127 | DWORD dwSize); |
| 128 | }; |
| 129 | |
| 130 | STDAPI |
| 131 | CreateAssemblyNameObject( |
| 132 | LPASSEMBLYNAME *ppAssemblyName, |
| 133 | LPCOLESTR szAssemblyName, |
| 134 | DWORD dwFlags, |
| 135 | LPVOID pvReserved); |
| 136 | |
| 137 | STDAPI |
| 138 | CreateAssemblyNameObjectFromMetaData( |
| 139 | LPASSEMBLYNAME *ppAssemblyName, |
| 140 | LPCOLESTR szAssemblyName, |
| 141 | ASSEMBLYMETADATA *pamd, |
| 142 | LPVOID pvReserved); |
| 143 | |
| 144 | namespace LegacyFusion |
| 145 | { |
| 146 | HRESULT SetStringProperty(IAssemblyName *pIAssemblyName, |
| 147 | DWORD dwPropertyId, |
| 148 | SString &value); |
| 149 | HRESULT SetBufferProperty(IAssemblyName *pIAssemblyName, |
| 150 | DWORD dwPropertyId, |
| 151 | SBuffer &value); |
| 152 | HRESULT SetWordProperty(IAssemblyName *pIAssemblyName, |
| 153 | DWORD dwPropertyId, |
| 154 | DWORD dwValue); |
| 155 | HRESULT SetDwordProperty(IAssemblyName *pIAssemblyName, |
| 156 | DWORD dwPropertyId, |
| 157 | DWORD dwValue); |
| 158 | }; |
| 159 | |
| 160 | namespace fusion |
| 161 | { |
| 162 | namespace util |
| 163 | { |
| 164 | // Fills the provided buffer with the contents of the property. pcbBuf is |
| 165 | // set to be either the required buffer space when insufficient buffer is |
| 166 | // provided, or the number of bytes written. |
| 167 | // |
| 168 | // Returns S_FALSE if the property has not been set, regardless of the values of pBuf and pcbBuf. |
| 169 | HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, PVOID pBuf, DWORD *pcbBuf); |
| 170 | |
| 171 | // Fills the provided buffer with the contents of the property. If no buffer is provided |
| 172 | // (*ppBuf == nullptr), then a buffer is allocated for the caller and ppBuf is set to point |
| 173 | // at the allocated buffer on return. pcbBuf is set to be either the required buffer space |
| 174 | // when insufficient buffer is provided, or the number of bytes written. |
| 175 | // |
| 176 | // Returns S_FALSE if the property has not been set, regardless of the values of pBuf and pcbBuf. |
| 177 | HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, PBYTE * ppBuf, DWORD *pcbBuf); |
| 178 | |
| 179 | // Fills the provided SString with the contents of the property. |
| 180 | // |
| 181 | // Returns S_FALSE if the property has not been set. |
| 182 | HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, SString & ssVal); |
| 183 | |
| 184 | // Returns an allocated buffer with the contents of the property. |
| 185 | // |
| 186 | // Returns S_FALSE if the property has not been set. |
| 187 | HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, __deref_out LPWSTR * pwzVal); |
| 188 | |
| 189 | inline HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, LPCWSTR *pwzOut) |
| 190 | { return GetProperty(pName, dwProperty, const_cast<LPWSTR*>(pwzOut)); } |
| 191 | |
| 192 | // Returns an allocated buffer with the contents of the property. |
| 193 | // |
| 194 | // Returns S_FALSE if the property has not been set. |
| 195 | HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, __deref_out LPSTR *pwzOut); |
| 196 | |
| 197 | inline HRESULT GetProperty(IAssemblyName * pName, DWORD dwProperty, LPCSTR *pwzOut) |
| 198 | { return GetProperty(pName, dwProperty, const_cast<LPSTR*>(pwzOut)); } |
| 199 | |
| 200 | template <typename T> inline |
| 201 | typename std::enable_if<!std::is_pointer< typename std::remove_cv< T >::type >::value, HRESULT>::type |
| 202 | GetProperty(IAssemblyName * pName, DWORD dwProperty, T * pVal) |
| 203 | { |
| 204 | DWORD cbBuf = sizeof(T); |
| 205 | HRESULT hr = GetProperty(pName, dwProperty, pVal, &cbBuf); |
| 206 | if (hr == S_OK && cbBuf != sizeof(T)) |
| 207 | hr = E_UNEXPECTED; |
| 208 | return hr; |
| 209 | } |
| 210 | |
| 211 | inline HRESULT GetSimpleName(IAssemblyName * pName, SString & ssName) |
| 212 | { return GetProperty(pName, ASM_NAME_NAME, ssName); } |
| 213 | } // namespace fusion.util |
| 214 | } // namespace fusion |
| 215 | |
| 216 | |
| 217 | #endif |
| 218 | |