Remove Marshaling MDA (#22579)
[platform/upstream/coreclr.git] / src / vm / mdaassistants.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5
6 #include "common.h"
7 #ifdef MDA_SUPPORTED
8 #include "mda.h"
9 #include "mdaassistants.h"
10 #include "field.h"
11 #include "dllimport.h"
12 #ifdef FEATURE_COMINTEROP
13 #include "runtimecallablewrapper.h"
14 #include "comcallablewrapper.h"
15 #include "comcache.h"
16 #include "comtoclrcall.h"
17 #include "mlinfo.h"
18 #endif
19 #include "sigformat.h"
20 #include "fieldmarshaler.h"
21 #include "dllimportcallback.h"
22 #include "dbginterface.h"
23 #include "finalizerthread.h"
24
25 #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
26 #include "olecontexthelpers.h"
27 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
28
29 #ifdef MDA_SUPPORTED
30 ////
31 //// Mda Assistants
32 ////
33
34
35 //
36 // MdaFramework
37 // 
38 void MdaFramework::DumpDiagnostics()
39 {
40     CONTRACTL
41     {
42         THROWS;
43         GC_TRIGGERS;
44         MODE_ANY;
45     }
46     CONTRACTL_END;
47     
48     ManagedDebuggingAssistants* pMda = g_mdaStaticHeap.m_pMda;
49
50 #ifdef _DEBUG
51     if (m_dumpSchemaSchema)
52     {
53         MdaXmlElement* pXmlSchemaSchema = pMda->m_pSchemaSchema->ToXml(pMda->m_pMdaXmlIndustry);
54 //        MdaXmlMessage::SendMessage(pXmlSchemaSchema, TRUE, pMda->m_pSchemaSchema);   
55     }
56
57     if (m_dumpAssistantSchema)
58     {
59         MdaXmlElement* pXmlAssistantMsgSchema = pMda->m_pAssistantMsgSchema->ToXml(pMda->m_pMdaXmlIndustry);
60 //        MdaXmlMessage::SendMessage(pXmlAssistantMsgSchema, TRUE, pMda->m_pSchemaSchema);   
61     }
62
63     if (m_dumpAssistantMsgSchema)
64     {
65         MdaXmlElement* pXmlAssistantSchema = pMda->m_pAssistantSchema->ToXml(pMda->m_pMdaXmlIndustry);
66 //        MdaXmlMessage::SendMessage(pXmlAssistantSchema, TRUE, pMda->m_pSchemaSchema);   
67     }
68 #endif
69 }
70
71 #ifdef _DEBUG
72 extern BOOL g_bMdaDisableAsserts;
73 #endif
74
75 void MdaFramework::Initialize(MdaXmlElement* pXmlInput)
76 {
77     CONTRACTL
78     {
79         THROWS;
80         GC_TRIGGERS;
81         MODE_ANY;
82     }
83     CONTRACTL_END;
84
85 #ifdef _DEBUG
86     ManagedDebuggingAssistants* pMda = g_mdaStaticHeap.m_pMda;
87     g_bMdaDisableAsserts = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(DisableAsserts));
88     MdaXmlElement* pXmlDiagnostics = pXmlInput->GetChild(MdaElemDecl(Diagnostics));
89             
90     if (pXmlDiagnostics)
91     {
92         m_dumpSchemaSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpSchemaSchema), FALSE);
93         m_dumpAssistantSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpAssistantSchema), FALSE);
94         m_dumpAssistantMsgSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpAssistantMsgSchema), FALSE);
95     }
96 #endif
97 }
98
99 //
100 // MdaGcUnmanagedToManaged
101 //
102 void MdaGcUnmanagedToManaged::TriggerGC()
103 {
104     WRAPPER_NO_CONTRACT;
105
106     TriggerGCForMDAInternal();
107 }
108
109
110 //
111 // MdaGcManagedToUnmanaged
112 //
113 void MdaGcManagedToUnmanaged::TriggerGC()
114 {
115     WRAPPER_NO_CONTRACT;
116
117     TriggerGCForMDAInternal();
118 }
119
120 void TriggerGCForMDAInternal()
121 {
122     CONTRACTL
123     {
124         NOTHROW;
125         GC_TRIGGERS;
126         MODE_COOPERATIVE;
127     }
128     CONTRACTL_END;
129
130     EX_TRY
131     {
132         GCHeapUtilities::GetGCHeap()->GarbageCollect();
133
134         //
135         // It is very dangerous to wait for finalizer thread here if we are inside a wait 
136         // operation, as the wait operation might call into interop which calls this MDA
137         // and call into FinalizerThreadWait. In this case, we might run into infinite recursion: 
138         //   SynchronizationContext.Wait -> P/Invoke -> WaitForPendingFinalizer ->
139         //   SynchronizationContext.Wait ....
140         // 
141         // So, if we are inside a SyncContext.Wait, don't call out to FinalizerThreadWait
142         //
143         if (!GetThread()->HasThreadStateNC(Thread::TSNC_InsideSyncContextWait))
144             // It is possible that user code run as part of finalization will wait for this thread.
145             // To avoid deadlocks, we limit the wait time to 10 seconds (an arbitrary number).
146             FinalizerThread::FinalizerThreadWait(10 * 1000);
147     }
148     EX_CATCH
149     {
150         // Caller cannot take exceptions.
151     }
152     EX_END_CATCH(SwallowAllExceptions);
153 }
154
155 //
156 // MdaCallbackOnCollectedDelegate
157 //
158 /*
159 MdaCallbackOnCollectedDelegate::~MdaCallbackOnCollectedDelegate()
160 {
161     WRAPPER_NO_CONTRACT;
162     
163     if (m_pList && m_size)
164     {
165         for (int i=0; i < m_size; i++)
166             ReplaceEntry(i, NULL);
167
168         delete[] m_pList;
169     }
170 }
171 */
172
173 void MdaCallbackOnCollectedDelegate::ReportViolation(MethodDesc* pMD)
174 {
175     CONTRACTL
176     {
177         THROWS;
178         GC_TRIGGERS;
179         MODE_ANY;
180     }
181     CONTRACTL_END;
182
183     MdaXmlElement* pXml;
184     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
185     MdaXmlElement* pDelegate = pXml->AddChild(MdaElemDecl(Delegate));
186     StackSString delegateName;
187
188     if(pMD)
189     {
190         AsMdaAssistant()->OutputMethodDesc(pMD, pDelegate);
191         AsMdaAssistant()->ToString(delegateName, pMD);
192     }
193
194     msg.SendMessagef(MDARC_CALLBACK_ON_COLLECTED_DELEGATE, delegateName.GetUnicode());
195 }
196
197 void MdaCallbackOnCollectedDelegate::AddToList(UMEntryThunk* pEntryThunk)
198 {
199     CONTRACTL
200     {
201         NOTHROW;
202         GC_NOTRIGGER;
203         MODE_ANY;
204         PRECONDITION(CheckPointer(pEntryThunk));
205     }
206     CONTRACTL_END;
207
208     // Get an index to use.
209     ULONG oldIndex = m_iIndex;
210     ULONG newIndex = oldIndex + 1;
211     if (newIndex >= (ULONG)m_size)
212         newIndex = 0;
213     
214     while ((ULONG)FastInterlockCompareExchange((LONG*)&m_iIndex, newIndex, oldIndex) != oldIndex)
215     {
216         oldIndex = m_iIndex;
217         newIndex = oldIndex + 1;
218         if (newIndex >= (ULONG)m_size)
219             newIndex = 0;
220     }
221
222     // We successfully incremented the index and can use the oldIndex value as our entry.
223     ReplaceEntry(oldIndex, pEntryThunk);
224 }
225
226 void MdaCallbackOnCollectedDelegate::ReplaceEntry(int index, UMEntryThunk* pET)
227 {
228     CONTRACTL
229     {
230         NOTHROW;
231         GC_NOTRIGGER;
232         MODE_ANY;
233         PRECONDITION((index >= 0) && (index < m_size));
234         PRECONDITION(CheckPointer(m_pList));
235     }
236     CONTRACTL_END;
237     
238     if ((m_pList) && (m_size > index) && (index >= 0))
239     {
240         UMEntryThunk* pETTemp = m_pList[index];
241         while (FastInterlockCompareExchangePointer((LPVOID*)&m_pList[index], (LPVOID)pET, (LPVOID)pETTemp) != (LPVOID)pETTemp)
242         {
243             pETTemp = m_pList[index];
244         }
245         
246         if (NULL != pETTemp)
247         {
248             pETTemp->Terminate();
249         }
250     }
251 }
252
253 #ifdef FEATURE_COMINTEROP   
254
255 void MdaInvalidMemberDeclaration::ReportViolation(ComCallMethodDesc *pCMD, OBJECTREF *pExceptionObj)
256 {
257     CONTRACTL
258     {
259         NOTHROW;
260         GC_TRIGGERS;
261         MODE_COOPERATIVE;
262     }
263     CONTRACTL_END;
264
265     EX_TRY
266     {
267         MdaXmlElement* pXml;
268         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
269
270         TypeHandle th;
271         StackSString strMemberName;
272         StackSString strTypeName;
273         StackSString strMessage;
274
275         GetExceptionMessage(*pExceptionObj, strMessage);
276
277         if (pCMD->IsFieldCall())
278         {
279             FieldDesc *pFD = pCMD->GetFieldDesc();
280
281             th = pFD->GetFieldTypeHandleThrowing();
282             strMemberName.SetUTF8(pFD->GetName());
283             AsMdaAssistant()->OutputFieldDesc(pFD, pXml->AddChild(MdaElemDecl(Field)));
284         }
285         else
286         {
287             MethodDesc *pMD = pCMD->GetCallMethodDesc();
288
289             th = TypeHandle(pMD->GetMethodTable());
290             strMemberName.SetUTF8(pMD->GetName());
291             AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));        
292         }
293
294         th.GetName(strTypeName);
295
296         AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
297         AsMdaAssistant()->OutputException(pExceptionObj, pXml->AddChild(MdaElemDecl(Exception)));
298             
299         msg.SendMessagef(MDARC_INVALID_MEMBER_DECLARATION, 
300             strMemberName.GetUnicode(), strTypeName.GetUnicode(), strMessage.GetUnicode());    
301     }
302     EX_CATCH
303     {
304         // Caller cannot take exceptions.
305     }
306     EX_END_CATCH(SwallowAllExceptions);
307 }
308
309 #endif //FEATURE_COMINTEROP
310
311
312 //
313 // MdaExceptionSwallowedOnCallFromCom
314 //
315 void MdaExceptionSwallowedOnCallFromCom::ReportViolation(MethodDesc *pMD, OBJECTREF *pExceptionObj)
316 {
317     CONTRACTL
318     {
319         NOTHROW;
320         GC_TRIGGERS;
321         MODE_ANY;
322     }
323     CONTRACTL_END;
324
325     EX_TRY
326     {
327         StackSString strMessage;
328         StackSString strTypeName;
329         StackSString strMemberName;
330             
331         MdaXmlElement* pXml;
332         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
333
334         TypeHandle th = TypeHandle(pMD->GetMethodTable());
335
336         GetExceptionMessage(*pExceptionObj, strMessage);
337         th.GetName(strTypeName);
338         strMemberName.SetUTF8(pMD->GetName());
339
340         AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));        
341         AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));        
342         AsMdaAssistant()->OutputException(pExceptionObj, pXml->AddChild(MdaElemDecl(Exception)));
343             
344         msg.SendMessagef(MDARC_EXCEPTION_SWALLOWED_COM_TO_CLR, 
345             strMemberName.GetUnicode(), strTypeName.GetUnicode(), strMessage.GetUnicode());    
346     }
347     EX_CATCH
348     {
349         // Caller cannot take exceptions.
350     }
351     EX_END_CATCH(SwallowAllExceptions);
352 }
353    
354     
355 //
356 // MdaInvalidVariant
357 //
358 void MdaInvalidVariant::ReportViolation()
359 {
360     CONTRACTL
361     {
362         THROWS;
363         GC_TRIGGERS;
364         MODE_ANY;
365     }
366     CONTRACTL_END;
367
368     MdaXmlElement* pXml;
369     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
370
371     msg.SendMessagef(MDARC_INVALID_VARIANT);
372 }
373
374
375 //
376 // MdaInvalidIUnknown
377 //
378 void MdaInvalidIUnknown::ReportViolation()
379 {
380     CONTRACTL
381     {
382         THROWS;
383         GC_TRIGGERS;
384         MODE_ANY;
385     }
386     CONTRACTL_END;
387
388     MdaXmlElement* pXml;
389     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
390
391     msg.SendMessagef(MDARC_INVALID_IUNKNOWN);
392 }
393
394
395 //
396 // MdaContextSwitchDeadlock
397 //
398 void MdaContextSwitchDeadlock::ReportDeadlock(LPVOID Origin, LPVOID Destination)
399 {
400     CONTRACTL
401     {
402         NOTHROW;
403         GC_TRIGGERS;
404         MODE_ANY;
405     }
406     CONTRACTL_END;
407
408     if (g_fEEShutDown == 0)
409     {
410         EX_TRY
411         {
412             MdaXmlElement* pXml;
413             MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
414
415             msg.SendMessagef(MDARC_CONTEXT_SWITCH_DEADLOCK, Origin, Destination);
416         }
417         EX_CATCH
418         {
419             // Caller cannot take exceptions.
420         }
421         EX_END_CATCH(SwallowAllExceptions);
422     }
423 }
424
425
426 //
427 // MdaRaceOnRCWCleanup
428 //
429 void MdaRaceOnRCWCleanup::ReportViolation()
430 {
431     CONTRACTL
432     {
433         THROWS;
434         GC_TRIGGERS;
435         MODE_ANY;
436     }
437     CONTRACTL_END;
438
439     MdaXmlElement* pXml;
440     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
441
442     msg.SendMessagef(MDARC_RCW_CLEANUP_RACE);
443 }
444
445
446 //
447 // MdaFailedQI
448 //
449 void MdaFailedQI::ReportAdditionalInfo(HRESULT hr, RCW* pRCW, GUID iid, MethodTable* pMT)
450 {
451     CONTRACTL
452     {
453         THROWS;
454         GC_TRIGGERS;
455         MODE_ANY;
456     }
457     CONTRACTL_END;
458
459     MdaXmlElement* pXml;
460     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
461     TypeHandle th(pMT);
462
463     SafeComHolder<IUnknown> pInnerUnk = pRCW->GetIUnknown(); 
464
465     // We are interested in the case where the QI fails because of wrong context.
466     if (!pRCW->IsFreeThreaded() && GetCurrentCtxCookie() != pRCW->GetWrapperCtxCookie())
467     {
468         // Try to change context and perform the QI in the new context again.
469         MdaFailedQIAssistantCallbackData    data;
470        
471         data.pWrapper   = pRCW;
472         data.iid        = iid;
473
474         pRCW->EnterContext(MdaFailedQIAssistantCallback, &data);
475         if (data.fSuccess)
476         {
477             // QI succeeds in the other context, i.e. the original QI fails because of wrong context.
478             pXml = AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
479
480             // Stringize IID
481             WCHAR strNativeItfIID[39];
482             StringFromGUID2(iid, strNativeItfIID, sizeof(strNativeItfIID) / sizeof(WCHAR));
483
484             // Map HRESULT to a message
485             StackSString sszHR2Description;
486             GetHRMsg(hr, sszHR2Description);
487
488             // Format the HRESULT as a string
489             StackSString sszHR2Hex;
490             sszHR2Hex.Printf("%.8x", hr);
491
492             StackSString sszTypeName;
493             th.GetName(sszTypeName);
494             
495             msg.SendMessagef(MDARC_FAILED_QI, sszTypeName.GetUnicode(), strNativeItfIID, sszHR2Hex.GetUnicode(), sszHR2Description.GetUnicode());
496         }
497     }
498     else if (hr == E_NOINTERFACE)
499     {
500
501         // BUG: You'd have to check the registry to ensure that the proxy stub it's not actually there as opposed to the 
502         // COM object QI simply returning a failure code.
503     
504     /*
505         // Check if pInnerUnk is actually pointing to a proxy, i.e. that it is pointing to an address
506         // within the loaded ole32.dll image.  Note that WszGetModuleHandle does not increment the 
507         // ref count.
508         HINSTANCE hModOle32 = WszGetModuleHandle(OLE32DLL);
509         if (hModOle32 && IsIPInModule(hModOle32, (BYTE *)(*(BYTE **)(IUnknown*)pInnerUnk)))
510         {
511             pXml = AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
512
513             WCHAR strGuid[40];
514             GuidToLPWSTR(iid, strGuid, 40);
515             msg.SendMessagef(MDARC_FAILED_QI, strGuid);
516         }
517    */
518     }
519 }
520
521 HRESULT MdaFailedQIAssistantCallback(LPVOID pData)
522 {
523     CONTRACTL
524     {
525         NOTHROW;
526         GC_TRIGGERS;
527         MODE_PREEMPTIVE;
528         PRECONDITION(CheckPointer(pData));
529     }
530     CONTRACTL_END;
531     
532     HRESULT                 hr = E_FAIL;
533
534     BEGIN_EXTERNAL_ENTRYPOINT(&hr)
535     {
536         SafeComHolder<IUnknown> pDummyUnk;
537         
538         MdaFailedQIAssistantCallbackData    *pCallbackData = (MdaFailedQIAssistantCallbackData *)pData;
539         
540         // Initialize the fSuccess flag to false until we know for a fact the QI will succeed.
541         pCallbackData->fSuccess = FALSE;
542         
543         // QI for the requested interface.
544         hr = pCallbackData->pWrapper->SafeQueryInterfaceRemoteAware(pCallbackData->iid, &pDummyUnk);
545         
546         // If the QI call succeded then set the fSuccess flag to true.
547         if (SUCCEEDED(hr))
548             pCallbackData->fSuccess = TRUE;
549     }
550     END_EXTERNAL_ENTRYPOINT;
551     
552     return S_OK;        // Need to return S_OK so that the assert in CtxEntry::EnterContext() won't fire.
553 }
554
555 //
556 // MdaDisconnectedContext
557 //
558 void MdaDisconnectedContext::ReportViolationDisconnected(LPVOID context, HRESULT hr)
559 {
560     CONTRACTL
561     {
562         THROWS;
563         GC_TRIGGERS;
564         MODE_ANY;
565     }
566     CONTRACTL_END;
567
568     if (g_fEEShutDown == 0)
569     {
570         MdaXmlElement* pXml;
571         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
572
573         StackSString strHRMsg;
574         GetHRMsg(hr, strHRMsg);
575         
576         msg.SendMessagef(MDARC_DISCONNECTED_CONTEXT_1, context, strHRMsg.GetUnicode());
577     }
578 }
579
580 void MdaDisconnectedContext::ReportViolationCleanup(LPVOID context1, LPVOID context2, HRESULT hr)
581 {
582     CONTRACTL
583     {
584         NOTHROW;
585         GC_TRIGGERS;
586         MODE_ANY;
587     }
588     CONTRACTL_END;
589
590     if (g_fEEShutDown == 0)
591     {
592         EX_TRY
593         {
594             MdaXmlElement* pXml;
595             MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
596
597             StackSString strHRMsg;
598             GetHRMsg(hr, strHRMsg);
599
600             msg.SendMessagef(MDARC_DISCONNECTED_CONTEXT_2, context1, strHRMsg.GetUnicode(), context2);        
601         }
602         EX_CATCH
603         {
604             // Caller cannot take exceptions.
605         }
606         EX_END_CATCH(SwallowAllExceptions)
607     }
608 }
609
610
611 //
612 // MdaInvalidApartmentStateChange
613 //
614 void MdaInvalidApartmentStateChange::ReportViolation(Thread* pThread, Thread::ApartmentState newstate, BOOL fAlreadySet)
615 {
616     CONTRACTL
617     {
618         NOTHROW;
619         GC_TRIGGERS;
620         MODE_ANY;
621     }
622     CONTRACTL_END;
623     
624     EX_TRY
625     {
626         MdaXmlElement* pXml;
627         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
628
629         AsMdaAssistant()->OutputThread(pThread, pXml->AddChild(MdaElemDecl(Thread)));
630
631         if (fAlreadySet)
632         {
633             if (newstate == Thread::AS_InSTA)
634             {
635                 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_SET, W("STA"), W("MTA"));
636             }
637             else
638             {
639                 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_SET, W("MTA"), W("STA"));
640             }
641         }
642         else
643         {
644             if (newstate == Thread::AS_InSTA)
645             {
646                 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_NOTSET, W("STA"), W("MTA"));
647             }
648             else
649             {
650                 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_NOTSET, W("MTA"), W("STA"));
651             }
652         }
653     }
654     EX_CATCH
655     {
656         // Caller cannot take exceptions.
657     }
658     EX_END_CATCH(SwallowAllExceptions);
659 }
660     
661 //
662 // MdaDllMainReturnsFalse
663 //
664 void MdaDllMainReturnsFalse::ReportError()
665 {
666     CONTRACTL
667     {
668         THROWS;
669         GC_TRIGGERS;
670         MODE_ANY;
671     }
672     CONTRACTL_END;
673
674     MdaXmlElement* pXml;
675     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
676
677     msg.SendMessagef(MDARC_DLLMAIN_RETURNS_FALSE);
678 }
679
680 //
681 // MdaOverlappedFreeError
682 //
683 void MdaOverlappedFreeError::ReportError(LPVOID pOverlapped)
684 {
685     CONTRACTL
686     {
687         THROWS;
688         GC_TRIGGERS;
689         MODE_ANY;
690     }
691     CONTRACTL_END;
692
693     MdaXmlElement* pXml;
694     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
695
696     msg.SendMessagef(MDARC_INVALID_OVERLAPPED_FREE,
697             pOverlapped);
698 }
699
700 //
701 // MdaInvalidOverlappedToPinvoke
702 //
703
704 // NOTE: the overlapped pointer needs to be named "overlapped". 
705 // It is embedded in the (Args) and (ArgsUsed) sections.
706
707
708 #define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed)                        \
709     DllName##_##Name,
710 enum {
711 #include "invalidoverlappedwrappers.h"
712 };
713 #undef CREATE_WRAPPER_FUNCTION
714
715 #define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed)                               \
716 Return Flags Mda_##Name Args                                                                                \
717 {                                                                                                           \
718     CONTRACTL                                                                                               \
719     {                                                                                                       \
720         THROWS;                                                                                             \
721         GC_TRIGGERS;                                                                                        \
722         MODE_ANY;                                                                                           \
723     }                                                                                                       \
724     CONTRACTL_END;                                                                                          \
725     Return (Flags *old##Name) Args;                                                                         \
726     MdaInvalidOverlappedToPinvoke *pOverlapCheck = MDA_GET_ASSISTANT(InvalidOverlappedToPinvoke);           \
727     _ASSERTE(pOverlapCheck);                                                                                \
728     *(PVOID *)&(old##Name) = pOverlapCheck->CheckOverlappedPointer(DllName##_##Name, (LPVOID) overlapped);  \
729     return old##Name ArgsUsed;                                                                              \
730 }
731 #include "invalidoverlappedwrappers.h"
732 #undef CREATE_WRAPPER_FUNCTION
733
734 #define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed)    \
735     { L#DllName W(".DLL"), L#Name, Mda_##Name, NULL, NULL },
736 static MdaInvalidOverlappedToPinvoke::pinvoke_entry PInvokeTable[] = {
737 #include "invalidoverlappedwrappers.h"
738 };
739 #undef CREATE_WRAPPER_FUNCTION
740
741 void MdaInvalidOverlappedToPinvoke::Initialize(MdaXmlElement* pXmlInput)
742 {
743     CONTRACTL
744     {
745         THROWS;
746         GC_TRIGGERS;
747         MODE_ANY;
748     }
749     CONTRACTL_END;
750
751     m_entries = PInvokeTable;
752     m_entryCount = sizeof(PInvokeTable) / sizeof(pinvoke_entry);
753     m_bJustMyCode = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(JustMyCode));    
754 }
755
756 BOOL MdaInvalidOverlappedToPinvoke::InitializeModuleFunctions(HINSTANCE hmod)
757 {
758     CONTRACTL
759     {
760         THROWS;
761         GC_TRIGGERS;
762         MODE_ANY;
763     }
764     CONTRACTL_END;
765
766     // For every entry where m_moduleName matches moduleName, fill in m_hmod with hmod
767     // and fill in the m_realFunction pointer.
768
769     BOOL bFoundSomething = FALSE;
770
771     SString moduleNameFullPath, moduleName;
772     ClrGetModuleFileNameNoThrow(hmod,moduleNameFullPath);
773     // Strip any path info
774     SString::CIterator iM = moduleNameFullPath.End();
775     if (moduleNameFullPath.FindBack(iM, W('\\')))
776     {
777         iM++;
778         moduleName.Set(moduleNameFullPath, iM, moduleNameFullPath.End());
779     }
780
781     for (UINT i=0; i<m_entryCount; i++)
782     {
783         if (SString::_wcsicmp(m_entries[i].m_moduleName, moduleName.GetUnicode()) == 0)
784         {
785             if (m_entries[i].m_hmod == NULL)
786             {
787                 SString moduleNameForLookup(m_entries[i].m_functionName);
788                 StackScratchBuffer ansiVersion;                
789                 m_entries[i].m_realFunction = GetProcAddress(hmod, moduleNameForLookup.GetANSI(ansiVersion));
790                 m_entries[i].m_hmod = hmod;                
791             }
792             bFoundSomething = TRUE;
793         }
794     }
795
796     return bFoundSomething;
797 }
798
799 LPVOID MdaInvalidOverlappedToPinvoke::CheckOverlappedPointer(UINT index, LPVOID pOverlapped)
800 {
801     CONTRACTL
802     {
803         THROWS;
804         GC_TRIGGERS;
805         MODE_ANY;
806     }
807     CONTRACTL_END;
808
809     MdaInvalidOverlappedToPinvoke::pinvoke_entry *pEntry = m_entries + index;
810
811     // pEntry should always be non-NULL, because we got the address of pvMdaFunction
812     // from the entries table in the first place.
813     _ASSERTE(pEntry);
814     if (pEntry == NULL)
815     {
816         return NULL;
817     }
818
819     // Is the overlapped pointer in the gc heap?
820     if (pOverlapped != NULL)
821     {
822         BOOL fHeapPointer;
823
824         {
825             GCX_COOP();
826             IGCHeap *pHeap = GCHeapUtilities::GetGCHeap();
827             fHeapPointer = pHeap->IsHeapPointer(pOverlapped);
828         }
829
830         if (!fHeapPointer)
831         {
832             // Output a message
833             MdaXmlElement* pXml;
834             MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
835
836             msg.SendMessagef(MDARC_INVALID_OVERLAPPED_TO_PINVOKE, 
837                 pOverlapped, 
838                 pEntry->m_functionName,
839                 pEntry->m_moduleName);
840         }
841     }
842     
843     return pEntry->m_realFunction;
844 }
845
846 // We want to hook the functions where it is in the user's code only, unless
847 // the attribute JustMyCode is set to false. In that case, we want all 
848 // occurances.
849 BOOL MdaInvalidOverlappedToPinvoke::ShouldHook(MethodDesc *pMD)
850 {
851     LIMITED_METHOD_CONTRACT;
852     return (m_bJustMyCode ? IsJustMyCode(pMD) : TRUE);
853 }
854
855 LPVOID MdaInvalidOverlappedToPinvoke::Register(HINSTANCE hmod,LPVOID pvTarget)
856 {
857     CONTRACTL
858     {
859         THROWS;
860         GC_TRIGGERS;
861         MODE_ANY;
862     }
863     CONTRACTL_END;
864
865     // Quick lookup - do we have a matching target?
866     // walk our entries, looking for a match.
867     BOOL bNullModules = FALSE;
868     BOOL bSeenThisModule = FALSE;
869     
870     for (UINT i=0; i<m_entryCount; i++)
871     {
872         MdaInvalidOverlappedToPinvoke::pinvoke_entry *pEntry = m_entries + i;
873         if (pvTarget == pEntry->m_realFunction)
874         {
875             return pEntry->m_mdaFunction;
876         }
877         
878         bNullModules |= (pEntry->m_hmod == NULL);
879         bSeenThisModule |= (pEntry->m_hmod == hmod);
880     }
881     
882     // if we have some NULL targets, do we have a matching hmod?
883     // if so, 
884     if (bNullModules && !bSeenThisModule)
885     {
886         if (InitializeModuleFunctions(hmod))
887         {
888             // Search once more
889             for (UINT i=0; i<m_entryCount; i++)
890             {
891                 pinvoke_entry *pEntry = m_entries + i;
892                 if (pvTarget == pEntry->m_realFunction)
893                 {
894                     return pEntry->m_mdaFunction;
895                 }                
896             }
897         }
898     }
899
900     return NULL;
901 }
902
903 //
904 // MdaPInvokeLog
905 //
906 BOOL MdaPInvokeLog::Filter(SString& sszDllName)
907 {
908     CONTRACTL
909     {
910         THROWS;
911         GC_TRIGGERS;
912         MODE_ANY;
913     }
914     CONTRACTL_END;
915
916     MdaXmlElement* pXmlFilter = m_pXmlInput->GetChild(MdaElemDecl(Filter));  
917     if (!pXmlFilter)
918         return TRUE;
919
920     BOOL bFound = FALSE;
921     for (COUNT_T i = 0; i < pXmlFilter->GetChildren().GetCount(); i ++)
922     {
923         if (pXmlFilter->GetChildren()[i]->GetAttribute(MdaAttrDecl(DllName))->GetValueAsCSString()->EqualsCaseInsensitive(sszDllName))
924         {
925             bFound = TRUE;
926             break;
927         }
928     }
929
930    return bFound;
931 }
932
933 void MdaPInvokeLog::LogPInvoke(NDirectMethodDesc* pMD, HINSTANCE hMod)
934 {   
935     CONTRACTL
936     {
937         NOTHROW;
938         GC_TRIGGERS;
939         MODE_ANY;
940     }
941     CONTRACTL_END;
942
943     EX_TRY
944     {
945         StackSString sszEntryPoint;
946         sszEntryPoint.SetUTF8(pMD->GetEntrypointName());
947
948         PathString szDllFullName ;
949         WCHAR szDrive[_MAX_PATH] = {0};
950         WCHAR szPath[_MAX_PATH] = {0};
951         WCHAR szFileName[_MAX_PATH] = {0};
952         WCHAR szExt[_MAX_PATH] = {0};
953         WszGetModuleFileName(hMod, szDllFullName);      
954         SplitPath(szDllFullName, szDrive, _MAX_PATH, szPath, _MAX_PATH, szFileName, _MAX_PATH, szExt, _MAX_PATH);
955
956         StackSString sszDllName;
957         sszDllName.Append(szFileName);
958         if (szExt)
959             sszDllName.Append(szExt);
960
961         if (Filter(sszDllName))
962         {
963             MdaXmlElement* pXml;
964             MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
965             
966             MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
967             AsMdaAssistant()->OutputMethodDesc(pMD, pMethod);
968
969             MdaXmlElement* pDllImport = pXml->AddChild(MdaElemDecl(DllImport));
970             pDllImport->AddAttributeSz(MdaAttrDecl(DllName), szDllFullName);
971             pDllImport->AddAttributeSz(MdaAttrDecl(EntryPoint), sszEntryPoint.GetUnicode());
972
973             msg.SendMessage();    
974         }
975     }
976     EX_CATCH
977     {
978         // Caller cannot take exceptions.
979     }
980     EX_END_CATCH(SwallowAllExceptions);
981 }
982
983
984 #ifdef _TARGET_X86_    
985 //
986 // MdaPInvokeStackImbalance
987 //
988 void MdaPInvokeStackImbalance::CheckStack(StackImbalanceCookie *pSICookie, DWORD dwPostEsp)
989 {
990     CONTRACTL
991     {
992         THROWS;
993         GC_TRIGGERS;
994         MODE_ANY;
995     }
996     CONTRACTL_END;
997
998     DWORD dwEspAfterPushedArgs = pSICookie->m_dwSavedEsp;
999     DWORD dwEspBeforePushedArgs = dwEspAfterPushedArgs + pSICookie->m_dwStackArgSize;
1000     BOOL bStackImbalance = false;
1001
1002     // Note: We use relaxed rules here depending on the NetFx40_PInvokeStackResilience compat switch in order to mimic 2.0 behavior.
1003     switch (pSICookie->m_callConv & pmCallConvMask)
1004     {
1005         // Caller cleans stack
1006         case pmCallConvCdecl:
1007             if (dwPostEsp != dwEspAfterPushedArgs)
1008             {
1009                 if (dwPostEsp != dwEspBeforePushedArgs)
1010                 {
1011                     bStackImbalance = true;
1012                 }
1013                 else
1014                 {
1015                     // If NetFx40_PInvokeStackResilience is on, ignore the case where we see that the callee cleaned the stack.
1016                     BOOL fPreV4Method = pSICookie->m_pMD->GetModule()->IsPreV4Assembly();
1017                     if (!g_pConfig->PInvokeRestoreEsp(fPreV4Method))
1018                         bStackImbalance = true;
1019                 }
1020             }
1021             break;
1022
1023         // Callee cleans stack
1024         case pmCallConvThiscall:
1025         case pmCallConvWinapi:
1026         case pmCallConvStdcall:
1027             if (dwPostEsp != dwEspBeforePushedArgs)
1028             {
1029                 if (dwPostEsp != dwEspAfterPushedArgs)
1030                 {
1031                     bStackImbalance = true;
1032                 }
1033                 else
1034                 {
1035                     // If NetFx40_PInvokeStackResilience is on, ignore the case where we see that the callee did not clean the stack
1036                     BOOL fPreV4Method = pSICookie->m_pMD->GetModule()->IsPreV4Assembly();
1037                     if (!g_pConfig->PInvokeRestoreEsp(fPreV4Method))
1038                         bStackImbalance = true;
1039                 }
1040             }
1041             break;
1042
1043         // Unsupported calling convention
1044         case pmCallConvFastcall:
1045         default:
1046             _ASSERTE(!"Unsupported calling convention");
1047             break;
1048     }
1049         
1050     if (!bStackImbalance)
1051         return;
1052
1053     MdaXmlElement* pXml;
1054     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1055     MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
1056     AsMdaAssistant()->OutputMethodDesc(pSICookie->m_pMD, pMethod);
1057     
1058     StackSString sszMethodName;
1059     msg.SendMessagef(MDARC_PINVOKE_SIGNATURE_MISMATCH, AsMdaAssistant()->ToString(sszMethodName, pSICookie->m_pMD).GetUnicode());
1060 }
1061 #endif
1062
1063     
1064 //
1065 // MdaJitCompilationStart
1066 //
1067 void MdaJitCompilationStart::Initialize(MdaXmlElement* pXmlInput)
1068 {
1069     CONTRACTL
1070     {
1071         THROWS;
1072         GC_TRIGGERS;
1073         MODE_ANY;
1074     }
1075     CONTRACTL_END;
1076
1077     m_bBreak = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(Break));
1078     MdaXmlElement* pXmlMethodFilter = pXmlInput->GetChild(MdaElemDecl(Methods));
1079     m_pMethodFilter = NULL;
1080
1081     if (pXmlMethodFilter)
1082     {
1083         m_pMethodFilter = new MdaQuery::CompiledQueries();
1084         MdaQuery::Compile(pXmlMethodFilter, m_pMethodFilter);
1085     }
1086 }
1087
1088 void MdaJitCompilationStart::NowCompiling(MethodDesc* pMD)
1089 {
1090     CONTRACTL
1091     {
1092         THROWS;
1093         GC_TRIGGERS;
1094         MODE_ANY;
1095     }
1096     CONTRACTL_END;
1097
1098     if (m_pMethodFilter && !m_pMethodFilter->Test(pMD))
1099         return;
1100
1101     MdaXmlElement* pXml;
1102     MdaXmlMessage msg(this->AsMdaAssistant(), m_bBreak, &pXml);
1103     
1104     MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
1105     AsMdaAssistant()->OutputMethodDesc(pMD, pMethod);
1106     
1107     msg.SendMessage();
1108 }
1109
1110 //
1111 // MdaLoadFromContext
1112 //
1113 void MdaLoadFromContext::NowLoading(IAssembly** ppIAssembly, StackCrawlMark *pCallerStackMark)
1114 {
1115     CONTRACTL
1116     {
1117         THROWS;
1118         GC_TRIGGERS;
1119         MODE_ANY;
1120     }
1121     CONTRACTL_END;
1122
1123     if (ppIAssembly && *ppIAssembly) {
1124
1125         // Send an MDA if this assembly was loaded in the LoadFrom context
1126         if ((*ppIAssembly)->GetFusionLoadContext() == LOADCTX_TYPE_LOADFROM) {
1127              // Apply MDA filtering
1128             if (g_pDebugInterface && pCallerStackMark && ManagedDebuggingAssistants::IsManagedDebuggerAttached()) {
1129                 MethodDesc *pMethodDesc = NULL;
1130                 {
1131                     GCX_COOP();
1132                     pMethodDesc = SystemDomain::GetCallersMethod(pCallerStackMark, NULL);
1133                 }
1134                 if (pMethodDesc && !g_pDebugInterface->IsJMCMethod(pMethodDesc->GetModule(), pMethodDesc->GetMemberDef()))
1135                     return;
1136             }
1137
1138             MdaXmlElement *pXml;
1139             MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1140
1141             MdaXmlElement *pXmlAssembly = pXml->AddChild(MdaElemDecl(AssemblyInfo));
1142             
1143             StackSString sszAssemblyName;
1144             StackSString sszCodeBase;
1145             SafeComHolder<IAssemblyName> pNameDef;
1146
1147             if (FAILED((*ppIAssembly)->GetAssemblyNameDef(&pNameDef))) {
1148                 return;
1149             }
1150
1151             if ((!FusionBind::GetAssemblyNameStringProperty(pNameDef, ASM_NAME_NAME, sszAssemblyName)) ||
1152                 (!FusionBind::GetAssemblyNameStringProperty(pNameDef, ASM_NAME_CODEBASE_URL, sszCodeBase))) {
1153                 return;
1154             }
1155             
1156             pXmlAssembly->AddAttributeSz(MdaAttrDecl(DisplayName), sszAssemblyName.GetUnicode());
1157             pXmlAssembly->AddAttributeSz(MdaAttrDecl(CodeBase), sszCodeBase.GetUnicode());
1158                    
1159             msg.SendMessagef(MDARC_LOAD_FROM_CONTEXT, sszAssemblyName.GetUnicode(), sszCodeBase.GetUnicode());
1160         }
1161     }
1162 }
1163
1164 const LPCWSTR ContextIdName[] =
1165 {
1166     W("Load"),
1167     W("LoadFrom"),
1168     W("Anonymous")
1169 };
1170
1171 //
1172 // MdaBindingFailure
1173 //
1174 void MdaBindingFailure::BindFailed(AssemblySpec *pSpec, OBJECTREF *pExceptionObj)
1175 {
1176     CONTRACTL
1177     {
1178         THROWS;
1179         GC_TRIGGERS;
1180         MODE_ANY;
1181     }
1182     CONTRACTL_END;
1183
1184     MdaXmlElement *pXml;
1185     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1186
1187     MdaXmlElement *pXmlAssembly = pXml->AddChild(MdaElemDecl(AssemblyInfo));
1188
1189     DWORD dwAppDomainId;
1190     SString sszAssemblyName;
1191     SString sszCodeBase;
1192     SString sszMessage;
1193     int iBindingContext;
1194     HRESULT hr;
1195
1196     // determine AppDomain ID
1197     AppDomain *appDomain = pSpec->GetAppDomain();
1198     if (appDomain) {     
1199         dwAppDomainId = appDomain->GetId().m_dwId;
1200     } else {
1201         dwAppDomainId = 0;
1202     }
1203     pXmlAssembly->AddAttributeInt(MdaAttrDecl(AppDomainId), dwAppDomainId);
1204
1205     // determine Assembly display name
1206     LPCSTR assemblyName = pSpec->GetName();
1207     if (assemblyName && assemblyName[0]) {
1208         sszAssemblyName.SetASCII(assemblyName);
1209     }
1210     pXmlAssembly->AddAttributeSz(MdaAttrDecl(DisplayName), sszAssemblyName.GetUnicode());
1211
1212     // determine Assembly code base
1213     if (pSpec->GetCodeBase() && pSpec->GetCodeBase()[0]) {
1214         sszCodeBase.Set(pSpec->GetCodeBase());
1215     }
1216     pXmlAssembly->AddAttributeSz(MdaAttrDecl(CodeBase), sszCodeBase.GetUnicode());
1217
1218     // retrieve the exception message.
1219     GetExceptionMessage(*pExceptionObj, sszMessage);
1220
1221     // determine failing HRESULT  
1222     hr = GetExceptionHResult(*pExceptionObj);
1223     pXmlAssembly->AddAttributeInt(MdaAttrDecl(HResult), hr);
1224
1225     // determine binding context Assembly would have been loaded in (based on parent)
1226     IAssembly* pParentAssembly = pSpec->GetParentIAssembly();
1227     if (pParentAssembly) {
1228         iBindingContext = pParentAssembly->GetFusionLoadContext();
1229     } else {
1230
1231         // if the parent hasn't been set but the code base has, it's in LoadFrom
1232         iBindingContext = LOADCTX_TYPE_LOADFROM;
1233     }
1234     pXmlAssembly->AddAttributeInt(MdaAttrDecl(BindingContextId), iBindingContext);
1235
1236     // Make sure the binding context ID isn't larger then our ID to name lookup table.
1237     _ASSERTE(iBindingContext < COUNTOF(ContextIdName));
1238     
1239     if (sszAssemblyName.IsEmpty())
1240     {
1241         _ASSERTE(!sszCodeBase.IsEmpty());
1242         msg.SendMessagef(MDARC_BINDING_FAILURE_CODEBASE_ONLY, sszCodeBase.GetUnicode(), 
1243                          ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1244     }
1245     else if (sszCodeBase.IsEmpty())
1246     {
1247         _ASSERTE(!sszAssemblyName.IsEmpty());
1248         msg.SendMessagef(MDARC_BINDING_FAILURE_DISPLAYNAME_ONLY, sszAssemblyName.GetUnicode(),  
1249                          ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1250     }
1251     else 
1252     {
1253         msg.SendMessagef(MDARC_BINDING_FAILURE, sszAssemblyName.GetUnicode(), sszCodeBase.GetUnicode(), 
1254                          ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1255     }
1256 }
1257
1258 //
1259 // MdaNotMarshalable
1260 //
1261 void MdaNotMarshalable::ReportViolation()
1262 {
1263     CONTRACTL
1264     {
1265         THROWS;
1266         GC_TRIGGERS;
1267         MODE_ANY;
1268     }
1269     CONTRACTL_END;
1270
1271     MdaXmlElement* pXml;
1272     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1273
1274     msg.SendMessagef(MDARC_NOTMARSHALABLE);
1275 }
1276
1277
1278 //
1279 // MdaMarshalCleanupError
1280 //
1281 void MdaMarshalCleanupError::ReportErrorThreadCulture(OBJECTREF *pExceptionObj)
1282 {
1283     CONTRACTL
1284     {
1285         NOTHROW;
1286         GC_TRIGGERS;
1287         MODE_ANY;
1288     }
1289     CONTRACTL_END;
1290
1291     EX_TRY
1292     {
1293         MdaXmlElement* pXml;
1294         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1295
1296         // retrieve the exception message.
1297         SString sszMessage;
1298         GetExceptionMessage(*pExceptionObj, sszMessage);
1299
1300         msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_THREADCULTURE, sszMessage.GetUnicode());
1301     }
1302     EX_CATCH
1303     {
1304     }
1305     EX_END_CATCH(SwallowAllExceptions);
1306 }
1307
1308 void MdaMarshalCleanupError::ReportErrorSafeHandleProp(OBJECTREF *pExceptionObj)
1309 {
1310     CONTRACTL
1311     {
1312         NOTHROW;
1313         GC_TRIGGERS;
1314         MODE_ANY;
1315     }
1316     CONTRACTL_END;
1317
1318     EX_TRY
1319     {
1320         MdaXmlElement* pXml;
1321         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1322
1323         // retrieve the exception message.
1324         SString sszMessage;
1325         GetExceptionMessage(*pExceptionObj, sszMessage);
1326
1327         msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_SAFEHANDLEPROP, sszMessage.GetUnicode());
1328     }
1329     EX_CATCH
1330     {
1331     }
1332     EX_END_CATCH(SwallowAllExceptions);
1333 }
1334
1335 void MdaMarshalCleanupError::ReportErrorCustomMarshalerCleanup(TypeHandle typeCustomMarshaler, OBJECTREF *pExceptionObj)
1336 {
1337     CONTRACTL
1338     {
1339         NOTHROW;
1340         GC_TRIGGERS;
1341         MODE_ANY;
1342     }
1343     CONTRACTL_END;
1344
1345     EX_TRY
1346     {
1347             
1348         MdaXmlElement* pXml;
1349         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1350
1351         // retrieve the exception message.
1352         SString sszMessage;
1353         GetExceptionMessage(*pExceptionObj, sszMessage);
1354
1355         // Retrieve the type name.
1356         StackSString sszType;
1357         typeCustomMarshaler.GetName(sszType);
1358
1359         msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_CUSTOMCLEANUP, sszType.GetUnicode(), sszMessage.GetUnicode());
1360     }
1361     EX_CATCH
1362     {
1363     }
1364     EX_END_CATCH(SwallowAllExceptions);
1365 }
1366
1367 //
1368 // MdaLoaderLock
1369 //
1370 void MdaLoaderLock::ReportViolation(HINSTANCE hInst)
1371 {
1372     CONTRACTL
1373     {
1374         NOTHROW;
1375         GC_TRIGGERS;
1376         MODE_ANY;
1377     }
1378     CONTRACTL_END;
1379
1380     EX_TRY
1381     {
1382         MdaXmlElement* pXml;
1383         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1384
1385         DWORD cName = 0;
1386         PathString szName;
1387         if (hInst)
1388         {
1389             cName = WszGetModuleFileName(hInst, szName);
1390         }
1391
1392         if (cName)
1393         {
1394             msg.SendMessagef(MDARC_LOADER_LOCK_DLL, szName);
1395         }
1396         else
1397         {
1398             msg.SendMessagef(MDARC_LOADER_LOCK);
1399         }
1400     }
1401     EX_CATCH
1402     {
1403         // Caller cannot take exceptions.
1404     }
1405     EX_END_CATCH(SwallowAllExceptions);
1406 }
1407
1408
1409 //
1410 // MdaReentrancy
1411 //
1412 void MdaReentrancy::ReportViolation()
1413 {
1414     CONTRACTL
1415     {
1416         NOTHROW;
1417         GC_TRIGGERS;
1418         MODE_ANY;
1419     }
1420     CONTRACTL_END;
1421
1422     EX_TRY
1423     {
1424         MdaXmlElement* pXml;
1425         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1426
1427         msg.SendMessagef(MDARC_REENTRANCY);
1428     }
1429     EX_CATCH
1430     {
1431         // Caller cannot take exceptions.
1432     }
1433     EX_END_CATCH(SwallowAllExceptions);
1434 }
1435
1436 //
1437 // MdaAsynchronousThreadAbort
1438 //
1439 void MdaAsynchronousThreadAbort::ReportViolation(Thread *pCallingThread, Thread *pAbortedThread)
1440 {
1441     CONTRACTL
1442     {
1443         NOTHROW;
1444         GC_TRIGGERS;
1445         MODE_ANY;
1446     }
1447     CONTRACTL_END;
1448
1449     EX_TRY
1450     {
1451         MdaXmlElement* pXml;
1452         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1453
1454         AsMdaAssistant()->OutputThread(pCallingThread, pXml->AddChild(MdaElemDecl(CallingThread)));
1455         AsMdaAssistant()->OutputThread(pAbortedThread, pXml->AddChild(MdaElemDecl(AbortedThread)));
1456
1457         msg.SendMessagef(MDARC_ASYNCHRONOUS_THREADABORT, pCallingThread->GetOSThreadId(), pAbortedThread->GetOSThreadId());
1458     }
1459     EX_CATCH
1460     {
1461         // Caller cannot take exceptions.
1462     }
1463     EX_END_CATCH(SwallowAllExceptions);
1464 }
1465
1466     
1467 //
1468 // MdaAsynchronousThreadAbort
1469 //
1470 void MdaDangerousThreadingAPI::ReportViolation(__in_z WCHAR *apiName)
1471 {
1472     CONTRACTL
1473     {
1474         THROWS;
1475         GC_TRIGGERS;
1476         MODE_ANY;
1477     }
1478     CONTRACTL_END;
1479
1480     MdaXmlElement* pXml;
1481     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1482
1483     msg.SendMessagef(MDARC_DANGEROUS_THREADINGAPI, apiName);
1484 }
1485
1486     
1487 //
1488 // MdaReportAvOnComRelease
1489 //
1490
1491 void MdaReportAvOnComRelease::ReportHandledException(RCW* pRCW)
1492 {
1493     CONTRACTL
1494     {
1495         NOTHROW;
1496         GC_TRIGGERS;
1497         MODE_ANY;
1498     }
1499     CONTRACTL_END;
1500
1501     EX_TRY
1502     {
1503         FAULT_NOT_FATAL();
1504     
1505         // TODO: comment this code...
1506         MdaXmlElement* pXml;
1507         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1508
1509         if (pRCW)
1510         {
1511             LPVOID vtablePtr = pRCW->GetVTablePtr();
1512             msg.SendMessagef(MDARC_REPORT_AV_ON_COM_RELEASE_WITH_VTABLE, vtablePtr);
1513         }
1514         else
1515         {
1516             msg.SendMessagef(MDARC_REPORT_AV_ON_COM_RELEASE);
1517         }
1518     }
1519     EX_CATCH
1520     {
1521         // Caller cannot take exceptions.
1522     }
1523     EX_END_CATCH(SwallowAllExceptions);
1524 }
1525
1526 void MdaInvalidFunctionPointerInDelegate::ReportViolation(LPVOID pFunc)
1527 {
1528     CONTRACTL
1529     {
1530         THROWS;
1531         GC_TRIGGERS;
1532         MODE_ANY;
1533     }
1534     CONTRACTL_END;
1535
1536     MdaXmlElement* pXml;
1537     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1538
1539     msg.SendMessagef(MDARC_INVALID_FUNCTION_PTR_IN_DELEGATE, pFunc);
1540 }
1541
1542 //
1543 // MdaDirtyCastAndCallOnInterface
1544 //
1545
1546 void MdaDirtyCastAndCallOnInterface::ReportViolation(IUnknown* pUnk)
1547 {
1548     CONTRACTL
1549     {
1550         THROWS;
1551         GC_TRIGGERS;
1552         MODE_ANY;
1553     }
1554     CONTRACTL_END;
1555
1556     MdaXmlElement* pXml;
1557     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1558
1559     msg.SendMessagef(MDARC_DIRTY_CAST_AND_CALL_ON_INTERFACE);
1560 }
1561
1562 //
1563 // MdaFatalExecutionEngineError
1564 //
1565 void MdaFatalExecutionEngineError::ReportFEEE(TADDR addrOfError, HRESULT hrError)
1566 {
1567     CONTRACTL
1568     {
1569         NOTHROW;
1570         GC_TRIGGERS;
1571         MODE_ANY;
1572     }
1573     CONTRACTL_END;
1574
1575     EX_TRY
1576     {
1577         MdaXmlElement* pXml;
1578         MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1579
1580         DWORD tid = GetCurrentThreadId();
1581
1582         msg.SendMessagef(MDARC_FATAL_EXECUTION_ENGINE_ERROR, addrOfError, tid, hrError);        
1583     }
1584     EX_CATCH
1585     {
1586         // Caller cannot take exceptions.
1587     }
1588     EX_END_CATCH(SwallowAllExceptions);
1589 }
1590
1591
1592 //
1593 // MdaInvalidCERCall
1594 //
1595 void MdaInvalidCERCall::ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset)
1596 {
1597     CONTRACTL
1598     {
1599         THROWS;
1600         GC_TRIGGERS;
1601         MODE_ANY;
1602     }
1603     CONTRACTL_END;
1604
1605     MdaXmlElement* pXml;
1606     MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1607
1608     AsMdaAssistant()->OutputMethodDesc(pCalleeMD, pXml->AddChild(MdaElemDecl(Method)));
1609     AsMdaAssistant()->OutputCallsite(pCallerMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
1610
1611     StackSString sszCalleeMethodName(SString::Utf8, pCalleeMD->GetName());
1612     StackSString sszCallerMethodName(SString::Utf8, pCallerMD->GetName());
1613     msg.SendMessagef(MDARC_INVALID_CER_CALL, sszCallerMethodName.GetUnicode(), dwOffset, sszCalleeMethodName.GetUnicode());
1614 }
1615
1616
1617 //
1618 // MdaVirtualCERCall
1619 //
1620 void MdaVirtualCERCall::ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset)
1621 {
1622     CONTRACTL
1623     {
1624         THROWS;
1625         GC_TRIGGERS;
1626         MODE_ANY;
1627     }
1628     CONTRACTL_END;
1629
1630     MdaXmlElement* pXml;
1631     MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1632
1633     AsMdaAssistant()->OutputMethodDesc(pCalleeMD, pXml->AddChild(MdaElemDecl(Method)));
1634     AsMdaAssistant()->OutputCallsite(pCallerMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
1635
1636     StackSString sszCalleeMethodName(SString::Utf8, pCalleeMD->GetName());
1637     StackSString sszCallerMethodName(SString::Utf8, pCallerMD->GetName());
1638     msg.SendMessagef(MDARC_VIRTUAL_CER_CALL, sszCallerMethodName.GetUnicode(), dwOffset, sszCalleeMethodName.GetUnicode());
1639 }
1640
1641
1642 //
1643 // MdaOpenGenericCERCall
1644 //
1645 void MdaOpenGenericCERCall::ReportViolation(MethodDesc* pMD)
1646 {
1647     CONTRACTL
1648     {
1649         THROWS;
1650         GC_TRIGGERS;
1651         MODE_ANY;
1652     }
1653     CONTRACTL_END;
1654
1655     MdaXmlElement* pXml;
1656     MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1657
1658     AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));
1659
1660     StackSString sszMethodName(SString::Utf8, pMD->GetName());
1661     msg.SendMessagef(MDARC_OPENGENERIC_CER_CALL, sszMethodName.GetUnicode());
1662 }
1663
1664
1665 //
1666 // MdaIllegalPrepareConstrainedRegion
1667 //
1668 void MdaIllegalPrepareConstrainedRegion::ReportViolation(MethodDesc* pMD, DWORD dwOffset)
1669 {
1670     CONTRACTL
1671     {
1672         THROWS;
1673         GC_TRIGGERS;
1674         MODE_ANY;
1675     }
1676     CONTRACTL_END;
1677
1678     MdaXmlElement* pXml;
1679     MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1680
1681     AsMdaAssistant()->OutputCallsite(pMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
1682
1683     StackSString sszMethodName(SString::Utf8, pMD->GetName());
1684     msg.SendMessagef(MDARC_ILLEGAL_PCR, sszMethodName.GetUnicode(), dwOffset);
1685 }
1686
1687
1688 //
1689 // MdaReleaseHandleFailed
1690 //
1691 void MdaReleaseHandleFailed::ReportViolation(TypeHandle th, LPVOID lpvHandle)
1692 {
1693     CONTRACTL
1694     {
1695         THROWS;
1696         GC_TRIGGERS;
1697         MODE_ANY;
1698     }
1699     CONTRACTL_END;
1700
1701     MdaXmlElement* pXml;
1702     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1703
1704     AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
1705
1706     StackSString sszHandle;
1707     sszHandle.Printf(W("0x%p"), lpvHandle);
1708     pXml->AddChild(MdaElemDecl(Handle))->AddAttributeSz(MdaAttrDecl(Value), sszHandle.GetUnicode());
1709
1710     StackSString sszType;
1711     th.GetName(sszType);
1712     msg.SendMessagef(MDARC_SAFEHANDLE_CRITICAL_FAILURE, sszType.GetUnicode(), lpvHandle);
1713 }
1714
1715
1716 #ifdef FEATURE_COMINTEROP   
1717 //
1718 // MdaReleaseHandleFailed
1719 //
1720 void MdaNonComVisibleBaseClass::ReportViolation(MethodTable *pMT, BOOL fForIDispatch)
1721 {
1722     CONTRACTL
1723     {
1724         THROWS;
1725         GC_TRIGGERS;
1726         MODE_ANY;
1727     }
1728     CONTRACTL_END;
1729
1730     MdaXmlElement* pXml;
1731     MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1732
1733     TypeHandle thDerived = TypeHandle(pMT);
1734     TypeHandle thBase = thDerived.GetParent();
1735     
1736     while (IsTypeVisibleFromCom(thBase))
1737         thBase = thBase.GetParent();
1738
1739     // If we get there, one of the parents must be non COM visible.
1740     _ASSERTE(!thBase.IsNull());
1741
1742     AsMdaAssistant()->OutputTypeHandle(thDerived, pXml->AddChild(MdaElemDecl(DerivedType)));
1743     AsMdaAssistant()->OutputTypeHandle(thBase, pXml->AddChild(MdaElemDecl(BaseType)));
1744
1745     SString strDerivedClassName;
1746     SString strBaseClassName;
1747
1748     thDerived.GetName(strDerivedClassName);
1749     thBase.GetName(strBaseClassName);
1750
1751
1752     msg.SendMessagef(fForIDispatch ? MDARC_NON_COMVISIBLE_BASE_CLASS_IDISPATCH : MDARC_NON_COMVISIBLE_BASE_CLASS_CLASSITF,
1753        strDerivedClassName.GetUnicode(), strBaseClassName.GetUnicode());
1754 }
1755 #endif //FEATURE_COMINTEROP
1756
1757
1758 #ifdef _DEBUG
1759 //
1760 // MdaXmlValidationError
1761 //
1762 void MdaXmlValidationError::ReportError(MdaSchema::ValidationResult* pValidationResult)
1763 {
1764     CONTRACTL
1765     {
1766         THROWS;
1767         GC_TRIGGERS;
1768         MODE_ANY;
1769         DEBUG_ONLY;
1770     }
1771     CONTRACTL_END;
1772     PRECONDITION(CheckPointer(pValidationResult->m_pViolatingElement));
1773     PRECONDITION(CheckPointer(pValidationResult->m_pViolatedElement));
1774
1775     MdaXmlElement* pXml;
1776     MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1777
1778     pXml->AddChild(MdaElemDecl(ViolatingXml))->AddChild(pValidationResult->m_pXmlRoot);
1779     pValidationResult->m_pSchema->ToXml(pXml->AddChild(MdaElemDecl(ViolatedXsd)));    
1780     
1781     msg.SendMessage(W("The following XML does not match its schema."));
1782 }
1783 #endif
1784
1785
1786 //
1787 // InvalidConfigFile
1788 //
1789 void MdaInvalidConfigFile::ReportError(MdaElemDeclDef configFile)
1790 {
1791     CONTRACTL
1792     {
1793         THROWS;
1794         GC_TRIGGERS;
1795         MODE_ANY;
1796         DEBUG_ONLY;
1797     }
1798     CONTRACTL_END;
1799
1800     MdaXmlElement* pXml;
1801     MdaXmlMessage report(this->AsMdaAssistant(), TRUE, &pXml);
1802
1803     LPCWSTR szConfigFile = MdaSchema::GetElementName(configFile);
1804     pXml->AddAttributeSz(MdaAttrDecl(ConfigFile), szConfigFile);  
1805     
1806     report.SendMessagef(MDARC_INVALID_CONFIG_FILE, szConfigFile);
1807 }
1808
1809 #endif
1810 #endif //MDA_SUPPORTED