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: task.cpp
6//
7
8//
9// ClrDataTask.
10//
11//*****************************************************************************
12
13#include "stdafx.h"
14
15// XXX Microsoft - Why aren't these extra MD APIs in a header?
16STDAPI GetMDPublicInterfaceFromInternal(
17 void *pIUnkPublic, // [IN] Given scope.
18 REFIID riid, // [in] The interface desired.
19 void **ppIUnkInternal); // [out] Return interface on success.
20
21STDAPI GetMetaDataPublicInterfaceFromInternal(
22 void *pv, // [IN] Given interface.
23 REFIID riid, // [IN] desired interface.
24 void **ppv) // [OUT] returned interface
25{
26 return GetMDPublicInterfaceFromInternal(pv, riid, ppv);
27}
28
29//----------------------------------------------------------------------------
30//
31// ClrDataTask.
32//
33//----------------------------------------------------------------------------
34
35ClrDataTask::ClrDataTask(ClrDataAccess* dac,
36 Thread* thread)
37{
38 m_dac = dac;
39 m_dac->AddRef();
40 m_instanceAge = m_dac->m_instanceAge;
41 m_thread = thread;
42 m_refs = 1;
43}
44
45ClrDataTask::~ClrDataTask(void)
46{
47 m_dac->Release();
48}
49
50STDMETHODIMP
51ClrDataTask::QueryInterface(THIS_
52 IN REFIID interfaceId,
53 OUT PVOID* iface)
54{
55 if (IsEqualIID(interfaceId, IID_IUnknown) ||
56 IsEqualIID(interfaceId, __uuidof(IXCLRDataTask)))
57 {
58 AddRef();
59 *iface = static_cast<IUnknown*>
60 (static_cast<IXCLRDataTask*>(this));
61 return S_OK;
62 }
63 else
64 {
65 *iface = NULL;
66 return E_NOINTERFACE;
67 }
68}
69
70STDMETHODIMP_(ULONG)
71ClrDataTask::AddRef(THIS)
72{
73 return InterlockedIncrement(&m_refs);
74}
75
76STDMETHODIMP_(ULONG)
77ClrDataTask::Release(THIS)
78{
79 SUPPORTS_DAC_HOST_ONLY;
80 LONG newRefs = InterlockedDecrement(&m_refs);
81 if (newRefs == 0)
82 {
83 delete this;
84 }
85 return newRefs;
86}
87
88HRESULT STDMETHODCALLTYPE
89ClrDataTask::GetProcess(
90 /* [out] */ IXCLRDataProcess **process)
91{
92 HRESULT status;
93
94 DAC_ENTER_SUB(m_dac);
95
96 EX_TRY
97 {
98 *process = static_cast<IXCLRDataProcess*>(m_dac);
99 m_dac->AddRef();
100 status = S_OK;
101 }
102 EX_CATCH
103 {
104 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
105 {
106 EX_RETHROW;
107 }
108 }
109 EX_END_CATCH(SwallowAllExceptions)
110
111 DAC_LEAVE();
112 return status;
113}
114
115HRESULT STDMETHODCALLTYPE
116ClrDataTask::GetCurrentAppDomain(
117 /* [out] */ IXCLRDataAppDomain **appDomain)
118{
119 HRESULT status;
120
121 DAC_ENTER_SUB(m_dac);
122
123 EX_TRY
124 {
125 if (m_thread->GetDomain())
126 {
127 *appDomain = new (nothrow)
128 ClrDataAppDomain(m_dac, m_thread->GetDomain());
129 status = *appDomain ? S_OK : E_OUTOFMEMORY;
130 }
131 else
132 {
133 status = E_INVALIDARG;
134 }
135 }
136 EX_CATCH
137 {
138 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
139 {
140 EX_RETHROW;
141 }
142 }
143 EX_END_CATCH(SwallowAllExceptions)
144
145 DAC_LEAVE();
146 return status;
147}
148
149HRESULT STDMETHODCALLTYPE
150ClrDataTask::GetName(
151 /* [in] */ ULONG32 bufLen,
152 /* [out] */ ULONG32 *nameLen,
153 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
154{
155 HRESULT status;
156
157 DAC_ENTER_SUB(m_dac);
158
159 EX_TRY
160 {
161 // XXX - Microsoft.
162 status = E_NOTIMPL;
163 }
164 EX_CATCH
165 {
166 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
167 {
168 EX_RETHROW;
169 }
170 }
171 EX_END_CATCH(SwallowAllExceptions)
172
173 DAC_LEAVE();
174 return status;
175}
176
177HRESULT STDMETHODCALLTYPE
178ClrDataTask::GetUniqueID(
179 /* [out] */ ULONG64 *id)
180{
181 HRESULT status;
182
183 DAC_ENTER_SUB(m_dac);
184
185 EX_TRY
186 {
187 *id = m_thread->GetThreadId();
188 status = S_OK;
189 }
190 EX_CATCH
191 {
192 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
193 {
194 EX_RETHROW;
195 }
196 }
197 EX_END_CATCH(SwallowAllExceptions)
198
199 DAC_LEAVE();
200 return status;
201}
202
203HRESULT STDMETHODCALLTYPE
204ClrDataTask::GetFlags(
205 /* [out] */ ULONG32 *flags)
206{
207 HRESULT status;
208
209 DAC_ENTER_SUB(m_dac);
210
211 EX_TRY
212 {
213 // XXX Microsoft - GC check.
214 *flags = CLRDATA_TASK_DEFAULT;
215 status = S_OK;
216 }
217 EX_CATCH
218 {
219 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
220 {
221 EX_RETHROW;
222 }
223 }
224 EX_END_CATCH(SwallowAllExceptions)
225
226 DAC_LEAVE();
227 return status;
228}
229
230HRESULT STDMETHODCALLTYPE
231ClrDataTask::IsSameObject(
232 /* [in] */ IXCLRDataTask* task)
233{
234 HRESULT status;
235
236 DAC_ENTER_SUB(m_dac);
237
238 EX_TRY
239 {
240 status = PTR_HOST_TO_TADDR(m_thread) ==
241 PTR_HOST_TO_TADDR(((ClrDataTask*)task)->m_thread) ?
242 S_OK : S_FALSE;
243 }
244 EX_CATCH
245 {
246 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
247 {
248 EX_RETHROW;
249 }
250 }
251 EX_END_CATCH(SwallowAllExceptions)
252
253 DAC_LEAVE();
254 return status;
255}
256
257HRESULT STDMETHODCALLTYPE
258ClrDataTask::GetManagedObject(
259 /* [out] */ IXCLRDataValue **value)
260{
261 HRESULT status;
262
263 DAC_ENTER_SUB(m_dac);
264
265 EX_TRY
266 {
267 // XXX Microsoft.
268 status = E_NOTIMPL;
269 }
270 EX_CATCH
271 {
272 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
273 {
274 EX_RETHROW;
275 }
276 }
277 EX_END_CATCH(SwallowAllExceptions)
278
279 DAC_LEAVE();
280 return status;
281}
282
283HRESULT STDMETHODCALLTYPE
284ClrDataTask::GetDesiredExecutionState(
285 /* [out] */ ULONG32 *state)
286{
287 HRESULT status;
288
289 DAC_ENTER_SUB(m_dac);
290
291 EX_TRY
292 {
293 // XXX Microsoft.
294 status = E_NOTIMPL;
295 }
296 EX_CATCH
297 {
298 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
299 {
300 EX_RETHROW;
301 }
302 }
303 EX_END_CATCH(SwallowAllExceptions)
304
305 DAC_LEAVE();
306 return status;
307}
308
309HRESULT STDMETHODCALLTYPE
310ClrDataTask::SetDesiredExecutionState(
311 /* [in] */ ULONG32 state)
312{
313 HRESULT status;
314
315 DAC_ENTER_SUB(m_dac);
316
317 EX_TRY
318 {
319 // XXX Microsoft.
320 status = E_NOTIMPL;
321 }
322 EX_CATCH
323 {
324 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
325 {
326 EX_RETHROW;
327 }
328 }
329 EX_END_CATCH(SwallowAllExceptions)
330
331 DAC_LEAVE();
332 return status;
333}
334
335HRESULT STDMETHODCALLTYPE
336ClrDataTask::CreateStackWalk(
337 /* [in] */ ULONG32 flags,
338 /* [out] */ IXCLRDataStackWalk **stackWalk)
339{
340 HRESULT status;
341
342 if (flags & ~SIMPFRAME_ALL)
343 {
344 return E_INVALIDARG;
345 }
346
347 DAC_ENTER_SUB(m_dac);
348
349 ClrDataStackWalk* walkClass = NULL;
350
351 EX_TRY
352 {
353 walkClass = new (nothrow) ClrDataStackWalk(m_dac, m_thread, flags);
354
355 if (!walkClass)
356 {
357 status = E_OUTOFMEMORY;
358 }
359 else if ((status = walkClass->Init()) != S_OK)
360 {
361 delete walkClass;
362 }
363 else
364 {
365 *stackWalk = static_cast<IXCLRDataStackWalk*>(walkClass);
366 }
367 }
368 EX_CATCH
369 {
370 if (walkClass)
371 {
372 delete walkClass;
373 }
374
375 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
376 {
377 EX_RETHROW;
378 }
379 }
380 EX_END_CATCH(SwallowAllExceptions)
381
382 DAC_LEAVE();
383 return status;
384}
385
386HRESULT STDMETHODCALLTYPE
387ClrDataTask::GetOSThreadID(
388 /* [out] */ ULONG32 *id)
389{
390 HRESULT status;
391
392 DAC_ENTER_SUB(m_dac);
393
394 EX_TRY
395 {
396 if (m_thread->GetOSThreadId() &&
397 m_thread->GetOSThreadId() != 0xbaadf00d)
398 {
399 *id = m_thread->GetOSThreadId();
400 status = S_OK;
401 }
402 else
403 {
404 *id = 0;
405 status = S_FALSE;
406 }
407 }
408 EX_CATCH
409 {
410 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
411 {
412 EX_RETHROW;
413 }
414 }
415 EX_END_CATCH(SwallowAllExceptions)
416
417 DAC_LEAVE();
418 return status;
419}
420
421HRESULT STDMETHODCALLTYPE
422ClrDataTask::GetContext(
423 /* [in] */ ULONG32 contextFlags,
424 /* [in] */ ULONG32 contextBufSize,
425 /* [out] */ ULONG32 *contextSize,
426 /* [size_is][out] */ BYTE contextBuf[ ])
427{
428 HRESULT status;
429
430 if (contextSize)
431 {
432 *contextSize = ContextSizeForFlags(contextFlags);
433 }
434
435 if (!CheckContextSizeForFlags(contextBufSize, contextFlags))
436 {
437 return E_INVALIDARG;
438 }
439
440 DAC_ENTER_SUB(m_dac);
441
442 EX_TRY
443 {
444 if (m_thread->GetOSThreadId())
445 {
446 status = m_dac->m_pTarget->
447 GetThreadContext(m_thread->GetOSThreadId(),
448 contextFlags,
449 contextBufSize,
450 contextBuf);
451 }
452 else
453 {
454 status = E_INVALIDARG;
455 }
456 }
457 EX_CATCH
458 {
459 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
460 {
461 EX_RETHROW;
462 }
463 }
464 EX_END_CATCH(SwallowAllExceptions)
465
466 DAC_LEAVE();
467 return status;
468}
469
470HRESULT STDMETHODCALLTYPE
471ClrDataTask::SetContext(
472 /* [in] */ ULONG32 contextSize,
473 /* [size_is][in] */ BYTE context[ ])
474{
475 HRESULT status;
476
477 if (!CheckContextSizeForBuffer(contextSize, context))
478 {
479 return E_INVALIDARG;
480 }
481
482 DAC_ENTER_SUB(m_dac);
483
484 EX_TRY
485 {
486 if (m_thread->GetOSThreadId())
487 {
488 status = m_dac->m_pMutableTarget->
489 SetThreadContext(m_thread->GetOSThreadId(),
490 contextSize,
491 context);
492 }
493 else
494 {
495 status = E_INVALIDARG;
496 }
497 }
498 EX_CATCH
499 {
500 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
501 {
502 EX_RETHROW;
503 }
504 }
505 EX_END_CATCH(SwallowAllExceptions)
506
507 DAC_LEAVE();
508 return status;
509}
510
511HRESULT STDMETHODCALLTYPE
512ClrDataTask::GetCurrentExceptionState(
513 /* [out] */ IXCLRDataExceptionState **exception)
514{
515 HRESULT status;
516
517 DAC_ENTER_SUB(m_dac);
518
519 EX_TRY
520 {
521 status = ClrDataExceptionState::NewFromThread(m_dac,
522 m_thread,
523 NULL,
524 exception);
525 }
526 EX_CATCH
527 {
528 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
529 {
530 EX_RETHROW;
531 }
532 }
533 EX_END_CATCH(SwallowAllExceptions)
534
535 DAC_LEAVE();
536 return status;
537}
538
539HRESULT STDMETHODCALLTYPE
540ClrDataTask::GetLastExceptionState(
541 /* [out] */ IXCLRDataExceptionState **exception)
542{
543 HRESULT status;
544
545 DAC_ENTER_SUB(m_dac);
546
547 EX_TRY
548 {
549 if (m_thread->m_LastThrownObjectHandle)
550 {
551 *exception = new (nothrow)
552 ClrDataExceptionState(m_dac,
553 m_thread->GetDomain(),
554 m_thread,
555 CLRDATA_EXCEPTION_PARTIAL,
556 NULL,
557 m_thread->m_LastThrownObjectHandle,
558 NULL);
559 status = *exception ? S_OK : E_OUTOFMEMORY;
560 }
561 else
562 {
563 status = E_NOINTERFACE;
564 }
565 }
566 EX_CATCH
567 {
568 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
569 {
570 EX_RETHROW;
571 }
572 }
573 EX_END_CATCH(SwallowAllExceptions)
574
575 DAC_LEAVE();
576 return status;
577}
578
579HRESULT STDMETHODCALLTYPE
580ClrDataTask::Request(
581 /* [in] */ ULONG32 reqCode,
582 /* [in] */ ULONG32 inBufferSize,
583 /* [size_is][in] */ BYTE *inBuffer,
584 /* [in] */ ULONG32 outBufferSize,
585 /* [size_is][out] */ BYTE *outBuffer)
586{
587 HRESULT status;
588
589 DAC_ENTER_SUB(m_dac);
590
591 EX_TRY
592 {
593 switch(reqCode)
594 {
595 case CLRDATA_REQUEST_REVISION:
596 if (inBufferSize != 0 ||
597 inBuffer ||
598 outBufferSize != sizeof(ULONG32))
599 {
600 status = E_INVALIDARG;
601 }
602 else
603 {
604 *(ULONG32*)outBuffer = 3;
605 status = S_OK;
606 }
607 break;
608
609 default:
610 status = E_INVALIDARG;
611 break;
612 }
613 }
614 EX_CATCH
615 {
616 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
617 {
618 EX_RETHROW;
619 }
620 }
621 EX_END_CATCH(SwallowAllExceptions)
622
623 DAC_LEAVE();
624 return status;
625}
626
627//----------------------------------------------------------------------------
628//
629// ClrDataAppDomain.
630//
631//----------------------------------------------------------------------------
632
633ClrDataAppDomain::ClrDataAppDomain(ClrDataAccess* dac,
634 AppDomain* appDomain)
635{
636 m_dac = dac;
637 m_dac->AddRef();
638 m_instanceAge = m_dac->m_instanceAge;
639 m_appDomain = appDomain;
640 m_refs = 1;
641}
642
643ClrDataAppDomain::~ClrDataAppDomain(void)
644{
645 m_dac->Release();
646}
647
648STDMETHODIMP
649ClrDataAppDomain::QueryInterface(THIS_
650 IN REFIID interfaceId,
651 OUT PVOID* iface)
652{
653 if (IsEqualIID(interfaceId, IID_IUnknown) ||
654 IsEqualIID(interfaceId, __uuidof(IXCLRDataAppDomain)))
655 {
656 AddRef();
657 *iface = static_cast<IUnknown*>
658 (static_cast<IXCLRDataAppDomain*>(this));
659 return S_OK;
660 }
661 else
662 {
663 *iface = NULL;
664 return E_NOINTERFACE;
665 }
666}
667
668STDMETHODIMP_(ULONG)
669ClrDataAppDomain::AddRef(THIS)
670{
671 return InterlockedIncrement(&m_refs);
672}
673
674STDMETHODIMP_(ULONG)
675ClrDataAppDomain::Release(THIS)
676{
677 SUPPORTS_DAC_HOST_ONLY;
678 LONG newRefs = InterlockedDecrement(&m_refs);
679 if (newRefs == 0)
680 {
681 delete this;
682 }
683 return newRefs;
684}
685
686HRESULT STDMETHODCALLTYPE
687ClrDataAppDomain::GetProcess(
688 /* [out] */ IXCLRDataProcess **process)
689{
690 HRESULT status;
691
692 DAC_ENTER_SUB(m_dac);
693
694 EX_TRY
695 {
696 *process = static_cast<IXCLRDataProcess*>(m_dac);
697 m_dac->AddRef();
698 status = S_OK;
699 }
700 EX_CATCH
701 {
702 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
703 {
704 EX_RETHROW;
705 }
706 }
707 EX_END_CATCH(SwallowAllExceptions)
708
709 DAC_LEAVE();
710 return status;
711}
712
713HRESULT STDMETHODCALLTYPE
714ClrDataAppDomain::GetName(
715 /* [in] */ ULONG32 bufLen,
716 /* [out] */ ULONG32 *nameLen,
717 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
718{
719 HRESULT status = S_OK;
720
721 DAC_ENTER_SUB(m_dac);
722
723 EX_TRY
724 {
725 bool isUtf8;
726 PVOID rawName = m_appDomain->GetFriendlyNameNoSet(&isUtf8);
727 if (rawName)
728 {
729 if (isUtf8)
730 {
731 status = ConvertUtf8((LPCUTF8)rawName,
732 bufLen, nameLen, name);
733 }
734 else
735 {
736 status = StringCchCopy(name, bufLen, (PCWSTR)rawName) == S_OK ?
737 S_OK : S_FALSE;
738 if (nameLen)
739 {
740 size_t cchName = wcslen((PCWSTR)rawName) + 1;
741 if (FitsIn<ULONG32>(cchName))
742 {
743 *nameLen = (ULONG32) cchName;
744 }
745 else
746 {
747 status = COR_E_OVERFLOW;
748 }
749 }
750 }
751 }
752 else
753 {
754 status = E_NOINTERFACE;
755 }
756 }
757 EX_CATCH
758 {
759 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
760 {
761 EX_RETHROW;
762 }
763 }
764 EX_END_CATCH(SwallowAllExceptions)
765
766 DAC_LEAVE();
767 return status;
768}
769
770HRESULT STDMETHODCALLTYPE
771ClrDataAppDomain::GetFlags(
772 /* [out] */ ULONG32 *flags)
773{
774 HRESULT status;
775
776 DAC_ENTER_SUB(m_dac);
777
778 EX_TRY
779 {
780 *flags = CLRDATA_DOMAIN_DEFAULT;
781 status = S_OK;
782 }
783 EX_CATCH
784 {
785 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
786 {
787 EX_RETHROW;
788 }
789 }
790 EX_END_CATCH(SwallowAllExceptions)
791
792 DAC_LEAVE();
793 return status;
794}
795
796HRESULT STDMETHODCALLTYPE
797ClrDataAppDomain::IsSameObject(
798 /* [in] */ IXCLRDataAppDomain* appDomain)
799{
800 HRESULT status;
801
802 DAC_ENTER_SUB(m_dac);
803
804 EX_TRY
805 {
806 status = PTR_HOST_TO_TADDR(m_appDomain) ==
807 PTR_HOST_TO_TADDR(((ClrDataAppDomain*)appDomain)->m_appDomain) ?
808 S_OK : S_FALSE;
809 }
810 EX_CATCH
811 {
812 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
813 {
814 EX_RETHROW;
815 }
816 }
817 EX_END_CATCH(SwallowAllExceptions)
818
819 DAC_LEAVE();
820 return status;
821}
822
823HRESULT STDMETHODCALLTYPE
824ClrDataAppDomain::GetManagedObject(
825 /* [out] */ IXCLRDataValue **value)
826{
827 HRESULT status;
828
829 DAC_ENTER_SUB(m_dac);
830
831 EX_TRY
832 {
833 // XXX Microsoft.
834 status = E_NOTIMPL;
835 }
836 EX_CATCH
837 {
838 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
839 {
840 EX_RETHROW;
841 }
842 }
843 EX_END_CATCH(SwallowAllExceptions)
844
845 DAC_LEAVE();
846 return status;
847}
848
849HRESULT STDMETHODCALLTYPE
850ClrDataAppDomain::GetUniqueID(
851 /* [out] */ ULONG64 *id)
852{
853 HRESULT status;
854
855 DAC_ENTER_SUB(m_dac);
856
857 EX_TRY
858 {
859 *id = m_appDomain->GetId().m_dwId;
860 status = S_OK;
861 }
862 EX_CATCH
863 {
864 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
865 {
866 EX_RETHROW;
867 }
868 }
869 EX_END_CATCH(SwallowAllExceptions)
870
871 DAC_LEAVE();
872 return status;
873}
874
875HRESULT STDMETHODCALLTYPE
876ClrDataAppDomain::Request(
877 /* [in] */ ULONG32 reqCode,
878 /* [in] */ ULONG32 inBufferSize,
879 /* [size_is][in] */ BYTE *inBuffer,
880 /* [in] */ ULONG32 outBufferSize,
881 /* [size_is][out] */ BYTE *outBuffer)
882{
883 HRESULT status;
884
885 DAC_ENTER_SUB(m_dac);
886
887 EX_TRY
888 {
889 status = E_INVALIDARG;
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
904//----------------------------------------------------------------------------
905//
906// ClrDataAssembly.
907//
908//----------------------------------------------------------------------------
909
910ClrDataAssembly::ClrDataAssembly(ClrDataAccess* dac,
911 Assembly* assembly)
912{
913 m_dac = dac;
914 m_dac->AddRef();
915 m_instanceAge = m_dac->m_instanceAge;
916 m_refs = 1;
917 m_assembly = assembly;
918}
919
920ClrDataAssembly::~ClrDataAssembly(void)
921{
922 m_dac->Release();
923}
924
925STDMETHODIMP
926ClrDataAssembly::QueryInterface(THIS_
927 IN REFIID interfaceId,
928 OUT PVOID* iface)
929{
930 if (IsEqualIID(interfaceId, IID_IUnknown) ||
931 IsEqualIID(interfaceId, __uuidof(IXCLRDataAssembly)))
932 {
933 AddRef();
934 *iface = static_cast<IUnknown*>
935 (static_cast<IXCLRDataAssembly*>(this));
936 return S_OK;
937 }
938 else
939 {
940 *iface = NULL;
941 return E_NOINTERFACE;
942 }
943}
944
945STDMETHODIMP_(ULONG)
946ClrDataAssembly::AddRef(THIS)
947{
948 return InterlockedIncrement(&m_refs);
949}
950
951STDMETHODIMP_(ULONG)
952ClrDataAssembly::Release(THIS)
953{
954 SUPPORTS_DAC_HOST_ONLY;
955 LONG newRefs = InterlockedDecrement(&m_refs);
956 if (newRefs == 0)
957 {
958 delete this;
959 }
960 return newRefs;
961}
962
963HRESULT STDMETHODCALLTYPE
964ClrDataAssembly::StartEnumModules(
965 /* [out] */ CLRDATA_ENUM* handle)
966{
967 HRESULT status;
968
969 DAC_ENTER_SUB(m_dac);
970
971 EX_TRY
972 {
973 Assembly::ModuleIterator* iter = new (nothrow)
974 Assembly::ModuleIterator;
975 if (iter)
976 {
977 *iter = m_assembly->IterateModules();
978 *handle = TO_CDENUM(iter);
979 status = S_OK;
980 }
981 else
982 {
983 status = E_OUTOFMEMORY;
984 }
985 }
986 EX_CATCH
987 {
988 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
989 {
990 EX_RETHROW;
991 }
992 }
993 EX_END_CATCH(SwallowAllExceptions)
994
995 DAC_LEAVE();
996 return status;
997}
998
999HRESULT STDMETHODCALLTYPE
1000ClrDataAssembly::EnumModule(
1001 /* [in, out] */ CLRDATA_ENUM* handle,
1002 /* [out] */ IXCLRDataModule **mod)
1003{
1004 HRESULT status;
1005
1006 DAC_ENTER_SUB(m_dac);
1007
1008 EX_TRY
1009 {
1010 Assembly::ModuleIterator* iter =
1011 FROM_CDENUM(Assembly::ModuleIterator, *handle);
1012 if (iter->Next())
1013 {
1014 *mod = new (nothrow)
1015 ClrDataModule(m_dac, iter->GetModule());
1016 status = *mod ? S_OK : E_OUTOFMEMORY;
1017 }
1018 else
1019 {
1020 status = S_FALSE;
1021 }
1022 }
1023 EX_CATCH
1024 {
1025 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1026 {
1027 EX_RETHROW;
1028 }
1029 }
1030 EX_END_CATCH(SwallowAllExceptions)
1031
1032 DAC_LEAVE();
1033 return status;
1034}
1035
1036HRESULT STDMETHODCALLTYPE
1037ClrDataAssembly::EndEnumModules(
1038 /* [in] */ CLRDATA_ENUM handle)
1039{
1040 HRESULT status;
1041
1042 DAC_ENTER_SUB(m_dac);
1043
1044 EX_TRY
1045 {
1046 Assembly::ModuleIterator* iter =
1047 FROM_CDENUM(Assembly::ModuleIterator, handle);
1048 delete iter;
1049 status = S_OK;
1050 }
1051 EX_CATCH
1052 {
1053 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1054 {
1055 EX_RETHROW;
1056 }
1057 }
1058 EX_END_CATCH(SwallowAllExceptions)
1059
1060 DAC_LEAVE();
1061 return status;
1062}
1063
1064HRESULT STDMETHODCALLTYPE
1065ClrDataAssembly::StartEnumAppDomains(
1066 /* [out] */ CLRDATA_ENUM* handle)
1067{
1068 HRESULT status;
1069
1070 DAC_ENTER_SUB(m_dac);
1071
1072 EX_TRY
1073 {
1074 // XXX Microsoft.
1075 status = E_NOTIMPL;
1076 }
1077 EX_CATCH
1078 {
1079 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1080 {
1081 EX_RETHROW;
1082 }
1083 }
1084 EX_END_CATCH(SwallowAllExceptions)
1085
1086 DAC_LEAVE();
1087 return status;
1088}
1089
1090HRESULT STDMETHODCALLTYPE
1091ClrDataAssembly::EnumAppDomain(
1092 /* [in, out] */ CLRDATA_ENUM* handle,
1093 /* [out] */ IXCLRDataAppDomain **appDomain)
1094{
1095 HRESULT status;
1096
1097 DAC_ENTER_SUB(m_dac);
1098
1099 EX_TRY
1100 {
1101 // XXX Microsoft.
1102 status = E_NOTIMPL;
1103 }
1104 EX_CATCH
1105 {
1106 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1107 {
1108 EX_RETHROW;
1109 }
1110 }
1111 EX_END_CATCH(SwallowAllExceptions)
1112
1113 DAC_LEAVE();
1114 return status;
1115}
1116
1117HRESULT STDMETHODCALLTYPE
1118ClrDataAssembly::EndEnumAppDomains(
1119 /* [in] */ CLRDATA_ENUM handle)
1120{
1121 HRESULT status;
1122
1123 DAC_ENTER_SUB(m_dac);
1124
1125 EX_TRY
1126 {
1127 // XXX Microsoft.
1128 status = E_NOTIMPL;
1129 }
1130 EX_CATCH
1131 {
1132 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1133 {
1134 EX_RETHROW;
1135 }
1136 }
1137 EX_END_CATCH(SwallowAllExceptions)
1138
1139 DAC_LEAVE();
1140 return status;
1141}
1142
1143HRESULT STDMETHODCALLTYPE
1144ClrDataAssembly::GetName(
1145 /* [in] */ ULONG32 bufLen,
1146 /* [out] */ ULONG32 *nameLen,
1147 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
1148{
1149 HRESULT status;
1150
1151 DAC_ENTER_SUB(m_dac);
1152
1153 EX_TRY
1154 {
1155 status = ConvertUtf8(m_assembly->GetSimpleName(),
1156 bufLen, nameLen, name);
1157 }
1158 EX_CATCH
1159 {
1160 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1161 {
1162 EX_RETHROW;
1163 }
1164 }
1165 EX_END_CATCH(SwallowAllExceptions)
1166
1167 DAC_LEAVE();
1168 return status;
1169}
1170
1171HRESULT STDMETHODCALLTYPE
1172ClrDataAssembly::GetFileName(
1173 /* [in] */ ULONG32 bufLen,
1174 /* [out] */ ULONG32 *nameLen,
1175 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
1176{
1177 HRESULT status;
1178
1179 DAC_ENTER_SUB(m_dac);
1180
1181 EX_TRY
1182 {
1183 COUNT_T _nameLen;
1184
1185 if (m_assembly->GetManifestFile()->GetPath().
1186 DacGetUnicode(bufLen, name, &_nameLen))
1187 {
1188 if (nameLen)
1189 {
1190 *nameLen = _nameLen;
1191 }
1192 status = S_OK;
1193 }
1194 else
1195 {
1196 status = E_FAIL;
1197 }
1198 }
1199 EX_CATCH
1200 {
1201 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1202 {
1203 EX_RETHROW;
1204 }
1205 }
1206 EX_END_CATCH(SwallowAllExceptions)
1207
1208 DAC_LEAVE();
1209 return status;
1210}
1211
1212HRESULT STDMETHODCALLTYPE
1213ClrDataAssembly::GetDisplayName(
1214 /* [in] */ ULONG32 bufLen,
1215 /* [out] */ ULONG32 *nameLen,
1216 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
1217{
1218 HRESULT status;
1219
1220 DAC_ENTER_SUB(m_dac);
1221
1222 EX_TRY
1223 {
1224 // XXX Microsoft.
1225 status = E_NOTIMPL;
1226 }
1227 EX_CATCH
1228 {
1229 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1230 {
1231 EX_RETHROW;
1232 }
1233 }
1234 EX_END_CATCH(SwallowAllExceptions)
1235
1236 DAC_LEAVE();
1237 return status;
1238}
1239
1240HRESULT STDMETHODCALLTYPE
1241ClrDataAssembly::GetFlags(
1242 /* [out] */ ULONG32 *flags)
1243{
1244 HRESULT status;
1245
1246 DAC_ENTER_SUB(m_dac);
1247
1248 EX_TRY
1249 {
1250 *flags = CLRDATA_ASSEMBLY_DEFAULT;
1251 status = S_OK;
1252 }
1253 EX_CATCH
1254 {
1255 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1256 {
1257 EX_RETHROW;
1258 }
1259 }
1260 EX_END_CATCH(SwallowAllExceptions)
1261
1262 DAC_LEAVE();
1263 return status;
1264}
1265
1266HRESULT STDMETHODCALLTYPE
1267ClrDataAssembly::IsSameObject(
1268 /* [in] */ IXCLRDataAssembly* assembly)
1269{
1270 HRESULT status;
1271
1272 DAC_ENTER_SUB(m_dac);
1273
1274 EX_TRY
1275 {
1276 status = (PTR_HOST_TO_TADDR(m_assembly) ==
1277 PTR_HOST_TO_TADDR(((ClrDataAssembly*)assembly)->
1278 m_assembly)) ?
1279 S_OK : S_FALSE;
1280 }
1281 EX_CATCH
1282 {
1283 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1284 {
1285 EX_RETHROW;
1286 }
1287 }
1288 EX_END_CATCH(SwallowAllExceptions)
1289
1290 DAC_LEAVE();
1291 return status;
1292}
1293
1294HRESULT STDMETHODCALLTYPE
1295ClrDataAssembly::Request(
1296 /* [in] */ ULONG32 reqCode,
1297 /* [in] */ ULONG32 inBufferSize,
1298 /* [size_is][in] */ BYTE *inBuffer,
1299 /* [in] */ ULONG32 outBufferSize,
1300 /* [size_is][out] */ BYTE *outBuffer)
1301{
1302 HRESULT status;
1303
1304 DAC_ENTER_SUB(m_dac);
1305
1306 EX_TRY
1307 {
1308 switch(reqCode)
1309 {
1310 case CLRDATA_REQUEST_REVISION:
1311 if (inBufferSize != 0 ||
1312 inBuffer ||
1313 outBufferSize != sizeof(ULONG32))
1314 {
1315 status = E_INVALIDARG;
1316 }
1317 else
1318 {
1319 *(ULONG32*)outBuffer = 2;
1320 status = S_OK;
1321 }
1322 break;
1323
1324 default:
1325 status = E_INVALIDARG;
1326 break;
1327 }
1328 }
1329 EX_CATCH
1330 {
1331 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1332 {
1333 EX_RETHROW;
1334 }
1335 }
1336 EX_END_CATCH(SwallowAllExceptions)
1337
1338 DAC_LEAVE();
1339 return status;
1340}
1341
1342//----------------------------------------------------------------------------
1343//
1344// ClrDataModule.
1345//
1346//----------------------------------------------------------------------------
1347
1348ClrDataModule::ClrDataModule(ClrDataAccess* dac,
1349 Module* module)
1350{
1351 m_dac = dac;
1352 m_dac->AddRef();
1353 m_instanceAge = m_dac->m_instanceAge;
1354 m_refs = 1;
1355 m_module = module;
1356 m_mdImport = NULL;
1357 m_setExtents = false;
1358}
1359
1360ClrDataModule::~ClrDataModule(void)
1361{
1362 m_dac->Release();
1363 if (m_mdImport)
1364 {
1365 m_mdImport->Release();
1366 }
1367}
1368
1369STDMETHODIMP
1370ClrDataModule::QueryInterface(THIS_
1371 IN REFIID interfaceId,
1372 OUT PVOID* iface)
1373{
1374 _ASSERTE(iface != NULL);
1375
1376 if (IsEqualIID(interfaceId, IID_IUnknown) ||
1377 IsEqualIID(interfaceId, __uuidof(IXCLRDataModule)))
1378 {
1379 AddRef();
1380 *iface = static_cast<IUnknown*>
1381 (static_cast<IXCLRDataModule*>(this));
1382 return S_OK;
1383 }
1384 else if (IsEqualIID(interfaceId, __uuidof(IXCLRDataModule2)))
1385 {
1386 AddRef();
1387 *iface = static_cast<IUnknown*>
1388 (static_cast<IXCLRDataModule2*>(this));
1389 return S_OK;
1390 }
1391 else if (IsEqualIID(interfaceId, IID_IMetaDataImport))
1392 {
1393 return GetMdInterface(iface);
1394 }
1395 else
1396 {
1397 *iface = NULL;
1398 return E_NOINTERFACE;
1399 }
1400}
1401
1402STDMETHODIMP_(ULONG)
1403ClrDataModule::AddRef(THIS)
1404{
1405 return InterlockedIncrement(&m_refs);
1406}
1407
1408STDMETHODIMP_(ULONG)
1409ClrDataModule::Release(THIS)
1410{
1411 SUPPORTS_DAC_HOST_ONLY;
1412 LONG newRefs = InterlockedDecrement(&m_refs);
1413 if (newRefs == 0)
1414 {
1415 delete this;
1416 }
1417 return newRefs;
1418}
1419
1420HRESULT STDMETHODCALLTYPE
1421ClrDataModule::StartEnumAssemblies(
1422 /* [out] */ CLRDATA_ENUM* handle)
1423{
1424 HRESULT status;
1425
1426 DAC_ENTER_SUB(m_dac);
1427
1428 EX_TRY
1429 {
1430 ProcessModIter* iter = new (nothrow) ProcessModIter;
1431 if (iter)
1432 {
1433 *handle = TO_CDENUM(iter);
1434 status = S_OK;
1435 }
1436 else
1437 {
1438 status = E_OUTOFMEMORY;
1439 }
1440 }
1441 EX_CATCH
1442 {
1443 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1444 {
1445 EX_RETHROW;
1446 }
1447 }
1448 EX_END_CATCH(SwallowAllExceptions)
1449
1450 DAC_LEAVE();
1451 return status;
1452}
1453
1454HRESULT STDMETHODCALLTYPE
1455ClrDataModule::EnumAssembly(
1456 /* [in, out] */ CLRDATA_ENUM* handle,
1457 /* [out] */ IXCLRDataAssembly **assembly)
1458{
1459 HRESULT status;
1460
1461 DAC_ENTER_SUB(m_dac);
1462
1463 EX_TRY
1464 {
1465 ProcessModIter* iter = FROM_CDENUM(ProcessModIter, *handle);
1466 Module* module;
1467
1468 //
1469 // Iterate over all of the modules in the process.
1470 // When this module is found, return the containing
1471 // assembly.
1472 // Is there a more direct way?
1473 //
1474
1475 for (;;)
1476 {
1477 if (!(module = iter->NextModule()))
1478 {
1479 status = S_FALSE;
1480 break;
1481 }
1482
1483 if (PTR_HOST_TO_TADDR(module) == PTR_HOST_TO_TADDR(m_module))
1484 {
1485 *assembly = new (nothrow)
1486 ClrDataAssembly(m_dac, iter->m_curAssem);
1487 status = *assembly ? S_OK : E_OUTOFMEMORY;
1488 break;
1489 }
1490 }
1491 }
1492 EX_CATCH
1493 {
1494 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1495 {
1496 EX_RETHROW;
1497 }
1498 }
1499 EX_END_CATCH(SwallowAllExceptions)
1500
1501 DAC_LEAVE();
1502 return status;
1503}
1504
1505HRESULT STDMETHODCALLTYPE
1506ClrDataModule::EndEnumAssemblies(
1507 /* [in] */ CLRDATA_ENUM handle)
1508{
1509 HRESULT status;
1510
1511 DAC_ENTER_SUB(m_dac);
1512
1513 EX_TRY
1514 {
1515 ProcessModIter* iter = FROM_CDENUM(ProcessModIter, handle);
1516 delete iter;
1517 status = S_OK;
1518 }
1519 EX_CATCH
1520 {
1521 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1522 {
1523 EX_RETHROW;
1524 }
1525 }
1526 EX_END_CATCH(SwallowAllExceptions)
1527
1528 DAC_LEAVE();
1529 return status;
1530}
1531
1532HRESULT STDMETHODCALLTYPE
1533ClrDataModule::StartEnumAppDomains(
1534 /* [out] */ CLRDATA_ENUM* handle)
1535{
1536 HRESULT status;
1537
1538 DAC_ENTER_SUB(m_dac);
1539
1540 EX_TRY
1541 {
1542 // XXX Microsoft.
1543 status = E_NOTIMPL;
1544 }
1545 EX_CATCH
1546 {
1547 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1548 {
1549 EX_RETHROW;
1550 }
1551 }
1552 EX_END_CATCH(SwallowAllExceptions)
1553
1554 DAC_LEAVE();
1555 return status;
1556}
1557
1558HRESULT STDMETHODCALLTYPE
1559ClrDataModule::EnumAppDomain(
1560 /* [in, out] */ CLRDATA_ENUM* handle,
1561 /* [out] */ IXCLRDataAppDomain **appDomain)
1562{
1563 HRESULT status;
1564
1565 DAC_ENTER_SUB(m_dac);
1566
1567 EX_TRY
1568 {
1569 // XXX Microsoft.
1570 status = E_NOTIMPL;
1571 }
1572 EX_CATCH
1573 {
1574 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1575 {
1576 EX_RETHROW;
1577 }
1578 }
1579 EX_END_CATCH(SwallowAllExceptions)
1580
1581 DAC_LEAVE();
1582 return status;
1583}
1584
1585HRESULT STDMETHODCALLTYPE
1586ClrDataModule::EndEnumAppDomains(
1587 /* [in] */ CLRDATA_ENUM handle)
1588{
1589 HRESULT status;
1590
1591 DAC_ENTER_SUB(m_dac);
1592
1593 EX_TRY
1594 {
1595 // XXX Microsoft.
1596 status = E_NOTIMPL;
1597 }
1598 EX_CATCH
1599 {
1600 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1601 {
1602 EX_RETHROW;
1603 }
1604 }
1605 EX_END_CATCH(SwallowAllExceptions)
1606
1607 DAC_LEAVE();
1608 return status;
1609}
1610
1611HRESULT STDMETHODCALLTYPE
1612ClrDataModule::StartEnumTypeDefinitions(
1613 /* [out] */ CLRDATA_ENUM* handle)
1614{
1615 HRESULT status;
1616
1617 DAC_ENTER_SUB(m_dac);
1618
1619 EX_TRY
1620 {
1621 status = MetaEnum::New(m_module,
1622 mdtTypeDef,
1623 0,
1624 NULL,
1625 NULL,
1626 handle);
1627 }
1628 EX_CATCH
1629 {
1630 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1631 {
1632 EX_RETHROW;
1633 }
1634 }
1635 EX_END_CATCH(SwallowAllExceptions)
1636
1637 DAC_LEAVE();
1638 return status;
1639}
1640
1641HRESULT STDMETHODCALLTYPE
1642ClrDataModule::EnumTypeDefinition(
1643 /* [in, out] */ CLRDATA_ENUM* handle,
1644 /* [out] */ IXCLRDataTypeDefinition **typeDefinition)
1645{
1646 HRESULT status;
1647
1648 DAC_ENTER_SUB(m_dac);
1649
1650 EX_TRY
1651 {
1652 mdTypeDef token;
1653
1654 if ((status = MetaEnum::CdNextToken(handle, &token)) == S_OK)
1655 {
1656 status = ClrDataTypeDefinition::
1657 NewFromModule(m_dac,
1658 m_module,
1659 token,
1660 NULL,
1661 typeDefinition);
1662 }
1663 }
1664 EX_CATCH
1665 {
1666 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1667 {
1668 EX_RETHROW;
1669 }
1670 }
1671 EX_END_CATCH(SwallowAllExceptions)
1672
1673 DAC_LEAVE();
1674 return status;
1675}
1676
1677HRESULT STDMETHODCALLTYPE
1678ClrDataModule::EndEnumTypeDefinitions(
1679 /* [in] */ CLRDATA_ENUM handle)
1680{
1681 HRESULT status;
1682
1683 DAC_ENTER_SUB(m_dac);
1684
1685 EX_TRY
1686 {
1687 status = MetaEnum::CdEnd(handle);
1688 }
1689 EX_CATCH
1690 {
1691 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1692 {
1693 EX_RETHROW;
1694 }
1695 }
1696 EX_END_CATCH(SwallowAllExceptions)
1697
1698 DAC_LEAVE();
1699 return status;
1700}
1701
1702HRESULT STDMETHODCALLTYPE
1703ClrDataModule::StartEnumTypeInstances(
1704 /* [in] */ IXCLRDataAppDomain* appDomain,
1705 /* [out] */ CLRDATA_ENUM* handle)
1706{
1707 HRESULT status;
1708
1709 DAC_ENTER_SUB(m_dac);
1710
1711 EX_TRY
1712 {
1713 status = MetaEnum::New(m_module,
1714 mdtTypeDef,
1715 0,
1716 appDomain,
1717 NULL,
1718 handle);
1719 }
1720 EX_CATCH
1721 {
1722 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1723 {
1724 EX_RETHROW;
1725 }
1726 }
1727 EX_END_CATCH(SwallowAllExceptions)
1728
1729 DAC_LEAVE();
1730 return status;
1731}
1732
1733HRESULT STDMETHODCALLTYPE
1734ClrDataModule::EnumTypeInstance(
1735 /* [in, out] */ CLRDATA_ENUM* handle,
1736 /* [out] */ IXCLRDataTypeInstance **typeInstance)
1737{
1738 HRESULT status;
1739
1740 DAC_ENTER_SUB(m_dac);
1741
1742 EX_TRY
1743 {
1744 for (;;)
1745 {
1746 AppDomain* appDomain;
1747 mdTypeDef token;
1748
1749 if ((status = MetaEnum::
1750 CdNextDomainToken(handle, &appDomain, &token)) != S_OK)
1751 {
1752 break;
1753 }
1754
1755 // If the type hasn't been used there won't be anything
1756 // loaded. It's not an instance, then, just keep going.
1757 if ((status = ClrDataTypeInstance::
1758 NewFromModule(m_dac,
1759 appDomain,
1760 m_module,
1761 token,
1762 NULL,
1763 typeInstance)) != E_INVALIDARG)
1764 {
1765 break;
1766 }
1767 }
1768 }
1769 EX_CATCH
1770 {
1771 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1772 {
1773 EX_RETHROW;
1774 }
1775 }
1776 EX_END_CATCH(SwallowAllExceptions)
1777
1778 DAC_LEAVE();
1779 return status;
1780}
1781
1782HRESULT STDMETHODCALLTYPE
1783ClrDataModule::EndEnumTypeInstances(
1784 /* [in] */ CLRDATA_ENUM handle)
1785{
1786 HRESULT status;
1787
1788 DAC_ENTER_SUB(m_dac);
1789
1790 EX_TRY
1791 {
1792 status = MetaEnum::CdEnd(handle);
1793 }
1794 EX_CATCH
1795 {
1796 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1797 {
1798 EX_RETHROW;
1799 }
1800 }
1801 EX_END_CATCH(SwallowAllExceptions)
1802
1803 DAC_LEAVE();
1804 return status;
1805}
1806
1807HRESULT STDMETHODCALLTYPE
1808ClrDataModule::StartEnumTypeDefinitionsByName(
1809 /* [in] */ LPCWSTR name,
1810 /* [in] */ ULONG32 flags,
1811 /* [out] */ CLRDATA_ENUM* handle)
1812{
1813 HRESULT status;
1814
1815 DAC_ENTER_SUB(m_dac);
1816
1817 EX_TRY
1818 {
1819 status = SplitName::CdStartType(name,
1820 flags,
1821 m_module,
1822 NULL,
1823 NULL,
1824 NULL,
1825 handle);
1826 }
1827 EX_CATCH
1828 {
1829 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1830 {
1831 EX_RETHROW;
1832 }
1833 }
1834 EX_END_CATCH(SwallowAllExceptions)
1835
1836 DAC_LEAVE();
1837 return status;
1838}
1839
1840HRESULT STDMETHODCALLTYPE
1841ClrDataModule::EnumTypeDefinitionByName(
1842 /* [out][in] */ CLRDATA_ENUM* handle,
1843 /* [out] */ IXCLRDataTypeDefinition **type)
1844{
1845 HRESULT status;
1846
1847 DAC_ENTER_SUB(m_dac);
1848
1849 EX_TRY
1850 {
1851 mdTypeDef token;
1852
1853 if ((status = SplitName::CdNextType(handle, &token)) == S_OK)
1854 {
1855 status = ClrDataTypeDefinition::
1856 NewFromModule(m_dac,
1857 m_module,
1858 token,
1859 NULL,
1860 type);
1861 }
1862 }
1863 EX_CATCH
1864 {
1865 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1866 {
1867 EX_RETHROW;
1868 }
1869 }
1870 EX_END_CATCH(SwallowAllExceptions)
1871
1872 DAC_LEAVE();
1873 return status;
1874}
1875
1876HRESULT STDMETHODCALLTYPE
1877ClrDataModule::EndEnumTypeDefinitionsByName(
1878 /* [in] */ CLRDATA_ENUM handle)
1879{
1880 HRESULT status;
1881
1882 DAC_ENTER_SUB(m_dac);
1883
1884 EX_TRY
1885 {
1886 status = SplitName::CdEnd(handle);
1887 }
1888 EX_CATCH
1889 {
1890 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1891 {
1892 EX_RETHROW;
1893 }
1894 }
1895 EX_END_CATCH(SwallowAllExceptions)
1896
1897 DAC_LEAVE();
1898 return status;
1899}
1900
1901HRESULT STDMETHODCALLTYPE
1902ClrDataModule::StartEnumTypeInstancesByName(
1903 /* [in] */ LPCWSTR name,
1904 /* [in] */ ULONG32 flags,
1905 /* [in] */ IXCLRDataAppDomain *appDomain,
1906 /* [out] */ CLRDATA_ENUM* handle)
1907{
1908 HRESULT status;
1909
1910 DAC_ENTER_SUB(m_dac);
1911
1912 EX_TRY
1913 {
1914 status = SplitName::CdStartType(name,
1915 flags,
1916 m_module,
1917 NULL,
1918 appDomain,
1919 NULL,
1920 handle);
1921 }
1922 EX_CATCH
1923 {
1924 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1925 {
1926 EX_RETHROW;
1927 }
1928 }
1929 EX_END_CATCH(SwallowAllExceptions)
1930
1931 DAC_LEAVE();
1932 return status;
1933}
1934
1935HRESULT STDMETHODCALLTYPE
1936ClrDataModule::EnumTypeInstanceByName(
1937 /* [out][in] */ CLRDATA_ENUM* handle,
1938 /* [out] */ IXCLRDataTypeInstance **type)
1939{
1940 HRESULT status;
1941
1942 DAC_ENTER_SUB(m_dac);
1943
1944 EX_TRY
1945 {
1946 SplitName* split; split = FROM_CDENUM(SplitName, *handle);
1947
1948 for (;;)
1949 {
1950 AppDomain* appDomain;
1951 mdTypeDef token;
1952
1953 if ((status = SplitName::
1954 CdNextDomainType(handle, &appDomain, &token)) != S_OK)
1955 {
1956 break;
1957 }
1958
1959 // If the type hasn't been used there won't be anything
1960 // loaded. It's not an instance, then, just keep going.
1961 if ((status = ClrDataTypeInstance::
1962 NewFromModule(m_dac,
1963 appDomain,
1964 m_module,
1965 token,
1966 NULL,
1967 type)) != E_INVALIDARG)
1968 {
1969 break;
1970 }
1971 }
1972 }
1973 EX_CATCH
1974 {
1975 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
1976 {
1977 EX_RETHROW;
1978 }
1979 }
1980 EX_END_CATCH(SwallowAllExceptions)
1981
1982 DAC_LEAVE();
1983 return status;
1984}
1985
1986HRESULT STDMETHODCALLTYPE
1987ClrDataModule::EndEnumTypeInstancesByName(
1988 /* [in] */ CLRDATA_ENUM handle)
1989{
1990 HRESULT status;
1991
1992 DAC_ENTER_SUB(m_dac);
1993
1994 EX_TRY
1995 {
1996 status = SplitName::CdEnd(handle);
1997 }
1998 EX_CATCH
1999 {
2000 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2001 {
2002 EX_RETHROW;
2003 }
2004 }
2005 EX_END_CATCH(SwallowAllExceptions)
2006
2007 DAC_LEAVE();
2008 return status;
2009}
2010
2011HRESULT STDMETHODCALLTYPE
2012ClrDataModule::GetTypeDefinitionByToken(
2013 /* [in] */ mdTypeDef token,
2014 /* [out] */ IXCLRDataTypeDefinition **typeDefinition)
2015{
2016 HRESULT status;
2017
2018 // This isn't critically necessary but it prevents
2019 // an assert in the metadata code.
2020 if (TypeFromToken(token) != mdtTypeDef)
2021 {
2022 return E_INVALIDARG;
2023 }
2024
2025 DAC_ENTER_SUB(m_dac);
2026
2027 EX_TRY
2028 {
2029 status = ClrDataTypeDefinition::
2030 NewFromModule(m_dac,
2031 m_module,
2032 token,
2033 NULL,
2034 typeDefinition);
2035 }
2036 EX_CATCH
2037 {
2038 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2039 {
2040 EX_RETHROW;
2041 }
2042 }
2043 EX_END_CATCH(SwallowAllExceptions)
2044
2045 DAC_LEAVE();
2046 return status;
2047}
2048
2049HRESULT STDMETHODCALLTYPE
2050ClrDataModule::StartEnumMethodDefinitionsByName(
2051 /* [in] */ LPCWSTR name,
2052 /* [in] */ ULONG32 flags,
2053 /* [out] */ CLRDATA_ENUM* handle)
2054{
2055 HRESULT status;
2056
2057 DAC_ENTER_SUB(m_dac);
2058
2059 EX_TRY
2060 {
2061 status = SplitName::CdStartMethod(name,
2062 flags,
2063 m_module,
2064 mdTypeDefNil,
2065 NULL,
2066 NULL,
2067 NULL,
2068 handle);
2069 }
2070 EX_CATCH
2071 {
2072 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2073 {
2074 EX_RETHROW;
2075 }
2076 }
2077 EX_END_CATCH(SwallowAllExceptions)
2078
2079 DAC_LEAVE();
2080 return status;
2081}
2082
2083HRESULT STDMETHODCALLTYPE
2084ClrDataModule::EnumMethodDefinitionByName(
2085 /* [out][in] */ CLRDATA_ENUM* handle,
2086 /* [out] */ IXCLRDataMethodDefinition **method)
2087{
2088 HRESULT status;
2089
2090 DAC_ENTER_SUB(m_dac);
2091
2092 EX_TRY
2093 {
2094 mdMethodDef token;
2095
2096 if ((status = SplitName::CdNextMethod(handle, &token)) == S_OK)
2097 {
2098 status = ClrDataMethodDefinition::
2099 NewFromModule(m_dac,
2100 m_module,
2101 token,
2102 NULL,
2103 method);
2104 }
2105 }
2106 EX_CATCH
2107 {
2108 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2109 {
2110 EX_RETHROW;
2111 }
2112 }
2113 EX_END_CATCH(SwallowAllExceptions)
2114
2115 DAC_LEAVE();
2116 return status;
2117}
2118
2119HRESULT STDMETHODCALLTYPE
2120ClrDataModule::EndEnumMethodDefinitionsByName(
2121 /* [in] */ CLRDATA_ENUM handle)
2122{
2123 HRESULT status;
2124
2125 DAC_ENTER_SUB(m_dac);
2126
2127 EX_TRY
2128 {
2129 status = SplitName::CdEnd(handle);
2130 }
2131 EX_CATCH
2132 {
2133 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2134 {
2135 EX_RETHROW;
2136 }
2137 }
2138 EX_END_CATCH(SwallowAllExceptions)
2139
2140 DAC_LEAVE();
2141 return status;
2142}
2143
2144HRESULT STDMETHODCALLTYPE
2145ClrDataModule::StartEnumMethodInstancesByName(
2146 /* [in] */ LPCWSTR name,
2147 /* [in] */ ULONG32 flags,
2148 /* [in] */ IXCLRDataAppDomain* appDomain,
2149 /* [out] */ CLRDATA_ENUM* handle)
2150{
2151 HRESULT status;
2152
2153 DAC_ENTER_SUB(m_dac);
2154
2155 EX_TRY
2156 {
2157 status = SplitName::CdStartMethod(name,
2158 flags,
2159 m_module,
2160 mdTypeDefNil,
2161 NULL,
2162 appDomain,
2163 NULL,
2164 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
2180ClrDataModule::EnumMethodInstanceByName(
2181 /* [out][in] */ CLRDATA_ENUM* handle,
2182 /* [out] */ IXCLRDataMethodInstance **method)
2183{
2184 HRESULT status;
2185
2186 DAC_ENTER_SUB(m_dac);
2187
2188 EX_TRY
2189 {
2190 SplitName* split; split = FROM_CDENUM(SplitName, *handle);
2191
2192 for (;;)
2193 {
2194 AppDomain* appDomain;
2195 mdMethodDef token;
2196
2197 if ((status = SplitName::
2198 CdNextDomainMethod(handle, &appDomain, &token)) != S_OK)
2199 {
2200 break;
2201 }
2202
2203 // If the method doesn't have a MethodDesc or hasn't
2204 // been JIT'ed yet it's not an instance and should
2205 // just be skipped.
2206 if ((status = ClrDataMethodInstance::
2207 NewFromModule(m_dac,
2208 appDomain,
2209 m_module,
2210 token,
2211 NULL,
2212 method)) != E_INVALIDARG)
2213 {
2214 break;
2215 }
2216 }
2217 }
2218 EX_CATCH
2219 {
2220 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2221 {
2222 EX_RETHROW;
2223 }
2224 }
2225 EX_END_CATCH(SwallowAllExceptions)
2226
2227 DAC_LEAVE();
2228 return status;
2229}
2230
2231HRESULT STDMETHODCALLTYPE
2232ClrDataModule::EndEnumMethodInstancesByName(
2233 /* [in] */ CLRDATA_ENUM handle)
2234{
2235 HRESULT status;
2236
2237 DAC_ENTER_SUB(m_dac);
2238
2239 EX_TRY
2240 {
2241 status = SplitName::CdEnd(handle);
2242 }
2243 EX_CATCH
2244 {
2245 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2246 {
2247 EX_RETHROW;
2248 }
2249 }
2250 EX_END_CATCH(SwallowAllExceptions)
2251
2252 DAC_LEAVE();
2253 return status;
2254}
2255
2256HRESULT STDMETHODCALLTYPE
2257ClrDataModule::GetMethodDefinitionByToken(
2258 /* [in] */ mdMethodDef token,
2259 /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
2260{
2261 HRESULT status;
2262
2263 // This isn't critically necessary but it prevents
2264 // an assert in the metadata code.
2265 if (TypeFromToken(token) != mdtMethodDef)
2266 {
2267 return E_INVALIDARG;
2268 }
2269
2270 DAC_ENTER_SUB(m_dac);
2271
2272 EX_TRY
2273 {
2274 status = ClrDataMethodDefinition::
2275 NewFromModule(m_dac,
2276 m_module,
2277 token,
2278 NULL,
2279 methodDefinition);
2280 }
2281 EX_CATCH
2282 {
2283 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2284 {
2285 EX_RETHROW;
2286 }
2287 }
2288 EX_END_CATCH(SwallowAllExceptions)
2289
2290 DAC_LEAVE();
2291 return status;
2292}
2293
2294HRESULT STDMETHODCALLTYPE
2295ClrDataModule::StartEnumDataByName(
2296 /* [in] */ LPCWSTR name,
2297 /* [in] */ ULONG32 flags,
2298 /* [in] */ IXCLRDataAppDomain* appDomain,
2299 /* [in] */ IXCLRDataTask* tlsTask,
2300 /* [out] */ CLRDATA_ENUM* handle)
2301{
2302 HRESULT status;
2303
2304 DAC_ENTER_SUB(m_dac);
2305
2306 EX_TRY
2307 {
2308 status = SplitName::CdStartField(name,
2309 flags,
2310 INH_STATIC,
2311 NULL,
2312 TypeHandle(),
2313 m_module,
2314 mdTypeDefNil,
2315 0,
2316 NULL,
2317 tlsTask,
2318 NULL,
2319 appDomain,
2320 NULL,
2321 handle);
2322 }
2323 EX_CATCH
2324 {
2325 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2326 {
2327 EX_RETHROW;
2328 }
2329 }
2330 EX_END_CATCH(SwallowAllExceptions)
2331
2332 DAC_LEAVE();
2333 return status;
2334}
2335
2336HRESULT STDMETHODCALLTYPE
2337ClrDataModule::EnumDataByName(
2338 /* [out][in] */ CLRDATA_ENUM* handle,
2339 /* [out] */ IXCLRDataValue **value)
2340{
2341 HRESULT status;
2342
2343 DAC_ENTER_SUB(m_dac);
2344
2345 EX_TRY
2346 {
2347 status = SplitName::CdNextDomainField(m_dac, handle, value);
2348 }
2349 EX_CATCH
2350 {
2351 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2352 {
2353 EX_RETHROW;
2354 }
2355 }
2356 EX_END_CATCH(SwallowAllExceptions)
2357
2358 DAC_LEAVE();
2359 return status;
2360}
2361
2362HRESULT STDMETHODCALLTYPE
2363ClrDataModule::EndEnumDataByName(
2364 /* [in] */ CLRDATA_ENUM handle)
2365{
2366 HRESULT status;
2367
2368 DAC_ENTER_SUB(m_dac);
2369
2370 EX_TRY
2371 {
2372 status = SplitName::CdEnd(handle);
2373 }
2374 EX_CATCH
2375 {
2376 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2377 {
2378 EX_RETHROW;
2379 }
2380 }
2381 EX_END_CATCH(SwallowAllExceptions)
2382
2383 DAC_LEAVE();
2384 return status;
2385}
2386
2387HRESULT STDMETHODCALLTYPE
2388ClrDataModule::GetName(
2389 /* [in] */ ULONG32 bufLen,
2390 /* [out] */ ULONG32 *nameLen,
2391 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
2392{
2393 HRESULT status;
2394
2395 DAC_ENTER_SUB(m_dac);
2396
2397 EX_TRY
2398 {
2399 status = ConvertUtf8(m_module->GetSimpleName(),
2400 bufLen, nameLen, name);
2401 }
2402 EX_CATCH
2403 {
2404 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2405 {
2406 EX_RETHROW;
2407 }
2408 }
2409 EX_END_CATCH(SwallowAllExceptions)
2410
2411 DAC_LEAVE();
2412 return status;
2413}
2414
2415HRESULT STDMETHODCALLTYPE
2416ClrDataModule::GetFileName(
2417 /* [in] */ ULONG32 bufLen,
2418 /* [out] */ ULONG32 *nameLen,
2419 /* [size_is][out] */ __out_ecount_part(bufLen, *nameLen) WCHAR name[ ])
2420{
2421 HRESULT status;
2422
2423 DAC_ENTER_SUB(m_dac);
2424
2425 EX_TRY
2426 {
2427 COUNT_T _nameLen;
2428
2429 // Try to get the file name through GetPath.
2430 // If the returned name is empty, then try to get the guessed module file name.
2431 // The guessed file name is propogated from metadata's module name.
2432 //
2433 if ((m_module->GetFile()->GetPath().DacGetUnicode(bufLen, name, &_nameLen) && name[0])||
2434 (m_module->GetFile()->GetModuleFileNameHint().DacGetUnicode(bufLen, name, &_nameLen) && name[0]))
2435 {
2436 if (nameLen)
2437 {
2438 *nameLen = _nameLen;
2439 }
2440 status = S_OK;
2441 }
2442 else
2443 {
2444 status = E_FAIL;
2445 }
2446 }
2447 EX_CATCH
2448 {
2449 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2450 {
2451 EX_RETHROW;
2452 }
2453 }
2454 EX_END_CATCH(SwallowAllExceptions)
2455
2456 DAC_LEAVE();
2457 return status;
2458}
2459
2460HRESULT STDMETHODCALLTYPE
2461ClrDataModule::GetVersionId(
2462 /* [out] */ GUID* vid)
2463{
2464 HRESULT status;
2465
2466 DAC_ENTER_SUB(m_dac);
2467
2468 EX_TRY
2469 {
2470 if (!m_module->GetFile()->HasMetadata())
2471 {
2472 status = E_NOINTERFACE;
2473 }
2474 else
2475 {
2476 GUID mdVid;
2477
2478 status = m_module->GetMDImport()->GetScopeProps(NULL, &mdVid);
2479 if (SUCCEEDED(status))
2480 {
2481 *vid = mdVid;
2482 }
2483 }
2484 }
2485 EX_CATCH
2486 {
2487 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2488 {
2489 EX_RETHROW;
2490 }
2491 }
2492 EX_END_CATCH(SwallowAllExceptions)
2493
2494 DAC_LEAVE();
2495 return status;
2496}
2497
2498HRESULT STDMETHODCALLTYPE
2499ClrDataModule::GetFlags(
2500 /* [out] */ ULONG32 *flags)
2501{
2502 HRESULT status;
2503
2504 DAC_ENTER_SUB(m_dac);
2505
2506 EX_TRY
2507 {
2508 *flags = 0;
2509
2510 if (m_module->IsReflection())
2511 {
2512 (*flags) |= CLRDATA_MODULE_IS_DYNAMIC;
2513 }
2514 if (m_module->IsIStream())
2515 {
2516 (*flags) |= CLRDATA_MODULE_IS_MEMORY_STREAM;
2517 }
2518
2519 status = S_OK;
2520 }
2521 EX_CATCH
2522 {
2523 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2524 {
2525 EX_RETHROW;
2526 }
2527 }
2528 EX_END_CATCH(SwallowAllExceptions)
2529
2530 DAC_LEAVE();
2531 return status;
2532}
2533
2534HRESULT STDMETHODCALLTYPE
2535ClrDataModule::IsSameObject(
2536 /* [in] */ IXCLRDataModule* mod)
2537{
2538 HRESULT status;
2539
2540 DAC_ENTER_SUB(m_dac);
2541
2542 EX_TRY
2543 {
2544 status = (PTR_HOST_TO_TADDR(m_module) ==
2545 PTR_HOST_TO_TADDR(((ClrDataModule*)mod)->
2546 m_module)) ?
2547 S_OK : S_FALSE;
2548 }
2549 EX_CATCH
2550 {
2551 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2552 {
2553 EX_RETHROW;
2554 }
2555 }
2556 EX_END_CATCH(SwallowAllExceptions)
2557
2558 DAC_LEAVE();
2559 return status;
2560}
2561
2562HRESULT STDMETHODCALLTYPE
2563ClrDataModule::StartEnumExtents(
2564 /* [out] */ CLRDATA_ENUM* handle)
2565{
2566 HRESULT status;
2567
2568 DAC_ENTER_SUB(m_dac);
2569
2570 EX_TRY
2571 {
2572 if (!m_setExtents)
2573 {
2574 PEFile* file = m_module->GetFile();
2575 if (!file)
2576 {
2577 *handle = 0;
2578 status = E_INVALIDARG;
2579 goto Exit;
2580 }
2581
2582 CLRDATA_MODULE_EXTENT* extent = m_extents;
2583
2584 if (file->GetLoadedImageContents() != NULL)
2585 {
2586 extent->base =
2587 TO_CDADDR( PTR_TO_TADDR(file->GetLoadedImageContents(&extent->length)) );
2588 extent->type = CLRDATA_MODULE_PE_FILE;
2589 extent++;
2590 }
2591 if (file->HasNativeImage())
2592 {
2593 extent->base = TO_CDADDR(PTR_TO_TADDR(file->GetLoadedNative()->GetBase()));
2594 extent->length = file->GetLoadedNative()->GetVirtualSize();
2595 extent->type = CLRDATA_MODULE_PREJIT_FILE;
2596 extent++;
2597 }
2598
2599 m_setExtents = true;
2600 m_extentsEnd = extent;
2601 }
2602
2603 *handle = TO_CDENUM(m_extents);
2604 status = m_extents != m_extentsEnd ? S_OK : S_FALSE;
2605
2606 Exit: ;
2607 }
2608 EX_CATCH
2609 {
2610 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2611 {
2612 EX_RETHROW;
2613 }
2614 }
2615 EX_END_CATCH(SwallowAllExceptions)
2616
2617 DAC_LEAVE();
2618 return status;
2619}
2620
2621HRESULT STDMETHODCALLTYPE
2622ClrDataModule::EnumExtent(
2623 /* [in, out] */ CLRDATA_ENUM* handle,
2624 /* [out] */ CLRDATA_MODULE_EXTENT *extent)
2625{
2626 HRESULT status;
2627
2628 DAC_ENTER_SUB(m_dac);
2629
2630 EX_TRY
2631 {
2632 CLRDATA_MODULE_EXTENT* curExtent =
2633 FROM_CDENUM(CLRDATA_MODULE_EXTENT, *handle);
2634 if (!m_setExtents ||
2635 curExtent < m_extents ||
2636 curExtent > m_extentsEnd)
2637 {
2638 status = E_INVALIDARG;
2639 }
2640 else if (curExtent < m_extentsEnd)
2641 {
2642 *extent = *curExtent++;
2643 *handle = TO_CDENUM(curExtent);
2644 status = S_OK;
2645 }
2646 else
2647 {
2648 status = S_FALSE;
2649 }
2650 }
2651 EX_CATCH
2652 {
2653 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2654 {
2655 EX_RETHROW;
2656 }
2657 }
2658 EX_END_CATCH(SwallowAllExceptions)
2659
2660 DAC_LEAVE();
2661 return status;
2662}
2663
2664HRESULT STDMETHODCALLTYPE
2665ClrDataModule::EndEnumExtents(
2666 /* [in] */ CLRDATA_ENUM handle)
2667{
2668 HRESULT status;
2669
2670 DAC_ENTER_SUB(m_dac);
2671
2672 EX_TRY
2673 {
2674 // Enumerator holds no resources.
2675 status = S_OK;
2676 }
2677 EX_CATCH
2678 {
2679 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2680 {
2681 EX_RETHROW;
2682 }
2683 }
2684 EX_END_CATCH(SwallowAllExceptions)
2685
2686 DAC_LEAVE();
2687 return status;
2688}
2689
2690HRESULT
2691ClrDataModule::RequestGetModulePtr(
2692 /* [in] */ ULONG32 inBufferSize,
2693 /* [size_is][in] */ BYTE *inBuffer,
2694 /* [in] */ ULONG32 outBufferSize,
2695 /* [size_is][out] */ BYTE *outBuffer)
2696{
2697 // Validate params.
2698 // Input: Nothing.
2699 // Output: a DacpGetModuleAddress structure.
2700 if ((inBufferSize != 0) ||
2701 (inBuffer != NULL) ||
2702 (outBufferSize != sizeof(DacpGetModuleAddress)) ||
2703 (outBuffer == NULL))
2704 {
2705 return E_INVALIDARG;
2706 }
2707
2708 DacpGetModuleAddress * outGMA = reinterpret_cast<DacpGetModuleAddress *> (outBuffer);
2709
2710 outGMA->ModulePtr = TO_CDADDR(PTR_HOST_TO_TADDR(m_module));
2711 return S_OK;
2712}
2713
2714HRESULT
2715ClrDataModule::RequestGetModuleData(
2716 /* [in] */ ULONG32 inBufferSize,
2717 /* [size_is][in] */ BYTE *inBuffer,
2718 /* [in] */ ULONG32 outBufferSize,
2719 /* [size_is][out] */ BYTE *outBuffer)
2720{
2721 // Validate params.
2722 // Input: Nothing.
2723 // Output: a DacpGetModuleData structure.
2724 if ((inBufferSize != 0) ||
2725 (inBuffer != NULL) ||
2726 (outBufferSize != sizeof(DacpGetModuleData)) ||
2727 (outBuffer == NULL))
2728 {
2729 return E_INVALIDARG;
2730 }
2731
2732 DacpGetModuleData * outGMD = reinterpret_cast<DacpGetModuleData *>(outBuffer);
2733 ZeroMemory(outGMD, sizeof(DacpGetModuleData));
2734
2735 Module* pModule = GetModule();
2736 PEFile *pPEFile = pModule->GetFile();
2737
2738 outGMD->PEFile = TO_CDADDR(PTR_HOST_TO_TADDR(pPEFile));
2739 outGMD->IsDynamic = pModule->IsReflection();
2740
2741 if (pPEFile != NULL)
2742 {
2743 outGMD->IsInMemory = pPEFile->GetPath().IsEmpty();
2744
2745 COUNT_T peSize;
2746 outGMD->LoadedPEAddress = TO_CDADDR(PTR_TO_TADDR(pPEFile->GetLoadedImageContents(&peSize)));
2747 outGMD->LoadedPESize = (ULONG64)peSize;
2748
2749 // Can not get the file layout for a dynamic module
2750 if (!outGMD->IsDynamic)
2751 {
2752 outGMD->IsFileLayout = pPEFile->GetLoaded()->IsFlat();
2753 }
2754 }
2755
2756 // If there is a in memory symbol stream
2757 CGrowableStream* stream = pModule->GetInMemorySymbolStream();
2758 if (stream != NULL)
2759 {
2760 // Save the in-memory PDB address and size
2761 MemoryRange range = stream->GetRawBuffer();
2762 outGMD->InMemoryPdbAddress = TO_CDADDR(PTR_TO_TADDR(range.StartAddress()));
2763 outGMD->InMemoryPdbSize = range.Size();
2764 }
2765
2766 return S_OK;
2767}
2768
2769HRESULT STDMETHODCALLTYPE
2770ClrDataModule::Request(
2771 /* [in] */ ULONG32 reqCode,
2772 /* [in] */ ULONG32 inBufferSize,
2773 /* [size_is][in] */ BYTE *inBuffer,
2774 /* [in] */ ULONG32 outBufferSize,
2775 /* [size_is][out] */ BYTE *outBuffer)
2776{
2777 HRESULT status;
2778
2779 DAC_ENTER_SUB(m_dac);
2780
2781 EX_TRY
2782 {
2783 switch(reqCode)
2784 {
2785 case CLRDATA_REQUEST_REVISION:
2786 if (inBufferSize != 0 ||
2787 inBuffer ||
2788 outBufferSize != sizeof(ULONG32))
2789 {
2790 status = E_INVALIDARG;
2791 }
2792 else
2793 {
2794 *(ULONG32*)outBuffer = 3;
2795 status = S_OK;
2796 }
2797 break;
2798
2799 case DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR:
2800 status = RequestGetModulePtr(inBufferSize, inBuffer, outBufferSize, outBuffer);
2801 break;
2802
2803 case DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA:
2804 status = RequestGetModuleData(inBufferSize, inBuffer, outBufferSize, outBuffer);
2805 break;
2806
2807 default:
2808 status = E_INVALIDARG;
2809 break;
2810 }
2811 }
2812 EX_CATCH
2813 {
2814 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2815 {
2816 EX_RETHROW;
2817 }
2818 }
2819 EX_END_CATCH(SwallowAllExceptions)
2820
2821 DAC_LEAVE();
2822 return status;
2823}
2824
2825HRESULT STDMETHODCALLTYPE
2826ClrDataModule::SetJITCompilerFlags(
2827 /* [in] */ DWORD dwFlags)
2828{
2829 // Note: this is similar but not equivalent to the DacDbi version of this function
2830 HRESULT hr = S_OK;
2831 DAC_ENTER_SUB(m_dac);
2832
2833 EX_TRY
2834 {
2835 // can't have a subset of these, eg 0x101, so make sure we have an exact match
2836 if ((dwFlags != CORDEBUG_JIT_DEFAULT) &&
2837 (dwFlags != CORDEBUG_JIT_DISABLE_OPTIMIZATION))
2838 {
2839 hr = E_INVALIDARG;
2840 }
2841#ifdef FEATURE_PREJIT
2842 else if (m_module->HasNativeImage())
2843 {
2844 hr = CORDBG_E_CANT_CHANGE_JIT_SETTING_FOR_ZAP_MODULE;
2845 }
2846#endif
2847 else
2848 {
2849 _ASSERTE(m_module != NULL);
2850
2851 BOOL fAllowJitOpts = ((dwFlags & CORDEBUG_JIT_DISABLE_OPTIMIZATION) != CORDEBUG_JIT_DISABLE_OPTIMIZATION);
2852
2853 // Initialize dwBits.
2854 DWORD dwBits = (m_module->GetDebuggerInfoBits() & ~(DACF_ALLOW_JIT_OPTS | DACF_ENC_ENABLED));
2855 dwBits &= DACF_CONTROL_FLAGS_MASK;
2856
2857 if (fAllowJitOpts)
2858 {
2859 dwBits |= DACF_ALLOW_JIT_OPTS;
2860 }
2861
2862 // Settings from the debugger take precedence over all other settings.
2863 dwBits |= DACF_USER_OVERRIDE;
2864
2865 // set flags. This will write back to the target
2866 m_module->SetDebuggerInfoBits((DebuggerAssemblyControlFlags)dwBits);
2867
2868 _ASSERTE(SUCCEEDED(hr));
2869 }
2870 }
2871 EX_CATCH
2872 {
2873 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &hr))
2874 {
2875 EX_RETHROW;
2876 }
2877 }
2878 EX_END_CATCH(SwallowAllExceptions)
2879
2880 DAC_LEAVE();
2881 return hr;
2882}
2883
2884HRESULT
2885ClrDataModule::GetMdInterface(PVOID* retIface)
2886{
2887 HRESULT status;
2888
2889 DAC_ENTER_SUB(m_dac);
2890
2891 EX_TRY
2892 {
2893 if (m_mdImport == NULL)
2894 {
2895 if (!m_module->GetFile()->HasMetadata())
2896 {
2897 status = E_NOINTERFACE;
2898 goto Exit;
2899 }
2900
2901 //
2902 // Make sure internal MD is in RW format.
2903 //
2904 IMDInternalImport* rwMd;
2905
2906 status = ConvertMDInternalImport(m_module->GetMDImport(), &rwMd);
2907 if (FAILED(status))
2908 {
2909 goto Exit;
2910 }
2911
2912 // If no conversion took place the same interface was
2913 // was returned without an AddRef. AddRef now so
2914 // that rwMd has a reference either way.
2915 if (status == S_FALSE)
2916 {
2917 rwMd->AddRef();
2918 }
2919
2920 status = GetMDPublicInterfaceFromInternal((PVOID)rwMd,
2921 IID_IMetaDataImport,
2922 (PVOID*)&m_mdImport);
2923
2924 rwMd->Release();
2925
2926 if (status != S_OK)
2927 {
2928 goto Exit;
2929 }
2930 }
2931
2932 _ASSERTE(m_mdImport != NULL);
2933 m_mdImport->AddRef();
2934 *retIface = m_mdImport;
2935 status = S_OK;
2936
2937 Exit: ;
2938 }
2939 EX_CATCH
2940 {
2941 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
2942 {
2943 EX_RETHROW;
2944 }
2945 }
2946 EX_END_CATCH(SwallowAllExceptions)
2947
2948 DAC_LEAVE();
2949 return status;
2950}
2951
2952//----------------------------------------------------------------------------
2953//
2954// ClrDataMethodDefinition.
2955//
2956//----------------------------------------------------------------------------
2957
2958ClrDataMethodDefinition::ClrDataMethodDefinition(ClrDataAccess* dac,
2959 Module* module,
2960 mdMethodDef token,
2961 MethodDesc* methodDesc)
2962{
2963 m_dac = dac;
2964 m_dac->AddRef();
2965 m_instanceAge = m_dac->m_instanceAge;
2966 m_refs = 1;
2967 m_module = module;
2968 m_token = token;
2969 m_methodDesc = methodDesc;
2970}
2971
2972ClrDataMethodDefinition::~ClrDataMethodDefinition(void)
2973{
2974 m_dac->Release();
2975}
2976
2977STDMETHODIMP
2978ClrDataMethodDefinition::QueryInterface(THIS_
2979 IN REFIID interfaceId,
2980 OUT PVOID* iface)
2981{
2982 if (IsEqualIID(interfaceId, IID_IUnknown) ||
2983 IsEqualIID(interfaceId, __uuidof(IXCLRDataMethodDefinition)))
2984 {
2985 AddRef();
2986 *iface = static_cast<IUnknown*>
2987 (static_cast<IXCLRDataMethodDefinition*>(this));
2988 return S_OK;
2989 }
2990 else
2991 {
2992 *iface = NULL;
2993 return E_NOINTERFACE;
2994 }
2995}
2996
2997STDMETHODIMP_(ULONG)
2998ClrDataMethodDefinition::AddRef(THIS)
2999{
3000 return InterlockedIncrement(&m_refs);
3001}
3002
3003STDMETHODIMP_(ULONG)
3004ClrDataMethodDefinition::Release(THIS)
3005{
3006 SUPPORTS_DAC_HOST_ONLY;
3007 LONG newRefs = InterlockedDecrement(&m_refs);
3008 if (newRefs == 0)
3009 {
3010 delete this;
3011 }
3012 return newRefs;
3013}
3014
3015HRESULT STDMETHODCALLTYPE
3016ClrDataMethodDefinition::GetTypeDefinition(
3017 /* [out] */ IXCLRDataTypeDefinition **typeDefinition)
3018{
3019 HRESULT status;
3020
3021 DAC_ENTER_SUB(m_dac);
3022
3023 EX_TRY
3024 {
3025 TypeHandle typeHandle;
3026 mdTypeDef token;
3027
3028 if (m_methodDesc)
3029 {
3030 typeHandle = TypeHandle(m_methodDesc->GetMethodTable());
3031 token = typeHandle.GetMethodTable()->GetCl();
3032 }
3033 else
3034 {
3035 if ((status = m_module->GetMDImport()->
3036 GetParentToken(m_token, &token)) != S_OK)
3037 {
3038 goto Exit;
3039 }
3040 }
3041
3042 *typeDefinition = new (nothrow)
3043 ClrDataTypeDefinition(m_dac, m_module, token, typeHandle);
3044 status = *typeDefinition ? S_OK : E_OUTOFMEMORY;
3045
3046 Exit: ;
3047 }
3048 EX_CATCH
3049 {
3050 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3051 {
3052 EX_RETHROW;
3053 }
3054 }
3055 EX_END_CATCH(SwallowAllExceptions)
3056
3057 DAC_LEAVE();
3058 return status;
3059}
3060
3061HRESULT STDMETHODCALLTYPE
3062ClrDataMethodDefinition::StartEnumInstances(
3063 /* [in] */ IXCLRDataAppDomain* appDomain,
3064 /* [out] */ CLRDATA_ENUM *handle)
3065{
3066 HRESULT status;
3067
3068 DAC_ENTER_SUB(m_dac);
3069
3070 EX_TRY
3071 {
3072 if (m_methodDesc)
3073 {
3074 status = EnumMethodInstances::CdStart(m_methodDesc, appDomain,
3075 handle);
3076 }
3077 else
3078 {
3079 status = S_FALSE;
3080 *handle = 0;
3081 }
3082 }
3083 EX_CATCH
3084 {
3085 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3086 {
3087 EX_RETHROW;
3088 }
3089 }
3090 EX_END_CATCH(SwallowAllExceptions)
3091
3092 DAC_LEAVE();
3093 return status;
3094}
3095
3096HRESULT STDMETHODCALLTYPE
3097ClrDataMethodDefinition::EnumInstance(
3098 /* [out][in] */ CLRDATA_ENUM *handle,
3099 /* [out] */ IXCLRDataMethodInstance **instance)
3100{
3101 HRESULT status;
3102
3103 DAC_ENTER_SUB(m_dac);
3104
3105 EX_TRY
3106 {
3107 status = EnumMethodInstances::CdNext(m_dac, handle, instance);
3108 }
3109 EX_CATCH
3110 {
3111 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3112 {
3113 EX_RETHROW;
3114 }
3115 }
3116 EX_END_CATCH(SwallowAllExceptions)
3117
3118 DAC_LEAVE();
3119 return status;
3120}
3121
3122HRESULT STDMETHODCALLTYPE
3123ClrDataMethodDefinition::EndEnumInstances(
3124 /* [in] */ CLRDATA_ENUM handle)
3125{
3126 HRESULT status;
3127
3128 DAC_ENTER_SUB(m_dac);
3129
3130 EX_TRY
3131 {
3132 status = EnumMethodInstances::CdEnd(handle);
3133 }
3134 EX_CATCH
3135 {
3136 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3137 {
3138 EX_RETHROW;
3139 }
3140 }
3141 EX_END_CATCH(SwallowAllExceptions)
3142
3143 DAC_LEAVE();
3144 return status;
3145}
3146
3147HRESULT STDMETHODCALLTYPE
3148ClrDataMethodDefinition::GetName(
3149 /* [in] */ ULONG32 flags,
3150 /* [in] */ ULONG32 bufLen,
3151 /* [out] */ ULONG32 *nameLen,
3152 /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR name[ ])
3153{
3154 HRESULT status;
3155
3156 if (flags != 0)
3157 {
3158 return E_INVALIDARG;
3159 }
3160
3161 DAC_ENTER_SUB(m_dac);
3162
3163 EX_TRY
3164 {
3165 if (m_methodDesc)
3166 {
3167 status = m_dac->GetFullMethodName(m_methodDesc,
3168 bufLen, nameLen, name);
3169 }
3170 else
3171 {
3172 char methName[MAX_CLASSNAME_LENGTH];
3173
3174 status = GetFullMethodNameFromMetadata(m_module->GetMDImport(),
3175 m_token,
3176 NumItems(methName),
3177 methName);
3178 if (status == S_OK)
3179 {
3180 status = ConvertUtf8(methName, bufLen, nameLen, name);
3181 }
3182 }
3183 }
3184 EX_CATCH
3185 {
3186 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3187 {
3188 EX_RETHROW;
3189 }
3190 }
3191 EX_END_CATCH(SwallowAllExceptions)
3192
3193 DAC_LEAVE();
3194 return status;
3195}
3196
3197HRESULT STDMETHODCALLTYPE
3198ClrDataMethodDefinition::GetTokenAndScope(
3199 /* [out] */ mdToken *token,
3200 /* [out] */ IXCLRDataModule **Module)
3201{
3202 HRESULT status;
3203
3204 DAC_ENTER_SUB(m_dac);
3205
3206 EX_TRY
3207 {
3208 status = S_OK;
3209
3210 if (token)
3211 {
3212 *token = m_token;
3213 }
3214
3215 if (Module)
3216 {
3217 *Module = new (nothrow)
3218 ClrDataModule(m_dac, m_module);
3219 status = *Module ? S_OK : E_OUTOFMEMORY;
3220 }
3221 }
3222 EX_CATCH
3223 {
3224 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3225 {
3226 EX_RETHROW;
3227 }
3228 }
3229 EX_END_CATCH(SwallowAllExceptions)
3230
3231 DAC_LEAVE();
3232 return status;
3233}
3234
3235HRESULT STDMETHODCALLTYPE
3236ClrDataMethodDefinition::GetFlags(
3237 /* [out] */ ULONG32 *flags)
3238{
3239 HRESULT status;
3240
3241 DAC_ENTER_SUB(m_dac);
3242
3243 EX_TRY
3244 {
3245 status = GetSharedMethodFlags(m_methodDesc, flags);
3246 }
3247 EX_CATCH
3248 {
3249 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3250 {
3251 EX_RETHROW;
3252 }
3253 }
3254 EX_END_CATCH(SwallowAllExceptions)
3255
3256 DAC_LEAVE();
3257 return status;
3258}
3259
3260HRESULT STDMETHODCALLTYPE
3261ClrDataMethodDefinition::IsSameObject(
3262 /* [in] */ IXCLRDataMethodDefinition* method)
3263{
3264 HRESULT status;
3265
3266 DAC_ENTER_SUB(m_dac);
3267
3268 EX_TRY
3269 {
3270 if (m_methodDesc)
3271 {
3272 status = (PTR_HOST_TO_TADDR(m_methodDesc) ==
3273 PTR_HOST_TO_TADDR(((ClrDataMethodDefinition*)method)->
3274 m_methodDesc)) ?
3275 S_OK : S_FALSE;
3276 }
3277 else
3278 {
3279 status = (PTR_HOST_TO_TADDR(m_module) ==
3280 PTR_HOST_TO_TADDR(((ClrDataMethodDefinition*)method)->
3281 m_module) &&
3282 m_token == ((ClrDataMethodDefinition*)method)->m_token) ?
3283 S_OK : S_FALSE;
3284 }
3285 }
3286 EX_CATCH
3287 {
3288 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3289 {
3290 EX_RETHROW;
3291 }
3292 }
3293 EX_END_CATCH(SwallowAllExceptions)
3294
3295 DAC_LEAVE();
3296 return status;
3297}
3298
3299HRESULT STDMETHODCALLTYPE
3300ClrDataMethodDefinition::GetLatestEnCVersion(
3301 /* [out] */ ULONG32* version)
3302{
3303 HRESULT status;
3304
3305 DAC_ENTER_SUB(m_dac);
3306
3307 EX_TRY
3308 {
3309 // XXX Microsoft.
3310 *version = 0;
3311 status = S_OK;
3312 }
3313 EX_CATCH
3314 {
3315 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3316 {
3317 EX_RETHROW;
3318 }
3319 }
3320 EX_END_CATCH(SwallowAllExceptions)
3321
3322 DAC_LEAVE();
3323 return status;
3324}
3325
3326HRESULT STDMETHODCALLTYPE
3327ClrDataMethodDefinition::StartEnumExtents(
3328 /* [out] */ CLRDATA_ENUM *handle)
3329{
3330 HRESULT status;
3331
3332 DAC_ENTER_SUB(m_dac);
3333
3334 EX_TRY
3335 {
3336 COR_ILMETHOD* ilMeth = GetIlMethod();
3337 status = ilMeth ? S_OK : S_FALSE;
3338 *handle = TO_CDENUM(ilMeth);
3339 }
3340 EX_CATCH
3341 {
3342 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3343 {
3344 EX_RETHROW;
3345 }
3346 }
3347 EX_END_CATCH(SwallowAllExceptions)
3348
3349 DAC_LEAVE();
3350 return status;
3351}
3352
3353HRESULT STDMETHODCALLTYPE
3354ClrDataMethodDefinition::EnumExtent(
3355 /* [out][in] */ CLRDATA_ENUM *handle,
3356 /* [out] */ CLRDATA_METHDEF_EXTENT *extent)
3357{
3358 HRESULT status;
3359
3360 DAC_ENTER_SUB(m_dac);
3361
3362 EX_TRY
3363 {
3364 if (*handle)
3365 {
3366 COR_ILMETHOD* ilMeth = FROM_CDENUM(COR_ILMETHOD, *handle);
3367 COR_ILMETHOD_DECODER ilDec(ilMeth);
3368 *handle = 0;
3369
3370 extent->startAddress = TO_CDADDR(PTR_HOST_TO_TADDR(ilMeth) +
3371 4 * ilDec.GetSize());
3372 extent->endAddress = extent->startAddress +
3373 ilDec.GetCodeSize() - 1;
3374 extent->type = CLRDATA_METHDEF_IL;
3375 // XXX Microsoft - EnC version.
3376 extent->enCVersion = 0;
3377
3378 status = S_OK;
3379 }
3380 else
3381 {
3382 status = E_INVALIDARG;
3383 }
3384 }
3385 EX_CATCH
3386 {
3387 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3388 {
3389 EX_RETHROW;
3390 }
3391 }
3392 EX_END_CATCH(SwallowAllExceptions)
3393
3394 DAC_LEAVE();
3395 return status;
3396}
3397
3398HRESULT STDMETHODCALLTYPE
3399ClrDataMethodDefinition::EndEnumExtents(
3400 /* [in] */ CLRDATA_ENUM handle)
3401{
3402 HRESULT status;
3403
3404 DAC_ENTER_SUB(m_dac);
3405
3406 EX_TRY
3407 {
3408 // Nothing to do.
3409 status = S_OK;
3410 }
3411 EX_CATCH
3412 {
3413 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3414 {
3415 EX_RETHROW;
3416 }
3417 }
3418 EX_END_CATCH(SwallowAllExceptions)
3419
3420 DAC_LEAVE();
3421 return status;
3422}
3423
3424HRESULT STDMETHODCALLTYPE
3425ClrDataMethodDefinition::GetCodeNotification(
3426 /* [out] */ ULONG32 *flags)
3427{
3428 HRESULT status;
3429
3430 DAC_ENTER_SUB(m_dac);
3431
3432 EX_TRY
3433 {
3434 JITNotifications jn(m_dac->GetHostJitNotificationTable());
3435 if (!jn.IsActive())
3436 {
3437 status = E_OUTOFMEMORY;
3438 }
3439 else
3440 {
3441 TADDR modulePtr = PTR_HOST_TO_TADDR(m_module);
3442 *flags = jn.Requested(modulePtr, m_token);
3443 status = S_OK;
3444 }
3445 }
3446 EX_CATCH
3447 {
3448 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3449 {
3450 EX_RETHROW;
3451 }
3452 }
3453 EX_END_CATCH(SwallowAllExceptions)
3454
3455 DAC_LEAVE();
3456 return status;
3457}
3458
3459HRESULT STDMETHODCALLTYPE
3460ClrDataMethodDefinition::SetCodeNotification(
3461 /* [in] */ ULONG32 flags)
3462{
3463 HRESULT status;
3464
3465 DAC_ENTER_SUB(m_dac);
3466
3467 EX_TRY
3468 {
3469 if (!IsValidMethodCodeNotification(flags))
3470 {
3471 status = E_INVALIDARG;
3472 }
3473 else
3474 {
3475 JITNotifications jn(m_dac->GetHostJitNotificationTable());
3476 if (!jn.IsActive())
3477 {
3478 status = E_OUTOFMEMORY;
3479 }
3480 else
3481 {
3482 TADDR modulePtr = PTR_HOST_TO_TADDR(m_module);
3483 USHORT NType = jn.Requested(modulePtr, m_token);
3484
3485 if (NType == flags)
3486 {
3487 // notification already set
3488 status = S_OK;
3489 }
3490 else
3491 {
3492 if (jn.SetNotification(modulePtr, m_token, flags) &&
3493 jn.UpdateOutOfProcTable())
3494 {
3495 // new notification added
3496 status = S_OK;
3497 }
3498 else
3499 {
3500 // error setting notification
3501 status = E_FAIL;
3502 }
3503 }
3504 }
3505 }
3506 }
3507 EX_CATCH
3508 {
3509 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3510 {
3511 EX_RETHROW;
3512 }
3513 }
3514 EX_END_CATCH(SwallowAllExceptions)
3515
3516 DAC_LEAVE();
3517 return status;
3518}
3519
3520HRESULT STDMETHODCALLTYPE
3521ClrDataMethodDefinition::GetRepresentativeEntryAddress(
3522 /* [out] */ CLRDATA_ADDRESS* addr)
3523{
3524 HRESULT status;
3525
3526 DAC_ENTER_SUB(m_dac);
3527
3528 EX_TRY
3529 {
3530 COR_ILMETHOD* ilMeth = GetIlMethod();
3531 if (ilMeth)
3532 {
3533 COR_ILMETHOD_DECODER ilDec(ilMeth);
3534 *addr = TO_CDADDR(PTR_HOST_TO_TADDR(ilMeth) +
3535 4 * ilDec.GetSize());
3536 status = S_OK;
3537 }
3538 else
3539 {
3540 status = E_UNEXPECTED;
3541 }
3542 }
3543 EX_CATCH
3544 {
3545 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3546 {
3547 EX_RETHROW;
3548 }
3549 }
3550 EX_END_CATCH(SwallowAllExceptions)
3551
3552 DAC_LEAVE();
3553 return status;
3554}
3555
3556HRESULT STDMETHODCALLTYPE
3557ClrDataMethodDefinition::HasClassOrMethodInstantiation(
3558 /* [out] */ BOOL* bGeneric)
3559{
3560 HRESULT status;
3561
3562 DAC_ENTER_SUB(m_dac);
3563
3564 EX_TRY
3565 {
3566 if (m_methodDesc)
3567 {
3568 *bGeneric = m_methodDesc->HasClassOrMethodInstantiation();
3569 status = S_OK;
3570 }
3571 else
3572 {
3573 status = E_UNEXPECTED;
3574 }
3575 }
3576 EX_CATCH
3577 {
3578 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3579 {
3580 EX_RETHROW;
3581 }
3582 }
3583 EX_END_CATCH(SwallowAllExceptions)
3584
3585 DAC_LEAVE();
3586 return status;
3587}
3588
3589HRESULT STDMETHODCALLTYPE
3590ClrDataMethodDefinition::Request(
3591 /* [in] */ ULONG32 reqCode,
3592 /* [in] */ ULONG32 inBufferSize,
3593 /* [size_is][in] */ BYTE *inBuffer,
3594 /* [in] */ ULONG32 outBufferSize,
3595 /* [size_is][out] */ BYTE *outBuffer)
3596{
3597 HRESULT status;
3598
3599 DAC_ENTER_SUB(m_dac);
3600
3601 EX_TRY
3602 {
3603 switch(reqCode)
3604 {
3605 case CLRDATA_REQUEST_REVISION:
3606 if (inBufferSize != 0 ||
3607 inBuffer ||
3608 outBufferSize != sizeof(ULONG32))
3609 {
3610 status = E_INVALIDARG;
3611 }
3612 else
3613 {
3614 *(ULONG32*)outBuffer = 1;
3615 status = S_OK;
3616 }
3617 break;
3618
3619 default:
3620 status = E_INVALIDARG;
3621 break;
3622 }
3623 }
3624 EX_CATCH
3625 {
3626 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3627 {
3628 EX_RETHROW;
3629 }
3630 }
3631 EX_END_CATCH(SwallowAllExceptions)
3632
3633 DAC_LEAVE();
3634 return status;
3635}
3636
3637COR_ILMETHOD*
3638ClrDataMethodDefinition::GetIlMethod(void)
3639{
3640 if (m_methodDesc)
3641 {
3642 if (!m_methodDesc->HasILHeader())
3643 {
3644 return NULL;
3645 }
3646 else
3647 {
3648 return m_methodDesc->GetILHeader();
3649 }
3650 }
3651 else
3652 {
3653 ULONG ilRva;
3654 ULONG implFlags;
3655
3656 if (FAILED(m_module->GetMDImport()->
3657 GetMethodImplProps(m_token, &ilRva, &implFlags)))
3658 {
3659 return NULL;
3660 }
3661 if (!ilRva)
3662 {
3663 return NULL;
3664 }
3665 else
3666 {
3667 return DacGetIlMethod(m_module->GetIL((RVA)ilRva));
3668 }
3669 }
3670}
3671
3672HRESULT
3673ClrDataMethodDefinition::NewFromModule(ClrDataAccess* dac,
3674 Module* module,
3675 mdMethodDef token,
3676 ClrDataMethodDefinition** methDef,
3677 IXCLRDataMethodDefinition** pubMethDef)
3678{
3679 // The method may not have internal runtime data yet,
3680 // so the absence of a MethodDesc is not a failure.
3681 // It'll just produce a metadata-query MethoDefinition.
3682 MethodDesc* methodDesc = module->LookupMethodDef(token);
3683
3684 ClrDataMethodDefinition* def = new (nothrow)
3685 ClrDataMethodDefinition(dac, module, token, methodDesc);
3686 if (!def)
3687 {
3688 return E_OUTOFMEMORY;
3689 }
3690
3691 PREFIX_ASSUME(methDef || pubMethDef);
3692
3693 if (methDef)
3694 {
3695 *methDef = def;
3696 }
3697 if (pubMethDef)
3698 {
3699 *pubMethDef = def;
3700 }
3701
3702 return S_OK;
3703}
3704
3705HRESULT
3706ClrDataMethodDefinition::GetSharedMethodFlags(MethodDesc* methodDesc,
3707 ULONG32* flags)
3708{
3709 *flags = CLRDATA_METHOD_DEFAULT;
3710
3711 if (methodDesc)
3712 {
3713 MetaSig sig(methodDesc);
3714
3715 if (sig.HasThis())
3716 {
3717 (*flags) |= CLRDATA_METHOD_HAS_THIS;
3718 }
3719 }
3720
3721 return S_OK;
3722}
3723
3724//----------------------------------------------------------------------------
3725//
3726// ClrDataMethodInstance.
3727//
3728//----------------------------------------------------------------------------
3729
3730ClrDataMethodInstance::ClrDataMethodInstance(ClrDataAccess* dac,
3731 AppDomain* appDomain,
3732 MethodDesc* methodDesc)
3733{
3734 m_dac = dac;
3735 m_dac->AddRef();
3736 m_instanceAge = m_dac->m_instanceAge;
3737 m_refs = 1;
3738 m_appDomain = appDomain;
3739 m_methodDesc = methodDesc;
3740}
3741
3742ClrDataMethodInstance::~ClrDataMethodInstance(void)
3743{
3744 m_dac->Release();
3745}
3746
3747STDMETHODIMP
3748ClrDataMethodInstance::QueryInterface(THIS_
3749 IN REFIID interfaceId,
3750 OUT PVOID* iface)
3751{
3752 if (IsEqualIID(interfaceId, IID_IUnknown) ||
3753 IsEqualIID(interfaceId, __uuidof(IXCLRDataMethodInstance)))
3754 {
3755 AddRef();
3756 *iface = static_cast<IUnknown*>
3757 (static_cast<IXCLRDataMethodInstance*>(this));
3758 return S_OK;
3759 }
3760 else
3761 {
3762 *iface = NULL;
3763 return E_NOINTERFACE;
3764 }
3765}
3766
3767STDMETHODIMP_(ULONG)
3768ClrDataMethodInstance::AddRef(THIS)
3769{
3770 SUPPORTS_DAC_HOST_ONLY;
3771 return InterlockedIncrement(&m_refs);
3772}
3773
3774STDMETHODIMP_(ULONG)
3775ClrDataMethodInstance::Release(THIS)
3776{
3777 LONG newRefs = InterlockedDecrement(&m_refs);
3778 if (newRefs == 0)
3779 {
3780 delete this;
3781 }
3782 return newRefs;
3783}
3784
3785HRESULT STDMETHODCALLTYPE
3786ClrDataMethodInstance::GetTypeInstance(
3787 /* [out] */ IXCLRDataTypeInstance **typeInstance)
3788{
3789 HRESULT status;
3790
3791 DAC_ENTER_SUB(m_dac);
3792
3793 EX_TRY
3794 {
3795 if (!m_appDomain)
3796 {
3797 status = E_UNEXPECTED;
3798 }
3799 else
3800 {
3801 *typeInstance = new (nothrow)
3802 ClrDataTypeInstance(m_dac,
3803 m_appDomain,
3804 TypeHandle(m_methodDesc->
3805 GetMethodTable()));
3806 status = *typeInstance ? S_OK : E_OUTOFMEMORY;
3807 }
3808 }
3809 EX_CATCH
3810 {
3811 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3812 {
3813 EX_RETHROW;
3814 }
3815 }
3816 EX_END_CATCH(SwallowAllExceptions)
3817
3818 DAC_LEAVE();
3819 return status;
3820}
3821
3822HRESULT STDMETHODCALLTYPE
3823ClrDataMethodInstance::GetDefinition(
3824 /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
3825{
3826 HRESULT status;
3827
3828 DAC_ENTER_SUB(m_dac);
3829
3830 EX_TRY
3831 {
3832 *methodDefinition = new (nothrow)
3833 ClrDataMethodDefinition(m_dac,
3834 m_methodDesc->GetModule(),
3835 m_methodDesc->GetMemberDef(),
3836 m_methodDesc);
3837 status = *methodDefinition ? S_OK : E_OUTOFMEMORY;
3838 }
3839 EX_CATCH
3840 {
3841 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3842 {
3843 EX_RETHROW;
3844 }
3845 }
3846 EX_END_CATCH(SwallowAllExceptions)
3847
3848 DAC_LEAVE();
3849 return status;
3850}
3851
3852HRESULT STDMETHODCALLTYPE
3853ClrDataMethodInstance::GetTokenAndScope(
3854 /* [out] */ mdToken *token,
3855 /* [out] */ IXCLRDataModule **mod)
3856{
3857 HRESULT status;
3858
3859 DAC_ENTER_SUB(m_dac);
3860
3861 EX_TRY
3862 {
3863 status = S_OK;
3864
3865 if (token)
3866 {
3867 *token = m_methodDesc->GetMemberDef();
3868 }
3869
3870 if (mod)
3871 {
3872 *mod = new (nothrow)
3873 ClrDataModule(m_dac, m_methodDesc->GetModule());
3874 status = *mod ? S_OK : E_OUTOFMEMORY;
3875 }
3876 }
3877 EX_CATCH
3878 {
3879 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3880 {
3881 EX_RETHROW;
3882 }
3883 }
3884 EX_END_CATCH(SwallowAllExceptions)
3885
3886 DAC_LEAVE();
3887 return status;
3888}
3889
3890HRESULT STDMETHODCALLTYPE
3891ClrDataMethodInstance::GetName(
3892 /* [in] */ ULONG32 flags,
3893 /* [in] */ ULONG32 bufLen,
3894 /* [out] */ ULONG32 *nameLen,
3895 /* [size_is][out] */ __out_ecount_part(bufLen, *nameLen) WCHAR name[ ])
3896{
3897 HRESULT status;
3898
3899 if (flags != 0)
3900 {
3901 return E_INVALIDARG;
3902 }
3903
3904 DAC_ENTER_SUB(m_dac);
3905
3906 EX_TRY
3907 {
3908 status = m_dac->GetFullMethodName(m_methodDesc, bufLen, nameLen, name);
3909 }
3910 EX_CATCH
3911 {
3912 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3913 {
3914 EX_RETHROW;
3915 }
3916 else
3917 {
3918 static WCHAR nameUnk[] = W("Unknown");
3919 wcscpy_s(name, bufLen, nameUnk);
3920 if (nameLen != NULL)
3921 {
3922 *nameLen = _countof(nameUnk);
3923 }
3924 status = S_OK;
3925 }
3926 }
3927 EX_END_CATCH(SwallowAllExceptions)
3928
3929 DAC_LEAVE();
3930 return status;
3931}
3932
3933HRESULT STDMETHODCALLTYPE
3934ClrDataMethodInstance::GetFlags(
3935 /* [out] */ ULONG32 *flags)
3936{
3937 HRESULT status;
3938
3939 DAC_ENTER_SUB(m_dac);
3940
3941 EX_TRY
3942 {
3943 status = ClrDataMethodDefinition::
3944 GetSharedMethodFlags(m_methodDesc, flags);
3945 }
3946 EX_CATCH
3947 {
3948 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3949 {
3950 EX_RETHROW;
3951 }
3952 }
3953 EX_END_CATCH(SwallowAllExceptions)
3954
3955 DAC_LEAVE();
3956 return status;
3957}
3958
3959HRESULT STDMETHODCALLTYPE
3960ClrDataMethodInstance::IsSameObject(
3961 /* [in] */ IXCLRDataMethodInstance* method)
3962{
3963 HRESULT status;
3964
3965 DAC_ENTER_SUB(m_dac);
3966
3967 EX_TRY
3968 {
3969 status = (PTR_HOST_TO_TADDR(m_appDomain) ==
3970 PTR_HOST_TO_TADDR(((ClrDataMethodInstance*)method)->
3971 m_appDomain) &&
3972 PTR_HOST_TO_TADDR(m_methodDesc) ==
3973 PTR_HOST_TO_TADDR(((ClrDataMethodInstance*)method)->
3974 m_methodDesc)) ?
3975 S_OK : S_FALSE;
3976 }
3977 EX_CATCH
3978 {
3979 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
3980 {
3981 EX_RETHROW;
3982 }
3983 }
3984 EX_END_CATCH(SwallowAllExceptions)
3985
3986 DAC_LEAVE();
3987 return status;
3988}
3989
3990HRESULT STDMETHODCALLTYPE
3991ClrDataMethodInstance::GetEnCVersion(
3992 /* [out] */ ULONG32* version)
3993{
3994 HRESULT status;
3995
3996 DAC_ENTER_SUB(m_dac);
3997
3998 EX_TRY
3999 {
4000 // XXX Microsoft.
4001 *version = 0;
4002 status = S_OK;
4003 }
4004 EX_CATCH
4005 {
4006 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4007 {
4008 EX_RETHROW;
4009 }
4010 }
4011 EX_END_CATCH(SwallowAllExceptions)
4012
4013 DAC_LEAVE();
4014 return status;
4015}
4016
4017HRESULT STDMETHODCALLTYPE
4018ClrDataMethodInstance::GetNumTypeArguments(
4019 /* [out] */ ULONG32 *numTypeArgs)
4020{
4021 HRESULT status;
4022
4023 DAC_ENTER_SUB(m_dac);
4024
4025 EX_TRY
4026 {
4027 // XXX Microsoft.
4028 status = E_NOTIMPL;
4029 }
4030 EX_CATCH
4031 {
4032 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4033 {
4034 EX_RETHROW;
4035 }
4036 }
4037 EX_END_CATCH(SwallowAllExceptions)
4038
4039 DAC_LEAVE();
4040 return status;
4041}
4042
4043HRESULT STDMETHODCALLTYPE
4044ClrDataMethodInstance::GetTypeArgumentByIndex(
4045 /* [in] */ ULONG32 index,
4046 /* [out] */ IXCLRDataTypeInstance **typeArg)
4047{
4048 HRESULT status;
4049
4050 DAC_ENTER_SUB(m_dac);
4051
4052 EX_TRY
4053 {
4054 // XXX Microsoft.
4055 status = E_NOTIMPL;
4056 }
4057 EX_CATCH
4058 {
4059 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4060 {
4061 EX_RETHROW;
4062 }
4063 }
4064 EX_END_CATCH(SwallowAllExceptions)
4065
4066 DAC_LEAVE();
4067 return status;
4068}
4069
4070HRESULT STDMETHODCALLTYPE
4071ClrDataMethodInstance::GetILOffsetsByAddress(
4072 /* [in] */ CLRDATA_ADDRESS address,
4073 /* [in] */ ULONG32 offsetsLen,
4074 /* [out] */ ULONG32 *offsetsNeeded,
4075 /* [size_is][out] */ ULONG32 ilOffsets[ ])
4076{
4077 HRESULT status;
4078 DebuggerILToNativeMap* map = NULL;
4079 bool mapAllocated = false;
4080
4081 DAC_ENTER_SUB(m_dac);
4082 EX_TRY
4083 {
4084 ULONG32 numMap;
4085 ULONG32 codeOffset;
4086 ULONG32 hits = 0;
4087
4088#ifdef _TARGET_ARM_
4089 address &= ~THUMB_CODE; // on ARM windbg passes in an address with the mode flag set... need to workaround
4090#endif
4091 if ((status = m_dac->GetMethodNativeMap(m_methodDesc,
4092 CLRDATA_ADDRESS_TO_TADDR(address),
4093 &numMap,
4094 &map,
4095 &mapAllocated,
4096 NULL,
4097 &codeOffset)) != S_OK)
4098 {
4099 goto Exit;
4100 }
4101
4102 for (ULONG32 i = 0; i < numMap; i++)
4103 {
4104 if (codeOffset >= map[i].nativeStartOffset &&
4105 (((LONG)map[i].ilOffset == ICorDebugInfo::EPILOG &&
4106 !map[i].nativeEndOffset) ||
4107 codeOffset < map[i].nativeEndOffset))
4108 {
4109 hits++;
4110
4111 if (offsetsLen && ilOffsets)
4112 {
4113 *ilOffsets = map[i].ilOffset;
4114 ilOffsets++;
4115 offsetsLen--;
4116 }
4117 }
4118 }
4119
4120 if (offsetsNeeded)
4121 {
4122 *offsetsNeeded = hits;
4123 }
4124 status = hits ? S_OK : E_NOINTERFACE;
4125
4126 Exit: ;
4127 }
4128 EX_CATCH
4129 {
4130 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4131 {
4132 EX_RETHROW;
4133 }
4134 }
4135 EX_END_CATCH(SwallowAllExceptions)
4136
4137 if (mapAllocated)
4138 {
4139 delete [] map;
4140 }
4141
4142 DAC_LEAVE();
4143 return status;
4144}
4145
4146HRESULT STDMETHODCALLTYPE
4147ClrDataMethodInstance::GetAddressRangesByILOffset(
4148 /* [in] */ ULONG32 ilOffset,
4149 /* [in] */ ULONG32 rangesLen,
4150 /* [out] */ ULONG32 *rangesNeeded,
4151 /* [size_is][out] */ CLRDATA_ADDRESS_RANGE addressRanges[ ])
4152{
4153 HRESULT status;
4154 DebuggerILToNativeMap* map = NULL;
4155 bool mapAllocated = false;
4156
4157 DAC_ENTER_SUB(m_dac);
4158
4159 EX_TRY
4160 {
4161 ULONG32 numMap;
4162 CLRDATA_ADDRESS codeStart;
4163 ULONG32 hits = 0;
4164
4165 if ((status = m_dac->GetMethodNativeMap(m_methodDesc,
4166 0,
4167 &numMap,
4168 &map,
4169 &mapAllocated,
4170 &codeStart,
4171 NULL)) != S_OK)
4172 {
4173 goto Exit;
4174 }
4175
4176 for (ULONG32 i = 0; i < numMap; i++)
4177 {
4178 if (map[i].ilOffset == ilOffset)
4179 {
4180 hits++;
4181
4182 if (rangesLen && addressRanges)
4183 {
4184 addressRanges->startAddress =
4185 TO_CDADDR(codeStart + map[i].nativeStartOffset);
4186 if ((LONG)map[i].ilOffset == ICorDebugInfo::EPILOG &&
4187 !map[i].nativeEndOffset)
4188 {
4189 addressRanges->endAddress = 0;
4190 }
4191 else
4192 {
4193 addressRanges->endAddress =
4194 TO_CDADDR(codeStart + map[i].nativeEndOffset);
4195 }
4196 addressRanges++;
4197 rangesLen--;
4198 }
4199 }
4200 }
4201
4202 if (rangesNeeded)
4203 {
4204 *rangesNeeded = hits;
4205 }
4206 status = hits ? S_OK : E_NOINTERFACE;
4207
4208 Exit: ;
4209 }
4210 EX_CATCH
4211 {
4212 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4213 {
4214 EX_RETHROW;
4215 }
4216 }
4217 EX_END_CATCH(SwallowAllExceptions)
4218
4219 if (mapAllocated)
4220 {
4221 delete [] map;
4222 }
4223
4224 DAC_LEAVE();
4225 return status;
4226}
4227
4228HRESULT STDMETHODCALLTYPE
4229ClrDataMethodInstance::GetILAddressMap(
4230 /* [in] */ ULONG32 mapLen,
4231 /* [out] */ ULONG32 *mapNeeded,
4232 /* [size_is][out] */ CLRDATA_IL_ADDRESS_MAP maps[ ])
4233{
4234 HRESULT status;
4235 DebuggerILToNativeMap* map = NULL;
4236 bool mapAllocated = false;
4237
4238 DAC_ENTER_SUB(m_dac);
4239
4240 EX_TRY
4241 {
4242 ULONG32 numMap;
4243 CLRDATA_ADDRESS codeStart;
4244
4245 if ((status = m_dac->GetMethodNativeMap(m_methodDesc,
4246 0,
4247 &numMap,
4248 &map,
4249 &mapAllocated,
4250 &codeStart,
4251 NULL)) != S_OK)
4252 {
4253 goto Exit;
4254 }
4255
4256 for (ULONG32 i = 0; i < numMap; i++)
4257 {
4258 if (mapLen && maps)
4259 {
4260 maps->ilOffset = map[i].ilOffset;
4261 maps->startAddress =
4262 TO_CDADDR(codeStart + map[i].nativeStartOffset);
4263 maps->endAddress =
4264 TO_CDADDR(codeStart + map[i].nativeEndOffset);
4265 // XXX Microsoft - Define types as mapping of
4266 // ICorDebugInfo::SourceTypes.
4267 maps->type = CLRDATA_SOURCE_TYPE_INVALID;
4268 maps++;
4269 mapLen--;
4270 }
4271 else
4272 {
4273 break;
4274 }
4275 }
4276
4277 if (mapNeeded)
4278 {
4279 *mapNeeded = numMap;
4280 }
4281 status = numMap ? S_OK : E_NOINTERFACE;
4282
4283 Exit: ;
4284 }
4285 EX_CATCH
4286 {
4287 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4288 {
4289 EX_RETHROW;
4290 }
4291 }
4292 EX_END_CATCH(SwallowAllExceptions)
4293
4294 if (mapAllocated)
4295 {
4296 delete [] map;
4297 }
4298
4299 DAC_LEAVE();
4300 return status;
4301}
4302
4303HRESULT STDMETHODCALLTYPE
4304ClrDataMethodInstance::StartEnumExtents(
4305 /* [out] */ CLRDATA_ENUM *handle)
4306{
4307 HRESULT status;
4308
4309 DAC_ENTER_SUB(m_dac);
4310
4311 EX_TRY
4312 {
4313 METH_EXTENTS* extents;
4314
4315 if ((status = m_dac->
4316 GetMethodExtents(m_methodDesc, &extents)) == S_OK)
4317 {
4318 *handle = TO_CDENUM(extents);
4319 }
4320 }
4321 EX_CATCH
4322 {
4323 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4324 {
4325 EX_RETHROW;
4326 }
4327 }
4328 EX_END_CATCH(SwallowAllExceptions)
4329
4330 DAC_LEAVE();
4331 return status;
4332}
4333
4334HRESULT STDMETHODCALLTYPE
4335ClrDataMethodInstance::EnumExtent(
4336 /* [out][in] */ CLRDATA_ENUM *handle,
4337 /* [out] */ CLRDATA_ADDRESS_RANGE *extent)
4338{
4339 HRESULT status;
4340
4341 DAC_ENTER_SUB(m_dac);
4342
4343 EX_TRY
4344 {
4345 METH_EXTENTS* extents =
4346 FROM_CDENUM(METH_EXTENTS, *handle);
4347 if (extents->curExtent >= extents->numExtents)
4348 {
4349 status = S_FALSE;
4350 }
4351 else
4352 {
4353 CLRDATA_ADDRESS_RANGE* curExtent =
4354 extents->extents + extents->curExtent++;
4355 *extent = *curExtent;
4356 status = S_OK;
4357 }
4358 }
4359 EX_CATCH
4360 {
4361 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4362 {
4363 EX_RETHROW;
4364 }
4365 }
4366 EX_END_CATCH(SwallowAllExceptions)
4367
4368 DAC_LEAVE();
4369 return status;
4370}
4371
4372HRESULT STDMETHODCALLTYPE
4373ClrDataMethodInstance::EndEnumExtents(
4374 /* [in] */ CLRDATA_ENUM handle)
4375{
4376 HRESULT status;
4377
4378 DAC_ENTER_SUB(m_dac);
4379
4380 EX_TRY
4381 {
4382 delete FROM_CDENUM(METH_EXTENTS, handle);
4383 status = S_OK;
4384 }
4385 EX_CATCH
4386 {
4387 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4388 {
4389 EX_RETHROW;
4390 }
4391 }
4392 EX_END_CATCH(SwallowAllExceptions)
4393
4394 DAC_LEAVE();
4395 return status;
4396}
4397
4398HRESULT STDMETHODCALLTYPE
4399ClrDataMethodInstance::GetRepresentativeEntryAddress(
4400 /* [out] */ CLRDATA_ADDRESS* addr)
4401{
4402 HRESULT status;
4403
4404 DAC_ENTER_SUB(m_dac);
4405
4406 EX_TRY
4407 {
4408 if (m_methodDesc->HasNativeCode())
4409 {
4410 *addr = TO_CDADDR(m_methodDesc->GetNativeCode());
4411 status = S_OK;
4412 }
4413 else
4414 {
4415 status = E_UNEXPECTED;
4416 }
4417 }
4418 EX_CATCH
4419 {
4420 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4421 {
4422 EX_RETHROW;
4423 }
4424 }
4425 EX_END_CATCH(SwallowAllExceptions)
4426
4427 DAC_LEAVE();
4428 return status;
4429}
4430
4431HRESULT STDMETHODCALLTYPE
4432ClrDataMethodInstance::Request(
4433 /* [in] */ ULONG32 reqCode,
4434 /* [in] */ ULONG32 inBufferSize,
4435 /* [size_is][in] */ BYTE *inBuffer,
4436 /* [in] */ ULONG32 outBufferSize,
4437 /* [size_is][out] */ BYTE *outBuffer)
4438{
4439 HRESULT status;
4440
4441 DAC_ENTER_SUB(m_dac);
4442
4443 EX_TRY
4444 {
4445 switch(reqCode)
4446 {
4447 case CLRDATA_REQUEST_REVISION:
4448 if (inBufferSize != 0 ||
4449 inBuffer ||
4450 outBufferSize != sizeof(ULONG32))
4451 {
4452 status = E_INVALIDARG;
4453 }
4454 else
4455 {
4456 *(ULONG32*)outBuffer = 1;
4457 status = S_OK;
4458 }
4459 break;
4460
4461 default:
4462 status = E_INVALIDARG;
4463 break;
4464 }
4465 }
4466 EX_CATCH
4467 {
4468 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4469 {
4470 EX_RETHROW;
4471 }
4472 }
4473 EX_END_CATCH(SwallowAllExceptions)
4474
4475 DAC_LEAVE();
4476 return status;
4477}
4478
4479HRESULT
4480ClrDataMethodInstance::NewFromModule(ClrDataAccess* dac,
4481 AppDomain* appDomain,
4482 Module* module,
4483 mdMethodDef token,
4484 ClrDataMethodInstance** methInst,
4485 IXCLRDataMethodInstance** pubMethInst)
4486{
4487 MethodDesc* methodDesc = module->LookupMethodDef(token);
4488 if (!methodDesc ||
4489 !methodDesc->HasNativeCode())
4490 {
4491 return E_INVALIDARG;
4492 }
4493
4494 ClrDataMethodInstance* inst = new (nothrow)
4495 ClrDataMethodInstance(dac, appDomain, methodDesc);
4496 if (!inst)
4497 {
4498 return E_OUTOFMEMORY;
4499 }
4500
4501 PREFIX_ASSUME(methInst || pubMethInst);
4502
4503 if (methInst)
4504 {
4505 *methInst = inst;
4506 }
4507 if (pubMethInst)
4508 {
4509 *pubMethInst = inst;
4510 }
4511
4512 return S_OK;
4513}
4514
4515//----------------------------------------------------------------------------
4516//
4517// ClrDataExceptionState.
4518//
4519//----------------------------------------------------------------------------
4520
4521ClrDataExceptionState::ClrDataExceptionState(ClrDataAccess* dac,
4522 AppDomain* appDomain,
4523 Thread* thread,
4524 ULONG32 flags,
4525 ClrDataExStateType* exInfo,
4526 OBJECTHANDLE throwable,
4527 ClrDataExStateType* prevExInfo)
4528{
4529 m_dac = dac;
4530 m_dac->AddRef();
4531 m_instanceAge = m_dac->m_instanceAge;
4532 m_appDomain = appDomain;
4533 m_thread = thread;
4534 m_flags = flags;
4535 m_exInfo = exInfo;
4536 m_throwable = throwable;
4537 m_prevExInfo = prevExInfo;
4538 m_refs = 1;
4539}
4540
4541ClrDataExceptionState::~ClrDataExceptionState(void)
4542{
4543 m_dac->Release();
4544}
4545
4546STDMETHODIMP
4547ClrDataExceptionState::QueryInterface(THIS_
4548 IN REFIID interfaceId,
4549 OUT PVOID* iface)
4550{
4551 if (IsEqualIID(interfaceId, IID_IUnknown) ||
4552 IsEqualIID(interfaceId, __uuidof(IXCLRDataExceptionState)))
4553 {
4554 AddRef();
4555 *iface = static_cast<IUnknown*>
4556 (static_cast<IXCLRDataExceptionState*>(this));
4557 return S_OK;
4558 }
4559 else
4560 {
4561 *iface = NULL;
4562 return E_NOINTERFACE;
4563 }
4564}
4565
4566STDMETHODIMP_(ULONG)
4567ClrDataExceptionState::AddRef(THIS)
4568{
4569 return InterlockedIncrement(&m_refs);
4570}
4571
4572STDMETHODIMP_(ULONG)
4573ClrDataExceptionState::Release(THIS)
4574{
4575 SUPPORTS_DAC_HOST_ONLY;
4576 LONG newRefs = InterlockedDecrement(&m_refs);
4577 if (newRefs == 0)
4578 {
4579 delete this;
4580 }
4581 return newRefs;
4582}
4583
4584HRESULT STDMETHODCALLTYPE
4585ClrDataExceptionState::GetFlags(
4586 /* [out] */ ULONG32 *flags)
4587{
4588 HRESULT status;
4589
4590 DAC_ENTER_SUB(m_dac);
4591
4592 EX_TRY
4593 {
4594 *flags = m_flags;
4595
4596 if (m_prevExInfo)
4597 {
4598 (*flags) |= CLRDATA_EXCEPTION_NESTED;
4599 }
4600
4601 status = S_OK;
4602 }
4603 EX_CATCH
4604 {
4605 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4606 {
4607 EX_RETHROW;
4608 }
4609 }
4610 EX_END_CATCH(SwallowAllExceptions)
4611
4612 DAC_LEAVE();
4613 return status;
4614}
4615
4616HRESULT STDMETHODCALLTYPE
4617ClrDataExceptionState::GetPrevious(
4618 /* [out] */ IXCLRDataExceptionState **exState)
4619{
4620 HRESULT status;
4621
4622 DAC_ENTER_SUB(m_dac);
4623
4624 EX_TRY
4625 {
4626 if (m_prevExInfo)
4627 {
4628 *exState = new (nothrow)
4629 ClrDataExceptionState(m_dac,
4630 m_appDomain,
4631 m_thread,
4632 CLRDATA_EXCEPTION_DEFAULT,
4633 m_prevExInfo,
4634 m_prevExInfo->m_hThrowable,
4635 m_prevExInfo->m_pPrevNestedInfo);
4636 status = *exState ? S_OK : E_OUTOFMEMORY;
4637 }
4638 else
4639 {
4640 *exState = NULL;
4641 status = S_FALSE;
4642 }
4643 }
4644 EX_CATCH
4645 {
4646 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4647 {
4648 EX_RETHROW;
4649 }
4650 }
4651 EX_END_CATCH(SwallowAllExceptions)
4652
4653 DAC_LEAVE();
4654 return status;
4655}
4656
4657HRESULT STDMETHODCALLTYPE
4658ClrDataExceptionState::GetManagedObject(
4659 /* [out] */ IXCLRDataValue **value)
4660{
4661 HRESULT status;
4662
4663 DAC_ENTER_SUB(m_dac);
4664
4665 EX_TRY
4666 {
4667 PTR_UNCHECKED_OBJECTREF throwRef(m_throwable);
4668 if (!throwRef.IsValid())
4669 {
4670 status = E_INVALIDARG;
4671 goto Exit;
4672 }
4673
4674 NativeVarLocation varLoc;
4675 ClrDataValue* RefVal;
4676
4677 varLoc.addr = TO_CDADDR(m_throwable);
4678 varLoc.size = sizeof(TADDR);
4679 varLoc.contextReg = false;
4680
4681 RefVal = new (nothrow)
4682 ClrDataValue(m_dac,
4683 m_appDomain,
4684 m_thread,
4685 CLRDATA_VALUE_IS_REFERENCE,
4686 TypeHandle((*throwRef)->GetMethodTable()),
4687 varLoc.addr,
4688 1, &varLoc);
4689 if (!RefVal)
4690 {
4691 status = E_OUTOFMEMORY;
4692 goto Exit;
4693 }
4694
4695 status = RefVal->GetAssociatedValue(value);
4696
4697 delete RefVal;
4698
4699 Exit: ;
4700 }
4701 EX_CATCH
4702 {
4703 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4704 {
4705 EX_RETHROW;
4706 }
4707 }
4708 EX_END_CATCH(SwallowAllExceptions)
4709
4710 DAC_LEAVE();
4711 return status;
4712}
4713
4714HRESULT STDMETHODCALLTYPE
4715ClrDataExceptionState::GetBaseType(
4716 /* [out] */ CLRDataBaseExceptionType *type)
4717{
4718 HRESULT status;
4719
4720 DAC_ENTER_SUB(m_dac);
4721
4722 EX_TRY
4723 {
4724 // XXX Microsoft.
4725 status = E_NOTIMPL;
4726 }
4727 EX_CATCH
4728 {
4729 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4730 {
4731 EX_RETHROW;
4732 }
4733 }
4734 EX_END_CATCH(SwallowAllExceptions)
4735
4736 DAC_LEAVE();
4737 return status;
4738}
4739
4740HRESULT STDMETHODCALLTYPE
4741ClrDataExceptionState::GetCode(
4742 /* [out] */ ULONG32 *code)
4743{
4744 HRESULT status;
4745
4746 DAC_ENTER_SUB(m_dac);
4747
4748 EX_TRY
4749 {
4750 // XXX Microsoft.
4751 status = E_NOTIMPL;
4752 }
4753 EX_CATCH
4754 {
4755 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4756 {
4757 EX_RETHROW;
4758 }
4759 }
4760 EX_END_CATCH(SwallowAllExceptions)
4761
4762 DAC_LEAVE();
4763 return status;
4764}
4765
4766HRESULT STDMETHODCALLTYPE
4767ClrDataExceptionState::GetString(
4768 /* [in] */ ULONG32 bufLen,
4769 /* [out] */ ULONG32 *strLen,
4770 /* [size_is][out] */ __out_ecount_part(bufLen, *strLen) WCHAR str[ ])
4771{
4772 HRESULT status = E_FAIL;
4773
4774 DAC_ENTER_SUB(m_dac);
4775
4776 EX_TRY
4777 {
4778 PTR_UNCHECKED_OBJECTREF throwRef(m_throwable);
4779 STRINGREF message = EXCEPTIONREF(*throwRef)->GetMessage();
4780
4781 if (message == NULL)
4782 {
4783 if (strLen)
4784 {
4785 *strLen = 0;
4786 }
4787 if (bufLen >= 1)
4788 {
4789 str[0] = 0;
4790 }
4791 status = S_OK;
4792 }
4793 else
4794 {
4795 PWSTR msgStr = DacInstantiateStringW((TADDR)message->GetBuffer(),
4796 message->GetStringLength(),
4797 true);
4798
4799 status = StringCchCopy(str, bufLen, msgStr) == S_OK ? S_OK : S_FALSE;
4800 if (strLen != NULL)
4801 {
4802 size_t cchName = wcslen(msgStr) + 1;
4803 if (FitsIn<ULONG32>(cchName))
4804 {
4805 *strLen = (ULONG32) cchName;
4806 }
4807 else
4808 {
4809 status = COR_E_OVERFLOW;
4810 }
4811 }
4812 }
4813 }
4814 EX_CATCH
4815 {
4816 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4817 {
4818 EX_RETHROW;
4819 }
4820 }
4821 EX_END_CATCH(SwallowAllExceptions)
4822
4823 DAC_LEAVE();
4824 return status;
4825}
4826
4827HRESULT STDMETHODCALLTYPE
4828ClrDataExceptionState::IsSameState(
4829 /* [in] */ EXCEPTION_RECORD64 *exRecord,
4830 /* [in] */ ULONG32 contextSize,
4831 /* [size_is][in] */ BYTE cxRecord[ ])
4832{
4833 return IsSameState2(CLRDATA_EXSAME_SECOND_CHANCE,
4834 exRecord, contextSize, cxRecord);
4835}
4836
4837HRESULT STDMETHODCALLTYPE
4838ClrDataExceptionState::IsSameState2(
4839 /* [in] */ ULONG32 flags,
4840 /* [in] */ EXCEPTION_RECORD64 *exRecord,
4841 /* [in] */ ULONG32 contextSize,
4842 /* [size_is][in] */ BYTE cxRecord[ ])
4843{
4844 HRESULT status;
4845
4846 if ((flags & ~(CLRDATA_EXSAME_SECOND_CHANCE |
4847 CLRDATA_EXSAME_FIRST_CHANCE)) != 0)
4848 {
4849 return E_INVALIDARG;
4850 }
4851
4852 DAC_ENTER_SUB(m_dac);
4853
4854 EX_TRY
4855 {
4856 PTR_EXCEPTION_RECORD infoExRecord;
4857
4858 // XXX Microsoft - This should also check that the
4859 // context matches the context at the time
4860 // of the exception, but it's not clear
4861 // how to do that in all cases.
4862
4863 status = S_FALSE;
4864
4865 if (!m_exInfo)
4866 {
4867 // We don't have full state, but that's expected
4868 // on a first chance exception so allow that.
4869 if ((flags & CLRDATA_EXSAME_FIRST_CHANCE) != 0)
4870 {
4871 status = S_OK;
4872 }
4873
4874 goto Exit;
4875 }
4876
4877 infoExRecord = GetCurrentExceptionRecord();
4878
4879 if ((TADDR)infoExRecord->ExceptionAddress ==
4880 (TADDR)exRecord->ExceptionAddress)
4881 {
4882 status = S_OK;
4883 }
4884
4885 Exit: ;
4886 }
4887 EX_CATCH
4888 {
4889 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4890 {
4891 EX_RETHROW;
4892 }
4893 }
4894 EX_END_CATCH(SwallowAllExceptions)
4895
4896 DAC_LEAVE();
4897 return status;
4898}
4899
4900HRESULT STDMETHODCALLTYPE
4901ClrDataExceptionState::GetTask(
4902 /* [out] */ IXCLRDataTask** task)
4903{
4904 HRESULT status;
4905
4906 DAC_ENTER_SUB(m_dac);
4907
4908 EX_TRY
4909 {
4910 *task = new (nothrow)
4911 ClrDataTask(m_dac,
4912 m_thread);
4913 status = *task ? S_OK : E_OUTOFMEMORY;
4914 }
4915 EX_CATCH
4916 {
4917 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4918 {
4919 EX_RETHROW;
4920 }
4921 }
4922 EX_END_CATCH(SwallowAllExceptions)
4923
4924 DAC_LEAVE();
4925 return status;
4926}
4927
4928HRESULT STDMETHODCALLTYPE
4929ClrDataExceptionState::Request(
4930 /* [in] */ ULONG32 reqCode,
4931 /* [in] */ ULONG32 inBufferSize,
4932 /* [size_is][in] */ BYTE *inBuffer,
4933 /* [in] */ ULONG32 outBufferSize,
4934 /* [size_is][out] */ BYTE *outBuffer)
4935{
4936 HRESULT status;
4937
4938 DAC_ENTER_SUB(m_dac);
4939
4940 EX_TRY
4941 {
4942 switch(reqCode)
4943 {
4944 case CLRDATA_REQUEST_REVISION:
4945 if (inBufferSize != 0 ||
4946 inBuffer ||
4947 outBufferSize != sizeof(ULONG32))
4948 {
4949 status = E_INVALIDARG;
4950 }
4951 else
4952 {
4953 *(ULONG32*)outBuffer = 2;
4954 status = S_OK;
4955 }
4956 break;
4957
4958 default:
4959 status = E_INVALIDARG;
4960 break;
4961 }
4962 }
4963 EX_CATCH
4964 {
4965 if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
4966 {
4967 EX_RETHROW;
4968 }
4969 }
4970 EX_END_CATCH(SwallowAllExceptions)
4971
4972 DAC_LEAVE();
4973 return status;
4974}
4975
4976HRESULT
4977ClrDataExceptionState::NewFromThread(ClrDataAccess* dac,
4978 Thread* thread,
4979 ClrDataExceptionState** exception,
4980 IXCLRDataExceptionState** pubException)
4981{
4982 if (!thread->HasException())
4983 {
4984 return E_NOINTERFACE;
4985 }
4986
4987 ClrDataExStateType* exState;
4988 ClrDataExceptionState* exIf;
4989
4990#ifdef WIN64EXCEPTIONS
4991 exState = thread->GetExceptionState()->m_pCurrentTracker;
4992#else
4993 exState = &(thread->GetExceptionState()->m_currentExInfo);
4994#endif // WIN64EXCEPTIONS
4995
4996 exIf = new (nothrow)
4997 ClrDataExceptionState(dac,
4998 thread->GetDomain(),
4999 thread,
5000 CLRDATA_EXCEPTION_DEFAULT,
5001 exState,
5002 exState->m_hThrowable,
5003 exState->m_pPrevNestedInfo);
5004 if (!exIf)
5005 {
5006 return E_OUTOFMEMORY;
5007 }
5008
5009 PREFIX_ASSUME(exception || pubException);
5010
5011 if (exception)
5012 {
5013 *exception = exIf;
5014 }
5015 if (pubException)
5016 {
5017 *pubException = exIf;
5018 }
5019
5020 return S_OK;
5021}
5022
5023PTR_EXCEPTION_RECORD
5024ClrDataExceptionState::GetCurrentExceptionRecord()
5025{
5026 PTR_EXCEPTION_RECORD pExRecord = NULL;
5027
5028#ifdef WIN64EXCEPTIONS
5029 pExRecord = m_exInfo->m_ptrs.ExceptionRecord;
5030#else // WIN64EXCEPTIONS
5031 pExRecord = m_exInfo->m_pExceptionRecord;
5032#endif // WIN64EXCEPTIONS
5033
5034 return pExRecord;
5035}
5036
5037PTR_CONTEXT
5038ClrDataExceptionState::GetCurrentContextRecord()
5039{
5040 PTR_CONTEXT pContext = NULL;
5041
5042#ifdef WIN64EXCEPTIONS
5043 pContext = m_exInfo->m_ptrs.ContextRecord;
5044#else // WIN64EXCEPTIONS
5045 pContext = m_exInfo->m_pContext;
5046#endif // WIN64EXCEPTIONS
5047
5048 return pContext;
5049}
5050
5051//----------------------------------------------------------------------------
5052//
5053// EnumMethodDefinitions.
5054//
5055//----------------------------------------------------------------------------
5056
5057HRESULT
5058EnumMethodDefinitions::Start(Module* mod,
5059 bool useAddrFilter,
5060 CLRDATA_ADDRESS addrFilter)
5061{
5062 m_module = mod;
5063 m_useAddrFilter = useAddrFilter;
5064 m_addrFilter = addrFilter;
5065 m_typeToken = mdTokenNil;
5066 m_needMethodStart = true;
5067 return m_typeEnum.Start(m_module->GetMDImport(), mdtTypeDef, mdTokenNil);
5068}
5069
5070HRESULT
5071EnumMethodDefinitions::Next(ClrDataAccess* dac,
5072 IXCLRDataMethodDefinition **method)
5073{
5074 HRESULT status;
5075
5076 NextType:
5077 if (m_typeToken == mdTokenNil)
5078 {
5079 if ((status = m_typeEnum.NextToken(&m_typeToken, NULL, NULL)) != S_OK)
5080 {
5081 return status;
5082 }
5083
5084 m_needMethodStart = true;
5085 }
5086
5087 if (m_needMethodStart)
5088 {
5089 if ((status = m_methodEnum.
5090 Start(m_module->GetMDImport(),
5091 mdtMethodDef, m_typeToken)) != S_OK)
5092 {
5093 return status;
5094 }
5095
5096 m_needMethodStart = false;
5097 }
5098
5099 NextMethod:
5100 mdToken methodToken;
5101
5102 if ((status = m_methodEnum.NextToken(&methodToken, NULL, NULL)) != S_OK)
5103 {
5104 if (status == S_FALSE)
5105 {
5106 m_typeToken = mdTokenNil;
5107 goto NextType;
5108 }
5109
5110 return status;
5111 }
5112
5113 if (m_useAddrFilter)
5114 {
5115 ULONG ilRva;
5116 ULONG implFlags;
5117
5118 status = m_module->GetMDImport()->
5119 GetMethodImplProps(methodToken, &ilRva, &implFlags);
5120 if (FAILED(status))
5121 {
5122 return status;
5123 }
5124 if (!ilRva)
5125 {
5126 goto NextMethod;
5127 }
5128
5129 COR_ILMETHOD* ilMeth =
5130 DacGetIlMethod(m_module->GetIL((RVA)ilRva));
5131 COR_ILMETHOD_DECODER ilDec(ilMeth);
5132
5133 CLRDATA_ADDRESS start =
5134 TO_CDADDR(PTR_HOST_TO_TADDR(ilMeth) + 4 * ilDec.GetSize());
5135 if (m_addrFilter < start ||
5136 m_addrFilter > start + ilDec.GetCodeSize() - 1)
5137 {
5138 goto NextMethod;
5139 }
5140 }
5141
5142 return ClrDataMethodDefinition::
5143 NewFromModule(dac,
5144 m_module,
5145 methodToken,
5146 NULL,
5147 method);
5148}
5149
5150HRESULT
5151EnumMethodDefinitions::CdStart(Module* mod,
5152 bool useAddrFilter,
5153 CLRDATA_ADDRESS addrFilter,
5154 CLRDATA_ENUM* handle)
5155{
5156 HRESULT status;
5157
5158 *handle = NULL;
5159
5160 if (!mod)
5161 {
5162 return S_FALSE;
5163 }
5164
5165 EnumMethodDefinitions* iter = new (nothrow)
5166 EnumMethodDefinitions;
5167 if (!iter)
5168 {
5169 return E_OUTOFMEMORY;
5170 }
5171
5172 if ((status = iter->Start(mod, useAddrFilter, addrFilter)) != S_OK)
5173 {
5174 delete iter;
5175 return status;
5176 }
5177
5178 *handle = TO_CDENUM(iter);
5179 return S_OK;
5180}
5181
5182HRESULT
5183EnumMethodDefinitions::CdNext(ClrDataAccess* dac,
5184 CLRDATA_ENUM* handle,
5185 IXCLRDataMethodDefinition** method)
5186{
5187 EnumMethodDefinitions* iter = FROM_CDENUM(EnumMethodDefinitions, *handle);
5188 if (!iter)
5189 {
5190 return S_FALSE;
5191 }
5192
5193 return iter->Next(dac, method);
5194}
5195
5196HRESULT
5197EnumMethodDefinitions::CdEnd(CLRDATA_ENUM handle)
5198{
5199 EnumMethodDefinitions* iter = FROM_CDENUM(EnumMethodDefinitions, handle);
5200 if (iter)
5201 {
5202 delete iter;
5203 return S_OK;
5204 }
5205 else
5206 {
5207 return E_INVALIDARG;
5208 }
5209}
5210
5211//----------------------------------------------------------------------------
5212//
5213// EnumMethodInstances.
5214//
5215//----------------------------------------------------------------------------
5216
5217EnumMethodInstances::EnumMethodInstances(MethodDesc* methodDesc,
5218 IXCLRDataAppDomain* givenAppDomain)
5219 : m_domainIter(FALSE)
5220{
5221 m_methodDesc = methodDesc;
5222 if (givenAppDomain)
5223 {
5224 m_givenAppDomain =
5225 ((ClrDataAppDomain*)givenAppDomain)->GetAppDomain();
5226 }
5227 else
5228 {
5229 m_givenAppDomain = NULL;
5230 }
5231 m_givenAppDomainUsed = false;
5232 m_appDomain = NULL;
5233}
5234
5235HRESULT
5236EnumMethodInstances::Next(ClrDataAccess* dac,
5237 IXCLRDataMethodInstance **instance)
5238{
5239 NextDomain:
5240 if (!m_appDomain)
5241 {
5242 if (m_givenAppDomainUsed ||
5243 !m_domainIter.Next())
5244 {
5245 return S_FALSE;
5246 }
5247
5248 if (m_givenAppDomain)
5249 {
5250 m_appDomain = m_givenAppDomain;
5251 m_givenAppDomainUsed = true;
5252 }
5253 else
5254 {
5255 m_appDomain = m_domainIter.GetDomain();
5256 }
5257
5258 m_methodIter.Start(m_appDomain,
5259 m_methodDesc->GetModule(), // module
5260 m_methodDesc->GetMemberDef(), // token
5261 m_methodDesc); // intial method desc
5262 }
5263
5264 NextMethod:
5265 {
5266 // Note: DAC doesn't need to keep the assembly alive - see code:CollectibleAssemblyHolder#CAH_DAC
5267 CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
5268 if (!m_methodIter.Next(pDomainAssembly.This()))
5269 {
5270 m_appDomain = NULL;
5271 goto NextDomain;
5272 }
5273 }
5274
5275 if (!m_methodIter.Current()->HasNativeCode())
5276 {
5277 goto NextMethod;
5278 }
5279
5280 *instance = new (nothrow)
5281 ClrDataMethodInstance(dac,
5282 m_appDomain,
5283 m_methodIter.Current());
5284 return *instance ? S_OK : E_OUTOFMEMORY;
5285}
5286
5287HRESULT
5288EnumMethodInstances::CdStart(MethodDesc* methodDesc,
5289 IXCLRDataAppDomain* appDomain,
5290 CLRDATA_ENUM* handle)
5291{
5292 if (!methodDesc->HasClassOrMethodInstantiation() &&
5293 !methodDesc->HasNativeCode())
5294 {
5295 *handle = 0;
5296 return S_FALSE;
5297 }
5298
5299 EnumMethodInstances* iter = new (nothrow)
5300 EnumMethodInstances(methodDesc, appDomain);
5301 if (iter)
5302 {
5303 *handle = TO_CDENUM(iter);
5304 return S_OK;
5305 }
5306 else
5307 {
5308 *handle = 0;
5309 return E_OUTOFMEMORY;
5310 }
5311}
5312
5313HRESULT
5314EnumMethodInstances::CdNext(ClrDataAccess* dac,
5315 CLRDATA_ENUM* handle,
5316 IXCLRDataMethodInstance** method)
5317{
5318 EnumMethodInstances* iter = FROM_CDENUM(EnumMethodInstances, *handle);
5319 if (!iter)
5320 {
5321 return S_FALSE;
5322 }
5323
5324 return iter->Next(dac, method);
5325}
5326
5327HRESULT
5328EnumMethodInstances::CdEnd(CLRDATA_ENUM handle)
5329{
5330 EnumMethodInstances* iter = FROM_CDENUM(EnumMethodInstances, handle);
5331 if (iter)
5332 {
5333 delete iter;
5334 return S_OK;
5335 }
5336 else
5337 {
5338 return E_INVALIDARG;
5339 }
5340}
5341