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 | // |
7 | // Contains helper types for assembly binding host infrastructure. |
8 | |
9 | #include "common.h" |
10 | |
11 | #include "utilcode.h" |
12 | #include "strsafe.h" |
13 | |
14 | #include "clrprivbinderutil.h" |
15 | |
16 | inline |
17 | LPWSTR CopyStringThrowing( |
18 | LPCWSTR wszString) |
19 | { |
20 | CONTRACTL |
21 | { |
22 | THROWS; |
23 | GC_NOTRIGGER; |
24 | } |
25 | CONTRACTL_END; |
26 | |
27 | NewArrayHolder<WCHAR> wszDup = NULL; |
28 | if (wszString != NULL) |
29 | { |
30 | size_t wszLen = wcslen(wszString); |
31 | wszDup = new WCHAR[wszLen + 1]; |
32 | IfFailThrow(StringCchCopy(wszDup, wszLen + 1, wszString)); |
33 | } |
34 | wszDup.SuppressRelease(); |
35 | |
36 | return wszDup; |
37 | } |
38 | |
39 | |
40 | namespace CLRPrivBinderUtil |
41 | { |
42 | //--------------------------------------------------------------------------------------------- |
43 | CLRPrivResourcePathImpl::CLRPrivResourcePathImpl(LPCWSTR wzPath) |
44 | : m_wzPath(CopyStringThrowing(wzPath)) |
45 | { STANDARD_VM_CONTRACT; } |
46 | |
47 | //--------------------------------------------------------------------------------------------- |
48 | HRESULT CLRPrivResourcePathImpl::GetPath( |
49 | DWORD cchBuffer, |
50 | LPDWORD pcchBuffer, |
51 | __inout_ecount_part(cchBuffer, *pcchBuffer) LPWSTR wzBuffer) |
52 | { |
53 | LIMITED_METHOD_CONTRACT; |
54 | HRESULT hr = S_OK; |
55 | |
56 | if (pcchBuffer == nullptr) |
57 | IfFailRet(E_INVALIDARG); |
58 | |
59 | *pcchBuffer = (DWORD)wcslen(m_wzPath); |
60 | |
61 | if (wzBuffer != nullptr) |
62 | { |
63 | if (FAILED(StringCchCopy(wzBuffer, cchBuffer, m_wzPath))) |
64 | IfFailRet(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)); |
65 | } |
66 | |
67 | return hr; |
68 | } |
69 | |
70 | //--------------------------------------------------------------------------------------------- |
71 | CLRPrivResourceStreamImpl::CLRPrivResourceStreamImpl(IStream * pStream) |
72 | : m_pStream(pStream) |
73 | { |
74 | LIMITED_METHOD_CONTRACT; |
75 | pStream->AddRef(); |
76 | } |
77 | |
78 | //--------------------------------------------------------------------------------------------- |
79 | HRESULT CLRPrivResourceStreamImpl::GetStream( |
80 | REFIID riid, |
81 | LPVOID * ppvStream) |
82 | { |
83 | LIMITED_METHOD_CONTRACT; |
84 | return m_pStream->QueryInterface(riid, ppvStream); |
85 | } |
86 | |
87 | //--------------------------------------------------------------------------------------------- |
88 | HRESULT AssemblyVersion::Initialize( |
89 | IAssemblyName * pAssemblyName) |
90 | { |
91 | WRAPPER_NO_CONTRACT; |
92 | HRESULT hr = pAssemblyName->GetVersion(&dwMajorMinor, &dwBuildRevision); |
93 | if (hr == FUSION_E_INVALID_NAME) |
94 | { |
95 | hr = S_FALSE; |
96 | } |
97 | return hr; |
98 | } |
99 | |
100 | //--------------------------------------------------------------------------------------------- |
101 | HRESULT AssemblyVersion::Initialize( |
102 | ICLRPrivAssemblyInfo * pAssemblyInfo) |
103 | { |
104 | WRAPPER_NO_CONTRACT; |
105 | return pAssemblyInfo->GetAssemblyVersion(&wMajor, &wMinor, &wBuild, &wRevision); |
106 | } |
107 | |
108 | //--------------------------------------------------------------------------------------------- |
109 | HRESULT PublicKey::Initialize( |
110 | ICLRPrivAssemblyInfo * pAssemblyInfo) |
111 | { |
112 | LIMITED_METHOD_CONTRACT; |
113 | HRESULT hr = S_OK; |
114 | |
115 | VALIDATE_PTR_RET(pAssemblyInfo); |
116 | |
117 | Uninitialize(); |
118 | |
119 | DWORD cbKeyDef = 0; |
120 | hr = pAssemblyInfo->GetAssemblyPublicKey(cbKeyDef, &cbKeyDef, nullptr); |
121 | |
122 | if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) |
123 | { |
124 | if (cbKeyDef != 0) |
125 | { |
126 | NewArrayHolder<BYTE> pbKeyDef = new (nothrow) BYTE[cbKeyDef]; |
127 | IfNullRet(pbKeyDef); |
128 | |
129 | if (SUCCEEDED(hr = pAssemblyInfo->GetAssemblyPublicKey(cbKeyDef, &cbKeyDef, pbKeyDef))) |
130 | { |
131 | m_key = pbKeyDef.Extract(); |
132 | m_key_owned = true; |
133 | m_size = cbKeyDef; |
134 | } |
135 | } |
136 | } |
137 | |
138 | return hr; |
139 | } |
140 | |
141 | //--------------------------------------------------------------------------------------------- |
142 | HRESULT PublicKeyToken::Initialize( |
143 | BYTE * pbKeyToken, |
144 | DWORD cbKeyToken) |
145 | { |
146 | LIMITED_METHOD_CONTRACT; |
147 | |
148 | VALIDATE_CONDITION((pbKeyToken == nullptr) == (cbKeyToken == 0), return E_INVALIDARG); |
149 | VALIDATE_ARG_RET(cbKeyToken == 0 || cbKeyToken == PUBLIC_KEY_TOKEN_LEN1); |
150 | |
151 | m_cbKeyToken = cbKeyToken; |
152 | |
153 | if (pbKeyToken != nullptr) |
154 | { |
155 | memcpy(m_rbKeyToken, pbKeyToken, PUBLIC_KEY_TOKEN_LEN1); |
156 | } |
157 | else |
158 | { |
159 | memset(m_rbKeyToken, 0, PUBLIC_KEY_TOKEN_LEN1); |
160 | } |
161 | |
162 | return S_OK; |
163 | } |
164 | |
165 | //--------------------------------------------------------------------------------------------- |
166 | HRESULT PublicKeyToken::Initialize( |
167 | PublicKey const & pk) |
168 | { |
169 | LIMITED_METHOD_CONTRACT; |
170 | |
171 | StrongNameBufferHolder<BYTE> pbKeyToken; |
172 | DWORD cbKeyToken; |
173 | |
174 | if (!StrongNameTokenFromPublicKey(const_cast<BYTE*>(pk.GetKey()), pk.GetSize(), &pbKeyToken, &cbKeyToken)) |
175 | { |
176 | return static_cast<HRESULT>(StrongNameErrorInfo()); |
177 | } |
178 | |
179 | return Initialize(pbKeyToken, cbKeyToken); |
180 | } |
181 | |
182 | //===================================================================================================================== |
183 | HRESULT PublicKeyToken::Initialize( |
184 | IAssemblyName * pName) |
185 | { |
186 | LIMITED_METHOD_CONTRACT; |
187 | |
188 | HRESULT hr = S_OK; |
189 | |
190 | DWORD cbKeyToken = sizeof(m_rbKeyToken); |
191 | hr = pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_rbKeyToken, &cbKeyToken); |
192 | if (SUCCEEDED(hr)) |
193 | { |
194 | m_cbKeyToken = cbKeyToken; |
195 | } |
196 | |
197 | if (hr == FUSION_E_INVALID_NAME) |
198 | { |
199 | hr = S_FALSE; |
200 | } |
201 | |
202 | return hr; |
203 | } |
204 | |
205 | //===================================================================================================================== |
206 | HRESULT PublicKeyToken::Initialize( |
207 | ICLRPrivAssemblyInfo * pName) |
208 | { |
209 | LIMITED_METHOD_CONTRACT; |
210 | |
211 | HRESULT hr = S_OK; |
212 | |
213 | PublicKey pk; |
214 | IfFailRet(pk.Initialize(pName)); |
215 | |
216 | if (hr == S_OK) // Can return S_FALSE if no public key/token defined. |
217 | { |
218 | hr = Initialize(pk); |
219 | } |
220 | |
221 | return hr; |
222 | } |
223 | |
224 | //===================================================================================================================== |
225 | bool operator==( |
226 | PublicKeyToken const & lhs, |
227 | PublicKeyToken const & rhs) |
228 | { |
229 | LIMITED_METHOD_CONTRACT; |
230 | |
231 | // Sizes must match |
232 | if (lhs.GetSize() != rhs.GetSize()) |
233 | { |
234 | return false; |
235 | } |
236 | |
237 | // Empty PKT values are considered to be equal. |
238 | if (lhs.GetSize() == 0) |
239 | { |
240 | return true; |
241 | } |
242 | |
243 | // Compare values. |
244 | return memcmp(lhs.GetToken(), rhs.GetToken(), lhs.GetSize()) == 0; |
245 | } |
246 | |
247 | //===================================================================================================================== |
248 | HRESULT AssemblyIdentity::Initialize( |
249 | LPCWSTR wzName) |
250 | { |
251 | LIMITED_METHOD_CONTRACT; |
252 | return StringCchCopy(Name, sizeof(Name) / sizeof(Name[0]), wzName); |
253 | } |
254 | |
255 | //===================================================================================================================== |
256 | HRESULT AssemblyIdentity::Initialize( |
257 | ICLRPrivAssemblyInfo * pAssemblyInfo) |
258 | { |
259 | STANDARD_BIND_CONTRACT; |
260 | HRESULT hr = S_OK; |
261 | |
262 | DWORD cchName = sizeof(Name) / sizeof(Name[0]); |
263 | IfFailRet(pAssemblyInfo->GetAssemblyName(cchName, &cchName, Name)); |
264 | IfFailRet(Version.Initialize(pAssemblyInfo)); |
265 | IfFailRet(KeyToken.Initialize(pAssemblyInfo)); |
266 | |
267 | return hr; |
268 | } |
269 | |
270 | //===================================================================================================================== |
271 | HRESULT AssemblyIdentity::Initialize( |
272 | IAssemblyName * pAssemblyName) |
273 | { |
274 | STANDARD_BIND_CONTRACT; |
275 | HRESULT hr = S_OK; |
276 | |
277 | DWORD cchName = sizeof(Name) / sizeof(Name[0]); |
278 | IfFailRet(pAssemblyName->GetName(&cchName, Name)); |
279 | IfFailRet(Version.Initialize(pAssemblyName)); |
280 | IfFailRet(KeyToken.Initialize(pAssemblyName)); |
281 | |
282 | return hr; |
283 | } |
284 | |
285 | |
286 | |
287 | //===================================================================================================================== |
288 | // Destroys list of strings (code:WStringList). |
289 | void |
290 | WStringList_Delete( |
291 | WStringList * pList) |
292 | { |
293 | LIMITED_METHOD_CONTRACT; |
294 | |
295 | if (pList != nullptr) |
296 | { |
297 | for (WStringListElem * pElem = pList->RemoveHead(); pElem != nullptr; pElem = pList->RemoveHead()) |
298 | { |
299 | // Delete the string |
300 | delete [] pElem->GetValue(); |
301 | delete pElem; |
302 | } |
303 | |
304 | delete pList; |
305 | } |
306 | } |
307 | |
308 | |
309 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
310 | ///// ----------------------------- Direct calls to VM ------------------------------------------- |
311 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
312 | } // namespace CLRPrivBinderUtil |
313 | |