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 | #ifndef __CLRPRIVBINDERUTIL_H__ |
10 | #define __CLRPRIVBINDERUTIL_H__ |
11 | |
12 | #include "holder.h" |
13 | #include "internalunknownimpl.h" |
14 | #include "clrprivbinding.h" |
15 | #include "slist.h" |
16 | #ifdef FEATURE_COMINTEROP |
17 | #include "windowsstring.h" |
18 | #endif // FEATURE_COMINTEROP |
19 | #include "strongnameholders.h" |
20 | |
21 | //===================================================================================================================== |
22 | #define STANDARD_BIND_CONTRACT \ |
23 | CONTRACTL { \ |
24 | NOTHROW; \ |
25 | GC_TRIGGERS; \ |
26 | MODE_PREEMPTIVE; \ |
27 | } CONTRACTL_END |
28 | |
29 | //===================================================================================================================== |
30 | // Forward declarations |
31 | interface ICLRPrivAssembly; |
32 | typedef DPTR(ICLRPrivAssembly) PTR_ICLRPrivAssembly; |
33 | typedef DPTR(ICLRPrivBinder) PTR_ICLRPrivBinder; |
34 | class PEAssembly; |
35 | class AssemblySpec; |
36 | |
37 | //===================================================================================================================== |
38 | #define VALIDATE_CONDITION(condition, fail_op) \ |
39 | do { \ |
40 | _ASSERTE((condition)); \ |
41 | if (!(condition)) \ |
42 | fail_op; \ |
43 | } while (false) |
44 | |
45 | #define VALIDATE_PTR_RET(val) VALIDATE_CONDITION(val != nullptr, return E_POINTER) |
46 | #define VALIDATE_PTR_THROW(val) VALIDATE_CONDITION(val != nullptr, ThrowHR(E_POINTER)) |
47 | #define VALIDATE_ARG_RET(condition) VALIDATE_CONDITION(condition, return E_INVALIDARG) |
48 | #define VALIDATE_ARG_THROW(condition) VALIDATE_CONDITION(condition, ThrowHR(E_INVALIDARG)) |
49 | |
50 | //===================================================================================================================== |
51 | namespace CLRPrivBinderUtil |
52 | { |
53 | //================================================================================================================= |
54 | enum BindFlags |
55 | { |
56 | BF_BindIL = 1, |
57 | BF_BindNI = 2, |
58 | BF_Default = BF_BindIL | BF_BindNI, |
59 | }; |
60 | |
61 | //================================================================================================================= |
62 | template <typename ItfT, typename ObjT> |
63 | inline ItfT * ToInterface( |
64 | ObjT * && pObj) |
65 | { |
66 | STATIC_CONTRACT_THROWS; |
67 | |
68 | ItfT * pItf = nullptr; |
69 | IfFailThrow(pObj->QueryInterface(__uuidof(ItfT), (void **)&pItf)); |
70 | return pItf; |
71 | } |
72 | |
73 | //================================================================================================================= |
74 | template <typename ItfT, typename ObjT> |
75 | inline ItfT * ToInterface_NoThrow( |
76 | ObjT * && pObj) |
77 | { |
78 | LIMITED_METHOD_CONTRACT; |
79 | |
80 | ItfT * pItf = nullptr; |
81 | if (FAILED(pObj->QueryInterface(__uuidof(ItfT), (void **)&pItf))) |
82 | { |
83 | return nullptr; |
84 | } |
85 | return pItf; |
86 | } |
87 | |
88 | //===================================================================================================================== |
89 | |
90 | //================================================================================================================= |
91 | // Used to create an identity-only ICLRPrivAssembly from an ICLRPrivBinder. This is currently used when |
92 | // creating dynamic assemblies as these use the parent assembly's ICLRPrivBinder object to provide binding |
93 | // functionaltiy. |
94 | |
95 | class CLRPrivBinderAsAssemblyWrapper : |
96 | public IUnknownCommon<ICLRPrivAssembly> |
97 | { |
98 | public: |
99 | //----------------------------------------------------------------------------------------------------------------- |
100 | CLRPrivBinderAsAssemblyWrapper( |
101 | ICLRPrivBinder *pWrapped) |
102 | : _pWrapped(clr::SafeAddRef(pWrapped)) |
103 | { |
104 | STANDARD_VM_CONTRACT; |
105 | VALIDATE_ARG_THROW(pWrapped); |
106 | } |
107 | |
108 | //----------------------------------------------------------------------------------------------------------------- |
109 | // Forwards to wrapped binder. |
110 | STDMETHOD(BindAssemblyByName)( |
111 | IAssemblyName * pAssemblyName, |
112 | ICLRPrivAssembly ** ppAssembly) |
113 | { |
114 | WRAPPER_NO_CONTRACT; |
115 | return _pWrapped->BindAssemblyByName(pAssemblyName, ppAssembly); |
116 | } |
117 | |
118 | //----------------------------------------------------------------------------------------------------------------- |
119 | // Forwards to wrapped binder. |
120 | STDMETHOD(GetBinderID)( |
121 | UINT_PTR *pBinderId) |
122 | { |
123 | WRAPPER_NO_CONTRACT; |
124 | return _pWrapped->GetBinderID(pBinderId); |
125 | } |
126 | |
127 | //----------------------------------------------------------------------------------------------------------------- |
128 | // Forwards to wrapped binder. |
129 | STDMETHOD(GetLoaderAllocator)( |
130 | LPVOID * pLoaderAllocator) |
131 | { |
132 | WRAPPER_NO_CONTRACT; |
133 | return _pWrapped->GetLoaderAllocator(pLoaderAllocator); |
134 | } |
135 | |
136 | //----------------------------------------------------------------------------------------------------------------- |
137 | // ICLRPrivAssembly method is unsupported. |
138 | STDMETHOD(IsShareable)( |
139 | BOOL * pbIsShareable) |
140 | { |
141 | LIMITED_METHOD_CONTRACT; |
142 | _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!" ); |
143 | VALIDATE_ARG_RET(pbIsShareable); |
144 | *pbIsShareable = FALSE; |
145 | return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); |
146 | } |
147 | |
148 | //----------------------------------------------------------------------------------------------------------------- |
149 | // ICLRPrivAssembly method is unsupported. |
150 | STDMETHOD(GetAvailableImageTypes)( |
151 | LPDWORD pdwImageTypes) |
152 | { |
153 | LIMITED_METHOD_CONTRACT; |
154 | _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!" ); |
155 | VALIDATE_ARG_RET(pdwImageTypes); |
156 | *pdwImageTypes = 0; |
157 | return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); |
158 | } |
159 | |
160 | //----------------------------------------------------------------------------------------------------------------- |
161 | // ICLRPrivAssembly method is unsupported. |
162 | STDMETHOD(GetImageResource)( |
163 | DWORD dwImageType, |
164 | DWORD* pdwImageType, |
165 | ICLRPrivResource ** ppIResource) |
166 | { |
167 | LIMITED_METHOD_CONTRACT; |
168 | _ASSERTE_MSG(false, "CLRPrivBinderAsAssemblyWrapper does not support ICLRPrivAssembly methods (just ICLRPrivBinder ones)!" ); |
169 | VALIDATE_ARG_RET(pdwImageType); |
170 | *pdwImageType = 0; |
171 | return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); |
172 | } |
173 | |
174 | private: |
175 | ReleaseHolder<ICLRPrivBinder> _pWrapped; |
176 | }; |
177 | |
178 | //================================================================================================================= |
179 | // Provides a struct that can be accessed at the QWORD, DWORD, or WORD level, and is structured |
180 | |
181 | struct AssemblyVersion |
182 | { |
183 | #if BIGENDIAN |
184 | union |
185 | { |
186 | UINT64 qwMajorMinorBuildRevision; |
187 | struct |
188 | { |
189 | union |
190 | { |
191 | DWORD dwMajorMinor; |
192 | struct |
193 | { |
194 | WORD wMajor; |
195 | WORD wMinor; |
196 | }; |
197 | }; |
198 | union |
199 | { |
200 | DWORD dwBuildRevision; |
201 | struct |
202 | { |
203 | WORD wBuild; |
204 | WORD wRevision; |
205 | }; |
206 | }; |
207 | }; |
208 | }; |
209 | #else |
210 | union |
211 | { |
212 | UINT64 qwMajorMinorBuildRevision; |
213 | struct |
214 | { |
215 | union |
216 | { |
217 | DWORD dwBuildRevision; |
218 | struct |
219 | { |
220 | WORD wRevision; |
221 | WORD wBuild; |
222 | }; |
223 | }; |
224 | union |
225 | { |
226 | DWORD dwMajorMinor; |
227 | struct |
228 | { |
229 | WORD wMinor; |
230 | WORD wMajor; |
231 | }; |
232 | }; |
233 | }; |
234 | }; |
235 | #endif |
236 | |
237 | // Default value is 0.0.0.0 |
238 | AssemblyVersion() |
239 | : qwMajorMinorBuildRevision(static_cast<UINT64>(0)) |
240 | { LIMITED_METHOD_CONTRACT; } |
241 | |
242 | // Copy constructor |
243 | AssemblyVersion(AssemblyVersion const & other) |
244 | : qwMajorMinorBuildRevision(other.qwMajorMinorBuildRevision) |
245 | { LIMITED_METHOD_CONTRACT; } |
246 | |
247 | // Initialize version using an IAssemblyName object. |
248 | HRESULT Initialize(IAssemblyName * pName); |
249 | |
250 | // Initialize version using an ICLRPrivAssemblyInfo object. |
251 | HRESULT Initialize(ICLRPrivAssemblyInfo * pInfo); |
252 | |
253 | // Relative ordering of versions. |
254 | static inline int Compare( |
255 | AssemblyVersion const & left, |
256 | AssemblyVersion const & right) |
257 | { |
258 | LIMITED_METHOD_CONTRACT; |
259 | |
260 | if (left.qwMajorMinorBuildRevision < right.qwMajorMinorBuildRevision) |
261 | return -1; |
262 | else if (left.qwMajorMinorBuildRevision == right.qwMajorMinorBuildRevision) |
263 | return 0; |
264 | else |
265 | return 1; |
266 | } |
267 | }; // struct AssemblyVersion |
268 | |
269 | inline bool operator ==(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
270 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision == rhs.qwMajorMinorBuildRevision; } |
271 | |
272 | inline bool operator !=(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
273 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision != rhs.qwMajorMinorBuildRevision; } |
274 | |
275 | inline bool operator <(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
276 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision < rhs.qwMajorMinorBuildRevision; } |
277 | |
278 | inline bool operator <=(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
279 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision <= rhs.qwMajorMinorBuildRevision; } |
280 | |
281 | inline bool operator >(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
282 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision > rhs.qwMajorMinorBuildRevision; } |
283 | |
284 | inline bool operator >=(AssemblyVersion const & lhs, AssemblyVersion const & rhs) |
285 | { LIMITED_METHOD_CONTRACT; return lhs.qwMajorMinorBuildRevision >= rhs.qwMajorMinorBuildRevision; } |
286 | |
287 | //================================================================================================================= |
288 | // Encapsulates PublicKey value, can be initialized using a variety of data sources. |
289 | |
290 | struct PublicKey |
291 | { |
292 | // Defaults to empty value. |
293 | PublicKey() |
294 | : m_key(nullptr) |
295 | , m_key_owned(false) |
296 | , m_size((DWORD)-1) |
297 | { LIMITED_METHOD_CONTRACT; } |
298 | |
299 | // Construct directly from existing public key data. |
300 | PublicKey(PBYTE pbKey, DWORD cbKey) |
301 | : m_key(pbKey) |
302 | , m_key_owned(false) |
303 | , m_size(cbKey) |
304 | { LIMITED_METHOD_CONTRACT; } |
305 | |
306 | ~PublicKey() |
307 | { WRAPPER_NO_CONTRACT; Uninitialize(); } |
308 | |
309 | // Frees any public key data and resets to default value. |
310 | void Uninitialize() |
311 | { |
312 | LIMITED_METHOD_CONTRACT; |
313 | |
314 | if (m_key_owned) |
315 | { |
316 | delete [] m_key; |
317 | m_key_owned = false; |
318 | } |
319 | m_key = nullptr; |
320 | m_size = 0; |
321 | } |
322 | |
323 | // Initialize PK data form an ICLRPrivAssemblyInfo object. |
324 | HRESULT Initialize(ICLRPrivAssemblyInfo * pAssemblyInfo); |
325 | |
326 | // Returns PK data pointer. |
327 | inline BYTE const * GetKey() const |
328 | { LIMITED_METHOD_CONTRACT; return m_key; } |
329 | |
330 | // Returns size in bytes of the PK data. |
331 | inline DWORD GetSize() const |
332 | { LIMITED_METHOD_CONTRACT; return m_size; } |
333 | |
334 | private: |
335 | PBYTE m_key; |
336 | bool m_key_owned; |
337 | DWORD m_size; |
338 | }; |
339 | |
340 | //================================================================================================================= |
341 | // Encapsulates PublicKeyToken value, can be initialized using a variety of data sources. |
342 | // |
343 | // Constraints: assumes that non-empty PKT data will always be 8 bytes long. |
344 | // |
345 | |
346 | struct PublicKeyToken |
347 | { |
348 | PublicKeyToken() |
349 | : m_cbKeyToken(0) |
350 | { LIMITED_METHOD_CONTRACT; ZeroMemory(&m_rbKeyToken, sizeof(m_rbKeyToken)); } |
351 | |
352 | PublicKeyToken(PublicKeyToken const & other) |
353 | : m_cbKeyToken(other.m_cbKeyToken) |
354 | { LIMITED_METHOD_CONTRACT; CopyMemory(m_rbKeyToken, other.m_rbKeyToken, sizeof(m_rbKeyToken)); } |
355 | |
356 | // Initialize directly from PKT data. |
357 | HRESULT Initialize(BYTE * pbKeyToken, DWORD cbKeyToken); |
358 | |
359 | // Converts PK data to PKT data. |
360 | HRESULT Initialize(PublicKey const & pk); |
361 | |
362 | // Initialize using the PKT value contained by pName; returns S_FALSE if there is no associated PKT. |
363 | HRESULT Initialize(IAssemblyName * pName); |
364 | |
365 | // Initialize using the PK data contained by pInfo; returns S_FALSE if there is no associated PK. |
366 | HRESULT Initialize(ICLRPrivAssemblyInfo * pInfo); |
367 | |
368 | // PKT data. |
369 | BYTE const * GetToken() const |
370 | { LIMITED_METHOD_CONTRACT; return m_rbKeyToken; } |
371 | |
372 | // Size in bytes of the PKT (should always be 0 or 8). |
373 | DWORD GetSize() const |
374 | { LIMITED_METHOD_CONTRACT; return m_cbKeyToken; } |
375 | |
376 | private: |
377 | static const DWORD PUBLIC_KEY_TOKEN_LEN1 = 8; |
378 | BYTE m_rbKeyToken[PUBLIC_KEY_TOKEN_LEN1]; |
379 | DWORD m_cbKeyToken; |
380 | }; |
381 | |
382 | bool operator==(PublicKeyToken const & lhs, PublicKeyToken const & rhs); |
383 | |
384 | inline bool operator!=(PublicKeyToken const & lhs, PublicKeyToken const & rhs) |
385 | { WRAPPER_NO_CONTRACT; return !(lhs == rhs); } |
386 | |
387 | //================================================================================================================= |
388 | // Encapsulates data required for packaged assembly identity: simple name, version, and public key token. |
389 | // |
390 | // Constraints: assumes that the assembly simple name is no longer than _MAX_PATH |
391 | // |
392 | |
393 | struct AssemblyIdentity |
394 | { |
395 | AssemblyIdentity() |
396 | { LIMITED_METHOD_CONTRACT; Name[0] = W('\0'); } |
397 | |
398 | AssemblyIdentity(AssemblyIdentity const & other) |
399 | : Version(other.Version) |
400 | , KeyToken(other.KeyToken) |
401 | { LIMITED_METHOD_CONTRACT; CopyMemory(Name, other.Name, sizeof(Name)); } |
402 | |
403 | // Initialize from assembly simple name; default version and empty PKT values are used. |
404 | HRESULT Initialize(LPCWSTR wzName); |
405 | |
406 | // Initialize from an ICLRPrivAssemblyInfo object. |
407 | HRESULT Initialize(ICLRPrivAssemblyInfo * pAssemblyInfo); |
408 | |
409 | // Initialize from an IAssemblyName object. |
410 | HRESULT Initialize(IAssemblyName * pAssemblyName); |
411 | |
412 | // Initialize from an AssemblySpec object. |
413 | HRESULT Initialize(AssemblySpec * pSpec); |
414 | |
415 | // Assembly simple name |
416 | WCHAR Name[_MAX_PATH]; |
417 | |
418 | // Assembly version; defaults to 0.0.0.0. |
419 | CLRPrivBinderUtil::AssemblyVersion Version; |
420 | |
421 | // Assembly public key token; defaults to none. |
422 | CLRPrivBinderUtil::PublicKeyToken KeyToken; |
423 | }; |
424 | |
425 | //================================================================================================= |
426 | template <typename ItfT> |
427 | struct CLRPrivResourceBase : |
428 | public IUnknownCommon<ICLRPrivResource> |
429 | { |
430 | //--------------------------------------------------------------------------------------------- |
431 | STDMETHOD(GetResourceType)( |
432 | IID *pIID) |
433 | { |
434 | LIMITED_METHOD_CONTRACT; |
435 | if (pIID == nullptr) |
436 | return E_INVALIDARG; |
437 | *pIID = __uuidof(ItfT); |
438 | return S_OK; |
439 | } |
440 | }; |
441 | |
442 | //================================================================================================================= |
443 | class CLRPrivResourcePathImpl : |
444 | public IUnknownCommon< ItfBase< CLRPrivResourceBase< ICLRPrivResourcePath > >, |
445 | ICLRPrivResourcePath > |
446 | { |
447 | public: |
448 | //--------------------------------------------------------------------------------------------- |
449 | CLRPrivResourcePathImpl(LPCWSTR wzPath); |
450 | |
451 | //--------------------------------------------------------------------------------------------- |
452 | LPCWSTR GetPath() |
453 | { return m_wzPath; } |
454 | |
455 | // |
456 | // ICLRPrivResourcePath methods |
457 | // |
458 | |
459 | //--------------------------------------------------------------------------------------------- |
460 | STDMETHOD(GetPath)( |
461 | DWORD cchBuffer, |
462 | LPDWORD pcchBuffer, |
463 | __inout_ecount_part(cchBuffer, *pcchBuffer) LPWSTR wzBuffer); |
464 | |
465 | private: |
466 | //--------------------------------------------------------------------------------------------- |
467 | NewArrayHolder<WCHAR> m_wzPath; |
468 | }; |
469 | |
470 | //================================================================================================================= |
471 | class CLRPrivResourceStreamImpl : |
472 | public IUnknownCommon< ItfBase< CLRPrivResourceBase<ICLRPrivResourceStream > >, |
473 | ICLRPrivResourceStream> |
474 | { |
475 | public: |
476 | //--------------------------------------------------------------------------------------------- |
477 | CLRPrivResourceStreamImpl(IStream * pStream); |
478 | |
479 | //--------------------------------------------------------------------------------------------- |
480 | STDMETHOD(GetStream)( |
481 | REFIID riid, |
482 | LPVOID * ppvStream); |
483 | |
484 | private: |
485 | //--------------------------------------------------------------------------------------------- |
486 | ReleaseHolder<IStream> m_pStream; |
487 | }; |
488 | |
489 | //================================================================================================================= |
490 | // Helper to prioritize binder errors. This class will ensure that all other errors have priority over |
491 | // CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT. This class should be used just like an HRESULT variable. |
492 | class BinderHRESULT |
493 | { |
494 | public: |
495 | BinderHRESULT() |
496 | : m_hr(S_OK) |
497 | {} |
498 | |
499 | BinderHRESULT(HRESULT hr) |
500 | : m_hr(hr) |
501 | {} |
502 | |
503 | operator HRESULT() const |
504 | { return m_hr; } |
505 | |
506 | BinderHRESULT & operator=(HRESULT hr) |
507 | { |
508 | // Always record change in success/failure status. |
509 | if (FAILED(hr) != FAILED(m_hr)) |
510 | m_hr = hr; |
511 | |
512 | if (FAILED(hr)) |
513 | { |
514 | if (SUCCEEDED(m_hr)) |
515 | m_hr = hr; |
516 | else if (m_hr == CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT) |
517 | m_hr = hr; |
518 | } |
519 | else |
520 | { |
521 | m_hr = hr; |
522 | } |
523 | return *this; |
524 | } |
525 | |
526 | private: |
527 | HRESULT m_hr; |
528 | }; // class BinderHRESULT |
529 | |
530 | //================================================================================================================= |
531 | // Types for WStringList (used in WinRT binders) |
532 | |
533 | typedef SListElem< PTR_WSTR > WStringListElem; |
534 | typedef DPTR(WStringListElem) PTR_WStringListElem; |
535 | typedef SList< WStringListElem, false /* = fHead default value */, PTR_WStringListElem > WStringList; |
536 | typedef DPTR(WStringList) PTR_WStringList; |
537 | |
538 | // Destroys list of strings (code:WStringList). |
539 | void WStringList_Delete(WStringList * pList); |
540 | |
541 | #ifndef DACCESS_COMPILE |
542 | //===================================================================================================================== |
543 | // Holder of allocated code:WStringList (helper class for WinRT binders - e.g. code:CLRPrivBinderWinRT::GetFileNameListForNamespace). |
544 | class WStringListHolder |
545 | { |
546 | public: |
547 | WStringListHolder(WStringList * pList = nullptr) |
548 | { |
549 | LIMITED_METHOD_CONTRACT; |
550 | m_pList = pList; |
551 | } |
552 | ~WStringListHolder() |
553 | { |
554 | LIMITED_METHOD_CONTRACT; |
555 | Destroy(); |
556 | } |
557 | |
558 | void InsertTail(LPCWSTR wszValue) |
559 | { |
560 | CONTRACTL |
561 | { |
562 | THROWS; |
563 | GC_NOTRIGGER; |
564 | MODE_ANY; |
565 | } |
566 | CONTRACTL_END; |
567 | |
568 | NewArrayHolder<WCHAR> wszElemValue = DuplicateStringThrowing(wszValue); |
569 | NewHolder<WStringListElem> pElem = new WStringListElem(wszElemValue); |
570 | |
571 | if (m_pList == nullptr) |
572 | { |
573 | m_pList = new WStringList(); |
574 | } |
575 | |
576 | m_pList->InsertTail(pElem.Extract()); |
577 | // The string is now owned by the list |
578 | wszElemValue.SuppressRelease(); |
579 | } |
580 | |
581 | WStringList * GetValue() |
582 | { |
583 | LIMITED_METHOD_CONTRACT; |
584 | return m_pList; |
585 | } |
586 | |
587 | WStringList * () |
588 | { |
589 | LIMITED_METHOD_CONTRACT; |
590 | |
591 | WStringList * pList = m_pList; |
592 | m_pList = nullptr; |
593 | return pList; |
594 | } |
595 | |
596 | private: |
597 | void Destroy() |
598 | { |
599 | LIMITED_METHOD_CONTRACT; |
600 | |
601 | if (m_pList != nullptr) |
602 | { |
603 | WStringList_Delete(m_pList); |
604 | m_pList = nullptr; |
605 | } |
606 | } |
607 | |
608 | private: |
609 | WStringList * m_pList; |
610 | }; // class WStringListHolder |
611 | #endif //!DACCESS_COMPILE |
612 | |
613 | #ifdef FEATURE_COMINTEROP |
614 | //===================================================================================================================== |
615 | // Holder of allocated array of HSTRINGs (helper class for WinRT binders - e.g. code:CLRPrivBinderWinRT::m_rgAltPaths). |
616 | class HSTRINGArrayHolder |
617 | { |
618 | public: |
619 | HSTRINGArrayHolder() |
620 | { |
621 | LIMITED_METHOD_CONTRACT; |
622 | |
623 | m_cValues = 0; |
624 | m_rgValues = nullptr; |
625 | } |
626 | #ifndef DACCESS_COMPILE |
627 | ~HSTRINGArrayHolder() |
628 | { |
629 | LIMITED_METHOD_CONTRACT; |
630 | Destroy(); |
631 | } |
632 | |
633 | // Destroys current array and allocates a new one with cValues elements. |
634 | void Allocate(DWORD cValues) |
635 | { |
636 | STANDARD_VM_CONTRACT; |
637 | |
638 | Destroy(); |
639 | _ASSERTE(m_cValues == 0); |
640 | |
641 | if (cValues > 0) |
642 | { |
643 | m_rgValues = new HSTRING[cValues]; |
644 | m_cValues = cValues; |
645 | |
646 | // Initialize the array values |
647 | for (DWORD i = 0; i < cValues; i++) |
648 | { |
649 | m_rgValues[i] = nullptr; |
650 | } |
651 | } |
652 | } |
653 | #endif //!DACCESS_COMPILE |
654 | |
655 | HSTRING GetAt(DWORD index) const |
656 | { |
657 | LIMITED_METHOD_CONTRACT; |
658 | return m_rgValues[index]; |
659 | } |
660 | |
661 | HSTRING * GetRawArray() |
662 | { |
663 | LIMITED_METHOD_CONTRACT; |
664 | return m_rgValues; |
665 | } |
666 | |
667 | DWORD GetCount() |
668 | { |
669 | LIMITED_METHOD_CONTRACT; |
670 | return m_cValues; |
671 | } |
672 | |
673 | private: |
674 | #ifndef DACCESS_COMPILE |
675 | void Destroy() |
676 | { |
677 | LIMITED_METHOD_CONTRACT; |
678 | |
679 | for (DWORD i = 0; i < m_cValues; i++) |
680 | { |
681 | if (m_rgValues[i] != nullptr) |
682 | { |
683 | WindowsDeleteString(m_rgValues[i]); |
684 | } |
685 | } |
686 | m_cValues = 0; |
687 | |
688 | if (m_rgValues != nullptr) |
689 | { |
690 | delete [] m_rgValues; |
691 | m_rgValues = nullptr; |
692 | } |
693 | } |
694 | #endif //!DACCESS_COMPILE |
695 | |
696 | private: |
697 | DWORD m_cValues; |
698 | HSTRING * m_rgValues; |
699 | }; // class HSTRINGArrayHolder |
700 | |
701 | #endif // FEATURE_COMINTEROP |
702 | |
703 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
704 | ///// ----------------------------- Questionable stuff ------------------------------------------- |
705 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
706 | |
707 | /** probably should be exposed on an instance (of something) method rather that magically calling GetAppDomain() **/ |
708 | ICLRPrivAssembly* RaiseAssemblyResolveEvent(IAssemblyName *pAssemblyName, ICLRPrivAssembly* pRequestingAssembly); |
709 | |
710 | /** Ultimately, only the binder can do ref-def matching, and it should be opaque to CLR. |
711 | This is not trivial to do, however, since we cannot do data conversion as the function is nofault **/ |
712 | BOOL CompareHostBinderSpecs(AssemblySpec* a1, AssemblySpec* a2); |
713 | |
714 | /** PLACEHOLDER - the same issue as CompareHostBinderSpecs applies to hashing assemblyspecs **/ |
715 | } // namespace CLRPrivBinderUtil |
716 | |
717 | #endif // __CLRPRIVBINDERUTIL_H__ |
718 | |