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// Why is ANYTHING in here marked SO_TOLERANT?? Presumably some of them are called from managed code????
36
37
38//
39// MdaFramework
40//
41void MdaFramework::DumpDiagnostics()
42{
43 CONTRACTL
44 {
45 THROWS;
46 GC_TRIGGERS;
47 MODE_ANY;
48 SO_NOT_MAINLINE;
49 }
50 CONTRACTL_END;
51
52 ManagedDebuggingAssistants* pMda = g_mdaStaticHeap.m_pMda;
53
54#ifdef _DEBUG
55 if (m_dumpSchemaSchema)
56 {
57 MdaXmlElement* pXmlSchemaSchema = pMda->m_pSchemaSchema->ToXml(pMda->m_pMdaXmlIndustry);
58// MdaXmlMessage::SendMessage(pXmlSchemaSchema, TRUE, pMda->m_pSchemaSchema);
59 }
60
61 if (m_dumpAssistantSchema)
62 {
63 MdaXmlElement* pXmlAssistantMsgSchema = pMda->m_pAssistantMsgSchema->ToXml(pMda->m_pMdaXmlIndustry);
64// MdaXmlMessage::SendMessage(pXmlAssistantMsgSchema, TRUE, pMda->m_pSchemaSchema);
65 }
66
67 if (m_dumpAssistantMsgSchema)
68 {
69 MdaXmlElement* pXmlAssistantSchema = pMda->m_pAssistantSchema->ToXml(pMda->m_pMdaXmlIndustry);
70// MdaXmlMessage::SendMessage(pXmlAssistantSchema, TRUE, pMda->m_pSchemaSchema);
71 }
72#endif
73}
74
75#ifdef _DEBUG
76extern BOOL g_bMdaDisableAsserts;
77#endif
78
79void MdaFramework::Initialize(MdaXmlElement* pXmlInput)
80{
81 CONTRACTL
82 {
83 THROWS;
84 GC_TRIGGERS;
85 MODE_ANY;
86 SO_INTOLERANT;
87 }
88 CONTRACTL_END;
89
90#ifdef _DEBUG
91 ManagedDebuggingAssistants* pMda = g_mdaStaticHeap.m_pMda;
92 g_bMdaDisableAsserts = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(DisableAsserts));
93 MdaXmlElement* pXmlDiagnostics = pXmlInput->GetChild(MdaElemDecl(Diagnostics));
94
95 if (pXmlDiagnostics)
96 {
97 m_dumpSchemaSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpSchemaSchema), FALSE);
98 m_dumpAssistantSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpAssistantSchema), FALSE);
99 m_dumpAssistantMsgSchema = pXmlDiagnostics->GetAttributeValueAsBool(MdaAttrDecl(DumpAssistantMsgSchema), FALSE);
100 }
101#endif
102}
103
104//
105// MdaGcUnmanagedToManaged
106//
107void MdaGcUnmanagedToManaged::TriggerGC()
108{
109 WRAPPER_NO_CONTRACT;
110
111 TriggerGCForMDAInternal();
112}
113
114
115//
116// MdaGcManagedToUnmanaged
117//
118void MdaGcManagedToUnmanaged::TriggerGC()
119{
120 WRAPPER_NO_CONTRACT;
121
122 TriggerGCForMDAInternal();
123}
124
125void TriggerGCForMDAInternal()
126{
127 CONTRACTL
128 {
129 NOTHROW;
130 GC_TRIGGERS;
131 MODE_COOPERATIVE;
132 SO_TOLERANT;
133 }
134 CONTRACTL_END;
135
136 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return);
137
138 EX_TRY
139 {
140 GCHeapUtilities::GetGCHeap()->GarbageCollect();
141
142 //
143 // It is very dangerous to wait for finalizer thread here if we are inside a wait
144 // operation, as the wait operation might call into interop which calls this MDA
145 // and call into FinalizerThreadWait. In this case, we might run into infinite recursion:
146 // SynchronizationContext.Wait -> P/Invoke -> WaitForPendingFinalizer ->
147 // SynchronizationContext.Wait ....
148 //
149 // So, if we are inside a SyncContext.Wait, don't call out to FinalizerThreadWait
150 //
151 if (!GetThread()->HasThreadStateNC(Thread::TSNC_InsideSyncContextWait))
152 // It is possible that user code run as part of finalization will wait for this thread.
153 // To avoid deadlocks, we limit the wait time to 10 seconds (an arbitrary number).
154 FinalizerThread::FinalizerThreadWait(10 * 1000);
155 }
156 EX_CATCH
157 {
158 // Caller cannot take exceptions.
159 }
160 EX_END_CATCH(SwallowAllExceptions);
161
162 END_SO_INTOLERANT_CODE;
163}
164
165//
166// MdaCallbackOnCollectedDelegate
167//
168/*
169MdaCallbackOnCollectedDelegate::~MdaCallbackOnCollectedDelegate()
170{
171 WRAPPER_NO_CONTRACT;
172
173 if (m_pList && m_size)
174 {
175 for (int i=0; i < m_size; i++)
176 ReplaceEntry(i, NULL);
177
178 delete[] m_pList;
179 }
180}
181*/
182
183void MdaCallbackOnCollectedDelegate::ReportViolation(MethodDesc* pMD)
184{
185 CONTRACTL
186 {
187 THROWS;
188 GC_TRIGGERS;
189 MODE_ANY;
190 SO_INTOLERANT;
191 }
192 CONTRACTL_END;
193
194 MdaXmlElement* pXml;
195 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
196 MdaXmlElement* pDelegate = pXml->AddChild(MdaElemDecl(Delegate));
197 StackSString delegateName;
198
199 if(pMD)
200 {
201 AsMdaAssistant()->OutputMethodDesc(pMD, pDelegate);
202 AsMdaAssistant()->ToString(delegateName, pMD);
203 }
204
205 msg.SendMessagef(MDARC_CALLBACK_ON_COLLECTED_DELEGATE, delegateName.GetUnicode());
206}
207
208void MdaCallbackOnCollectedDelegate::AddToList(UMEntryThunk* pEntryThunk)
209{
210 CONTRACTL
211 {
212 NOTHROW;
213 GC_NOTRIGGER;
214 MODE_ANY;
215 SO_INTOLERANT;
216 PRECONDITION(CheckPointer(pEntryThunk));
217 }
218 CONTRACTL_END;
219
220 // Get an index to use.
221 ULONG oldIndex = m_iIndex;
222 ULONG newIndex = oldIndex + 1;
223 if (newIndex >= (ULONG)m_size)
224 newIndex = 0;
225
226 while ((ULONG)FastInterlockCompareExchange((LONG*)&m_iIndex, newIndex, oldIndex) != oldIndex)
227 {
228 oldIndex = m_iIndex;
229 newIndex = oldIndex + 1;
230 if (newIndex >= (ULONG)m_size)
231 newIndex = 0;
232 }
233
234 // We successfully incremented the index and can use the oldIndex value as our entry.
235 ReplaceEntry(oldIndex, pEntryThunk);
236}
237
238void MdaCallbackOnCollectedDelegate::ReplaceEntry(int index, UMEntryThunk* pET)
239{
240 CONTRACTL
241 {
242 NOTHROW;
243 GC_NOTRIGGER;
244 MODE_ANY;
245 SO_INTOLERANT;
246 PRECONDITION((index >= 0) && (index < m_size));
247 PRECONDITION(CheckPointer(m_pList));
248 }
249 CONTRACTL_END;
250
251 if ((m_pList) && (m_size > index) && (index >= 0))
252 {
253 UMEntryThunk* pETTemp = m_pList[index];
254 while (FastInterlockCompareExchangePointer((LPVOID*)&m_pList[index], (LPVOID)pET, (LPVOID)pETTemp) != (LPVOID)pETTemp)
255 {
256 pETTemp = m_pList[index];
257 }
258
259 if (NULL != pETTemp)
260 {
261 pETTemp->Terminate();
262 }
263 }
264}
265
266#ifdef FEATURE_COMINTEROP
267
268void MdaInvalidMemberDeclaration::ReportViolation(ComCallMethodDesc *pCMD, OBJECTREF *pExceptionObj)
269{
270 CONTRACTL
271 {
272 NOTHROW;
273 GC_TRIGGERS;
274 MODE_COOPERATIVE;
275 SO_INTOLERANT;
276 }
277 CONTRACTL_END;
278
279 EX_TRY
280 {
281 MdaXmlElement* pXml;
282 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
283
284 TypeHandle th;
285 StackSString strMemberName;
286 StackSString strTypeName;
287 StackSString strMessage;
288
289 GetExceptionMessage(*pExceptionObj, strMessage);
290
291 if (pCMD->IsFieldCall())
292 {
293 FieldDesc *pFD = pCMD->GetFieldDesc();
294
295 th = pFD->GetFieldTypeHandleThrowing();
296 strMemberName.SetUTF8(pFD->GetName());
297 AsMdaAssistant()->OutputFieldDesc(pFD, pXml->AddChild(MdaElemDecl(Field)));
298 }
299 else
300 {
301 MethodDesc *pMD = pCMD->GetCallMethodDesc();
302
303 th = TypeHandle(pMD->GetMethodTable());
304 strMemberName.SetUTF8(pMD->GetName());
305 AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));
306 }
307
308 th.GetName(strTypeName);
309
310 AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
311 AsMdaAssistant()->OutputException(pExceptionObj, pXml->AddChild(MdaElemDecl(Exception)));
312
313 msg.SendMessagef(MDARC_INVALID_MEMBER_DECLARATION,
314 strMemberName.GetUnicode(), strTypeName.GetUnicode(), strMessage.GetUnicode());
315 }
316 EX_CATCH
317 {
318 // Caller cannot take exceptions.
319 }
320 EX_END_CATCH(SwallowAllExceptions);
321}
322
323#endif //FEATURE_COMINTEROP
324
325
326//
327// MdaExceptionSwallowedOnCallFromCom
328//
329void MdaExceptionSwallowedOnCallFromCom::ReportViolation(MethodDesc *pMD, OBJECTREF *pExceptionObj)
330{
331 CONTRACTL
332 {
333 NOTHROW;
334 GC_TRIGGERS;
335 MODE_ANY;
336 SO_INTOLERANT;
337 }
338 CONTRACTL_END;
339
340 EX_TRY
341 {
342 StackSString strMessage;
343 StackSString strTypeName;
344 StackSString strMemberName;
345
346 MdaXmlElement* pXml;
347 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
348
349 TypeHandle th = TypeHandle(pMD->GetMethodTable());
350
351 GetExceptionMessage(*pExceptionObj, strMessage);
352 th.GetName(strTypeName);
353 strMemberName.SetUTF8(pMD->GetName());
354
355 AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));
356 AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
357 AsMdaAssistant()->OutputException(pExceptionObj, pXml->AddChild(MdaElemDecl(Exception)));
358
359 msg.SendMessagef(MDARC_EXCEPTION_SWALLOWED_COM_TO_CLR,
360 strMemberName.GetUnicode(), strTypeName.GetUnicode(), strMessage.GetUnicode());
361 }
362 EX_CATCH
363 {
364 // Caller cannot take exceptions.
365 }
366 EX_END_CATCH(SwallowAllExceptions);
367}
368
369
370//
371// MdaInvalidVariant
372//
373void MdaInvalidVariant::ReportViolation()
374{
375 CONTRACTL
376 {
377 THROWS;
378 GC_TRIGGERS;
379 MODE_ANY;
380 SO_INTOLERANT;
381 }
382 CONTRACTL_END;
383
384 MdaXmlElement* pXml;
385 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
386
387 msg.SendMessagef(MDARC_INVALID_VARIANT);
388}
389
390
391//
392// MdaInvalidIUnknown
393//
394void MdaInvalidIUnknown::ReportViolation()
395{
396 CONTRACTL
397 {
398 THROWS;
399 GC_TRIGGERS;
400 MODE_ANY;
401 SO_INTOLERANT;
402 }
403 CONTRACTL_END;
404
405 MdaXmlElement* pXml;
406 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
407
408 msg.SendMessagef(MDARC_INVALID_IUNKNOWN);
409}
410
411
412//
413// MdaContextSwitchDeadlock
414//
415void MdaContextSwitchDeadlock::ReportDeadlock(LPVOID Origin, LPVOID Destination)
416{
417 CONTRACTL
418 {
419 NOTHROW;
420 GC_TRIGGERS;
421 MODE_ANY;
422 SO_INTOLERANT;
423 }
424 CONTRACTL_END;
425
426 if (g_fEEShutDown == 0)
427 {
428 EX_TRY
429 {
430 MdaXmlElement* pXml;
431 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
432
433 msg.SendMessagef(MDARC_CONTEXT_SWITCH_DEADLOCK, Origin, Destination);
434 }
435 EX_CATCH
436 {
437 // Caller cannot take exceptions.
438 }
439 EX_END_CATCH(SwallowAllExceptions);
440 }
441}
442
443
444//
445// MdaRaceOnRCWCleanup
446//
447void MdaRaceOnRCWCleanup::ReportViolation()
448{
449 CONTRACTL
450 {
451 THROWS;
452 GC_TRIGGERS;
453 MODE_ANY;
454 SO_INTOLERANT;
455 }
456 CONTRACTL_END;
457
458 MdaXmlElement* pXml;
459 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
460
461 msg.SendMessagef(MDARC_RCW_CLEANUP_RACE);
462}
463
464
465//
466// MdaFailedQI
467//
468void MdaFailedQI::ReportAdditionalInfo(HRESULT hr, RCW* pRCW, GUID iid, MethodTable* pMT)
469{
470 CONTRACTL
471 {
472 THROWS;
473 GC_TRIGGERS;
474 MODE_ANY;
475 SO_INTOLERANT;
476 }
477 CONTRACTL_END;
478
479 MdaXmlElement* pXml;
480 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
481 TypeHandle th(pMT);
482
483 SafeComHolder<IUnknown> pInnerUnk = pRCW->GetIUnknown();
484
485 // We are interested in the case where the QI fails because of wrong context.
486 if (!pRCW->IsFreeThreaded() && GetCurrentCtxCookie() != pRCW->GetWrapperCtxCookie())
487 {
488 // Try to change context and perform the QI in the new context again.
489 MdaFailedQIAssistantCallbackData data;
490
491 data.pWrapper = pRCW;
492 data.iid = iid;
493
494 pRCW->EnterContext(MdaFailedQIAssistantCallback, &data);
495 if (data.fSuccess)
496 {
497 // QI succeeds in the other context, i.e. the original QI fails because of wrong context.
498 pXml = AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
499
500 // Stringize IID
501 WCHAR strNativeItfIID[39];
502 StringFromGUID2(iid, strNativeItfIID, sizeof(strNativeItfIID) / sizeof(WCHAR));
503
504 // Map HRESULT to a message
505 StackSString sszHR2Description;
506 GetHRMsg(hr, sszHR2Description);
507
508 // Format the HRESULT as a string
509 StackSString sszHR2Hex;
510 sszHR2Hex.Printf("%.8x", hr);
511
512 StackSString sszTypeName;
513 th.GetName(sszTypeName);
514
515 msg.SendMessagef(MDARC_FAILED_QI, sszTypeName.GetUnicode(), strNativeItfIID, sszHR2Hex.GetUnicode(), sszHR2Description.GetUnicode());
516 }
517 }
518 else if (hr == E_NOINTERFACE)
519 {
520
521 // BUG: You'd have to check the registry to ensure that the proxy stub it's not actually there as opposed to the
522 // COM object QI simply returning a failure code.
523
524 /*
525 // Check if pInnerUnk is actually pointing to a proxy, i.e. that it is pointing to an address
526 // within the loaded ole32.dll image. Note that WszGetModuleHandle does not increment the
527 // ref count.
528 HINSTANCE hModOle32 = WszGetModuleHandle(OLE32DLL);
529 if (hModOle32 && IsIPInModule(hModOle32, (BYTE *)(*(BYTE **)(IUnknown*)pInnerUnk)))
530 {
531 pXml = AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
532
533 WCHAR strGuid[40];
534 GuidToLPWSTR(iid, strGuid, 40);
535 msg.SendMessagef(MDARC_FAILED_QI, strGuid);
536 }
537 */
538 }
539}
540
541HRESULT MdaFailedQIAssistantCallback(LPVOID pData)
542{
543 CONTRACTL
544 {
545 NOTHROW;
546 GC_TRIGGERS;
547 MODE_PREEMPTIVE;
548 SO_TOLERANT;
549 PRECONDITION(CheckPointer(pData));
550 }
551 CONTRACTL_END;
552
553 HRESULT hr = E_FAIL;
554
555 BEGIN_EXTERNAL_ENTRYPOINT(&hr)
556 {
557 SafeComHolder<IUnknown> pDummyUnk;
558
559 MdaFailedQIAssistantCallbackData *pCallbackData = (MdaFailedQIAssistantCallbackData *)pData;
560
561 // Initialize the fSuccess flag to false until we know for a fact the QI will succeed.
562 pCallbackData->fSuccess = FALSE;
563
564 // QI for the requested interface.
565 hr = pCallbackData->pWrapper->SafeQueryInterfaceRemoteAware(pCallbackData->iid, &pDummyUnk);
566
567 // If the QI call succeded then set the fSuccess flag to true.
568 if (SUCCEEDED(hr))
569 pCallbackData->fSuccess = TRUE;
570 }
571 END_EXTERNAL_ENTRYPOINT;
572
573 return S_OK; // Need to return S_OK so that the assert in CtxEntry::EnterContext() won't fire.
574}
575
576//
577// MdaDisconnectedContext
578//
579void MdaDisconnectedContext::ReportViolationDisconnected(LPVOID context, HRESULT hr)
580{
581 CONTRACTL
582 {
583 THROWS;
584 GC_TRIGGERS;
585 MODE_ANY;
586 SO_INTOLERANT;
587 }
588 CONTRACTL_END;
589
590 if (g_fEEShutDown == 0)
591 {
592 MdaXmlElement* pXml;
593 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
594
595 StackSString strHRMsg;
596 GetHRMsg(hr, strHRMsg);
597
598 msg.SendMessagef(MDARC_DISCONNECTED_CONTEXT_1, context, strHRMsg.GetUnicode());
599 }
600}
601
602void MdaDisconnectedContext::ReportViolationCleanup(LPVOID context1, LPVOID context2, HRESULT hr)
603{
604 CONTRACTL
605 {
606 NOTHROW;
607 GC_TRIGGERS;
608 MODE_ANY;
609 SO_INTOLERANT;
610 }
611 CONTRACTL_END;
612
613 if (g_fEEShutDown == 0)
614 {
615 EX_TRY
616 {
617 MdaXmlElement* pXml;
618 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
619
620 StackSString strHRMsg;
621 GetHRMsg(hr, strHRMsg);
622
623 msg.SendMessagef(MDARC_DISCONNECTED_CONTEXT_2, context1, strHRMsg.GetUnicode(), context2);
624 }
625 EX_CATCH
626 {
627 // Caller cannot take exceptions.
628 }
629 EX_END_CATCH(SwallowAllExceptions)
630 }
631}
632
633
634//
635// MdaInvalidApartmentStateChange
636//
637void MdaInvalidApartmentStateChange::ReportViolation(Thread* pThread, Thread::ApartmentState newstate, BOOL fAlreadySet)
638{
639 CONTRACTL
640 {
641 NOTHROW;
642 GC_TRIGGERS;
643 MODE_ANY;
644 SO_INTOLERANT;
645 }
646 CONTRACTL_END;
647
648 EX_TRY
649 {
650 MdaXmlElement* pXml;
651 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
652
653 AsMdaAssistant()->OutputThread(pThread, pXml->AddChild(MdaElemDecl(Thread)));
654
655 if (fAlreadySet)
656 {
657 if (newstate == Thread::AS_InSTA)
658 {
659 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_SET, W("STA"), W("MTA"));
660 }
661 else
662 {
663 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_SET, W("MTA"), W("STA"));
664 }
665 }
666 else
667 {
668 if (newstate == Thread::AS_InSTA)
669 {
670 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_NOTSET, W("STA"), W("MTA"));
671 }
672 else
673 {
674 msg.SendMessagef(MDARC_INVALID_APT_STATE_CHANGE_NOTSET, W("MTA"), W("STA"));
675 }
676 }
677 }
678 EX_CATCH
679 {
680 // Caller cannot take exceptions.
681 }
682 EX_END_CATCH(SwallowAllExceptions);
683}
684
685//
686// MdaDllMainReturnsFalse
687//
688void MdaDllMainReturnsFalse::ReportError()
689{
690 CONTRACTL
691 {
692 THROWS;
693 GC_TRIGGERS;
694 MODE_ANY;
695 SO_TOLERANT;
696 }
697 CONTRACTL_END;
698
699 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return);
700
701 MdaXmlElement* pXml;
702 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
703
704 msg.SendMessagef(MDARC_DLLMAIN_RETURNS_FALSE);
705
706 END_SO_INTOLERANT_CODE;
707}
708
709//
710// MdaOverlappedFreeError
711//
712void MdaOverlappedFreeError::ReportError(LPVOID pOverlapped)
713{
714 CONTRACTL
715 {
716 THROWS;
717 GC_TRIGGERS;
718 MODE_ANY;
719 SO_INTOLERANT;
720 }
721 CONTRACTL_END;
722
723 MdaXmlElement* pXml;
724 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
725
726 msg.SendMessagef(MDARC_INVALID_OVERLAPPED_FREE,
727 pOverlapped);
728}
729
730//
731// MdaInvalidOverlappedToPinvoke
732//
733
734// NOTE: the overlapped pointer needs to be named "overlapped".
735// It is embedded in the (Args) and (ArgsUsed) sections.
736
737
738#define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed) \
739 DllName##_##Name,
740enum {
741#include "invalidoverlappedwrappers.h"
742};
743#undef CREATE_WRAPPER_FUNCTION
744
745#define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed) \
746Return Flags Mda_##Name Args \
747{ \
748 CONTRACTL \
749 { \
750 THROWS; \
751 GC_TRIGGERS; \
752 SO_TOLERANT; \
753 MODE_ANY; \
754 } \
755 CONTRACTL_END; \
756 Return (Flags *old##Name) Args; \
757 MdaInvalidOverlappedToPinvoke *pOverlapCheck = MDA_GET_ASSISTANT(InvalidOverlappedToPinvoke); \
758 _ASSERTE(pOverlapCheck); \
759 *(PVOID *)&(old##Name) = pOverlapCheck->CheckOverlappedPointer(DllName##_##Name, (LPVOID) overlapped); \
760 return old##Name ArgsUsed; \
761}
762#include "invalidoverlappedwrappers.h"
763#undef CREATE_WRAPPER_FUNCTION
764
765#define CREATE_WRAPPER_FUNCTION(DllName, Return, Flags, Name, Args, ArgsUsed) \
766 { L#DllName W(".DLL"), L#Name, Mda_##Name, NULL, NULL },
767static MdaInvalidOverlappedToPinvoke::pinvoke_entry PInvokeTable[] = {
768#include "invalidoverlappedwrappers.h"
769};
770#undef CREATE_WRAPPER_FUNCTION
771
772void MdaInvalidOverlappedToPinvoke::Initialize(MdaXmlElement* pXmlInput)
773{
774 CONTRACTL
775 {
776 THROWS;
777 GC_TRIGGERS;
778 MODE_ANY;
779 }
780 CONTRACTL_END;
781
782// TODO: CONTRACT_VIOLATION(SOToleranceViolation);
783
784 m_entries = PInvokeTable;
785 m_entryCount = sizeof(PInvokeTable) / sizeof(pinvoke_entry);
786 m_bJustMyCode = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(JustMyCode));
787}
788
789BOOL MdaInvalidOverlappedToPinvoke::InitializeModuleFunctions(HINSTANCE hmod)
790{
791 CONTRACTL
792 {
793 THROWS;
794 GC_TRIGGERS;
795 MODE_ANY;
796 SO_TOLERANT;
797 }
798 CONTRACTL_END;
799
800 // For every entry where m_moduleName matches moduleName, fill in m_hmod with hmod
801 // and fill in the m_realFunction pointer.
802
803 BOOL bFoundSomething = FALSE;
804
805 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return FALSE);
806
807 SString moduleNameFullPath, moduleName;
808 ClrGetModuleFileNameNoThrow(hmod,moduleNameFullPath);
809 // Strip any path info
810 SString::CIterator iM = moduleNameFullPath.End();
811 if (moduleNameFullPath.FindBack(iM, W('\\')))
812 {
813 iM++;
814 moduleName.Set(moduleNameFullPath, iM, moduleNameFullPath.End());
815 }
816
817 for (UINT i=0; i<m_entryCount; i++)
818 {
819 if (SString::_wcsicmp(m_entries[i].m_moduleName, moduleName.GetUnicode()) == 0)
820 {
821 if (m_entries[i].m_hmod == NULL)
822 {
823 SString moduleNameForLookup(m_entries[i].m_functionName);
824 StackScratchBuffer ansiVersion;
825 m_entries[i].m_realFunction = GetProcAddress(hmod, moduleNameForLookup.GetANSI(ansiVersion));
826 m_entries[i].m_hmod = hmod;
827 }
828 bFoundSomething = TRUE;
829 }
830 }
831
832 END_SO_INTOLERANT_CODE;
833
834 return bFoundSomething;
835}
836
837LPVOID MdaInvalidOverlappedToPinvoke::CheckOverlappedPointer(UINT index, LPVOID pOverlapped)
838{
839 CONTRACTL
840 {
841 THROWS;
842 GC_TRIGGERS;
843 MODE_ANY;
844 SO_TOLERANT;
845 }
846 CONTRACTL_END;
847
848 MdaInvalidOverlappedToPinvoke::pinvoke_entry *pEntry = m_entries + index;
849
850 // pEntry should always be non-NULL, because we got the address of pvMdaFunction
851 // from the entries table in the first place.
852 _ASSERTE(pEntry);
853 if (pEntry == NULL)
854 {
855 return NULL;
856 }
857
858 // Is the overlapped pointer in the gc heap?
859 if (pOverlapped != NULL)
860 {
861 // If a stack overflow occurs, we would just want to continue and
862 // return the function pointer as expected.
863 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return pEntry->m_realFunction);
864
865 BOOL fHeapPointer;
866
867 {
868 GCX_COOP();
869 IGCHeap *pHeap = GCHeapUtilities::GetGCHeap();
870 fHeapPointer = pHeap->IsHeapPointer(pOverlapped);
871 }
872
873 if (!fHeapPointer)
874 {
875 // Output a message
876 MdaXmlElement* pXml;
877 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
878
879 msg.SendMessagef(MDARC_INVALID_OVERLAPPED_TO_PINVOKE,
880 pOverlapped,
881 pEntry->m_functionName,
882 pEntry->m_moduleName);
883 }
884
885 END_SO_INTOLERANT_CODE;
886 }
887
888 return pEntry->m_realFunction;
889}
890
891// We want to hook the functions where it is in the user's code only, unless
892// the attribute JustMyCode is set to false. In that case, we want all
893// occurances.
894BOOL MdaInvalidOverlappedToPinvoke::ShouldHook(MethodDesc *pMD)
895{
896 LIMITED_METHOD_CONTRACT;
897 return (m_bJustMyCode ? IsJustMyCode(pMD) : TRUE);
898}
899
900LPVOID MdaInvalidOverlappedToPinvoke::Register(HINSTANCE hmod,LPVOID pvTarget)
901{
902 CONTRACTL
903 {
904 THROWS;
905 GC_TRIGGERS;
906 MODE_ANY;
907 SO_TOLERANT;
908 }
909 CONTRACTL_END;
910
911 // Quick lookup - do we have a matching target?
912 // walk our entries, looking for a match.
913 BOOL bNullModules = FALSE;
914 BOOL bSeenThisModule = FALSE;
915
916 for (UINT i=0; i<m_entryCount; i++)
917 {
918 MdaInvalidOverlappedToPinvoke::pinvoke_entry *pEntry = m_entries + i;
919 if (pvTarget == pEntry->m_realFunction)
920 {
921 return pEntry->m_mdaFunction;
922 }
923
924 bNullModules |= (pEntry->m_hmod == NULL);
925 bSeenThisModule |= (pEntry->m_hmod == hmod);
926 }
927
928 // if we have some NULL targets, do we have a matching hmod?
929 // if so,
930 if (bNullModules && !bSeenThisModule)
931 {
932 if (InitializeModuleFunctions(hmod))
933 {
934 // Search once more
935 for (UINT i=0; i<m_entryCount; i++)
936 {
937 pinvoke_entry *pEntry = m_entries + i;
938 if (pvTarget == pEntry->m_realFunction)
939 {
940 return pEntry->m_mdaFunction;
941 }
942 }
943 }
944 }
945
946 return NULL;
947}
948
949//
950// MdaPInvokeLog
951//
952BOOL MdaPInvokeLog::Filter(SString& sszDllName)
953{
954 CONTRACTL
955 {
956 THROWS;
957 GC_TRIGGERS;
958 MODE_ANY;
959 SO_INTOLERANT;
960 }
961 CONTRACTL_END;
962
963 MdaXmlElement* pXmlFilter = m_pXmlInput->GetChild(MdaElemDecl(Filter));
964 if (!pXmlFilter)
965 return TRUE;
966
967 BOOL bFound = FALSE;
968 for (COUNT_T i = 0; i < pXmlFilter->GetChildren().GetCount(); i ++)
969 {
970 if (pXmlFilter->GetChildren()[i]->GetAttribute(MdaAttrDecl(DllName))->GetValueAsCSString()->EqualsCaseInsensitive(sszDllName))
971 {
972 bFound = TRUE;
973 break;
974 }
975 }
976
977 return bFound;
978}
979
980void MdaPInvokeLog::LogPInvoke(NDirectMethodDesc* pMD, HINSTANCE hMod)
981{
982 CONTRACTL
983 {
984 NOTHROW;
985 GC_TRIGGERS;
986 MODE_ANY;
987 SO_INTOLERANT;
988 }
989 CONTRACTL_END;
990
991 EX_TRY
992 {
993 StackSString sszEntryPoint;
994 sszEntryPoint.SetUTF8(pMD->GetEntrypointName());
995
996 PathString szDllFullName ;
997 WCHAR szDrive[_MAX_PATH] = {0};
998 WCHAR szPath[_MAX_PATH] = {0};
999 WCHAR szFileName[_MAX_PATH] = {0};
1000 WCHAR szExt[_MAX_PATH] = {0};
1001 WszGetModuleFileName(hMod, szDllFullName);
1002 SplitPath(szDllFullName, szDrive, _MAX_PATH, szPath, _MAX_PATH, szFileName, _MAX_PATH, szExt, _MAX_PATH);
1003
1004 StackSString sszDllName;
1005 sszDllName.Append(szFileName);
1006 if (szExt)
1007 sszDllName.Append(szExt);
1008
1009 if (Filter(sszDllName))
1010 {
1011 MdaXmlElement* pXml;
1012 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1013
1014 MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
1015 AsMdaAssistant()->OutputMethodDesc(pMD, pMethod);
1016
1017 MdaXmlElement* pDllImport = pXml->AddChild(MdaElemDecl(DllImport));
1018 pDllImport->AddAttributeSz(MdaAttrDecl(DllName), szDllFullName);
1019 pDllImport->AddAttributeSz(MdaAttrDecl(EntryPoint), sszEntryPoint.GetUnicode());
1020
1021 msg.SendMessage();
1022 }
1023 }
1024 EX_CATCH
1025 {
1026 // Caller cannot take exceptions.
1027 }
1028 EX_END_CATCH(SwallowAllExceptions);
1029}
1030
1031
1032#ifdef _TARGET_X86_
1033//
1034// MdaPInvokeStackImbalance
1035//
1036void MdaPInvokeStackImbalance::CheckStack(StackImbalanceCookie *pSICookie, DWORD dwPostEsp)
1037{
1038 CONTRACTL
1039 {
1040 THROWS;
1041 GC_TRIGGERS;
1042 MODE_ANY;
1043 SO_TOLERANT;
1044 }
1045 CONTRACTL_END;
1046
1047 DWORD dwEspAfterPushedArgs = pSICookie->m_dwSavedEsp;
1048 DWORD dwEspBeforePushedArgs = dwEspAfterPushedArgs + pSICookie->m_dwStackArgSize;
1049 BOOL bStackImbalance = false;
1050
1051 // Note: We use relaxed rules here depending on the NetFx40_PInvokeStackResilience compat switch in order to mimic 2.0 behavior.
1052 switch (pSICookie->m_callConv & pmCallConvMask)
1053 {
1054 // Caller cleans stack
1055 case pmCallConvCdecl:
1056 if (dwPostEsp != dwEspAfterPushedArgs)
1057 {
1058 if (dwPostEsp != dwEspBeforePushedArgs)
1059 {
1060 bStackImbalance = true;
1061 }
1062 else
1063 {
1064 // If NetFx40_PInvokeStackResilience is on, ignore the case where we see that the callee cleaned the stack.
1065 BOOL fPreV4Method = pSICookie->m_pMD->GetModule()->IsPreV4Assembly();
1066 if (!g_pConfig->PInvokeRestoreEsp(fPreV4Method))
1067 bStackImbalance = true;
1068 }
1069 }
1070 break;
1071
1072 // Callee cleans stack
1073 case pmCallConvThiscall:
1074 case pmCallConvWinapi:
1075 case pmCallConvStdcall:
1076 if (dwPostEsp != dwEspBeforePushedArgs)
1077 {
1078 if (dwPostEsp != dwEspAfterPushedArgs)
1079 {
1080 bStackImbalance = true;
1081 }
1082 else
1083 {
1084 // If NetFx40_PInvokeStackResilience is on, ignore the case where we see that the callee did not clean the stack
1085 BOOL fPreV4Method = pSICookie->m_pMD->GetModule()->IsPreV4Assembly();
1086 if (!g_pConfig->PInvokeRestoreEsp(fPreV4Method))
1087 bStackImbalance = true;
1088 }
1089 }
1090 break;
1091
1092 // Unsupported calling convention
1093 case pmCallConvFastcall:
1094 default:
1095 _ASSERTE(!"Unsupported calling convention");
1096 break;
1097 }
1098
1099 if (!bStackImbalance)
1100 return;
1101
1102 BEGIN_SO_INTOLERANT_CODE(GetThread());
1103
1104 MdaXmlElement* pXml;
1105 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1106 MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
1107 AsMdaAssistant()->OutputMethodDesc(pSICookie->m_pMD, pMethod);
1108
1109 StackSString sszMethodName;
1110 msg.SendMessagef(MDARC_PINVOKE_SIGNATURE_MISMATCH, AsMdaAssistant()->ToString(sszMethodName, pSICookie->m_pMD).GetUnicode());
1111
1112 END_SO_INTOLERANT_CODE;
1113}
1114#endif
1115
1116
1117//
1118// MdaJitCompilationStart
1119//
1120void MdaJitCompilationStart::Initialize(MdaXmlElement* pXmlInput)
1121{
1122 CONTRACTL
1123 {
1124 THROWS;
1125 GC_TRIGGERS;
1126 MODE_ANY;
1127 SO_INTOLERANT;
1128 }
1129 CONTRACTL_END;
1130
1131 m_bBreak = pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(Break));
1132 MdaXmlElement* pXmlMethodFilter = pXmlInput->GetChild(MdaElemDecl(Methods));
1133 m_pMethodFilter = NULL;
1134
1135 if (pXmlMethodFilter)
1136 {
1137 m_pMethodFilter = new MdaQuery::CompiledQueries();
1138 MdaQuery::Compile(pXmlMethodFilter, m_pMethodFilter);
1139 }
1140}
1141
1142void MdaJitCompilationStart::NowCompiling(MethodDesc* pMD)
1143{
1144 CONTRACTL
1145 {
1146 THROWS;
1147 GC_TRIGGERS;
1148 MODE_ANY;
1149 SO_INTOLERANT;
1150 }
1151 CONTRACTL_END;
1152
1153 if (m_pMethodFilter && !m_pMethodFilter->Test(pMD))
1154 return;
1155
1156 MdaXmlElement* pXml;
1157 MdaXmlMessage msg(this->AsMdaAssistant(), m_bBreak, &pXml);
1158
1159 MdaXmlElement* pMethod = pXml->AddChild(MdaElemDecl(Method));
1160 AsMdaAssistant()->OutputMethodDesc(pMD, pMethod);
1161
1162 msg.SendMessage();
1163}
1164
1165//
1166// MdaLoadFromContext
1167//
1168void MdaLoadFromContext::NowLoading(IAssembly** ppIAssembly, StackCrawlMark *pCallerStackMark)
1169{
1170 CONTRACTL
1171 {
1172 THROWS;
1173 GC_TRIGGERS;
1174 MODE_ANY;
1175 SO_INTOLERANT;
1176 }
1177 CONTRACTL_END;
1178
1179 if (ppIAssembly && *ppIAssembly) {
1180
1181 // Send an MDA if this assembly was loaded in the LoadFrom context
1182 if ((*ppIAssembly)->GetFusionLoadContext() == LOADCTX_TYPE_LOADFROM) {
1183 // Apply MDA filtering
1184 if (g_pDebugInterface && pCallerStackMark && ManagedDebuggingAssistants::IsManagedDebuggerAttached()) {
1185 MethodDesc *pMethodDesc = NULL;
1186 {
1187 GCX_COOP();
1188 pMethodDesc = SystemDomain::GetCallersMethod(pCallerStackMark, NULL);
1189 }
1190 if (pMethodDesc && !g_pDebugInterface->IsJMCMethod(pMethodDesc->GetModule(), pMethodDesc->GetMemberDef()))
1191 return;
1192 }
1193
1194 MdaXmlElement *pXml;
1195 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1196
1197 MdaXmlElement *pXmlAssembly = pXml->AddChild(MdaElemDecl(AssemblyInfo));
1198
1199 StackSString sszAssemblyName;
1200 StackSString sszCodeBase;
1201 SafeComHolder<IAssemblyName> pNameDef;
1202
1203 if (FAILED((*ppIAssembly)->GetAssemblyNameDef(&pNameDef))) {
1204 return;
1205 }
1206
1207 if ((!FusionBind::GetAssemblyNameStringProperty(pNameDef, ASM_NAME_NAME, sszAssemblyName)) ||
1208 (!FusionBind::GetAssemblyNameStringProperty(pNameDef, ASM_NAME_CODEBASE_URL, sszCodeBase))) {
1209 return;
1210 }
1211
1212 pXmlAssembly->AddAttributeSz(MdaAttrDecl(DisplayName), sszAssemblyName.GetUnicode());
1213 pXmlAssembly->AddAttributeSz(MdaAttrDecl(CodeBase), sszCodeBase.GetUnicode());
1214
1215 msg.SendMessagef(MDARC_LOAD_FROM_CONTEXT, sszAssemblyName.GetUnicode(), sszCodeBase.GetUnicode());
1216 }
1217 }
1218}
1219
1220const LPCWSTR ContextIdName[] =
1221{
1222 W("Load"),
1223 W("LoadFrom"),
1224 W("Anonymous")
1225};
1226
1227//
1228// MdaBindingFailure
1229//
1230void MdaBindingFailure::BindFailed(AssemblySpec *pSpec, OBJECTREF *pExceptionObj)
1231{
1232 CONTRACTL
1233 {
1234 THROWS;
1235 GC_TRIGGERS;
1236 MODE_ANY;
1237 SO_INTOLERANT;
1238 }
1239 CONTRACTL_END;
1240
1241 MdaXmlElement *pXml;
1242 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1243
1244 MdaXmlElement *pXmlAssembly = pXml->AddChild(MdaElemDecl(AssemblyInfo));
1245
1246 DWORD dwAppDomainId;
1247 SString sszAssemblyName;
1248 SString sszCodeBase;
1249 SString sszMessage;
1250 int iBindingContext;
1251 HRESULT hr;
1252
1253 // determine AppDomain ID
1254 AppDomain *appDomain = pSpec->GetAppDomain();
1255 if (appDomain) {
1256 dwAppDomainId = appDomain->GetId().m_dwId;
1257 } else {
1258 dwAppDomainId = 0;
1259 }
1260 pXmlAssembly->AddAttributeInt(MdaAttrDecl(AppDomainId), dwAppDomainId);
1261
1262 // determine Assembly display name
1263 LPCSTR assemblyName = pSpec->GetName();
1264 if (assemblyName && assemblyName[0]) {
1265 sszAssemblyName.SetASCII(assemblyName);
1266 }
1267 pXmlAssembly->AddAttributeSz(MdaAttrDecl(DisplayName), sszAssemblyName.GetUnicode());
1268
1269 // determine Assembly code base
1270 if (pSpec->GetCodeBase() && pSpec->GetCodeBase()[0]) {
1271 sszCodeBase.Set(pSpec->GetCodeBase());
1272 }
1273 pXmlAssembly->AddAttributeSz(MdaAttrDecl(CodeBase), sszCodeBase.GetUnicode());
1274
1275 // retrieve the exception message.
1276 GetExceptionMessage(*pExceptionObj, sszMessage);
1277
1278 // determine failing HRESULT
1279 hr = GetExceptionHResult(*pExceptionObj);
1280 pXmlAssembly->AddAttributeInt(MdaAttrDecl(HResult), hr);
1281
1282 // determine binding context Assembly would have been loaded in (based on parent)
1283 IAssembly* pParentAssembly = pSpec->GetParentIAssembly();
1284 if (pParentAssembly) {
1285 iBindingContext = pParentAssembly->GetFusionLoadContext();
1286 } else {
1287
1288 // if the parent hasn't been set but the code base has, it's in LoadFrom
1289 iBindingContext = LOADCTX_TYPE_LOADFROM;
1290 }
1291 pXmlAssembly->AddAttributeInt(MdaAttrDecl(BindingContextId), iBindingContext);
1292
1293 // Make sure the binding context ID isn't larger then our ID to name lookup table.
1294 _ASSERTE(iBindingContext < COUNTOF(ContextIdName));
1295
1296 if (sszAssemblyName.IsEmpty())
1297 {
1298 _ASSERTE(!sszCodeBase.IsEmpty());
1299 msg.SendMessagef(MDARC_BINDING_FAILURE_CODEBASE_ONLY, sszCodeBase.GetUnicode(),
1300 ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1301 }
1302 else if (sszCodeBase.IsEmpty())
1303 {
1304 _ASSERTE(!sszAssemblyName.IsEmpty());
1305 msg.SendMessagef(MDARC_BINDING_FAILURE_DISPLAYNAME_ONLY, sszAssemblyName.GetUnicode(),
1306 ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1307 }
1308 else
1309 {
1310 msg.SendMessagef(MDARC_BINDING_FAILURE, sszAssemblyName.GetUnicode(), sszCodeBase.GetUnicode(),
1311 ContextIdName[iBindingContext], dwAppDomainId, sszMessage.GetUnicode());
1312 }
1313}
1314
1315
1316//
1317// MdaReflection
1318//
1319FCIMPL0(void, MdaManagedSupport::MemberInfoCacheCreation)
1320{
1321 FCALL_CONTRACT;
1322
1323 HELPER_METHOD_FRAME_BEGIN_0();
1324 {
1325 MdaMemberInfoCacheCreation* pMda = MDA_GET_ASSISTANT(MemberInfoCacheCreation);
1326 if (pMda)
1327 {
1328 pMda->MemberInfoCacheCreation();
1329 }
1330 }
1331 HELPER_METHOD_FRAME_END();
1332}
1333FCIMPLEND
1334
1335void MdaMemberInfoCacheCreation::MemberInfoCacheCreation()
1336{
1337 CONTRACTL
1338 {
1339 THROWS;
1340 GC_TRIGGERS;
1341 MODE_ANY;
1342 SO_INTOLERANT;
1343 }
1344 CONTRACTL_END;
1345
1346 MdaXmlElement* pXml;
1347 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1348
1349 msg.SendMessage(MDARC_REFLECTION_PERFORMANCE_MEMBERINFOCACHECREATION);
1350}
1351
1352
1353FCIMPL0(FC_BOOL_RET, MdaManagedSupport::IsStreamWriterBufferedDataLostEnabled)
1354{
1355 FCALL_CONTRACT;
1356
1357 // To see if it's enabled, allocate one then throw it away.
1358 MdaStreamWriterBufferedDataLost* pMda = MDA_GET_ASSISTANT(StreamWriterBufferedDataLost);
1359
1360 FC_RETURN_BOOL(pMda != NULL);
1361}
1362FCIMPLEND
1363
1364FCIMPL0(FC_BOOL_RET, MdaManagedSupport::IsStreamWriterBufferedDataLostCaptureAllocatedCallStack)
1365{
1366 FCALL_CONTRACT;
1367
1368 // To see if it's enabled, allocate one then throw it away.
1369 MdaStreamWriterBufferedDataLost* pMda = MDA_GET_ASSISTANT(StreamWriterBufferedDataLost);
1370
1371 FC_RETURN_BOOL((pMda != NULL) && (pMda->CaptureAllocatedCallStack()));
1372}
1373FCIMPLEND
1374
1375FCIMPL1(void, MdaManagedSupport::ReportStreamWriterBufferedDataLost, StringObject * stringRef)
1376{
1377 FCALL_CONTRACT;
1378
1379 STRINGREF str(stringRef);
1380 MdaStreamWriterBufferedDataLost* pMda = MDA_GET_ASSISTANT(StreamWriterBufferedDataLost);
1381 if (pMda)
1382 {
1383 HELPER_METHOD_FRAME_BEGIN_1(str);
1384 StackSString message(str->GetBuffer());
1385 pMda->ReportError(message);
1386 HELPER_METHOD_FRAME_END();
1387 }
1388}
1389FCIMPLEND
1390
1391FCIMPL0(FC_BOOL_RET, MdaManagedSupport::IsInvalidGCHandleCookieProbeEnabled)
1392{
1393 FCALL_CONTRACT;
1394
1395 // To see if it's enabled, allocate one then throw it away.
1396 MdaInvalidGCHandleCookie* pMda = MDA_GET_ASSISTANT(InvalidGCHandleCookie);
1397
1398 FC_RETURN_BOOL(pMda != NULL);
1399}
1400FCIMPLEND
1401
1402FCIMPL1(void, MdaManagedSupport::FireInvalidGCHandleCookieProbe, LPVOID cookie)
1403{
1404 FCALL_CONTRACT;
1405
1406 MdaInvalidGCHandleCookie* pMda = MDA_GET_ASSISTANT(InvalidGCHandleCookie);
1407 if (pMda)
1408 {
1409 HELPER_METHOD_FRAME_BEGIN_0();
1410 pMda->ReportError(cookie);
1411 HELPER_METHOD_FRAME_END();
1412 }
1413}
1414FCIMPLEND
1415
1416FCIMPL1(void, MdaManagedSupport::ReportErrorSafeHandleRelease, ExceptionObject * exceptionRef)
1417{
1418 FCALL_CONTRACT;
1419
1420 OBJECTREF exception(exceptionRef);
1421 MdaMarshalCleanupError* pMda = MDA_GET_ASSISTANT(MarshalCleanupError);
1422 if (pMda)
1423 {
1424 HELPER_METHOD_FRAME_BEGIN_1(exception);
1425 pMda->ReportErrorSafeHandleRelease(&exception);
1426 HELPER_METHOD_FRAME_END();
1427 }
1428}
1429FCIMPLEND
1430
1431void MdaInvalidGCHandleCookie::ReportError(LPVOID cookie)
1432{
1433 CONTRACTL
1434 {
1435 THROWS;
1436 GC_TRIGGERS;
1437 MODE_ANY;
1438 SO_INTOLERANT;
1439 }
1440 CONTRACTL_END;
1441
1442 MdaXmlElement* pXml;
1443 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1444
1445 msg.SendMessagef(MDARC_INVALID_GCHANDLE_COOKIE, cookie);
1446}
1447
1448void MdaStreamWriterBufferedDataLost::ReportError(SString text)
1449{
1450 CONTRACTL
1451 {
1452 THROWS;
1453 GC_TRIGGERS;
1454 MODE_ANY;
1455 SO_INTOLERANT;
1456 }
1457 CONTRACTL_END;
1458
1459 MdaXmlElement* pXml;
1460 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1461
1462 msg.SendMessage(text);
1463}
1464
1465
1466//
1467// MdaNotMarshalable
1468//
1469void MdaNotMarshalable::ReportViolation()
1470{
1471 CONTRACTL
1472 {
1473 THROWS;
1474 GC_TRIGGERS;
1475 MODE_ANY;
1476 SO_INTOLERANT;
1477 }
1478 CONTRACTL_END;
1479
1480 MdaXmlElement* pXml;
1481 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1482
1483 msg.SendMessagef(MDARC_NOTMARSHALABLE);
1484}
1485
1486
1487//
1488// MdaMarshalCleanupError
1489//
1490void MdaMarshalCleanupError::ReportErrorThreadCulture(OBJECTREF *pExceptionObj)
1491{
1492 CONTRACTL
1493 {
1494 NOTHROW;
1495 GC_TRIGGERS;
1496 MODE_ANY;
1497 SO_INTOLERANT;
1498 }
1499 CONTRACTL_END;
1500
1501 EX_TRY
1502 {
1503 MdaXmlElement* pXml;
1504 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1505
1506 // retrieve the exception message.
1507 SString sszMessage;
1508 GetExceptionMessage(*pExceptionObj, sszMessage);
1509
1510 msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_THREADCULTURE, sszMessage.GetUnicode());
1511 }
1512 EX_CATCH
1513 {
1514 }
1515 EX_END_CATCH(SwallowAllExceptions);
1516}
1517
1518void MdaMarshalCleanupError::ReportErrorSafeHandleRelease(OBJECTREF *pExceptionObj)
1519{
1520 CONTRACTL
1521 {
1522 NOTHROW;
1523 GC_TRIGGERS;
1524 MODE_ANY;
1525 SO_INTOLERANT;
1526 }
1527 CONTRACTL_END;
1528
1529 EX_TRY
1530 {
1531 MdaXmlElement* pXml;
1532 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1533
1534 // retrieve the exception message.
1535 SString sszMessage;
1536 GetExceptionMessage(*pExceptionObj, sszMessage);
1537
1538 msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_SAFEHANDLERELEASE, sszMessage.GetUnicode());
1539 }
1540 EX_CATCH
1541 {
1542 }
1543 EX_END_CATCH(SwallowAllExceptions);
1544}
1545
1546void MdaMarshalCleanupError::ReportErrorSafeHandleProp(OBJECTREF *pExceptionObj)
1547{
1548 CONTRACTL
1549 {
1550 NOTHROW;
1551 GC_TRIGGERS;
1552 MODE_ANY;
1553 SO_INTOLERANT;
1554 }
1555 CONTRACTL_END;
1556
1557 EX_TRY
1558 {
1559 MdaXmlElement* pXml;
1560 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1561
1562 // retrieve the exception message.
1563 SString sszMessage;
1564 GetExceptionMessage(*pExceptionObj, sszMessage);
1565
1566 msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_SAFEHANDLEPROP, sszMessage.GetUnicode());
1567 }
1568 EX_CATCH
1569 {
1570 }
1571 EX_END_CATCH(SwallowAllExceptions);
1572}
1573
1574void MdaMarshalCleanupError::ReportErrorCustomMarshalerCleanup(TypeHandle typeCustomMarshaler, OBJECTREF *pExceptionObj)
1575{
1576 CONTRACTL
1577 {
1578 NOTHROW;
1579 GC_TRIGGERS;
1580 MODE_ANY;
1581 SO_INTOLERANT;
1582 }
1583 CONTRACTL_END;
1584
1585 EX_TRY
1586 {
1587
1588 MdaXmlElement* pXml;
1589 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1590
1591 // retrieve the exception message.
1592 SString sszMessage;
1593 GetExceptionMessage(*pExceptionObj, sszMessage);
1594
1595 // Retrieve the type name.
1596 StackSString sszType;
1597 typeCustomMarshaler.GetName(sszType);
1598
1599 msg.SendMessagef(MDARC_MARSHALCLEANUPERROR_CUSTOMCLEANUP, sszType.GetUnicode(), sszMessage.GetUnicode());
1600 }
1601 EX_CATCH
1602 {
1603 }
1604 EX_END_CATCH(SwallowAllExceptions);
1605}
1606
1607//
1608// MdaMarshaling
1609//
1610void MdaMarshaling::Initialize(MdaXmlElement* pXmlInput)
1611{
1612 CONTRACTL
1613 {
1614 THROWS;
1615 GC_TRIGGERS;
1616 MODE_ANY;
1617 SO_INTOLERANT;
1618 }
1619 CONTRACTL_END;
1620
1621 m_pMethodFilter = new MdaQuery::CompiledQueries();
1622 m_pFieldFilter = new MdaQuery::CompiledQueries();
1623
1624 MdaXmlElement* pXmlMethodFilter = pXmlInput->GetChild(MdaElemDecl(MethodFilter));
1625 if (pXmlMethodFilter)
1626 MdaQuery::Compile(pXmlMethodFilter, m_pMethodFilter);
1627
1628 MdaXmlElement* pXmlFieldFilter = pXmlInput->GetChild(MdaElemDecl(FieldFilter));
1629 if (pXmlFieldFilter)
1630 MdaQuery::Compile(pXmlFieldFilter, m_pFieldFilter);
1631}
1632
1633void MdaMarshaling::ReportFieldMarshal(FieldMarshaler* pFM)
1634{
1635 CONTRACTL
1636 {
1637 THROWS;
1638 GC_TRIGGERS;
1639 MODE_ANY;
1640 SO_INTOLERANT;
1641 PRECONDITION(CheckPointer(pFM));
1642 }
1643 CONTRACTL_END;
1644
1645 FieldDesc* pFD = pFM->GetFieldDesc();
1646
1647 if (!pFD || !m_pFieldFilter->Test(pFD))
1648 return;
1649
1650 MdaXmlElement* pXml;
1651 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
1652
1653 MdaXmlElement* pField = pXml->AddChild(MdaElemDecl(MarshalingField));
1654 AsMdaAssistant()->OutputFieldDesc(pFD, pField);
1655
1656 StackSString sszField;
1657 SString managed;
1658 SString unmanaged;
1659
1660 GetManagedSideForField(managed, pFD);
1661 GetUnmanagedSideForField(unmanaged, pFM);
1662
1663 msg.SendMessagef(MDARC_MARSHALING_FIELD, AsMdaAssistant()->ToString(sszField, pFD).GetUnicode(), managed.GetUnicode(), unmanaged.GetUnicode());
1664}
1665
1666
1667void MdaMarshaling::GetManagedSideForField(SString& strManagedMarshalType, FieldDesc* pFD)
1668{
1669 CONTRACTL
1670 {
1671 THROWS;
1672 GC_TRIGGERS;
1673 MODE_ANY;
1674 SO_INTOLERANT;
1675 }
1676 CONTRACTL_END;
1677
1678 if (!CheckForPrimitiveType(pFD->GetFieldType(), strManagedMarshalType))
1679 {
1680 // The following workaround is added to avoid a recursion caused by calling GetTypeHandle on
1681 // the m_value field of the UIntPtr class.
1682 LPCUTF8 szNamespace, szClassName;
1683 IfFailThrow(pFD->GetMDImport()->GetNameOfTypeDef(pFD->GetApproxEnclosingMethodTable()->GetCl(), &szClassName, &szNamespace));
1684
1685 if (strcmp(szNamespace, "System") == 0 && strcmp(szClassName, "UIntPtr") == 0)
1686 {
1687 static LPWSTR strRetVal = W("Void*");
1688 strManagedMarshalType.Set(strRetVal);
1689 }
1690 else
1691 {
1692 MetaSig fSig(pFD);
1693 fSig.NextArgNormalized();
1694 TypeHandle th = fSig.GetLastTypeHandleNT();
1695 if (th.IsNull())
1696 {
1697 static const WCHAR strErrorMsg[] = W("<error>");
1698 strManagedMarshalType.Set(strErrorMsg);
1699 }
1700 else
1701 {
1702 SigFormat sigFmt;
1703 sigFmt.AddType(th);
1704 UINT iManagedTypeLen = (UINT)strlen(sigFmt.GetCString()) + 1;
1705
1706 WCHAR* buffer = strManagedMarshalType.OpenUnicodeBuffer(iManagedTypeLen);
1707 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sigFmt.GetCString(), -1, buffer, iManagedTypeLen);
1708 strManagedMarshalType.CloseBuffer();
1709 }
1710 }
1711 }
1712}
1713
1714void MdaMarshaling::GetUnmanagedSideForField(SString& strUnmanagedMarshalType, FieldMarshaler* pFM)
1715{
1716 CONTRACTL
1717 {
1718 THROWS;
1719 GC_NOTRIGGER;
1720 MODE_ANY;
1721 SO_INTOLERANT;
1722 }
1723 CONTRACTL_END;
1724
1725 NStructFieldTypeToString(pFM, strUnmanagedMarshalType);
1726}
1727
1728
1729void MdaMarshaling::GetManagedSideForMethod(SString& strManagedMarshalType, Module* pModule, SigPointer sig, CorElementType elemType)
1730{
1731 CONTRACTL
1732 {
1733 THROWS;
1734 GC_TRIGGERS;
1735 MODE_ANY;
1736 SO_INTOLERANT;
1737 }
1738 CONTRACTL_END;
1739
1740 if (!CheckForPrimitiveType(elemType, strManagedMarshalType))
1741 {
1742 // an empty type context is sufficient: all methods should be non-generic
1743 SigTypeContext emptyTypeContext;
1744
1745 TypeHandle th = sig.GetTypeHandleNT(pModule, &emptyTypeContext);
1746 if (th.IsNull())
1747 {
1748 strManagedMarshalType.Set(W("<error>"));
1749 }
1750 else
1751 {
1752 SigFormat sigfmt;
1753 sigfmt.AddType(th);
1754 UINT iManagedMarshalTypeLength = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sigfmt.GetCString(), -1, NULL, 0);
1755
1756 WCHAR* str = strManagedMarshalType.OpenUnicodeBuffer(iManagedMarshalTypeLength);
1757 MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sigfmt.GetCString(), -1, str, iManagedMarshalTypeLength);
1758 strManagedMarshalType.CloseBuffer();
1759 }
1760 }
1761}
1762
1763
1764void MdaMarshaling::GetUnmanagedSideForMethod(SString& strNativeMarshalType, MarshalInfo* mi, BOOL fSizeIsSpecified)
1765{
1766 CONTRACTL
1767 {
1768 THROWS;
1769 GC_TRIGGERS;
1770 MODE_ANY;
1771 SO_INTOLERANT;
1772 }
1773 CONTRACTL_END;
1774
1775 mi->MarshalTypeToString(strNativeMarshalType, fSizeIsSpecified);
1776}
1777
1778BOOL MdaMarshaling::CheckForPrimitiveType(CorElementType elemType, SString& strPrimitiveType)
1779{
1780 CONTRACTL
1781 {
1782 THROWS;
1783 GC_NOTRIGGER;
1784 MODE_ANY;
1785 SO_INTOLERANT;
1786 INJECT_FAULT(COMPlusThrowOM());
1787 }
1788 CONTRACTL_END;
1789
1790 LPWSTR strRetVal;
1791
1792 switch (elemType)
1793 {
1794 case ELEMENT_TYPE_VOID:
1795 strRetVal = W("Void");
1796 break;
1797 case ELEMENT_TYPE_BOOLEAN:
1798 strRetVal = W("Boolean");
1799 break;
1800 case ELEMENT_TYPE_I1:
1801 strRetVal = W("SByte");
1802 break;
1803 case ELEMENT_TYPE_U1:
1804 strRetVal = W("Byte");
1805 break;
1806 case ELEMENT_TYPE_I2:
1807 strRetVal = W("Int16");
1808 break;
1809 case ELEMENT_TYPE_U2:
1810 strRetVal = W("UInt16");
1811 break;
1812 case ELEMENT_TYPE_CHAR:
1813 strRetVal = W("Char");
1814 break;
1815 case ELEMENT_TYPE_I:
1816 strRetVal = W("IntPtr");
1817 break;
1818 case ELEMENT_TYPE_U:
1819 strRetVal = W("UIntPtr");
1820 break;
1821 case ELEMENT_TYPE_I4:
1822 strRetVal = W("Int32");
1823 break;
1824 case ELEMENT_TYPE_U4:
1825 strRetVal = W("UInt32");
1826 break;
1827 case ELEMENT_TYPE_I8:
1828 strRetVal = W("Int64");
1829 break;
1830 case ELEMENT_TYPE_U8:
1831 strRetVal = W("UInt64");
1832 break;
1833 case ELEMENT_TYPE_R4:
1834 strRetVal = W("Single");
1835 break;
1836 case ELEMENT_TYPE_R8:
1837 strRetVal = W("Double");
1838 break;
1839 default:
1840 return FALSE;
1841 }
1842
1843 strPrimitiveType.Set(strRetVal);
1844 return TRUE;
1845}
1846
1847//
1848// MdaLoaderLock
1849//
1850void MdaLoaderLock::ReportViolation(HINSTANCE hInst)
1851{
1852 CONTRACTL
1853 {
1854 NOTHROW;
1855 GC_TRIGGERS;
1856 MODE_ANY;
1857 // Called from SO_TOLERANT CODE
1858 SO_TOLERANT;
1859 }
1860 CONTRACTL_END;
1861
1862 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return);
1863
1864 EX_TRY
1865 {
1866 MdaXmlElement* pXml;
1867 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1868
1869 DWORD cName = 0;
1870 PathString szName;
1871 if (hInst)
1872 {
1873 cName = WszGetModuleFileName(hInst, szName);
1874 }
1875
1876 if (cName)
1877 {
1878 msg.SendMessagef(MDARC_LOADER_LOCK_DLL, szName);
1879 }
1880 else
1881 {
1882 msg.SendMessagef(MDARC_LOADER_LOCK);
1883 }
1884 }
1885 EX_CATCH
1886 {
1887 // Caller cannot take exceptions.
1888 }
1889 EX_END_CATCH(SwallowAllExceptions);
1890
1891 END_SO_INTOLERANT_CODE;
1892}
1893
1894
1895//
1896// MdaReentrancy
1897//
1898void MdaReentrancy::ReportViolation()
1899{
1900 CONTRACTL
1901 {
1902 NOTHROW;
1903 GC_TRIGGERS;
1904 MODE_ANY;
1905 SO_TOLERANT;
1906 }
1907 CONTRACTL_END;
1908
1909 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return);
1910
1911 EX_TRY
1912 {
1913 MdaXmlElement* pXml;
1914 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1915
1916 msg.SendMessagef(MDARC_REENTRANCY);
1917 }
1918 EX_CATCH
1919 {
1920 // Caller cannot take exceptions.
1921 }
1922 EX_END_CATCH(SwallowAllExceptions);
1923
1924 END_SO_INTOLERANT_CODE;
1925}
1926
1927//
1928// MdaAsynchronousThreadAbort
1929//
1930void MdaAsynchronousThreadAbort::ReportViolation(Thread *pCallingThread, Thread *pAbortedThread)
1931{
1932 CONTRACTL
1933 {
1934 NOTHROW;
1935 GC_TRIGGERS;
1936 MODE_ANY;
1937 SO_INTOLERANT;
1938 }
1939 CONTRACTL_END;
1940
1941 EX_TRY
1942 {
1943 MdaXmlElement* pXml;
1944 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1945
1946 AsMdaAssistant()->OutputThread(pCallingThread, pXml->AddChild(MdaElemDecl(CallingThread)));
1947 AsMdaAssistant()->OutputThread(pAbortedThread, pXml->AddChild(MdaElemDecl(AbortedThread)));
1948
1949 msg.SendMessagef(MDARC_ASYNCHRONOUS_THREADABORT, pCallingThread->GetOSThreadId(), pAbortedThread->GetOSThreadId());
1950 }
1951 EX_CATCH
1952 {
1953 // Caller cannot take exceptions.
1954 }
1955 EX_END_CATCH(SwallowAllExceptions);
1956}
1957
1958
1959//
1960// MdaAsynchronousThreadAbort
1961//
1962void MdaDangerousThreadingAPI::ReportViolation(__in_z WCHAR *apiName)
1963{
1964 CONTRACTL
1965 {
1966 THROWS;
1967 GC_TRIGGERS;
1968 MODE_ANY;
1969 SO_INTOLERANT;
1970 }
1971 CONTRACTL_END;
1972
1973 MdaXmlElement* pXml;
1974 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
1975
1976 msg.SendMessagef(MDARC_DANGEROUS_THREADINGAPI, apiName);
1977}
1978
1979
1980//
1981// MdaReportAvOnComRelease
1982//
1983
1984void MdaReportAvOnComRelease::ReportHandledException(RCW* pRCW)
1985{
1986 CONTRACTL
1987 {
1988 NOTHROW;
1989 GC_TRIGGERS;
1990 MODE_ANY;
1991 SO_INTOLERANT;
1992 }
1993 CONTRACTL_END;
1994
1995 EX_TRY
1996 {
1997 FAULT_NOT_FATAL();
1998
1999 // TODO: comment this code...
2000 MdaXmlElement* pXml;
2001 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2002
2003 if (pRCW)
2004 {
2005 LPVOID vtablePtr = pRCW->GetVTablePtr();
2006 msg.SendMessagef(MDARC_REPORT_AV_ON_COM_RELEASE_WITH_VTABLE, vtablePtr);
2007 }
2008 else
2009 {
2010 msg.SendMessagef(MDARC_REPORT_AV_ON_COM_RELEASE);
2011 }
2012 }
2013 EX_CATCH
2014 {
2015 // Caller cannot take exceptions.
2016 }
2017 EX_END_CATCH(SwallowAllExceptions);
2018}
2019
2020void MdaInvalidFunctionPointerInDelegate::ReportViolation(LPVOID pFunc)
2021{
2022 CONTRACTL
2023 {
2024 THROWS;
2025 GC_TRIGGERS;
2026 MODE_ANY;
2027 SO_INTOLERANT;
2028 }
2029 CONTRACTL_END;
2030
2031 MdaXmlElement* pXml;
2032 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2033
2034 msg.SendMessagef(MDARC_INVALID_FUNCTION_PTR_IN_DELEGATE, pFunc);
2035}
2036
2037//
2038// MdaDirtyCastAndCallOnInterface
2039//
2040
2041void MdaDirtyCastAndCallOnInterface::ReportViolation(IUnknown* pUnk)
2042{
2043 CONTRACTL
2044 {
2045 THROWS;
2046 GC_TRIGGERS;
2047 MODE_ANY;
2048 SO_INTOLERANT;
2049 }
2050 CONTRACTL_END;
2051
2052 MdaXmlElement* pXml;
2053 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2054
2055 msg.SendMessagef(MDARC_DIRTY_CAST_AND_CALL_ON_INTERFACE);
2056}
2057
2058//
2059// MdaFatalExecutionEngineError
2060//
2061void MdaFatalExecutionEngineError::ReportFEEE(TADDR addrOfError, HRESULT hrError)
2062{
2063 CONTRACTL
2064 {
2065 NOTHROW;
2066 GC_TRIGGERS;
2067 MODE_ANY;
2068 SO_INTOLERANT;
2069 }
2070 CONTRACTL_END;
2071
2072 EX_TRY
2073 {
2074 MdaXmlElement* pXml;
2075 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2076
2077 DWORD tid = GetCurrentThreadId();
2078
2079 msg.SendMessagef(MDARC_FATAL_EXECUTION_ENGINE_ERROR, addrOfError, tid, hrError);
2080 }
2081 EX_CATCH
2082 {
2083 // Caller cannot take exceptions.
2084 }
2085 EX_END_CATCH(SwallowAllExceptions);
2086}
2087
2088
2089//
2090// MdaInvalidCERCall
2091//
2092void MdaInvalidCERCall::ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset)
2093{
2094 CONTRACTL
2095 {
2096 THROWS;
2097 GC_TRIGGERS;
2098 MODE_ANY;
2099 SO_INTOLERANT;
2100 }
2101 CONTRACTL_END;
2102
2103 MdaXmlElement* pXml;
2104 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
2105
2106 AsMdaAssistant()->OutputMethodDesc(pCalleeMD, pXml->AddChild(MdaElemDecl(Method)));
2107 AsMdaAssistant()->OutputCallsite(pCallerMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
2108
2109 StackSString sszCalleeMethodName(SString::Utf8, pCalleeMD->GetName());
2110 StackSString sszCallerMethodName(SString::Utf8, pCallerMD->GetName());
2111 msg.SendMessagef(MDARC_INVALID_CER_CALL, sszCallerMethodName.GetUnicode(), dwOffset, sszCalleeMethodName.GetUnicode());
2112}
2113
2114
2115//
2116// MdaVirtualCERCall
2117//
2118void MdaVirtualCERCall::ReportViolation(MethodDesc* pCallerMD, MethodDesc *pCalleeMD, DWORD dwOffset)
2119{
2120 CONTRACTL
2121 {
2122 THROWS;
2123 GC_TRIGGERS;
2124 MODE_ANY;
2125 SO_INTOLERANT;
2126 }
2127 CONTRACTL_END;
2128
2129 MdaXmlElement* pXml;
2130 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
2131
2132 AsMdaAssistant()->OutputMethodDesc(pCalleeMD, pXml->AddChild(MdaElemDecl(Method)));
2133 AsMdaAssistant()->OutputCallsite(pCallerMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
2134
2135 StackSString sszCalleeMethodName(SString::Utf8, pCalleeMD->GetName());
2136 StackSString sszCallerMethodName(SString::Utf8, pCallerMD->GetName());
2137 msg.SendMessagef(MDARC_VIRTUAL_CER_CALL, sszCallerMethodName.GetUnicode(), dwOffset, sszCalleeMethodName.GetUnicode());
2138}
2139
2140
2141//
2142// MdaOpenGenericCERCall
2143//
2144void MdaOpenGenericCERCall::ReportViolation(MethodDesc* pMD)
2145{
2146 CONTRACTL
2147 {
2148 THROWS;
2149 GC_TRIGGERS;
2150 MODE_ANY;
2151 SO_INTOLERANT;
2152 }
2153 CONTRACTL_END;
2154
2155 MdaXmlElement* pXml;
2156 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
2157
2158 AsMdaAssistant()->OutputMethodDesc(pMD, pXml->AddChild(MdaElemDecl(Method)));
2159
2160 StackSString sszMethodName(SString::Utf8, pMD->GetName());
2161 msg.SendMessagef(MDARC_OPENGENERIC_CER_CALL, sszMethodName.GetUnicode());
2162}
2163
2164
2165//
2166// MdaIllegalPrepareConstrainedRegion
2167//
2168void MdaIllegalPrepareConstrainedRegion::ReportViolation(MethodDesc* pMD, DWORD dwOffset)
2169{
2170 CONTRACTL
2171 {
2172 THROWS;
2173 GC_TRIGGERS;
2174 MODE_ANY;
2175 SO_INTOLERANT;
2176 }
2177 CONTRACTL_END;
2178
2179 MdaXmlElement* pXml;
2180 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
2181
2182 AsMdaAssistant()->OutputCallsite(pMD, dwOffset, pXml->AddChild(MdaElemDecl(Callsite)));
2183
2184 StackSString sszMethodName(SString::Utf8, pMD->GetName());
2185 msg.SendMessagef(MDARC_ILLEGAL_PCR, sszMethodName.GetUnicode(), dwOffset);
2186}
2187
2188
2189//
2190// MdaReleaseHandleFailed
2191//
2192void MdaReleaseHandleFailed::ReportViolation(TypeHandle th, LPVOID lpvHandle)
2193{
2194 CONTRACTL
2195 {
2196 THROWS;
2197 GC_TRIGGERS;
2198 MODE_ANY;
2199 SO_INTOLERANT;
2200 }
2201 CONTRACTL_END;
2202
2203 MdaXmlElement* pXml;
2204 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2205
2206 AsMdaAssistant()->OutputTypeHandle(th, pXml->AddChild(MdaElemDecl(Type)));
2207
2208 StackSString sszHandle;
2209 sszHandle.Printf(W("0x%p"), lpvHandle);
2210 pXml->AddChild(MdaElemDecl(Handle))->AddAttributeSz(MdaAttrDecl(Value), sszHandle.GetUnicode());
2211
2212 StackSString sszType;
2213 th.GetName(sszType);
2214 msg.SendMessagef(MDARC_SAFEHANDLE_CRITICAL_FAILURE, sszType.GetUnicode(), lpvHandle);
2215}
2216
2217
2218#ifdef FEATURE_COMINTEROP
2219//
2220// MdaReleaseHandleFailed
2221//
2222void MdaNonComVisibleBaseClass::ReportViolation(MethodTable *pMT, BOOL fForIDispatch)
2223{
2224 CONTRACTL
2225 {
2226 THROWS;
2227 GC_TRIGGERS;
2228 MODE_ANY;
2229 SO_INTOLERANT;
2230 }
2231 CONTRACTL_END;
2232
2233 MdaXmlElement* pXml;
2234 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2235
2236 TypeHandle thDerived = TypeHandle(pMT);
2237 TypeHandle thBase = thDerived.GetParent();
2238
2239 while (IsTypeVisibleFromCom(thBase))
2240 thBase = thBase.GetParent();
2241
2242 // If we get there, one of the parents must be non COM visible.
2243 _ASSERTE(!thBase.IsNull());
2244
2245 AsMdaAssistant()->OutputTypeHandle(thDerived, pXml->AddChild(MdaElemDecl(DerivedType)));
2246 AsMdaAssistant()->OutputTypeHandle(thBase, pXml->AddChild(MdaElemDecl(BaseType)));
2247
2248 SString strDerivedClassName;
2249 SString strBaseClassName;
2250
2251 thDerived.GetName(strDerivedClassName);
2252 thBase.GetName(strBaseClassName);
2253
2254
2255 msg.SendMessagef(fForIDispatch ? MDARC_NON_COMVISIBLE_BASE_CLASS_IDISPATCH : MDARC_NON_COMVISIBLE_BASE_CLASS_CLASSITF,
2256 strDerivedClassName.GetUnicode(), strBaseClassName.GetUnicode());
2257}
2258#endif //FEATURE_COMINTEROP
2259
2260
2261#ifdef _DEBUG
2262//
2263// MdaXmlValidationError
2264//
2265void MdaXmlValidationError::ReportError(MdaSchema::ValidationResult* pValidationResult)
2266{
2267 CONTRACTL
2268 {
2269 THROWS;
2270 GC_TRIGGERS;
2271 MODE_ANY;
2272 DEBUG_ONLY;
2273 SO_NOT_MAINLINE;
2274 }
2275 CONTRACTL_END;
2276 PRECONDITION(CheckPointer(pValidationResult->m_pViolatingElement));
2277 PRECONDITION(CheckPointer(pValidationResult->m_pViolatedElement));
2278
2279 MdaXmlElement* pXml;
2280 MdaXmlMessage msg(this->AsMdaAssistant(), FALSE, &pXml);
2281
2282 pXml->AddChild(MdaElemDecl(ViolatingXml))->AddChild(pValidationResult->m_pXmlRoot);
2283 pValidationResult->m_pSchema->ToXml(pXml->AddChild(MdaElemDecl(ViolatedXsd)));
2284
2285 msg.SendMessage(W("The following XML does not match its schema."));
2286}
2287#endif
2288
2289
2290//
2291// InvalidConfigFile
2292//
2293void MdaInvalidConfigFile::ReportError(MdaElemDeclDef configFile)
2294{
2295 CONTRACTL
2296 {
2297 THROWS;
2298 GC_TRIGGERS;
2299 MODE_ANY;
2300 DEBUG_ONLY;
2301 SO_NOT_MAINLINE;
2302 }
2303 CONTRACTL_END;
2304
2305 MdaXmlElement* pXml;
2306 MdaXmlMessage report(this->AsMdaAssistant(), TRUE, &pXml);
2307
2308 LPCWSTR szConfigFile = MdaSchema::GetElementName(configFile);
2309 pXml->AddAttributeSz(MdaAttrDecl(ConfigFile), szConfigFile);
2310
2311 report.SendMessagef(MDARC_INVALID_CONFIG_FILE, szConfigFile);
2312}
2313
2314//
2315// MdaDateTimeInvalidLocalFormat
2316//
2317void MdaDateTimeInvalidLocalFormat::ReportError()
2318{
2319 CONTRACTL
2320 {
2321 THROWS;
2322 GC_TRIGGERS;
2323 MODE_ANY;
2324 DEBUG_ONLY;
2325 SO_NOT_MAINLINE;
2326 }
2327 CONTRACTL_END;
2328
2329 MdaXmlElement* pXml;
2330 MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml);
2331
2332 msg.SendMessagef(MDARC_DATETIME_INVALID_LOCAL_FORMAT);
2333}
2334
2335FCIMPL0(void, MdaManagedSupport::DateTimeInvalidLocalFormat)
2336{
2337 FCALL_CONTRACT;
2338
2339 MdaDateTimeInvalidLocalFormat* pMda = MDA_GET_ASSISTANT(DateTimeInvalidLocalFormat);
2340 if (pMda)
2341 {
2342 HELPER_METHOD_FRAME_BEGIN_0();
2343 pMda->ReportError();
2344 HELPER_METHOD_FRAME_END();
2345 }
2346}
2347FCIMPLEND
2348
2349#endif
2350#endif //MDA_SUPPORTED
2351