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// File: inspect.cpp
6//
7
8//
9// ClrData object inspection.
10//
11//*****************************************************************************
12
13#include "stdafx.h"
14
15
16HRESULT
17InitFieldIter(DeepFieldDescIterator* fieldIter,
18 TypeHandle typeHandle,
19 bool canHaveFields,
20 ULONG32 flags,
21 IXCLRDataTypeInstance* fromType)
22{
23 // Currently we can't filter on kinds so
24 // require them all.
25 if ((flags & ~CLRDATA_FIELD_ALL_FIELDS) != 0 ||
26 (flags & CLRDATA_TYPE_ALL_KINDS) != CLRDATA_TYPE_ALL_KINDS ||
27 (flags & CLRDATA_FIELD_ALL_LOCATIONS) == 0)
28 {
29 return E_INVALIDARG;
30 }
31
32 if (!canHaveFields)
33 {
34 // Leave default empty initialization.
35 return S_OK;
36 }
37
38 int fieldIterFlags = ApproxFieldDescIterator::ALL_FIELDS;
39
40 if ((flags & CLRDATA_FIELD_FROM_INSTANCE) == 0)
41 {
42 fieldIterFlags &= ~ApproxFieldDescIterator::INSTANCE_FIELDS;
43 }
44 if ((flags & CLRDATA_FIELD_FROM_STATIC) == 0)
45 {
46 fieldIterFlags &= ~ApproxFieldDescIterator::STATIC_FIELDS;
47 }
48
49 bool includeParents;
50
51 if ((flags & CLRDATA_FIELD_IS_INHERITED) == 0)
52 {
53 if (fromType)
54 {
55 typeHandle = ((ClrDataTypeInstance*)fromType)->GetTypeHandle();
56 }
57 includeParents = false;
58 }
59 else if (fromType)
60 {
61 return E_INVALIDARG;
62 }
63 else
64 {
65 includeParents = true;
66 }
67
68 if (typeHandle.IsNull() ||
69 !typeHandle.GetMethodTable() ||
70 !typeHandle.IsRestored())
71 {
72 return E_INVALIDARG;
73 }
74
75 fieldIter->Init(typeHandle.GetMethodTable(), fieldIterFlags, includeParents);
76
77 return S_OK;
78}
79
80ULONG32
81GetTypeFieldValueFlags(TypeHandle typeHandle,
82 FieldDesc* fieldDesc,
83 ULONG32 otherFlags,
84 bool isDeref)
85{
86 otherFlags &= ~(CLRDATA_VALUE_IS_PRIMITIVE |
87 CLRDATA_VALUE_IS_VALUE_TYPE |
88 CLRDATA_VALUE_IS_STRING |
89 CLRDATA_VALUE_IS_ARRAY |
90 CLRDATA_VALUE_IS_REFERENCE |
91 CLRDATA_VALUE_IS_POINTER |
92 CLRDATA_VALUE_IS_ENUM);
93
94 CorElementType eltType;
95
96 if (fieldDesc)
97 {
98 eltType = fieldDesc->GetFieldType();
99 }
100 else
101 {
102 _ASSERTE(!typeHandle.IsNull());
103 eltType = typeHandle.GetInternalCorElementType();
104 }
105
106 if (!isDeref && CorTypeInfo::IsObjRef_NoThrow(eltType))
107 {
108 otherFlags |= CLRDATA_VALUE_IS_REFERENCE;
109 }
110 else if (typeHandle.IsEnum())
111 {
112 otherFlags |= CLRDATA_VALUE_IS_ENUM;
113 }
114 else if (eltType == ELEMENT_TYPE_STRING)
115 {
116 otherFlags |= CLRDATA_VALUE_IS_STRING;
117 }
118 else if (eltType == ELEMENT_TYPE_PTR)
119 {
120 otherFlags |= CLRDATA_VALUE_IS_POINTER;
121 }
122 else if (CorTypeInfo::IsPrimitiveType_NoThrow(eltType))
123 {
124 otherFlags |= CLRDATA_VALUE_IS_PRIMITIVE;
125 }
126 else if (typeHandle.IsArray())
127 {
128 otherFlags |= CLRDATA_VALUE_IS_ARRAY;
129 }
130 else if (typeHandle.IsValueType())
131 {
132 otherFlags |= CLRDATA_VALUE_IS_VALUE_TYPE;
133 }
134 else if (eltType == ELEMENT_TYPE_CLASS)
135 {
136 //
137 // Perform extra checks to identify well-known classes.
138 //
139
140 if ((&g_Mscorlib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING))
141 {
142 otherFlags |= CLRDATA_VALUE_IS_STRING;
143 }
144 }
145
146 if (fieldDesc)
147 {
148 otherFlags &= ~(CLRDATA_VALUE_IS_LITERAL |
149 CLRDATA_VALUE_FROM_INSTANCE |
150 CLRDATA_VALUE_FROM_TASK_LOCAL |
151 CLRDATA_VALUE_FROM_STATIC);
152
153 if ((isDeref ||
154 (otherFlags & CLRDATA_VALUE_IS_REFERENCE) == 0) &&
155 IsFdLiteral(fieldDesc->GetAttributes()))
156 {
157 otherFlags |= CLRDATA_VALUE_IS_LITERAL;
158 }
159
160 if (fieldDesc->IsStatic())
161 {
162 otherFlags |= CLRDATA_VALUE_FROM_STATIC;
163 }
164 else if (fieldDesc->IsThreadStatic())
165 {
166 otherFlags |= CLRDATA_VALUE_FROM_TASK_LOCAL;
167 }
168 else
169 {
170 otherFlags |= CLRDATA_VALUE_FROM_INSTANCE;
171 }
172 }
173
174 return otherFlags;
175}
176
177//----------------------------------------------------------------------------
178//
179// ClrDataValue.
180//
181//----------------------------------------------------------------------------
182
183ClrDataValue::ClrDataValue(ClrDataAccess* dac,
184 AppDomain* appDomain,
185 Thread* thread,
186 ULONG32 flags,
187 TypeHandle typeHandle,
188 ULONG64 baseAddr,
189 ULONG32 numLocs,
190 NativeVarLocation* locs)
191{
192 m_dac = dac;
193 m_dac->AddRef();
194 m_instanceAge = m_dac->m_instanceAge;
195 m_refs = 1;
196 m_appDomain = appDomain;
197 m_thread = thread;
198 m_flags = flags;
199 m_typeHandle = typeHandle;
200 m_baseAddr = baseAddr;
201 m_numLocs = numLocs;
202 if (numLocs)
203 {
204 memcpy(m_locs, locs, numLocs * sizeof(m_locs[0]));
205 }
206
207 if (numLocs && (m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
208 {
209 m_totalSize = sizeof(TADDR);
210 }
211 else
212 {
213 m_totalSize = 0;
214 for (ULONG32 i = 0; i < m_numLocs; i++)
215 {
216 m_totalSize += m_locs[i].size;
217 }
218 }
219}
220
221ClrDataValue::~ClrDataValue(void)
222{
223 m_dac->Release();
224}
225
226STDMETHODIMP
227ClrDataValue::QueryInterface(THIS_
228 IN REFIID interfaceId,
229 OUT PVOID* iface)
230{
231 if (IsEqualIID(interfaceId, IID_IUnknown) ||
232 IsEqualIID(interfaceId, __uuidof(IXCLRDataValue)))
233 {
234 AddRef();
235 *iface = static_cast<IUnknown*>
236 (static_cast<IXCLRDataValue*>(this));
237 return S_OK;
238 }
239 else
240 {
241 *iface = NULL;
242 return E_NOINTERFACE;
243 }
244}
245
246STDMETHODIMP_(ULONG)
247ClrDataValue::AddRef(THIS)
248{
249 return InterlockedIncrement(&m_refs);
250}
251
252STDMETHODIMP_(ULONG)
253ClrDataValue::Release(THIS)
254{
255 SUPPORTS_DAC_HOST_ONLY;
256 LONG newRefs = InterlockedDecrement(&m_refs);
257 if (newRefs == 0)
258 {
259 delete this;
260 }
261 return newRefs;
262}
263
264HRESULT STDMETHODCALLTYPE
265ClrDataValue::GetFlags(
266 /* [out] */ ULONG32 *flags)
267{
268 HRESULT status;
269
270 DAC_ENTER_SUB(m_dac);
271
272 EX_TRY
273 {
274 *flags = m_flags;
275 status = S_OK;
276 }
277 EX_CATCH
278 {
279 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
280 {
281 EX_RETHROW;
282 }
283 }
284 EX_END_CATCH(SwallowAllExceptions)
285
286 DAC_LEAVE();
287 return status;
288}
289
290HRESULT STDMETHODCALLTYPE
291ClrDataValue::GetAddress(
292 /* [out] */ CLRDATA_ADDRESS *address)
293{
294 HRESULT status;
295
296 DAC_ENTER_SUB(m_dac);
297
298 EX_TRY
299 {
300 // This query can only be answered if there's a
301 // single non-register address.
302 if (m_numLocs == 1 &&
303 !m_locs[0].contextReg)
304 {
305 *address = TO_CDADDR(m_locs[0].addr);
306 status = S_OK;
307 }
308 else
309 {
310 status = E_NOINTERFACE;
311 }
312 }
313 EX_CATCH
314 {
315 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
316 {
317 EX_RETHROW;
318 }
319 }
320 EX_END_CATCH(SwallowAllExceptions)
321
322 DAC_LEAVE();
323 return status;
324}
325
326HRESULT STDMETHODCALLTYPE
327ClrDataValue::GetSize(
328 /* [out] */ ULONG64 *size)
329{
330 HRESULT status;
331
332 DAC_ENTER_SUB(m_dac);
333
334 EX_TRY
335 {
336 if (m_totalSize)
337 {
338 *size = m_totalSize;
339 status = S_OK;
340 }
341 else
342 {
343 status = E_NOINTERFACE;
344 }
345 }
346 EX_CATCH
347 {
348 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
349 {
350 EX_RETHROW;
351 }
352 }
353 EX_END_CATCH(SwallowAllExceptions)
354
355 DAC_LEAVE();
356 return status;
357}
358
359HRESULT
360ClrDataValue::IntGetBytes(
361 /* [in] */ ULONG32 bufLen,
362 /* [size_is][out] */ BYTE buffer[ ])
363{
364 HRESULT status;
365
366 NativeVarLocation* loc = m_locs;
367 for (ULONG32 i = 0; i < m_numLocs; i++)
368 {
369 if (loc->contextReg)
370 {
371 memcpy(buffer, (void*)(ULONG_PTR)loc->addr, loc->size);
372 buffer += loc->size;
373 }
374 else
375 {
376 ULONG32 done;
377
378 _ASSERTE(FitsIn<ULONG32>(loc->size));
379 status = m_dac->m_pTarget->
380 ReadVirtual(loc->addr, buffer, static_cast<ULONG32>(loc->size),
381 &done);
382 if (status != S_OK)
383 {
384 return CORDBG_E_READVIRTUAL_FAILURE;
385 }
386 if (done != loc->size)
387 {
388 return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
389 }
390
391 buffer += loc->size;
392 }
393
394 loc++;
395 }
396
397 return S_OK;
398}
399
400HRESULT STDMETHODCALLTYPE
401ClrDataValue::GetBytes(
402 /* [in] */ ULONG32 bufLen,
403 /* [out] */ ULONG32 *dataSize,
404 /* [size_is][out] */ BYTE buffer[ ])
405{
406 HRESULT status;
407
408 DAC_ENTER_SUB(m_dac);
409
410 EX_TRY
411 {
412 if (!m_totalSize)
413 {
414 status = E_NOINTERFACE;
415 goto Exit;
416 }
417
418 if (dataSize)
419 {
420 _ASSERTE(FitsIn<ULONG32>(m_totalSize));
421 *dataSize = static_cast<ULONG32>(m_totalSize);
422 }
423
424 if (bufLen < m_totalSize)
425 {
426 status = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
427 goto Exit;
428 }
429
430 status = IntGetBytes(bufLen, buffer);
431
432 Exit: ;
433 }
434 EX_CATCH
435 {
436 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
437 {
438 EX_RETHROW;
439 }
440 }
441 EX_END_CATCH(SwallowAllExceptions)
442
443 DAC_LEAVE();
444 return status;
445}
446
447HRESULT STDMETHODCALLTYPE
448ClrDataValue::SetBytes(
449 /* [in] */ ULONG32 bufLen,
450 /* [out] */ ULONG32 *dataSize,
451 /* [size_is][in] */ BYTE buffer[ ])
452{
453 HRESULT status;
454
455 DAC_ENTER_SUB(m_dac);
456
457 EX_TRY
458 {
459 NativeVarLocation* loc = NULL;
460
461 if (!m_totalSize)
462 {
463 status = E_NOINTERFACE;
464 goto Exit;
465 }
466
467 if (dataSize)
468 {
469 _ASSERTE(FitsIn<ULONG32>(m_totalSize));
470 *dataSize = static_cast<ULONG32>(m_totalSize);
471 }
472
473 if (bufLen < m_totalSize)
474 {
475 status = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
476 goto Exit;
477 }
478
479 loc = m_locs;
480 for (ULONG32 i = 0; i < m_numLocs; i++)
481 {
482 if (loc->contextReg)
483 {
484 // XXX Microsoft - Context update?
485 // memcpy(buffer, (void*)(ULONG_PTR)loc->addr, loc->size);
486 // buffer += loc->size;
487 // until drew decides, return notimpl
488 status = E_NOTIMPL;
489 goto Exit;
490 }
491 else
492 {
493 _ASSERT(FitsIn<ULONG32>(loc->size));
494 status = m_dac->m_pMutableTarget->
495 WriteVirtual(loc->addr, buffer, static_cast<ULONG32>(loc->size));
496 if (status != S_OK)
497 {
498 goto Exit;
499 }
500
501 buffer += loc->size;
502 }
503
504 loc++;
505 }
506
507 status = S_OK;
508
509 Exit: ;
510 }
511 EX_CATCH
512 {
513 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
514 {
515 EX_RETHROW;
516 }
517 }
518 EX_END_CATCH(SwallowAllExceptions)
519
520 DAC_LEAVE();
521 return status;
522}
523
524HRESULT STDMETHODCALLTYPE
525ClrDataValue::GetType(
526 /* [out] */ IXCLRDataTypeInstance **typeInstance)
527{
528 HRESULT status;
529
530 DAC_ENTER_SUB(m_dac);
531
532 EX_TRY
533 {
534 if ((m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
535 {
536 *typeInstance = NULL;
537 status = S_FALSE;
538 }
539 else if (!m_appDomain ||
540 m_typeHandle.IsNull())
541 {
542 status = E_NOTIMPL;
543 }
544 else
545 {
546 *typeInstance = new (nothrow)
547 ClrDataTypeInstance(m_dac, m_appDomain, m_typeHandle);
548 status = *typeInstance ? S_OK : E_OUTOFMEMORY;
549 }
550 }
551 EX_CATCH
552 {
553 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
554 {
555 EX_RETHROW;
556 }
557 }
558 EX_END_CATCH(SwallowAllExceptions)
559
560 DAC_LEAVE();
561 return status;
562}
563
564HRESULT STDMETHODCALLTYPE
565ClrDataValue::GetNumFields(
566 /* [out] */ ULONG32 *numFields)
567{
568 // XXX Microsoft - Obsolete method, never implemented.
569 return E_UNEXPECTED;
570}
571
572HRESULT STDMETHODCALLTYPE
573ClrDataValue::GetFieldByIndex(
574 /* [in] */ ULONG32 index,
575 /* [out] */ IXCLRDataValue **field,
576 /* [in] */ ULONG32 bufLen,
577 /* [out] */ ULONG32 *nameLen,
578 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
579 /* [out] */ mdFieldDef *token)
580{
581 // XXX Microsoft - Obsolete method, never implemented.
582 return E_UNEXPECTED;
583}
584
585HRESULT STDMETHODCALLTYPE
586ClrDataValue::GetNumFields2(
587 /* [in] */ ULONG32 flags,
588 /* [in] */ IXCLRDataTypeInstance *fromType,
589 /* [out] */ ULONG32 *numFields)
590{
591 HRESULT status;
592
593 DAC_ENTER_SUB(m_dac);
594
595 EX_TRY
596 {
597 DeepFieldDescIterator fieldIter;
598
599 if ((status = InitFieldIter(&fieldIter, m_typeHandle, CanHaveFields(),
600 flags, fromType)) == S_OK)
601 {
602 *numFields = fieldIter.Count();
603 }
604 }
605 EX_CATCH
606 {
607 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
608 {
609 EX_RETHROW;
610 }
611 }
612 EX_END_CATCH(SwallowAllExceptions)
613
614 DAC_LEAVE();
615 return status;
616}
617
618HRESULT STDMETHODCALLTYPE
619ClrDataValue::StartEnumFields(
620 /* [in] */ ULONG32 flags,
621 /* [in] */ IXCLRDataTypeInstance *fromType,
622 /* [out] */ CLRDATA_ENUM *handle)
623{
624 HRESULT status;
625
626 DAC_ENTER_SUB(m_dac);
627
628 EX_TRY
629 {
630 status = SplitName::
631 CdStartField(NULL,
632 0,
633 flags,
634 fromType,
635 m_typeHandle,
636 NULL,
637 mdTypeDefNil,
638 m_baseAddr,
639 m_thread,
640 NULL,
641 m_appDomain,
642 NULL,
643 NULL,
644 handle);
645 }
646 EX_CATCH
647 {
648 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
649 {
650 EX_RETHROW;
651 }
652 }
653 EX_END_CATCH(SwallowAllExceptions)
654
655 DAC_LEAVE();
656 return status;
657}
658
659HRESULT STDMETHODCALLTYPE
660ClrDataValue::EnumField(
661 /* [out][in] */ CLRDATA_ENUM *handle,
662 /* [out] */ IXCLRDataValue **field,
663 /* [in] */ ULONG32 nameBufLen,
664 /* [out] */ ULONG32 *nameLen,
665 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
666 /* [out] */ mdFieldDef *token)
667{
668 return EnumField2(handle, field, nameBufLen, nameLen, nameBuf,
669 NULL, token);
670}
671
672HRESULT STDMETHODCALLTYPE
673ClrDataValue::EnumField2(
674 /* [out][in] */ CLRDATA_ENUM *handle,
675 /* [out] */ IXCLRDataValue **field,
676 /* [in] */ ULONG32 nameBufLen,
677 /* [out] */ ULONG32 *nameLen,
678 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
679 /* [out] */ IXCLRDataModule** tokenScope,
680 /* [out] */ mdFieldDef *token)
681{
682 HRESULT status;
683
684 DAC_ENTER_SUB(m_dac);
685
686 EX_TRY
687 {
688 status = SplitName::CdNextField(m_dac, handle, NULL, NULL, field,
689 nameBufLen, nameLen, nameBuf,
690 tokenScope, token);
691 }
692 EX_CATCH
693 {
694 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
695 {
696 EX_RETHROW;
697 }
698 }
699 EX_END_CATCH(SwallowAllExceptions)
700
701 DAC_LEAVE();
702 return status;
703}
704
705HRESULT STDMETHODCALLTYPE
706ClrDataValue::EndEnumFields(
707 /* [in] */ CLRDATA_ENUM handle)
708{
709 HRESULT status;
710
711 DAC_ENTER_SUB(m_dac);
712
713 EX_TRY
714 {
715 status = SplitName::CdEnd(handle);
716 }
717 EX_CATCH
718 {
719 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
720 {
721 EX_RETHROW;
722 }
723 }
724 EX_END_CATCH(SwallowAllExceptions)
725
726 DAC_LEAVE();
727 return status;
728}
729
730HRESULT STDMETHODCALLTYPE
731ClrDataValue::StartEnumFieldsByName(
732 /* [in] */ LPCWSTR name,
733 /* [in] */ ULONG32 nameFlags,
734 /* [in] */ ULONG32 fieldFlags,
735 /* [in] */ IXCLRDataTypeInstance *fromType,
736 /* [out] */ CLRDATA_ENUM *handle)
737{
738 HRESULT status;
739
740 DAC_ENTER_SUB(m_dac);
741
742 EX_TRY
743 {
744 status = SplitName::
745 CdStartField(name,
746 nameFlags,
747 fieldFlags,
748 fromType,
749 m_typeHandle,
750 NULL,
751 mdTypeDefNil,
752 m_baseAddr,
753 m_thread,
754 NULL,
755 m_appDomain,
756 NULL,
757 NULL,
758 handle);
759 }
760 EX_CATCH
761 {
762 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
763 {
764 EX_RETHROW;
765 }
766 }
767 EX_END_CATCH(SwallowAllExceptions)
768
769 DAC_LEAVE();
770 return status;
771}
772
773HRESULT STDMETHODCALLTYPE
774ClrDataValue::EnumFieldByName(
775 /* [out][in] */ CLRDATA_ENUM *handle,
776 /* [out] */ IXCLRDataValue **field,
777 /* [out] */ mdFieldDef *token)
778{
779 return EnumFieldByName2(handle, field, NULL, token);
780}
781
782HRESULT STDMETHODCALLTYPE
783ClrDataValue::EnumFieldByName2(
784 /* [out][in] */ CLRDATA_ENUM *handle,
785 /* [out] */ IXCLRDataValue **field,
786 /* [out] */ IXCLRDataModule** tokenScope,
787 /* [out] */ mdFieldDef *token)
788{
789 HRESULT status;
790
791 DAC_ENTER_SUB(m_dac);
792
793 EX_TRY
794 {
795 status = SplitName::CdNextField(m_dac, handle, NULL, NULL, field,
796 0, NULL, NULL,
797 tokenScope, token);
798 }
799 EX_CATCH
800 {
801 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
802 {
803 EX_RETHROW;
804 }
805 }
806 EX_END_CATCH(SwallowAllExceptions)
807
808 DAC_LEAVE();
809 return status;
810}
811
812HRESULT STDMETHODCALLTYPE
813ClrDataValue::EndEnumFieldsByName(
814 /* [in] */ CLRDATA_ENUM handle)
815{
816 HRESULT status;
817
818 DAC_ENTER_SUB(m_dac);
819
820 EX_TRY
821 {
822 status = SplitName::CdEnd(handle);
823 }
824 EX_CATCH
825 {
826 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
827 {
828 EX_RETHROW;
829 }
830 }
831 EX_END_CATCH(SwallowAllExceptions)
832
833 DAC_LEAVE();
834 return status;
835}
836
837HRESULT STDMETHODCALLTYPE
838ClrDataValue::GetFieldByToken(
839 /* [in] */ mdFieldDef token,
840 /* [out] */ IXCLRDataValue **field,
841 /* [in] */ ULONG32 bufLen,
842 /* [out] */ ULONG32 *nameLen,
843 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
844{
845 return GetFieldByToken2(NULL, token, field, bufLen, nameLen, nameBuf);
846}
847
848HRESULT STDMETHODCALLTYPE
849ClrDataValue::GetFieldByToken2(
850 /* [in] */ IXCLRDataModule* tokenScope,
851 /* [in] */ mdFieldDef token,
852 /* [out] */ IXCLRDataValue **field,
853 /* [in] */ ULONG32 bufLen,
854 /* [out] */ ULONG32 *nameLen,
855 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
856{
857 HRESULT status;
858
859 DAC_ENTER_SUB(m_dac);
860
861 EX_TRY
862 {
863 DeepFieldDescIterator fieldIter;
864
865 if ((status = InitFieldIter(&fieldIter, m_typeHandle, CanHaveFields(),
866 CLRDATA_VALUE_ALL_FIELDS, NULL)) == S_OK)
867 {
868 FieldDesc* fieldDesc;
869
870 status = E_INVALIDARG;
871 while ((fieldDesc = fieldIter.Next()))
872 {
873 if ((!tokenScope ||
874 PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
875 GetModule()) ==
876 PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
877 fieldDesc->GetMemberDef() == token)
878 {
879 status = NewFromSubField(fieldDesc,
880 fieldIter.
881 IsFieldFromParentClass() ?
882 CLRDATA_VALUE_IS_INHERITED : 0,
883 NULL, field,
884 bufLen, nameLen, nameBuf,
885 NULL, NULL);
886 break;
887 }
888 }
889 }
890 }
891 EX_CATCH
892 {
893 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
894 {
895 EX_RETHROW;
896 }
897 }
898 EX_END_CATCH(SwallowAllExceptions)
899
900 DAC_LEAVE();
901 return status;
902}
903
904HRESULT
905ClrDataValue::GetRefAssociatedValue(IXCLRDataValue** assocValue)
906{
907 HRESULT status;
908
909 if (m_typeHandle.IsNull())
910 {
911 return E_NOINTERFACE;
912 }
913
914 TADDR refAddr;
915
916 _ASSERTE(m_totalSize == sizeof(refAddr));
917
918 if ((status = IntGetBytes(sizeof(refAddr),
919 (PBYTE)&refAddr)) != S_OK)
920 {
921 return status;
922 }
923
924 // We assume that objrefs always refer
925 // to objects so there is no ref chain.
926 ULONG32 valueFlags =
927 GetTypeFieldValueFlags(m_typeHandle, NULL,
928 m_flags & CLRDATA_VALUE_ALL_LOCATIONS, true);
929
930 NativeVarLocation loc;
931
932 loc.addr = TO_CDADDR(refAddr);
933 // XXX Microsoft - Good way to get the right size for everything?
934 loc.size = (m_typeHandle.GetMethodTable())->GetBaseSize();
935 loc.contextReg = false;
936
937 *assocValue = new (nothrow)
938 ClrDataValue(m_dac,
939 m_appDomain,
940 m_thread,
941 valueFlags,
942 m_typeHandle,
943 loc.addr,
944 1,
945 &loc);
946 return *assocValue ? S_OK : E_OUTOFMEMORY;
947}
948
949HRESULT STDMETHODCALLTYPE
950ClrDataValue::GetAssociatedValue(
951 /* [out] */ IXCLRDataValue **assocValue)
952{
953 HRESULT status;
954
955 DAC_ENTER_SUB(m_dac);
956
957 EX_TRY
958 {
959 if (m_numLocs && (m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
960 {
961 status = GetRefAssociatedValue(assocValue);
962 }
963 else
964 {
965 status = E_NOINTERFACE;
966 }
967 }
968 EX_CATCH
969 {
970 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
971 {
972 EX_RETHROW;
973 }
974 }
975 EX_END_CATCH(SwallowAllExceptions)
976
977 DAC_LEAVE();
978 return status;
979}
980
981HRESULT STDMETHODCALLTYPE
982ClrDataValue::GetAssociatedType(
983 /* [out] */ IXCLRDataTypeInstance **assocType)
984{
985 HRESULT status;
986
987 DAC_ENTER_SUB(m_dac);
988
989 EX_TRY
990 {
991 TypeHandle dacType;
992
993 if ((m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
994 {
995 dacType = m_typeHandle;
996 }
997 else if ((m_flags & CLRDATA_VALUE_IS_ARRAY) != 0)
998 {
999 ArrayBase* arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
1000 dacType = arrayBase->GetArrayElementTypeHandle();
1001 }
1002
1003 if (dacType.IsNull())
1004 {
1005 status = E_NOINTERFACE;
1006 }
1007 else
1008 {
1009 *assocType = new (nothrow)
1010 ClrDataTypeInstance(m_dac,
1011 m_appDomain,
1012 dacType);
1013 status = *assocType ? S_OK : E_OUTOFMEMORY;
1014 }
1015 }
1016 EX_CATCH
1017 {
1018 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1019 {
1020 EX_RETHROW;
1021 }
1022 }
1023 EX_END_CATCH(SwallowAllExceptions)
1024
1025 DAC_LEAVE();
1026 return status;
1027}
1028
1029HRESULT STDMETHODCALLTYPE
1030ClrDataValue::GetString(
1031 /* [in] */ ULONG32 bufLen,
1032 /* [out] */ ULONG32 *strLen,
1033 /* [size_is][out] */ __out_ecount_part(bufLen, *strLen) WCHAR str[ ])
1034{
1035 HRESULT status;
1036
1037 DAC_ENTER_SUB(m_dac);
1038
1039 EX_TRY
1040 {
1041 if ((m_flags & CLRDATA_VALUE_IS_STRING) != 0)
1042 {
1043 STRINGREF message = STRINGREF(TO_TADDR(m_baseAddr));
1044
1045 PWSTR msgStr = DacInstantiateStringW((TADDR)message->GetBuffer(),
1046 message->GetStringLength(),
1047 true);
1048
1049 if (strLen)
1050 {
1051 *strLen = static_cast<ULONG32>(wcslen(msgStr) + 1);
1052 }
1053 status = StringCchCopy(str, bufLen, msgStr) == S_OK ?
1054 S_OK : S_FALSE;
1055 }
1056 else
1057 {
1058 status = E_INVALIDARG;
1059 }
1060 }
1061 EX_CATCH
1062 {
1063 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1064 {
1065 EX_RETHROW;
1066 }
1067 }
1068 EX_END_CATCH(SwallowAllExceptions)
1069
1070 DAC_LEAVE();
1071 return status;
1072}
1073
1074HRESULT STDMETHODCALLTYPE
1075ClrDataValue::GetArrayProperties(
1076 /* [out] */ ULONG32 *rank,
1077 /* [out] */ ULONG32 *totalElements,
1078 /* [in] */ ULONG32 numDim,
1079 /* [size_is][out] */ ULONG32 dims[ ],
1080 /* [in] */ ULONG32 numBases,
1081 /* [size_is][out] */ LONG32 bases[ ])
1082{
1083 HRESULT status;
1084
1085 DAC_ENTER_SUB(m_dac);
1086
1087 EX_TRY
1088 {
1089 if ((m_flags & CLRDATA_VALUE_IS_ARRAY) != 0)
1090 {
1091 ArrayBase* arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
1092 unsigned baseRank = arrayBase->GetRank();
1093 unsigned i;
1094
1095 if (rank)
1096 {
1097 *rank = baseRank;
1098 }
1099
1100 if (totalElements)
1101 {
1102 *totalElements = arrayBase->GetNumComponents();
1103 }
1104
1105 if (numDim)
1106 {
1107 PTR_INT32 bounds = arrayBase->GetBoundsPtr();
1108
1109 for (i = 0; i < baseRank; i++)
1110 {
1111 if (i < numDim)
1112 {
1113 dims[i] = bounds[i];
1114 }
1115 else
1116 {
1117 break;
1118 }
1119 }
1120 }
1121
1122 if (numBases)
1123 {
1124 PTR_INT32 lowBounds = arrayBase->GetLowerBoundsPtr();
1125
1126 for (i = 0; i < baseRank; i++)
1127 {
1128 if (i < numBases)
1129 {
1130 bases[i] = lowBounds[i];
1131 }
1132 else
1133 {
1134 break;
1135 }
1136 }
1137 }
1138
1139 status = S_OK;
1140 }
1141 else
1142 {
1143 status = E_INVALIDARG;
1144 }
1145 }
1146 EX_CATCH
1147 {
1148 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1149 {
1150 EX_RETHROW;
1151 }
1152 }
1153 EX_END_CATCH(SwallowAllExceptions)
1154
1155 DAC_LEAVE();
1156 return status;
1157}
1158
1159HRESULT STDMETHODCALLTYPE
1160ClrDataValue::GetArrayElement(
1161 /* [in] */ ULONG32 numInd,
1162 /* [size_is][in] */ LONG32 indices[ ],
1163 /* [out] */ IXCLRDataValue **value)
1164{
1165 HRESULT status;
1166
1167 DAC_ENTER_SUB(m_dac);
1168
1169 EX_TRY
1170 {
1171 PTR_INT32 bounds, lowBounds;
1172 TypeHandle eltType;
1173
1174 if ((m_flags & CLRDATA_VALUE_IS_ARRAY) == 0)
1175 {
1176 status = E_INVALIDARG;
1177 goto Exit;
1178 }
1179
1180 ArrayBase* arrayBase;
1181 unsigned baseRank;
1182
1183 arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
1184 baseRank = arrayBase->GetRank();
1185 if (numInd != baseRank)
1186 {
1187 status = E_INVALIDARG;
1188 goto Exit;
1189 }
1190
1191 eltType = arrayBase->GetArrayElementTypeHandle();
1192 if (eltType.IsNull())
1193 {
1194 status = E_INVALIDARG;
1195 goto Exit;
1196 }
1197
1198 unsigned dim;
1199 ULONG64 offs;
1200 SIZE_T dimSize;
1201
1202 dim = baseRank;
1203 offs = TO_CDADDR(PTR_TO_TADDR(arrayBase->GetDataPtr()));
1204 dimSize = arrayBase->GetComponentSize();
1205 bounds = arrayBase->GetBoundsPtr();
1206 lowBounds = arrayBase->GetLowerBoundsPtr();
1207
1208 while (dim-- > 0)
1209 {
1210 if (indices[dim] < lowBounds[dim])
1211 {
1212 status = E_INVALIDARG;
1213 goto Exit;
1214 }
1215
1216 UINT32 uindex = (UINT32)(indices[dim] - lowBounds[dim]);
1217 if (uindex >= (UINT32)bounds[dim])
1218 {
1219 status = E_INVALIDARG;
1220 goto Exit;
1221 }
1222
1223 offs += dimSize * uindex;
1224
1225 dimSize *= (UINT64)bounds[dim];
1226 }
1227
1228 NativeVarLocation loc;
1229
1230 loc.addr = offs;
1231 loc.size = eltType.GetSize();
1232 loc.contextReg = false;
1233
1234 *value = new (nothrow)
1235 ClrDataValue(m_dac, m_appDomain, m_thread,
1236 GetTypeFieldValueFlags(eltType, NULL, 0, false),
1237 eltType, offs, 1, &loc);
1238 status = *value ? S_OK : E_OUTOFMEMORY;
1239
1240 Exit: ;
1241 }
1242 EX_CATCH
1243 {
1244 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1245 {
1246 EX_RETHROW;
1247 }
1248 }
1249 EX_END_CATCH(SwallowAllExceptions)
1250
1251 DAC_LEAVE();
1252 return status;
1253}
1254
1255HRESULT STDMETHODCALLTYPE
1256ClrDataValue::GetNumLocations(
1257 /* [out] */ ULONG32* numLocs)
1258{
1259 HRESULT status;
1260
1261 DAC_ENTER_SUB(m_dac);
1262
1263 EX_TRY
1264 {
1265 *numLocs = m_numLocs;
1266 status = S_OK;
1267 }
1268 EX_CATCH
1269 {
1270 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1271 {
1272 EX_RETHROW;
1273 }
1274 }
1275 EX_END_CATCH(SwallowAllExceptions)
1276
1277 DAC_LEAVE();
1278 return status;
1279}
1280
1281HRESULT STDMETHODCALLTYPE
1282ClrDataValue::GetLocationByIndex(
1283 /* [in] */ ULONG32 loc,
1284 /* [out] */ ULONG32* flags,
1285 /* [out] */ CLRDATA_ADDRESS* arg)
1286{
1287 HRESULT status;
1288
1289 DAC_ENTER_SUB(m_dac);
1290
1291 EX_TRY
1292 {
1293 if (loc < m_numLocs)
1294 {
1295 if (m_locs[loc].contextReg)
1296 {
1297 *flags = CLRDATA_VLOC_REGISTER;
1298 *arg = 0;
1299 }
1300 else
1301 {
1302 *flags = CLRDATA_VLOC_MEMORY;
1303 *arg = TO_CDADDR(m_locs[loc].addr);
1304 }
1305
1306 status = S_OK;
1307 }
1308 else
1309 {
1310 status = E_INVALIDARG;
1311 }
1312 }
1313 EX_CATCH
1314 {
1315 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1316 {
1317 EX_RETHROW;
1318 }
1319 }
1320 EX_END_CATCH(SwallowAllExceptions)
1321
1322 DAC_LEAVE();
1323 return status;
1324}
1325
1326HRESULT STDMETHODCALLTYPE
1327ClrDataValue::Request(
1328 /* [in] */ ULONG32 reqCode,
1329 /* [in] */ ULONG32 inBufferSize,
1330 /* [size_is][in] */ BYTE *inBuffer,
1331 /* [in] */ ULONG32 outBufferSize,
1332 /* [size_is][out] */ BYTE *outBuffer)
1333{
1334 HRESULT status;
1335
1336 DAC_ENTER_SUB(m_dac);
1337
1338 EX_TRY
1339 {
1340 switch(reqCode)
1341 {
1342 case CLRDATA_REQUEST_REVISION:
1343 if (inBufferSize != 0 ||
1344 inBuffer ||
1345 outBufferSize != sizeof(ULONG32))
1346 {
1347 status = E_INVALIDARG;
1348 }
1349 else
1350 {
1351 *(ULONG32*)outBuffer = 3;
1352 status = S_OK;
1353 }
1354 break;
1355
1356 default:
1357 status = E_INVALIDARG;
1358 break;
1359 }
1360 }
1361 EX_CATCH
1362 {
1363 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1364 {
1365 EX_RETHROW;
1366 }
1367 }
1368 EX_END_CATCH(SwallowAllExceptions)
1369
1370 DAC_LEAVE();
1371 return status;
1372}
1373
1374HRESULT
1375ClrDataValue::NewFromFieldDesc(ClrDataAccess* dac,
1376 AppDomain* appDomain,
1377 ULONG32 flags,
1378 FieldDesc* fieldDesc,
1379 ULONG64 objBase,
1380 Thread* tlsThread,
1381 ClrDataValue** value,
1382 IXCLRDataValue** pubValue,
1383 ULONG32 nameBufRetLen,
1384 ULONG32 *nameLenRet,
1385 __out_ecount_part_opt(nameBufRetLen, *nameLenRet) WCHAR nameBufRet[ ],
1386 IXCLRDataModule** tokenScopeRet,
1387 mdFieldDef *tokenRet)
1388{
1389 HRESULT status;
1390 ClrDataValue* field;
1391 ULONG numLocs = 1;
1392 NativeVarLocation varLoc, *locs = &varLoc;
1393 ULONG64 baseAddr;
1394 LPCUTF8 szFieldName;
1395
1396 status = fieldDesc->GetName_NoThrow(&szFieldName);
1397 if (status != S_OK)
1398 {
1399 return status;
1400 }
1401
1402 status = ConvertUtf8(
1403 szFieldName,
1404 nameBufRetLen,
1405 nameLenRet,
1406 nameBufRet);
1407 if (status != S_OK)
1408 {
1409 return status;
1410 }
1411
1412 if (tokenRet != NULL)
1413 {
1414 *tokenRet = fieldDesc->GetMemberDef();
1415 }
1416
1417 if (fieldDesc->GetEnclosingMethodTable()->ContainsGenericVariables())
1418 {
1419 // This field is for a generic type definition and
1420 // so doesn't have a real location. Produce
1421 // a placeholder no-data value.
1422 numLocs = 0;
1423 locs = NULL;
1424 baseAddr = 0;
1425 }
1426 else if (fieldDesc->IsThreadStatic())
1427 {
1428 if (!tlsThread)
1429 {
1430 return E_INVALIDARG;
1431 }
1432
1433 baseAddr =
1434 TO_CDADDR(tlsThread->GetStaticFieldAddrNoCreate(fieldDesc));
1435 }
1436 else if (fieldDesc->IsStatic())
1437 {
1438 baseAddr = TO_CDADDR
1439 (PTR_TO_TADDR(fieldDesc->GetStaticAddressHandle
1440 (fieldDesc->GetBaseInDomain(appDomain))));
1441 }
1442 else
1443 {
1444 // objBase is basically a CLRDATA_ADDRESS, which is a pointer-sized target address sign-extened to
1445 // 64-bit. We need to get a TADDR here, which is a pointer-size unsigned value.
1446 baseAddr = TO_CDADDR(PTR_TO_TADDR(fieldDesc->GetAddress(PTR_VOID(CLRDATA_ADDRESS_TO_TADDR(objBase)))));
1447 }
1448
1449 if (locs)
1450 {
1451 locs->addr = baseAddr;
1452 locs->size = fieldDesc->GetSize();
1453 locs->contextReg = false;
1454 }
1455
1456 TypeHandle typeHandle = fieldDesc->LookupFieldTypeHandle();
1457
1458 // We allow no-type situations for reference fields
1459 // as they can still be useful even though they cannot
1460 // be expanded. This is also a common case where the
1461 // referred-to type may not be loaded if the field
1462 // is holding null.
1463 if (typeHandle.IsNull() && !fieldDesc->IsObjRef())
1464 {
1465 return E_INVALIDARG;
1466 }
1467
1468 flags = GetTypeFieldValueFlags(typeHandle, fieldDesc, flags, false);
1469
1470 if (tokenScopeRet)
1471 {
1472 *tokenScopeRet = new (nothrow)
1473 ClrDataModule(dac, fieldDesc->GetModule());
1474 if (!*tokenScopeRet)
1475 {
1476 return E_OUTOFMEMORY;
1477 }
1478 }
1479
1480 field = new (nothrow) ClrDataValue(dac,
1481 appDomain,
1482 tlsThread,
1483 flags,
1484 typeHandle,
1485 baseAddr,
1486 numLocs,
1487 locs);
1488 if (value)
1489 {
1490 *value = field;
1491 }
1492 if (pubValue)
1493 {
1494 *pubValue = field;
1495 }
1496
1497 if (!field)
1498 {
1499 if (tokenScopeRet)
1500 {
1501 delete (ClrDataModule*)*tokenScopeRet;
1502 }
1503 return E_OUTOFMEMORY;
1504 }
1505
1506 return S_OK;
1507}
1508
1509//----------------------------------------------------------------------------
1510//
1511// ClrDataTypeDefinition.
1512//
1513//----------------------------------------------------------------------------
1514
1515ClrDataTypeDefinition::ClrDataTypeDefinition(ClrDataAccess* dac,
1516 Module* module,
1517 mdTypeDef token,
1518 TypeHandle typeHandle)
1519{
1520 m_dac = dac;
1521 m_dac->AddRef();
1522 m_instanceAge = m_dac->m_instanceAge;
1523 m_refs = 1;
1524 m_module = module;
1525 m_token = token;
1526 m_typeHandle = typeHandle;
1527}
1528
1529ClrDataTypeDefinition::~ClrDataTypeDefinition(void)
1530{
1531 m_dac->Release();
1532}
1533
1534STDMETHODIMP
1535ClrDataTypeDefinition::QueryInterface(THIS_
1536 IN REFIID interfaceId,
1537 OUT PVOID* iface)
1538{
1539 if (IsEqualIID(interfaceId, IID_IUnknown) ||
1540 IsEqualIID(interfaceId, __uuidof(IXCLRDataTypeDefinition)))
1541 {
1542 AddRef();
1543 *iface = static_cast<IUnknown*>
1544 (static_cast<IXCLRDataTypeDefinition*>(this));
1545 return S_OK;
1546 }
1547 else
1548 {
1549 *iface = NULL;
1550 return E_NOINTERFACE;
1551 }
1552}
1553
1554STDMETHODIMP_(ULONG)
1555ClrDataTypeDefinition::AddRef(THIS)
1556{
1557 return InterlockedIncrement(&m_refs);
1558}
1559
1560STDMETHODIMP_(ULONG)
1561ClrDataTypeDefinition::Release(THIS)
1562{
1563 SUPPORTS_DAC_HOST_ONLY;
1564 LONG newRefs = InterlockedDecrement(&m_refs);
1565 if (newRefs == 0)
1566 {
1567 delete this;
1568 }
1569 return newRefs;
1570}
1571
1572HRESULT STDMETHODCALLTYPE
1573ClrDataTypeDefinition::GetModule(
1574 /* [out] */ IXCLRDataModule **mod)
1575{
1576 HRESULT status;
1577
1578 DAC_ENTER_SUB(m_dac);
1579
1580 EX_TRY
1581 {
1582 *mod = new (nothrow)
1583 ClrDataModule(m_dac, m_module);
1584 status = *mod ? S_OK : E_OUTOFMEMORY;
1585 }
1586 EX_CATCH
1587 {
1588 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1589 {
1590 EX_RETHROW;
1591 }
1592 }
1593 EX_END_CATCH(SwallowAllExceptions)
1594
1595 DAC_LEAVE();
1596 return status;
1597}
1598
1599HRESULT STDMETHODCALLTYPE
1600ClrDataTypeDefinition::StartEnumMethodDefinitions(
1601 /* [out] */ CLRDATA_ENUM* handle)
1602{
1603 HRESULT status;
1604
1605 DAC_ENTER_SUB(m_dac);
1606
1607 EX_TRY
1608 {
1609 status = MetaEnum::New(m_module,
1610 mdtMethodDef,
1611 m_token,
1612 NULL,
1613 NULL,
1614 handle);
1615 }
1616 EX_CATCH
1617 {
1618 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1619 {
1620 EX_RETHROW;
1621 }
1622 }
1623 EX_END_CATCH(SwallowAllExceptions)
1624
1625 DAC_LEAVE();
1626 return status;
1627}
1628
1629HRESULT STDMETHODCALLTYPE
1630ClrDataTypeDefinition::EnumMethodDefinition(
1631 /* [in, out] */ CLRDATA_ENUM* handle,
1632 /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
1633{
1634 HRESULT status;
1635
1636 DAC_ENTER_SUB(m_dac);
1637
1638 EX_TRY
1639 {
1640 mdMethodDef token;
1641
1642 if ((status = MetaEnum::CdNextToken(handle, &token)) == S_OK)
1643 {
1644 status = ClrDataMethodDefinition::
1645 NewFromModule(m_dac,
1646 m_module,
1647 token,
1648 NULL,
1649 methodDefinition);
1650 }
1651 }
1652 EX_CATCH
1653 {
1654 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1655 {
1656 EX_RETHROW;
1657 }
1658 }
1659 EX_END_CATCH(SwallowAllExceptions)
1660
1661 DAC_LEAVE();
1662 return status;
1663}
1664
1665HRESULT STDMETHODCALLTYPE
1666ClrDataTypeDefinition::EndEnumMethodDefinitions(
1667 /* [in] */ CLRDATA_ENUM handle)
1668{
1669 HRESULT status;
1670
1671 DAC_ENTER_SUB(m_dac);
1672
1673 EX_TRY
1674 {
1675 status = MetaEnum::CdEnd(handle);
1676 }
1677 EX_CATCH
1678 {
1679 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1680 {
1681 EX_RETHROW;
1682 }
1683 }
1684 EX_END_CATCH(SwallowAllExceptions)
1685
1686 DAC_LEAVE();
1687 return status;
1688}
1689
1690HRESULT STDMETHODCALLTYPE
1691ClrDataTypeDefinition::StartEnumMethodDefinitionsByName(
1692 /* [in] */ LPCWSTR name,
1693 /* [in] */ ULONG32 flags,
1694 /* [out] */ CLRDATA_ENUM* handle)
1695{
1696 HRESULT status;
1697
1698 DAC_ENTER_SUB(m_dac);
1699
1700 EX_TRY
1701 {
1702 status = SplitName::CdStartMethod(name,
1703 flags,
1704 m_module,
1705 m_token,
1706 NULL,
1707 NULL,
1708 NULL,
1709 handle);
1710 }
1711 EX_CATCH
1712 {
1713 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1714 {
1715 EX_RETHROW;
1716 }
1717 }
1718 EX_END_CATCH(SwallowAllExceptions)
1719
1720 DAC_LEAVE();
1721 return status;
1722}
1723
1724HRESULT STDMETHODCALLTYPE
1725ClrDataTypeDefinition::EnumMethodDefinitionByName(
1726 /* [out][in] */ CLRDATA_ENUM* handle,
1727 /* [out] */ IXCLRDataMethodDefinition **method)
1728{
1729 HRESULT status;
1730
1731 DAC_ENTER_SUB(m_dac);
1732
1733 EX_TRY
1734 {
1735 mdMethodDef token;
1736
1737 if ((status = SplitName::CdNextMethod(handle, &token)) == S_OK)
1738 {
1739 status = ClrDataMethodDefinition::
1740 NewFromModule(m_dac,
1741 m_module,
1742 token,
1743 NULL,
1744 method);
1745 }
1746 }
1747 EX_CATCH
1748 {
1749 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1750 {
1751 EX_RETHROW;
1752 }
1753 }
1754 EX_END_CATCH(SwallowAllExceptions)
1755
1756 DAC_LEAVE();
1757 return status;
1758}
1759
1760HRESULT STDMETHODCALLTYPE
1761ClrDataTypeDefinition::EndEnumMethodDefinitionsByName(
1762 /* [in] */ CLRDATA_ENUM handle)
1763{
1764 HRESULT status;
1765
1766 DAC_ENTER_SUB(m_dac);
1767
1768 EX_TRY
1769 {
1770 status = SplitName::CdEnd(handle);
1771 }
1772 EX_CATCH
1773 {
1774 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1775 {
1776 EX_RETHROW;
1777 }
1778 }
1779 EX_END_CATCH(SwallowAllExceptions)
1780
1781 DAC_LEAVE();
1782 return status;
1783}
1784
1785HRESULT STDMETHODCALLTYPE
1786ClrDataTypeDefinition::GetMethodDefinitionByToken(
1787 /* [in] */ mdMethodDef token,
1788 /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
1789{
1790 HRESULT status;
1791
1792 // This isn't critically necessary but it prevents
1793 // an assert in the metadata code.
1794 if (TypeFromToken(token) != mdtMethodDef)
1795 {
1796 return E_INVALIDARG;
1797 }
1798
1799 DAC_ENTER_SUB(m_dac);
1800
1801 EX_TRY
1802 {
1803 status = ClrDataMethodDefinition::
1804 NewFromModule(m_dac,
1805 m_module,
1806 token,
1807 NULL,
1808 methodDefinition);
1809 }
1810 EX_CATCH
1811 {
1812 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1813 {
1814 EX_RETHROW;
1815 }
1816 }
1817 EX_END_CATCH(SwallowAllExceptions)
1818
1819 DAC_LEAVE();
1820 return status;
1821}
1822
1823HRESULT STDMETHODCALLTYPE
1824ClrDataTypeDefinition::StartEnumInstances(
1825 /* [in] */ IXCLRDataAppDomain* appDomain,
1826 /* [out] */ CLRDATA_ENUM *handle)
1827{
1828 HRESULT status;
1829
1830 DAC_ENTER_SUB(m_dac);
1831
1832 EX_TRY
1833 {
1834 // XXX Microsoft.
1835 status = E_NOTIMPL;
1836 }
1837 EX_CATCH
1838 {
1839 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1840 {
1841 EX_RETHROW;
1842 }
1843 }
1844 EX_END_CATCH(SwallowAllExceptions)
1845
1846 DAC_LEAVE();
1847 return status;
1848}
1849
1850HRESULT STDMETHODCALLTYPE
1851ClrDataTypeDefinition::EnumInstance(
1852 /* [out][in] */ CLRDATA_ENUM *handle,
1853 /* [out] */ IXCLRDataTypeInstance **instance)
1854{
1855 HRESULT status;
1856
1857 DAC_ENTER_SUB(m_dac);
1858
1859 EX_TRY
1860 {
1861 // XXX Microsoft.
1862 status = E_NOTIMPL;
1863 }
1864 EX_CATCH
1865 {
1866 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1867 {
1868 EX_RETHROW;
1869 }
1870 }
1871 EX_END_CATCH(SwallowAllExceptions)
1872
1873 DAC_LEAVE();
1874 return status;
1875}
1876
1877HRESULT STDMETHODCALLTYPE
1878ClrDataTypeDefinition::EndEnumInstances(
1879 /* [in] */ CLRDATA_ENUM handle)
1880{
1881 HRESULT status;
1882
1883 DAC_ENTER_SUB(m_dac);
1884
1885 EX_TRY
1886 {
1887 // XXX Microsoft.
1888 status = E_NOTIMPL;
1889 }
1890 EX_CATCH
1891 {
1892 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1893 {
1894 EX_RETHROW;
1895 }
1896 }
1897 EX_END_CATCH(SwallowAllExceptions)
1898
1899 DAC_LEAVE();
1900 return status;
1901}
1902
1903HRESULT STDMETHODCALLTYPE
1904ClrDataTypeDefinition::GetNumFields(
1905 /* [in] */ ULONG32 flags,
1906 /* [out] */ ULONG32 *numFields)
1907{
1908 HRESULT status;
1909
1910 DAC_ENTER_SUB(m_dac);
1911
1912 EX_TRY
1913 {
1914 if (m_typeHandle.IsNull())
1915 {
1916 status = E_NOTIMPL;
1917 }
1918 else
1919 {
1920 DeepFieldDescIterator fieldIter;
1921
1922 if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
1923 flags, NULL)) == S_OK)
1924 {
1925 *numFields = fieldIter.Count();
1926 }
1927 }
1928 }
1929 EX_CATCH
1930 {
1931 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1932 {
1933 EX_RETHROW;
1934 }
1935 }
1936 EX_END_CATCH(SwallowAllExceptions)
1937
1938 DAC_LEAVE();
1939 return status;
1940}
1941
1942HRESULT STDMETHODCALLTYPE
1943ClrDataTypeDefinition::StartEnumFields(
1944 /* [in] */ ULONG32 flags,
1945 /* [out] */ CLRDATA_ENUM *handle)
1946{
1947 HRESULT status;
1948
1949 DAC_ENTER_SUB(m_dac);
1950
1951 EX_TRY
1952 {
1953 if (m_typeHandle.IsNull())
1954 {
1955 *handle = 0;
1956 status = E_NOTIMPL;
1957 }
1958 else
1959 {
1960 status = SplitName::
1961 CdStartField(NULL,
1962 0,
1963 flags,
1964 NULL,
1965 m_typeHandle,
1966 NULL,
1967 mdTypeDefNil,
1968 0,
1969 NULL,
1970 NULL,
1971 NULL,
1972 NULL,
1973 NULL,
1974 handle);
1975 }
1976 }
1977 EX_CATCH
1978 {
1979 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1980 {
1981 EX_RETHROW;
1982 }
1983 }
1984 EX_END_CATCH(SwallowAllExceptions)
1985
1986 DAC_LEAVE();
1987 return status;
1988}
1989
1990HRESULT STDMETHODCALLTYPE
1991ClrDataTypeDefinition::EnumField(
1992 /* [out][in] */ CLRDATA_ENUM *handle,
1993 /* [in] */ ULONG32 nameBufLen,
1994 /* [out] */ ULONG32 *nameLen,
1995 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
1996 /* [out] */ IXCLRDataTypeDefinition **type,
1997 /* [out] */ ULONG32 *flags,
1998 /* [out] */ mdFieldDef *token)
1999{
2000 return EnumField2(handle, nameBufLen, nameLen, nameBuf,
2001 type, flags, NULL, token);
2002}
2003
2004HRESULT STDMETHODCALLTYPE
2005ClrDataTypeDefinition::EnumField2(
2006 /* [out][in] */ CLRDATA_ENUM *handle,
2007 /* [in] */ ULONG32 nameBufLen,
2008 /* [out] */ ULONG32 *nameLen,
2009 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
2010 /* [out] */ IXCLRDataTypeDefinition **type,
2011 /* [out] */ ULONG32 *flags,
2012 /* [out] */ IXCLRDataModule** tokenScope,
2013 /* [out] */ mdFieldDef *token)
2014{
2015 HRESULT status;
2016
2017 DAC_ENTER_SUB(m_dac);
2018
2019 EX_TRY
2020 {
2021 status = SplitName::CdNextField(m_dac, handle, type, flags, NULL,
2022 nameBufLen, nameLen, nameBuf,
2023 tokenScope, token);
2024 }
2025 EX_CATCH
2026 {
2027 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2028 {
2029 EX_RETHROW;
2030 }
2031 }
2032 EX_END_CATCH(SwallowAllExceptions)
2033
2034 DAC_LEAVE();
2035 return status;
2036}
2037
2038HRESULT STDMETHODCALLTYPE
2039ClrDataTypeDefinition::EndEnumFields(
2040 /* [in] */ CLRDATA_ENUM handle)
2041{
2042 HRESULT status;
2043
2044 DAC_ENTER_SUB(m_dac);
2045
2046 EX_TRY
2047 {
2048 status = SplitName::CdEnd(handle);
2049 }
2050 EX_CATCH
2051 {
2052 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2053 {
2054 EX_RETHROW;
2055 }
2056 }
2057 EX_END_CATCH(SwallowAllExceptions)
2058
2059 DAC_LEAVE();
2060 return status;
2061}
2062
2063HRESULT STDMETHODCALLTYPE
2064ClrDataTypeDefinition::StartEnumFieldsByName(
2065 /* [in] */ LPCWSTR name,
2066 /* [in] */ ULONG32 nameFlags,
2067 /* [in] */ ULONG32 fieldFlags,
2068 /* [out] */ CLRDATA_ENUM *handle)
2069{
2070 HRESULT status;
2071
2072 DAC_ENTER_SUB(m_dac);
2073
2074 EX_TRY
2075 {
2076 if (m_typeHandle.IsNull())
2077 {
2078 *handle = 0;
2079 status = E_NOTIMPL;
2080 }
2081 else
2082 {
2083 status = SplitName::
2084 CdStartField(name,
2085 nameFlags,
2086 fieldFlags,
2087 NULL,
2088 m_typeHandle,
2089 NULL,
2090 mdTypeDefNil,
2091 0,
2092 NULL,
2093 NULL,
2094 NULL,
2095 NULL,
2096 NULL,
2097 handle);
2098 }
2099 }
2100 EX_CATCH
2101 {
2102 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2103 {
2104 EX_RETHROW;
2105 }
2106 }
2107 EX_END_CATCH(SwallowAllExceptions)
2108
2109 DAC_LEAVE();
2110 return status;
2111}
2112
2113HRESULT STDMETHODCALLTYPE
2114ClrDataTypeDefinition::EnumFieldByName(
2115 /* [out][in] */ CLRDATA_ENUM *handle,
2116 /* [out] */ IXCLRDataTypeDefinition **type,
2117 /* [out] */ ULONG32 *flags,
2118 /* [out] */ mdFieldDef *token)
2119{
2120 return EnumFieldByName2(handle, type, flags, NULL, token);
2121}
2122
2123HRESULT STDMETHODCALLTYPE
2124ClrDataTypeDefinition::EnumFieldByName2(
2125 /* [out][in] */ CLRDATA_ENUM *handle,
2126 /* [out] */ IXCLRDataTypeDefinition **type,
2127 /* [out] */ ULONG32 *flags,
2128 /* [out] */ IXCLRDataModule** tokenScope,
2129 /* [out] */ mdFieldDef *token)
2130{
2131 HRESULT status;
2132
2133 DAC_ENTER_SUB(m_dac);
2134
2135 EX_TRY
2136 {
2137 status = SplitName::CdNextField(m_dac, handle, type, flags, NULL,
2138 0, NULL, NULL,
2139 tokenScope, token);
2140 }
2141 EX_CATCH
2142 {
2143 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2144 {
2145 EX_RETHROW;
2146 }
2147 }
2148 EX_END_CATCH(SwallowAllExceptions)
2149
2150 DAC_LEAVE();
2151 return status;
2152}
2153
2154HRESULT STDMETHODCALLTYPE
2155ClrDataTypeDefinition::EndEnumFieldsByName(
2156 /* [in] */ CLRDATA_ENUM handle)
2157{
2158 HRESULT status;
2159
2160 DAC_ENTER_SUB(m_dac);
2161
2162 EX_TRY
2163 {
2164 status = SplitName::CdEnd(handle);
2165 }
2166 EX_CATCH
2167 {
2168 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2169 {
2170 EX_RETHROW;
2171 }
2172 }
2173 EX_END_CATCH(SwallowAllExceptions)
2174
2175 DAC_LEAVE();
2176 return status;
2177}
2178
2179HRESULT STDMETHODCALLTYPE
2180ClrDataTypeDefinition::GetFieldByToken(
2181 /* [in] */ mdFieldDef token,
2182 /* [in] */ ULONG32 nameBufLen,
2183 /* [out] */ ULONG32 *nameLen,
2184 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
2185 /* [out] */ IXCLRDataTypeDefinition **type,
2186 /* [out] */ ULONG32 *flags)
2187{
2188 return GetFieldByToken2(NULL, token, nameBufLen, nameLen, nameBuf,
2189 type, flags);
2190}
2191
2192HRESULT STDMETHODCALLTYPE
2193ClrDataTypeDefinition::GetFieldByToken2(
2194 /* [in] */ IXCLRDataModule* tokenScope,
2195 /* [in] */ mdFieldDef token,
2196 /* [in] */ ULONG32 nameBufLen,
2197 /* [out] */ ULONG32 *nameLen,
2198 /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
2199 /* [out] */ IXCLRDataTypeDefinition **type,
2200 /* [out] */ ULONG32 *flags)
2201{
2202 HRESULT status;
2203
2204 DAC_ENTER_SUB(m_dac);
2205
2206 EX_TRY
2207 {
2208 DeepFieldDescIterator fieldIter;
2209
2210 if (m_typeHandle.IsNull())
2211 {
2212 status = E_NOTIMPL;
2213 goto Exit;
2214 }
2215
2216 if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
2217 CLRDATA_VALUE_ALL_FIELDS, NULL)) == S_OK)
2218 {
2219 FieldDesc* fieldDesc;
2220
2221 status = E_INVALIDARG;
2222 while ((fieldDesc = fieldIter.Next()))
2223 {
2224 if ((!tokenScope ||
2225 PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
2226 GetModule()) ==
2227 PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
2228 fieldDesc->GetMemberDef() == token)
2229 {
2230 if (flags)
2231 {
2232 *flags = GetTypeFieldValueFlags(m_typeHandle,
2233 fieldDesc,
2234 fieldIter.IsFieldFromParentClass() ?
2235 CLRDATA_VALUE_IS_INHERITED : 0,
2236 false);
2237 }
2238
2239 status = ConvertUtf8(fieldDesc->GetName(),
2240 nameBufLen, nameLen, nameBuf);
2241
2242 if (SUCCEEDED(status) && type)
2243 {
2244 TypeHandle fieldTypeHandle =
2245 fieldDesc->LookupFieldTypeHandle();
2246 *type = new (nothrow)
2247 ClrDataTypeDefinition(m_dac,
2248 fieldTypeHandle.GetModule(),
2249 fieldTypeHandle.
2250 GetMethodTable()->GetCl(),
2251 fieldTypeHandle);
2252 status = *type ? S_OK : E_OUTOFMEMORY;
2253 }
2254
2255 break;
2256 }
2257 }
2258 }
2259
2260 Exit: ;
2261 }
2262 EX_CATCH
2263 {
2264 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2265 {
2266 EX_RETHROW;
2267 }
2268 }
2269 EX_END_CATCH(SwallowAllExceptions)
2270
2271 DAC_LEAVE();
2272 return status;
2273}
2274
2275HRESULT STDMETHODCALLTYPE
2276ClrDataTypeDefinition::GetName(
2277 /* [in] */ ULONG32 flags,
2278 /* [in] */ ULONG32 bufLen,
2279 /* [out] */ ULONG32 *nameLen,
2280 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
2281{
2282 HRESULT status = S_OK;
2283
2284 if (flags != 0)
2285 {
2286 return E_INVALIDARG;
2287 }
2288
2289 DAC_ENTER_SUB(m_dac);
2290
2291 EX_TRY
2292 {
2293 char classNameBuf[MAX_CLASSNAME_LENGTH];
2294
2295 if (m_typeHandle.IsNull())
2296 {
2297 if ((status =
2298 GetFullClassNameFromMetadata(m_module->GetMDImport(),
2299 m_token,
2300 NumItems(classNameBuf),
2301 classNameBuf)) == S_OK)
2302 {
2303 status = ConvertUtf8(classNameBuf, bufLen, nameLen, nameBuf);
2304 }
2305 }
2306 else
2307 {
2308 StackSString ssClassNameBuf;
2309 m_typeHandle.GetName(ssClassNameBuf);
2310 if (wcsncpy_s(nameBuf, bufLen, ssClassNameBuf.GetUnicode(), _TRUNCATE) == STRUNCATE)
2311 {
2312 status = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
2313 }
2314 if (nameLen != NULL)
2315 {
2316 size_t cchName = ssClassNameBuf.GetCount() + 1;
2317 if (FitsIn<ULONG32>(cchName))
2318 {
2319 *nameLen = (ULONG32) cchName;
2320 }
2321 else
2322 {
2323 status = COR_E_OVERFLOW;
2324 }
2325 }
2326 }
2327 }
2328 EX_CATCH
2329 {
2330 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2331 {
2332 EX_RETHROW;
2333 }
2334 }
2335 EX_END_CATCH(SwallowAllExceptions)
2336
2337 DAC_LEAVE();
2338 return status;
2339}
2340
2341HRESULT STDMETHODCALLTYPE
2342ClrDataTypeDefinition::GetTokenAndScope(
2343 /* [out] */ mdTypeDef *token,
2344 /* [out] */ IXCLRDataModule **mod)
2345{
2346 HRESULT status;
2347
2348 DAC_ENTER_SUB(m_dac);
2349
2350 EX_TRY
2351 {
2352 status = S_OK;
2353
2354 if (token)
2355 {
2356 *token = m_token;
2357 }
2358
2359 if (mod)
2360 {
2361 *mod = new (nothrow)
2362 ClrDataModule(m_dac, m_module);
2363 status = *mod ? S_OK : E_OUTOFMEMORY;
2364 }
2365
2366 }
2367 EX_CATCH
2368 {
2369 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2370 {
2371 EX_RETHROW;
2372 }
2373 }
2374 EX_END_CATCH(SwallowAllExceptions)
2375
2376 DAC_LEAVE();
2377 return status;
2378}
2379
2380HRESULT STDMETHODCALLTYPE
2381ClrDataTypeDefinition::GetCorElementType(
2382 /* [out] */ CorElementType *type)
2383{
2384 HRESULT status;
2385
2386 DAC_ENTER_SUB(m_dac);
2387
2388 EX_TRY
2389 {
2390 if (m_typeHandle.IsNull())
2391 {
2392 status = E_NOTIMPL;
2393 }
2394 else
2395 {
2396 *type = m_typeHandle.GetInternalCorElementType();
2397 status = S_OK;
2398 }
2399 }
2400 EX_CATCH
2401 {
2402 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2403 {
2404 EX_RETHROW;
2405 }
2406 }
2407 EX_END_CATCH(SwallowAllExceptions)
2408
2409 DAC_LEAVE();
2410 return status;
2411}
2412
2413HRESULT STDMETHODCALLTYPE
2414ClrDataTypeDefinition::GetFlags(
2415 /* [out] */ ULONG32 *flags)
2416{
2417 HRESULT status;
2418
2419 DAC_ENTER_SUB(m_dac);
2420
2421 EX_TRY
2422 {
2423 *flags = CLRDATA_TYPE_DEFAULT;
2424 status = S_OK;
2425 }
2426 EX_CATCH
2427 {
2428 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2429 {
2430 EX_RETHROW;
2431 }
2432 }
2433 EX_END_CATCH(SwallowAllExceptions)
2434
2435 DAC_LEAVE();
2436 return status;
2437}
2438
2439HRESULT STDMETHODCALLTYPE
2440ClrDataTypeDefinition::GetBase(
2441 /* [out] */ IXCLRDataTypeDefinition **base)
2442{
2443 HRESULT status;
2444
2445 DAC_ENTER_SUB(m_dac);
2446
2447 EX_TRY
2448 {
2449 mdTypeDef token;
2450 TypeHandle typeHandle;
2451
2452 if (m_typeHandle.IsNull())
2453 {
2454 ULONG attr;
2455
2456 status = m_module->GetMDImport()->GetTypeDefProps(m_token, &attr, &token);
2457 if (FAILED(status))
2458 {
2459 goto Exit;
2460 }
2461 }
2462 else
2463 {
2464 typeHandle = m_typeHandle.GetParent();
2465 if (typeHandle.IsNull() ||
2466 !typeHandle.GetMethodTable())
2467 {
2468 status = E_NOINTERFACE;
2469 goto Exit;
2470 }
2471
2472 token = typeHandle.GetMethodTable()->GetCl();
2473 }
2474
2475 *base = new (nothrow)
2476 ClrDataTypeDefinition(m_dac, m_module, token, typeHandle);
2477 status = *base ? S_OK : E_OUTOFMEMORY;
2478
2479 Exit: ;
2480 }
2481 EX_CATCH
2482 {
2483 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2484 {
2485 EX_RETHROW;
2486 }
2487 }
2488 EX_END_CATCH(SwallowAllExceptions)
2489
2490 DAC_LEAVE();
2491 return status;
2492}
2493
2494HRESULT STDMETHODCALLTYPE
2495ClrDataTypeDefinition::GetArrayRank(
2496 /* [out] */ ULONG32* rank)
2497{
2498 HRESULT status;
2499
2500 DAC_ENTER_SUB(m_dac);
2501
2502 EX_TRY
2503 {
2504 if (m_typeHandle.IsNull())
2505 {
2506 status = E_NOTIMPL;
2507 }
2508 else
2509 {
2510 MethodTable* pMT = m_typeHandle.GetMethodTable();
2511
2512 if (!m_typeHandle.IsArray() ||
2513 (pMT == NULL))
2514 {
2515 status = E_NOINTERFACE;
2516 }
2517 else
2518 {
2519 *rank = pMT->GetRank();
2520 status = S_OK;
2521 }
2522 }
2523 }
2524 EX_CATCH
2525 {
2526 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2527 {
2528 EX_RETHROW;
2529 }
2530 }
2531 EX_END_CATCH(SwallowAllExceptions)
2532
2533 DAC_LEAVE();
2534 return status;
2535}
2536
2537HRESULT STDMETHODCALLTYPE
2538ClrDataTypeDefinition::IsSameObject(
2539 /* [in] */ IXCLRDataTypeDefinition* type)
2540{
2541 HRESULT status;
2542
2543 DAC_ENTER_SUB(m_dac);
2544
2545 EX_TRY
2546 {
2547 if (m_typeHandle.IsNull())
2548 {
2549 status = (PTR_HOST_TO_TADDR(m_module) ==
2550 PTR_HOST_TO_TADDR(((ClrDataTypeDefinition*)type)->
2551 m_module) &&
2552 m_token == ((ClrDataTypeDefinition*)type)->m_token) ?
2553 S_OK : S_FALSE;
2554 }
2555 else
2556 {
2557 status = (m_typeHandle.AsTAddr() ==
2558 ((ClrDataTypeDefinition*)type)->m_typeHandle.AsTAddr()) ?
2559 S_OK : S_FALSE;
2560 }
2561 }
2562 EX_CATCH
2563 {
2564 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2565 {
2566 EX_RETHROW;
2567 }
2568 }
2569 EX_END_CATCH(SwallowAllExceptions)
2570
2571 DAC_LEAVE();
2572 return status;
2573}
2574
2575HRESULT STDMETHODCALLTYPE
2576ClrDataTypeDefinition::GetTypeNotification(
2577 /* [out] */ ULONG32* flags)
2578{
2579 HRESULT status;
2580
2581 DAC_ENTER_SUB(m_dac);
2582
2583 EX_TRY
2584 {
2585 // XXX Microsoft.
2586 status = E_NOTIMPL;
2587 }
2588 EX_CATCH
2589 {
2590 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2591 {
2592 EX_RETHROW;
2593 }
2594 }
2595 EX_END_CATCH(SwallowAllExceptions)
2596
2597 DAC_LEAVE();
2598 return status;
2599}
2600
2601HRESULT STDMETHODCALLTYPE
2602ClrDataTypeDefinition::SetTypeNotification(
2603 /* [in] */ ULONG32 flags)
2604{
2605 HRESULT status;
2606
2607 DAC_ENTER_SUB(m_dac);
2608
2609 EX_TRY
2610 {
2611 // XXX Microsoft.
2612 status = E_NOTIMPL;
2613 }
2614 EX_CATCH
2615 {
2616 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2617 {
2618 EX_RETHROW;
2619 }
2620 }
2621 EX_END_CATCH(SwallowAllExceptions)
2622
2623 DAC_LEAVE();
2624 return status;
2625}
2626
2627HRESULT STDMETHODCALLTYPE
2628ClrDataTypeDefinition::Request(
2629 /* [in] */ ULONG32 reqCode,
2630 /* [in] */ ULONG32 inBufferSize,
2631 /* [size_is][in] */ BYTE *inBuffer,
2632 /* [in] */ ULONG32 outBufferSize,
2633 /* [size_is][out] */ BYTE *outBuffer)
2634{
2635 HRESULT status;
2636
2637 DAC_ENTER_SUB(m_dac);
2638
2639 EX_TRY
2640 {
2641 switch(reqCode)
2642 {
2643 case CLRDATA_REQUEST_REVISION:
2644 if (inBufferSize != 0 ||
2645 inBuffer ||
2646 outBufferSize != sizeof(ULONG32))
2647 {
2648 status = E_INVALIDARG;
2649 }
2650 else
2651 {
2652 *(ULONG32*)outBuffer = 2;
2653 status = S_OK;
2654 }
2655 break;
2656
2657 default:
2658 status = E_INVALIDARG;
2659 break;
2660 }
2661 }
2662 EX_CATCH
2663 {
2664 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2665 {
2666 EX_RETHROW;
2667 }
2668 }
2669 EX_END_CATCH(SwallowAllExceptions)
2670
2671 DAC_LEAVE();
2672 return status;
2673}
2674
2675HRESULT
2676ClrDataTypeDefinition::NewFromModule(ClrDataAccess* dac,
2677 Module* module,
2678 mdTypeDef token,
2679 ClrDataTypeDefinition** typeDef,
2680 IXCLRDataTypeDefinition** pubTypeDef)
2681{
2682 // The type may not be loaded yet so the
2683 // absence of a TypeHandle is not fatal.
2684 // If the type isn't loaded a metadata-query
2685 // TypeDefinition is produced.
2686 TypeHandle typeHandle = module->LookupTypeDef(token);
2687 if (!typeHandle.IsNull() &&
2688 !typeHandle.IsRestored())
2689 {
2690 // The type isn't fully usable so just go with metadata.
2691 typeHandle = TypeHandle();
2692 }
2693
2694 ClrDataTypeDefinition* def = new (nothrow)
2695 ClrDataTypeDefinition(dac, module, token, typeHandle);
2696 if (!def)
2697 {
2698 return E_OUTOFMEMORY;
2699 }
2700
2701 PREFIX_ASSUME(typeDef || pubTypeDef);
2702
2703 if (typeDef)
2704 {
2705 *typeDef = def;
2706 }
2707 if (pubTypeDef)
2708 {
2709 *pubTypeDef = def;
2710 }
2711
2712 return S_OK;
2713}
2714
2715//----------------------------------------------------------------------------
2716//
2717// ClrDataTypeInstance.
2718//
2719//----------------------------------------------------------------------------
2720
2721ClrDataTypeInstance::ClrDataTypeInstance(ClrDataAccess* dac,
2722 AppDomain* appDomain,
2723 TypeHandle typeHandle)
2724{
2725 m_dac = dac;
2726 m_dac->AddRef();
2727 m_instanceAge = m_dac->m_instanceAge;
2728 m_refs = 1;
2729 m_appDomain = appDomain;
2730 m_typeHandle = typeHandle;
2731}
2732
2733ClrDataTypeInstance::~ClrDataTypeInstance(void)
2734{
2735 m_dac->Release();
2736}
2737
2738STDMETHODIMP
2739ClrDataTypeInstance::QueryInterface(THIS_
2740 IN REFIID interfaceId,
2741 OUT PVOID* iface)
2742{
2743 if (IsEqualIID(interfaceId, IID_IUnknown) ||
2744 IsEqualIID(interfaceId, __uuidof(IXCLRDataTypeInstance)))
2745 {
2746 AddRef();
2747 *iface = static_cast<IUnknown*>
2748 (static_cast<IXCLRDataTypeInstance*>(this));
2749 return S_OK;
2750 }
2751 else
2752 {
2753 *iface = NULL;
2754 return E_NOINTERFACE;
2755 }
2756}
2757
2758STDMETHODIMP_(ULONG)
2759ClrDataTypeInstance::AddRef(THIS)
2760{
2761 return InterlockedIncrement(&m_refs);
2762}
2763
2764STDMETHODIMP_(ULONG)
2765ClrDataTypeInstance::Release(THIS)
2766{
2767 SUPPORTS_DAC_HOST_ONLY;
2768 LONG newRefs = InterlockedDecrement(&m_refs);
2769 if (newRefs == 0)
2770 {
2771 delete this;
2772 }
2773 return newRefs;
2774}
2775
2776HRESULT STDMETHODCALLTYPE
2777ClrDataTypeInstance::StartEnumMethodInstances(
2778 /* [out] */ CLRDATA_ENUM* handle)
2779{
2780 HRESULT status;
2781
2782 DAC_ENTER_SUB(m_dac);
2783
2784 EX_TRY
2785 {
2786 if (!m_typeHandle.GetMethodTable())
2787 {
2788 *handle = 0;
2789 status = S_FALSE;
2790 goto Exit;
2791 }
2792
2793 status = MetaEnum::New(m_typeHandle.GetModule(),
2794 mdtMethodDef,
2795 m_typeHandle.GetCl(),
2796 NULL,
2797 NULL,
2798 handle);
2799
2800 Exit: ;
2801 }
2802 EX_CATCH
2803 {
2804 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2805 {
2806 EX_RETHROW;
2807 }
2808 }
2809 EX_END_CATCH(SwallowAllExceptions)
2810
2811 DAC_LEAVE();
2812 return status;
2813}
2814
2815HRESULT STDMETHODCALLTYPE
2816ClrDataTypeInstance::EnumMethodInstance(
2817 /* [in, out] */ CLRDATA_ENUM* handle,
2818 /* [out] */ IXCLRDataMethodInstance **method)
2819{
2820 HRESULT status;
2821
2822 DAC_ENTER_SUB(m_dac);
2823
2824 EX_TRY
2825 {
2826 for (;;)
2827 {
2828 mdMethodDef token;
2829
2830 if ((status = MetaEnum::CdNextToken(handle, &token)) != S_OK)
2831 {
2832 break;
2833 }
2834
2835 // If the method doesn't have a MethodDesc or hasn't
2836 // been JIT'ed yet it's not an instance and should
2837 // just be skipped.
2838 if ((status = ClrDataMethodInstance::
2839 NewFromModule(m_dac,
2840 m_appDomain,
2841 m_typeHandle.GetModule(),
2842 token,
2843 NULL,
2844 method)) != E_INVALIDARG)
2845 {
2846 break;
2847 }
2848 }
2849 }
2850 EX_CATCH
2851 {
2852 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2853 {
2854 EX_RETHROW;
2855 }
2856 }
2857 EX_END_CATCH(SwallowAllExceptions)
2858
2859 DAC_LEAVE();
2860 return status;
2861}
2862
2863HRESULT STDMETHODCALLTYPE
2864ClrDataTypeInstance::EndEnumMethodInstances(
2865 /* [in] */ CLRDATA_ENUM handle)
2866{
2867 HRESULT status;
2868
2869 DAC_ENTER_SUB(m_dac);
2870
2871 EX_TRY
2872 {
2873 status = MetaEnum::CdEnd(handle);
2874 }
2875 EX_CATCH
2876 {
2877 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2878 {
2879 EX_RETHROW;
2880 }
2881 }
2882 EX_END_CATCH(SwallowAllExceptions)
2883
2884 DAC_LEAVE();
2885 return status;
2886}
2887
2888HRESULT STDMETHODCALLTYPE
2889ClrDataTypeInstance::StartEnumMethodInstancesByName(
2890 /* [in] */ LPCWSTR name,
2891 /* [in] */ ULONG32 flags,
2892 /* [out] */ CLRDATA_ENUM* handle)
2893{
2894 HRESULT status;
2895
2896 DAC_ENTER_SUB(m_dac);
2897
2898 EX_TRY
2899 {
2900 if (!m_typeHandle.GetMethodTable())
2901 {
2902 *handle = 0;
2903 status = S_FALSE;
2904 goto Exit;
2905 }
2906
2907 status = SplitName::CdStartMethod(name,
2908 flags,
2909 m_typeHandle.GetModule(),
2910 m_typeHandle.GetCl(),
2911 m_appDomain,
2912 NULL,
2913 NULL,
2914 handle);
2915
2916 Exit: ;
2917 }
2918 EX_CATCH
2919 {
2920 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2921 {
2922 EX_RETHROW;
2923 }
2924 }
2925 EX_END_CATCH(SwallowAllExceptions)
2926
2927 DAC_LEAVE();
2928 return status;
2929}
2930
2931HRESULT STDMETHODCALLTYPE
2932ClrDataTypeInstance::EnumMethodInstanceByName(
2933 /* [out][in] */ CLRDATA_ENUM* handle,
2934 /* [out] */ IXCLRDataMethodInstance **method)
2935{
2936 HRESULT status;
2937
2938 DAC_ENTER_SUB(m_dac);
2939
2940 EX_TRY
2941 {
2942 for (;;)
2943 {
2944 mdMethodDef token;
2945
2946 if ((status = SplitName::CdNextMethod(handle, &token)) != S_OK)
2947 {
2948 break;
2949 }
2950
2951 // If the method doesn't have a MethodDesc or hasn't
2952 // been JIT'ed yet it's not an instance and should
2953 // just be skipped.
2954 if ((status = ClrDataMethodInstance::
2955 NewFromModule(m_dac,
2956 m_appDomain,
2957 m_typeHandle.GetModule(),
2958 token,
2959 NULL,
2960 method)) != E_INVALIDARG)
2961 {
2962 break;
2963 }
2964 }
2965 }
2966 EX_CATCH
2967 {
2968 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2969 {
2970 EX_RETHROW;
2971 }
2972 }
2973 EX_END_CATCH(SwallowAllExceptions)
2974
2975 DAC_LEAVE();
2976 return status;
2977}
2978
2979HRESULT STDMETHODCALLTYPE
2980ClrDataTypeInstance::EndEnumMethodInstancesByName(
2981 /* [in] */ CLRDATA_ENUM handle)
2982{
2983 HRESULT status;
2984
2985 DAC_ENTER_SUB(m_dac);
2986
2987 EX_TRY
2988 {
2989 status = SplitName::CdEnd(handle);
2990 }
2991 EX_CATCH
2992 {
2993 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2994 {
2995 EX_RETHROW;
2996 }
2997 }
2998 EX_END_CATCH(SwallowAllExceptions)
2999
3000 DAC_LEAVE();
3001 return status;
3002}
3003
3004HRESULT STDMETHODCALLTYPE
3005ClrDataTypeInstance::GetNumStaticFields(
3006 /* [out] */ ULONG32 *numFields)
3007{
3008 return GetNumStaticFields2(INH_STATIC, numFields);
3009}
3010
3011HRESULT STDMETHODCALLTYPE
3012ClrDataTypeInstance::GetStaticFieldByIndex(
3013 /* [in] */ ULONG32 index,
3014 /* [in] */ IXCLRDataTask *tlsTask,
3015 /* [out] */ IXCLRDataValue **field,
3016 /* [in] */ ULONG32 bufLen,
3017 /* [out] */ ULONG32 *nameLen,
3018 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
3019 /* [out] */ mdFieldDef *token)
3020{
3021 HRESULT status;
3022
3023 DAC_ENTER_SUB(m_dac);
3024
3025 EX_TRY
3026 {
3027 DeepFieldDescIterator fieldIter;
3028
3029 if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
3030 INH_STATIC, NULL)) == S_OK)
3031 {
3032 ULONG32 count = 0;
3033 FieldDesc* fieldDesc;
3034
3035 status = E_INVALIDARG;
3036 while ((fieldDesc = fieldIter.Next()))
3037 {
3038 if (count++ == index)
3039 {
3040 Thread* tlsThread = tlsTask ?
3041 ((ClrDataTask*)tlsTask)->GetThread() : NULL;
3042
3043 status = ClrDataValue::
3044 NewFromFieldDesc(m_dac,
3045 m_appDomain,
3046 fieldIter.IsFieldFromParentClass() ?
3047 CLRDATA_VALUE_IS_INHERITED : 0,
3048 fieldDesc,
3049 0,
3050 tlsThread,
3051 NULL,
3052 field,
3053 bufLen,
3054 nameLen,
3055 nameBuf,
3056 NULL,
3057 token);
3058 break;
3059 }
3060 }
3061 }
3062 }
3063 EX_CATCH
3064 {
3065 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3066 {
3067 EX_RETHROW;
3068 }
3069 }
3070 EX_END_CATCH(SwallowAllExceptions)
3071
3072 DAC_LEAVE();
3073 return status;
3074}
3075
3076HRESULT STDMETHODCALLTYPE
3077ClrDataTypeInstance::StartEnumStaticFieldsByName(
3078 /* [in] */ LPCWSTR name,
3079 /* [in] */ ULONG32 flags,
3080 /* [in] */ IXCLRDataTask* tlsTask,
3081 /* [out] */ CLRDATA_ENUM* handle)
3082{
3083 return StartEnumStaticFieldsByName2(name, flags, INH_STATIC, tlsTask,
3084 handle);
3085}
3086
3087HRESULT STDMETHODCALLTYPE
3088ClrDataTypeInstance::EnumStaticFieldByName(
3089 /* [out][in] */ CLRDATA_ENUM* handle,
3090 /* [out] */ IXCLRDataValue **value)
3091{
3092 return EnumStaticFieldByName2(handle, value);
3093}
3094
3095HRESULT STDMETHODCALLTYPE
3096ClrDataTypeInstance::EndEnumStaticFieldsByName(
3097 /* [in] */ CLRDATA_ENUM handle)
3098{
3099 return EndEnumStaticFieldsByName2(handle);
3100}
3101
3102HRESULT STDMETHODCALLTYPE
3103ClrDataTypeInstance::GetNumStaticFields2(
3104 /* [in] */ ULONG32 flags,
3105 /* [out] */ ULONG32 *numFields)
3106{
3107 HRESULT status;
3108
3109 DAC_ENTER_SUB(m_dac);
3110
3111 EX_TRY
3112 {
3113 DeepFieldDescIterator fieldIter;
3114
3115 if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
3116 flags, NULL)) == S_OK)
3117 {
3118 *numFields = fieldIter.Count();
3119 }
3120 }
3121 EX_CATCH
3122 {
3123 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3124 {
3125 EX_RETHROW;
3126 }
3127 }
3128 EX_END_CATCH(SwallowAllExceptions)
3129
3130 DAC_LEAVE();
3131 return status;
3132}
3133
3134HRESULT STDMETHODCALLTYPE
3135ClrDataTypeInstance::StartEnumStaticFields(
3136 /* [in] */ ULONG32 flags,
3137 /* [in] */ IXCLRDataTask* tlsTask,
3138 /* [out] */ CLRDATA_ENUM* handle)
3139{
3140 HRESULT status;
3141
3142 DAC_ENTER_SUB(m_dac);
3143
3144 EX_TRY
3145 {
3146 status = SplitName::
3147 CdStartField(NULL,
3148 0,
3149 flags,
3150 NULL,
3151 m_typeHandle,
3152 NULL,
3153 mdTypeDefNil,
3154 0,
3155 NULL,
3156 tlsTask,
3157 m_appDomain,
3158 NULL,
3159 NULL,
3160 handle);
3161 }
3162 EX_CATCH
3163 {
3164 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3165 {
3166 EX_RETHROW;
3167 }
3168 }
3169 EX_END_CATCH(SwallowAllExceptions)
3170
3171 DAC_LEAVE();
3172 return status;
3173}
3174
3175HRESULT STDMETHODCALLTYPE
3176ClrDataTypeInstance::EnumStaticField(
3177 /* [out][in] */ CLRDATA_ENUM* handle,
3178 /* [out] */ IXCLRDataValue **value)
3179{
3180 return EnumStaticField2(handle, value, 0, NULL, NULL,
3181 NULL, NULL);
3182}
3183
3184HRESULT STDMETHODCALLTYPE
3185ClrDataTypeInstance::EnumStaticField2(
3186 /* [out][in] */ CLRDATA_ENUM* handle,
3187 /* [out] */ IXCLRDataValue **value,
3188 /* [in] */ ULONG32 bufLen,
3189 /* [out] */ ULONG32 *nameLen,
3190 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
3191 /* [out] */ IXCLRDataModule** tokenScope,
3192 /* [out] */ mdFieldDef *token)
3193{
3194 HRESULT status;
3195
3196 DAC_ENTER_SUB(m_dac);
3197
3198 EX_TRY
3199 {
3200 status = SplitName::CdNextField(m_dac, handle, NULL, NULL, value,
3201 bufLen, nameLen, nameBuf,
3202 tokenScope, token);
3203 }
3204 EX_CATCH
3205 {
3206 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3207 {
3208 EX_RETHROW;
3209 }
3210 }
3211 EX_END_CATCH(SwallowAllExceptions)
3212
3213 DAC_LEAVE();
3214 return status;
3215}
3216
3217HRESULT STDMETHODCALLTYPE
3218ClrDataTypeInstance::EndEnumStaticFields(
3219 /* [in] */ CLRDATA_ENUM handle)
3220{
3221 HRESULT status;
3222
3223 DAC_ENTER_SUB(m_dac);
3224
3225 EX_TRY
3226 {
3227 status = SplitName::CdEnd(handle);
3228 }
3229 EX_CATCH
3230 {
3231 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3232 {
3233 EX_RETHROW;
3234 }
3235 }
3236 EX_END_CATCH(SwallowAllExceptions)
3237
3238 DAC_LEAVE();
3239 return status;
3240}
3241
3242HRESULT STDMETHODCALLTYPE
3243ClrDataTypeInstance::StartEnumStaticFieldsByName2(
3244 /* [in] */ LPCWSTR name,
3245 /* [in] */ ULONG32 nameFlags,
3246 /* [in] */ ULONG32 fieldFlags,
3247 /* [in] */ IXCLRDataTask* tlsTask,
3248 /* [out] */ CLRDATA_ENUM* handle)
3249{
3250 HRESULT status;
3251
3252 DAC_ENTER_SUB(m_dac);
3253
3254 EX_TRY
3255 {
3256 status = SplitName::
3257 CdStartField(name,
3258 nameFlags,
3259 fieldFlags,
3260 NULL,
3261 m_typeHandle,
3262 NULL,
3263 mdTypeDefNil,
3264 0,
3265 NULL,
3266 tlsTask,
3267 m_appDomain,
3268 NULL,
3269 NULL,
3270 handle);
3271 }
3272 EX_CATCH
3273 {
3274 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3275 {
3276 EX_RETHROW;
3277 }
3278 }
3279 EX_END_CATCH(SwallowAllExceptions)
3280
3281 DAC_LEAVE();
3282 return status;
3283}
3284
3285HRESULT STDMETHODCALLTYPE
3286ClrDataTypeInstance::EnumStaticFieldByName2(
3287 /* [out][in] */ CLRDATA_ENUM* handle,
3288 /* [out] */ IXCLRDataValue **value)
3289{
3290 return EnumStaticFieldByName3(handle, value, NULL, NULL);
3291}
3292
3293HRESULT STDMETHODCALLTYPE
3294ClrDataTypeInstance::EnumStaticFieldByName3(
3295 /* [out][in] */ CLRDATA_ENUM* handle,
3296 /* [out] */ IXCLRDataValue **value,
3297 /* [out] */ IXCLRDataModule** tokenScope,
3298 /* [out] */ mdFieldDef *token)
3299{
3300 HRESULT status;
3301
3302 DAC_ENTER_SUB(m_dac);
3303
3304 EX_TRY
3305 {
3306 status = SplitName::CdNextField(m_dac, handle, NULL, NULL, value,
3307 0, NULL, NULL,
3308 tokenScope, token);
3309 }
3310 EX_CATCH
3311 {
3312 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3313 {
3314 EX_RETHROW;
3315 }
3316 }
3317 EX_END_CATCH(SwallowAllExceptions)
3318
3319 DAC_LEAVE();
3320 return status;
3321}
3322
3323HRESULT STDMETHODCALLTYPE
3324ClrDataTypeInstance::EndEnumStaticFieldsByName2(
3325 /* [in] */ CLRDATA_ENUM handle)
3326{
3327 HRESULT status;
3328
3329 DAC_ENTER_SUB(m_dac);
3330
3331 EX_TRY
3332 {
3333 status = SplitName::CdEnd(handle);
3334 }
3335 EX_CATCH
3336 {
3337 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3338 {
3339 EX_RETHROW;
3340 }
3341 }
3342 EX_END_CATCH(SwallowAllExceptions)
3343
3344 DAC_LEAVE();
3345 return status;
3346}
3347
3348HRESULT STDMETHODCALLTYPE
3349ClrDataTypeInstance::GetStaticFieldByToken(
3350 /* [in] */ mdFieldDef token,
3351 /* [in] */ IXCLRDataTask *tlsTask,
3352 /* [out] */ IXCLRDataValue **field,
3353 /* [in] */ ULONG32 bufLen,
3354 /* [out] */ ULONG32 *nameLen,
3355 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
3356{
3357 return GetStaticFieldByToken2(NULL, token, tlsTask, field,
3358 bufLen, nameLen, nameBuf);
3359}
3360
3361HRESULT STDMETHODCALLTYPE
3362ClrDataTypeInstance::GetStaticFieldByToken2(
3363 /* [in] */ IXCLRDataModule* tokenScope,
3364 /* [in] */ mdFieldDef token,
3365 /* [in] */ IXCLRDataTask *tlsTask,
3366 /* [out] */ IXCLRDataValue **field,
3367 /* [in] */ ULONG32 bufLen,
3368 /* [out] */ ULONG32 *nameLen,
3369 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
3370{
3371 HRESULT status;
3372
3373 DAC_ENTER_SUB(m_dac);
3374
3375 EX_TRY
3376 {
3377 DeepFieldDescIterator fieldIter;
3378
3379 if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
3380 INH_STATIC, NULL)) == S_OK)
3381 {
3382 FieldDesc* fieldDesc;
3383
3384 status = E_INVALIDARG;
3385 while ((fieldDesc = fieldIter.Next()))
3386 {
3387 if ((!tokenScope ||
3388 PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
3389 GetModule()) ==
3390 PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
3391 fieldDesc->GetMemberDef() == token)
3392 {
3393 Thread* tlsThread = tlsTask ?
3394 ((ClrDataTask*)tlsTask)->GetThread() : NULL;
3395
3396 status = ClrDataValue::
3397 NewFromFieldDesc(m_dac,
3398 m_appDomain,
3399 fieldIter.IsFieldFromParentClass() ?
3400 CLRDATA_VALUE_IS_INHERITED : 0,
3401 fieldDesc,
3402 0,
3403 tlsThread,
3404 NULL,
3405 field,
3406 bufLen,
3407 nameLen,
3408 nameBuf,
3409 NULL,
3410 NULL);
3411 break;
3412 }
3413 }
3414 }
3415 }
3416 EX_CATCH
3417 {
3418 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3419 {
3420 EX_RETHROW;
3421 }
3422 }
3423 EX_END_CATCH(SwallowAllExceptions)
3424
3425 DAC_LEAVE();
3426 return status;
3427}
3428
3429HRESULT STDMETHODCALLTYPE
3430ClrDataTypeInstance::GetName(
3431 /* [in] */ ULONG32 flags,
3432 /* [in] */ ULONG32 bufLen,
3433 /* [out] */ ULONG32 *nameLen,
3434 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
3435{
3436 HRESULT status = S_OK;
3437
3438 if (flags != 0)
3439 {
3440 return E_INVALIDARG;
3441 }
3442
3443 DAC_ENTER_SUB(m_dac);
3444
3445 EX_TRY
3446 {
3447 StackSString ssClassNameBuf;
3448
3449#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
3450 PAL_CPP_TRY
3451 {
3452#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
3453
3454 m_typeHandle.GetName(ssClassNameBuf);
3455
3456#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
3457 }
3458 PAL_CPP_CATCH_ALL
3459 {
3460 // if metadata is unavailable try the DAC's MdCache
3461 ssClassNameBuf.Clear();
3462 PTR_MethodTable pMT = m_typeHandle.AsMethodTable();
3463 if (pMT != NULL)
3464 {
3465 if (!DacMdCacheGetEEName(dac_cast<TADDR>(pMT), ssClassNameBuf))
3466 {
3467 ssClassNameBuf.Clear();
3468 }
3469 }
3470 if (ssClassNameBuf.IsEmpty())
3471 {
3472 PAL_CPP_RETHROW;
3473 }
3474 }
3475 PAL_CPP_ENDTRY
3476#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
3477
3478 if (wcsncpy_s(nameBuf, bufLen, ssClassNameBuf.GetUnicode(), _TRUNCATE) == STRUNCATE)
3479 {
3480 status = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
3481 }
3482 if (nameLen != NULL)
3483 {
3484 size_t cchName = ssClassNameBuf.GetCount() + 1;
3485 if (FitsIn<ULONG32>(cchName))
3486 {
3487 *nameLen = (ULONG32) cchName;
3488 }
3489 else
3490 {
3491 status = COR_E_OVERFLOW;
3492 }
3493 }
3494 }
3495 EX_CATCH
3496 {
3497 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3498 {
3499 EX_RETHROW;
3500 }
3501 }
3502 EX_END_CATCH(SwallowAllExceptions)
3503
3504 DAC_LEAVE();
3505 return status;
3506}
3507
3508HRESULT STDMETHODCALLTYPE
3509ClrDataTypeInstance::GetModule(
3510 /* [out] */ IXCLRDataModule **mod)
3511{
3512 HRESULT status;
3513
3514 DAC_ENTER_SUB(m_dac);
3515
3516 EX_TRY
3517 {
3518 *mod = new (nothrow)
3519 ClrDataModule(m_dac, m_typeHandle.GetModule());
3520 status = *mod ? S_OK : E_OUTOFMEMORY;
3521
3522 }
3523 EX_CATCH
3524 {
3525 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3526 {
3527 EX_RETHROW;
3528 }
3529 }
3530 EX_END_CATCH(SwallowAllExceptions)
3531
3532 DAC_LEAVE();
3533 return status;
3534}
3535
3536HRESULT STDMETHODCALLTYPE
3537ClrDataTypeInstance::GetDefinition(
3538 /* [out] */ IXCLRDataTypeDefinition **typeDefinition)
3539{
3540 HRESULT status;
3541
3542 DAC_ENTER_SUB(m_dac);
3543
3544 EX_TRY
3545 {
3546 TypeHandle defType;
3547
3548 if (m_typeHandle.IsArray() || m_typeHandle.IsFnPtrType())
3549 {
3550 // Arrays don't necessarily have metadata so
3551 // we can't rely on being able to look up
3552 // a definition that way.
3553
3554 // Also ByRef and FUNC_PTR does not have typedef token backing it.
3555
3556 // Instead, just use the same type handle.
3557 // XXX Microsoft - Generics issues?
3558
3559 // Question - what does the GetCl return return here? The underlying element type?
3560 // If so, we are lossing informaiton.
3561 //
3562 defType = m_typeHandle;
3563 *typeDefinition = new (nothrow)
3564 ClrDataTypeDefinition(m_dac,
3565 defType.GetModule(),
3566 defType.GetCl(),
3567 defType);
3568 }
3569
3570 else if (m_typeHandle.IsTypeDesc() && m_typeHandle.AsTypeDesc()->HasTypeParam())
3571 {
3572 // HasTypeParam is true for - ParamTypeDesc (ARRAY, SZARRAY, BYREF, PTR)
3573 defType = m_typeHandle.AsTypeDesc()->GetTypeParam();
3574
3575 // The DefinitionType won't contain ByRef, PTR.
3576 *typeDefinition = new (nothrow)
3577 ClrDataTypeDefinition(m_dac,
3578 defType.GetModule(),
3579 defType.GetCl(),
3580 defType);
3581 }
3582 else
3583 {
3584 // @TODO:: Should this be only for generic?
3585 //
3586 defType = m_typeHandle.GetModule()->
3587 LookupTypeDef(m_typeHandle.GetCl());
3588 *typeDefinition = new (nothrow)
3589 ClrDataTypeDefinition(m_dac,
3590 m_typeHandle.GetModule(),
3591 m_typeHandle.GetCl(),
3592 defType);
3593 }
3594
3595 status = *typeDefinition ? S_OK : E_OUTOFMEMORY;
3596 }
3597 EX_CATCH
3598 {
3599 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3600 {
3601 EX_RETHROW;
3602 }
3603 }
3604 EX_END_CATCH(SwallowAllExceptions)
3605
3606 DAC_LEAVE();
3607 return status;
3608}
3609
3610HRESULT STDMETHODCALLTYPE
3611ClrDataTypeInstance::GetFlags(
3612 /* [out] */ ULONG32 *flags)
3613{
3614 HRESULT status;
3615
3616 DAC_ENTER_SUB(m_dac);
3617
3618 EX_TRY
3619 {
3620 *flags = CLRDATA_TYPE_DEFAULT;
3621 status = S_OK;
3622 }
3623 EX_CATCH
3624 {
3625 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3626 {
3627 EX_RETHROW;
3628 }
3629 }
3630 EX_END_CATCH(SwallowAllExceptions)
3631
3632 DAC_LEAVE();
3633 return status;
3634}
3635
3636HRESULT STDMETHODCALLTYPE
3637ClrDataTypeInstance::GetBase(
3638 /* [out] */ IXCLRDataTypeInstance **base)
3639{
3640 HRESULT status;
3641
3642 DAC_ENTER_SUB(m_dac);
3643
3644 EX_TRY
3645 {
3646 *base = new (nothrow)
3647 ClrDataTypeInstance(m_dac, m_appDomain, m_typeHandle.GetParent());
3648 status = *base ? S_OK : E_OUTOFMEMORY;
3649 }
3650 EX_CATCH
3651 {
3652 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3653 {
3654 EX_RETHROW;
3655 }
3656 }
3657 EX_END_CATCH(SwallowAllExceptions)
3658
3659 DAC_LEAVE();
3660 return status;
3661}
3662
3663HRESULT STDMETHODCALLTYPE
3664ClrDataTypeInstance::IsSameObject(
3665 /* [in] */ IXCLRDataTypeInstance* type)
3666{
3667 HRESULT status;
3668
3669 DAC_ENTER_SUB(m_dac);
3670
3671 EX_TRY
3672 {
3673 status = (PTR_HOST_TO_TADDR(m_appDomain) ==
3674 PTR_HOST_TO_TADDR(((ClrDataTypeInstance*)type)->
3675 m_appDomain) &&
3676 m_typeHandle == ((ClrDataTypeInstance*)type)->
3677 m_typeHandle) ?
3678 S_OK : S_FALSE;
3679 }
3680 EX_CATCH
3681 {
3682 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3683 {
3684 EX_RETHROW;
3685 }
3686 }
3687 EX_END_CATCH(SwallowAllExceptions)
3688
3689 DAC_LEAVE();
3690 return status;
3691}
3692
3693HRESULT STDMETHODCALLTYPE
3694ClrDataTypeInstance::GetNumTypeArguments(
3695 /* [out] */ ULONG32 *numTypeArgs)
3696{
3697 HRESULT status;
3698
3699 DAC_ENTER_SUB(m_dac);
3700
3701 EX_TRY
3702 {
3703 // XXX Microsoft.
3704 status = E_NOTIMPL;
3705 }
3706 EX_CATCH
3707 {
3708 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3709 {
3710 EX_RETHROW;
3711 }
3712 }
3713 EX_END_CATCH(SwallowAllExceptions)
3714
3715 DAC_LEAVE();
3716 return status;
3717}
3718
3719HRESULT STDMETHODCALLTYPE
3720ClrDataTypeInstance::GetTypeArgumentByIndex(
3721 /* [in] */ ULONG32 index,
3722 /* [out] */ IXCLRDataTypeInstance **typeArg)
3723{
3724 HRESULT status;
3725
3726 DAC_ENTER_SUB(m_dac);
3727
3728 EX_TRY
3729 {
3730 // XXX Microsoft.
3731 status = E_NOTIMPL;
3732 }
3733 EX_CATCH
3734 {
3735 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3736 {
3737 EX_RETHROW;
3738 }
3739 }
3740 EX_END_CATCH(SwallowAllExceptions)
3741
3742 DAC_LEAVE();
3743 return status;
3744}
3745
3746HRESULT STDMETHODCALLTYPE
3747ClrDataTypeInstance::Request(
3748 /* [in] */ ULONG32 reqCode,
3749 /* [in] */ ULONG32 inBufferSize,
3750 /* [size_is][in] */ BYTE *inBuffer,
3751 /* [in] */ ULONG32 outBufferSize,
3752 /* [size_is][out] */ BYTE *outBuffer)
3753{
3754 HRESULT status;
3755
3756 DAC_ENTER_SUB(m_dac);
3757
3758 EX_TRY
3759 {
3760 switch(reqCode)
3761 {
3762 case CLRDATA_REQUEST_REVISION:
3763 if (inBufferSize != 0 ||
3764 inBuffer ||
3765 outBufferSize != sizeof(ULONG32))
3766 {
3767 status = E_INVALIDARG;
3768 }
3769 else
3770 {
3771 *(ULONG32*)outBuffer = 2;
3772 status = S_OK;
3773 }
3774 break;
3775
3776 default:
3777 status = E_INVALIDARG;
3778 break;
3779 }
3780 }
3781 EX_CATCH
3782 {
3783 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3784 {
3785 EX_RETHROW;
3786 }
3787 }
3788 EX_END_CATCH(SwallowAllExceptions)
3789
3790 DAC_LEAVE();
3791 return status;
3792}
3793
3794HRESULT
3795ClrDataTypeInstance::NewFromModule(ClrDataAccess* dac,
3796 AppDomain* appDomain,
3797 Module* module,
3798 mdTypeDef token,
3799 ClrDataTypeInstance** typeInst,
3800 IXCLRDataTypeInstance** pubTypeInst)
3801{
3802 TypeHandle typeHandle = module->LookupTypeDef(token);
3803 if (typeHandle.IsNull() ||
3804 !typeHandle.IsRestored())
3805 {
3806 return E_INVALIDARG;
3807 }
3808
3809 ClrDataTypeInstance* inst = new (nothrow)
3810 ClrDataTypeInstance(dac, appDomain, typeHandle);
3811 if (!inst)
3812 {
3813 return E_OUTOFMEMORY;
3814 }
3815
3816 PREFIX_ASSUME(typeInst || pubTypeInst);
3817
3818 if (typeInst)
3819 {
3820 *typeInst = inst;
3821 }
3822 if (pubTypeInst)
3823 {
3824 *pubTypeInst = inst;
3825 }
3826
3827 return S_OK;
3828}
3829
3830
3831