1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | // |
7 | |
8 | #include "common.h" |
9 | #include "testhookmgr.h" |
10 | #include "appdomain.hpp" |
11 | #include "appdomain.inl" |
12 | #include "finalizerthread.h" |
13 | |
14 | #ifdef FEATURE_TESTHOOKS |
15 | CLRTestHookManager* CLRTestHookManager::g_pManager=NULL; |
16 | CLRTestHookManager::~CLRTestHookManager() |
17 | { |
18 | |
19 | } |
20 | |
21 | HRESULT CLRTestHookManager::AddTestHook(ICLRTestHook* hook) |
22 | { |
23 | WRAPPER_NO_CONTRACT; |
24 | DWORD newidx=FastInterlockIncrement(&m_nHooks); |
25 | if (newidx>=NumItems(m_pHooks)) |
26 | { |
27 | FastInterlockDecrement(&m_nHooks); |
28 | return DISP_E_OVERFLOW; |
29 | } |
30 | m_pHooks[newidx-1].Set(hook); |
31 | return S_OK; |
32 | } |
33 | |
34 | |
35 | ICLRTestHookManager* CLRTestHookManager::Start() |
36 | { |
37 | LIMITED_METHOD_CONTRACT; |
38 | if (g_pManager==NULL) |
39 | { |
40 | CLRTestHookManager* newman=new (nothrow)CLRTestHookManager(); |
41 | if (newman!=NULL && FastInterlockCompareExchangePointer(&g_pManager, newman, 0)!=0) |
42 | delete newman; |
43 | } |
44 | if(g_pManager) |
45 | g_pManager->AddRef(); |
46 | return g_pManager; |
47 | } |
48 | |
49 | CLRTestHookManager::CLRTestHookManager() |
50 | { |
51 | WRAPPER_NO_CONTRACT; |
52 | m_nHooks=0; |
53 | m_cRef=1; |
54 | ZeroMemory(m_pHooks,sizeof(m_pHooks)); |
55 | } |
56 | |
57 | HRESULT CLRTestHookManager::AppDomainStageChanged(DWORD adid,DWORD oldstage,DWORD newstage) |
58 | { |
59 | STATIC_CONTRACT_NOTHROW; |
60 | |
61 | struct Param |
62 | { |
63 | CLRTestHookManager *pThis; |
64 | DWORD adid; |
65 | DWORD oldstage; |
66 | DWORD newstage; |
67 | } param; |
68 | param.pThis = this; |
69 | param.adid = adid; |
70 | param.oldstage = oldstage; |
71 | param.newstage = newstage; |
72 | |
73 | PAL_TRY(Param *, pParam, ¶m) |
74 | { |
75 | //ignores the returned codes |
76 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
77 | { |
78 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
79 | if(hook) |
80 | { |
81 | HRESULT hr=hook->AppDomainStageChanged(pParam->adid, pParam->oldstage, pParam->newstage); |
82 | _ASSERTE(SUCCEEDED(hr)); |
83 | } |
84 | } |
85 | } |
86 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
87 | { |
88 | _ASSERTE(!"Test Hook threw an exception." ); |
89 | } |
90 | PAL_ENDTRY; |
91 | |
92 | return S_OK; |
93 | }; |
94 | |
95 | |
96 | HRESULT CLRTestHookManager::NextFileLoadLevel(DWORD adid, LPVOID domainfile,DWORD newlevel) |
97 | { |
98 | STATIC_CONTRACT_THROWS; |
99 | HRESULT hr=S_OK; |
100 | { |
101 | for (LONG i=0;i<m_nHooks;i++) |
102 | { |
103 | ICLRTestHook* hook=m_pHooks[i].v1(); |
104 | if(hook) |
105 | { |
106 | HRESULT hr2=hook->NextFileLoadLevel( adid, domainfile, newlevel); |
107 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
108 | if (SUCCEEDED(hr)) |
109 | hr=hr2; |
110 | } |
111 | } |
112 | } |
113 | IfFailThrow(hr); |
114 | return hr; |
115 | } |
116 | |
117 | HRESULT CLRTestHookManager::CompletingFileLoadLevel(DWORD adid, LPVOID domainfile,DWORD newlevel) |
118 | { |
119 | STATIC_CONTRACT_THROWS; |
120 | HRESULT hr=S_OK; |
121 | { |
122 | for (LONG i=0;i<m_nHooks;i++) |
123 | { |
124 | ICLRTestHook* hook=m_pHooks[i].v1(); |
125 | if(hook) |
126 | { |
127 | HRESULT hr2=hook->CompletingFileLoadLevel( adid, domainfile, newlevel); |
128 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
129 | if (SUCCEEDED(hr)) |
130 | hr=hr2; |
131 | } |
132 | } |
133 | } |
134 | |
135 | |
136 | IfFailThrow(hr); |
137 | return hr; |
138 | } |
139 | |
140 | HRESULT CLRTestHookManager::CompletedFileLoadLevel(DWORD adid, LPVOID domainfile,DWORD newlevel) |
141 | { |
142 | STATIC_CONTRACT_NOTHROW; |
143 | |
144 | struct Param |
145 | { |
146 | CLRTestHookManager *pThis; |
147 | DWORD adid; |
148 | LPVOID domainfile; |
149 | DWORD newlevel; |
150 | } param; |
151 | param.pThis = this; |
152 | param.adid = adid; |
153 | param.domainfile = domainfile; |
154 | param.newlevel = newlevel; |
155 | |
156 | PAL_TRY(Param *, pParam, ¶m) |
157 | { |
158 | //ignores the returned codes |
159 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
160 | { |
161 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
162 | if(hook) |
163 | { |
164 | HRESULT hr=hook->CompletedFileLoadLevel(pParam->adid, pParam->domainfile, pParam->newlevel); |
165 | _ASSERTE(SUCCEEDED(hr)); |
166 | } |
167 | } |
168 | } |
169 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
170 | { |
171 | _ASSERTE(!"Test Hook threw an exception." ); |
172 | } |
173 | PAL_ENDTRY |
174 | |
175 | return S_OK; |
176 | } |
177 | |
178 | HRESULT CLRTestHookManager::EnteringAppDomain(DWORD adid) |
179 | { |
180 | STATIC_CONTRACT_THROWS; |
181 | HRESULT hr=S_OK; |
182 | { |
183 | for (LONG i=0;i<m_nHooks;i++) |
184 | { |
185 | ICLRTestHook* hook=m_pHooks[i].v1(); |
186 | if(hook) |
187 | { |
188 | HRESULT hr2=hook->EnteringAppDomain(adid); |
189 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
190 | if (SUCCEEDED(hr)) |
191 | hr=hr2; |
192 | } |
193 | } |
194 | } |
195 | IfFailThrow(hr); |
196 | return hr; |
197 | } |
198 | |
199 | HRESULT CLRTestHookManager::EnteredAppDomain(DWORD adid) |
200 | { |
201 | STATIC_CONTRACT_THROWS; |
202 | HRESULT hr=S_OK; |
203 | { |
204 | for (LONG i=0;i<m_nHooks;i++) |
205 | { |
206 | ICLRTestHook* hook=m_pHooks[i].v1(); |
207 | if(hook) |
208 | { |
209 | HRESULT hr2=hook->EnteredAppDomain(adid); |
210 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
211 | if (SUCCEEDED(hr)) |
212 | hr=hr2; |
213 | } |
214 | } |
215 | } |
216 | IfFailThrow(hr); |
217 | return hr; |
218 | } |
219 | |
220 | HRESULT CLRTestHookManager::LeavingAppDomain(DWORD adid) |
221 | { |
222 | STATIC_CONTRACT_THROWS; |
223 | HRESULT hr=S_OK; |
224 | { |
225 | for (LONG i=0;i<m_nHooks;i++) |
226 | { |
227 | ICLRTestHook* hook=m_pHooks[i].v1(); |
228 | if(hook) |
229 | { |
230 | HRESULT hr2=hook->LeavingAppDomain(adid); |
231 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
232 | if (SUCCEEDED(hr)) |
233 | hr=hr2; |
234 | } |
235 | } |
236 | } |
237 | IfFailThrow(hr); |
238 | return hr; |
239 | } |
240 | |
241 | HRESULT CLRTestHookManager::LeftAppDomain(DWORD adid) |
242 | { |
243 | STATIC_CONTRACT_THROWS; |
244 | HRESULT hr=S_OK; |
245 | { |
246 | for (LONG i=0;i<m_nHooks;i++) |
247 | { |
248 | ICLRTestHook* hook=m_pHooks[i].v1(); |
249 | if(hook) |
250 | { |
251 | HRESULT hr2=hook->LeftAppDomain(adid); |
252 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
253 | if (SUCCEEDED(hr)) |
254 | hr=hr2; |
255 | } |
256 | } |
257 | } |
258 | IfFailThrow(hr); |
259 | return hr; |
260 | } |
261 | |
262 | HRESULT CLRTestHookManager::UnwindingThreads(DWORD adid) |
263 | { |
264 | STATIC_CONTRACT_NOTHROW; |
265 | |
266 | struct Param |
267 | { |
268 | CLRTestHookManager *pThis; |
269 | DWORD adid; |
270 | } param; |
271 | param.pThis = this; |
272 | param.adid = adid; |
273 | |
274 | PAL_TRY(Param *, pParam, ¶m) |
275 | { |
276 | //ignores the returned codes |
277 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
278 | { |
279 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
280 | if(hook) |
281 | { |
282 | HRESULT hr=hook->UnwindingThreads(pParam->adid); |
283 | _ASSERTE(SUCCEEDED(hr)); |
284 | } |
285 | } |
286 | } |
287 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
288 | { |
289 | _ASSERTE(!"Test Hook threw an exception." ); |
290 | } |
291 | PAL_ENDTRY |
292 | |
293 | return S_OK; |
294 | } |
295 | |
296 | HRESULT CLRTestHookManager::RuntimeStarted(DWORD code) |
297 | { |
298 | STATIC_CONTRACT_NOTHROW; |
299 | |
300 | struct Param |
301 | { |
302 | CLRTestHookManager *pThis; |
303 | DWORD code; |
304 | } param; |
305 | param.pThis = this; |
306 | param.code = code; |
307 | |
308 | PAL_TRY(Param *, pParam, ¶m) |
309 | { |
310 | //ignores the returned codes |
311 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
312 | { |
313 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
314 | if(hook) |
315 | { |
316 | HRESULT hr=hook->RuntimeStarted(pParam->code); |
317 | _ASSERTE(SUCCEEDED(hr)); |
318 | } |
319 | } |
320 | } |
321 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
322 | { |
323 | _ASSERTE(!"Test Hook threw an exception." ); |
324 | } |
325 | PAL_ENDTRY |
326 | |
327 | return S_OK; |
328 | } |
329 | |
330 | HRESULT CLRTestHookManager::UnwoundThreads(DWORD adid) |
331 | { |
332 | STATIC_CONTRACT_NOTHROW; |
333 | |
334 | struct Param |
335 | { |
336 | CLRTestHookManager *pThis; |
337 | DWORD adid; |
338 | } param; |
339 | param.pThis = this; |
340 | param.adid = adid; |
341 | |
342 | PAL_TRY(Param *, pParam, ¶m) |
343 | { |
344 | //ignores the returned codes |
345 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
346 | { |
347 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
348 | if(hook) |
349 | { |
350 | HRESULT hr=hook->UnwoundThreads(pParam->adid); |
351 | _ASSERTE(SUCCEEDED(hr)); |
352 | } |
353 | } |
354 | } |
355 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
356 | { |
357 | _ASSERTE(!"Test Hook threw an exception." ); |
358 | } |
359 | PAL_ENDTRY |
360 | |
361 | return S_OK; |
362 | } |
363 | |
364 | HRESULT CLRTestHookManager::AppDomainDestroyed(DWORD adid) |
365 | { |
366 | STATIC_CONTRACT_NOTHROW; |
367 | |
368 | struct Param |
369 | { |
370 | CLRTestHookManager *pThis; |
371 | DWORD adid; |
372 | } param; |
373 | param.pThis = this; |
374 | param.adid = adid; |
375 | |
376 | PAL_TRY(Param *, pParam, ¶m) |
377 | { |
378 | //ignores the returned codes |
379 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
380 | { |
381 | ICLRTestHook* hook = pParam->pThis->m_pHooks[i].v1(); |
382 | if(hook) |
383 | { |
384 | HRESULT hr=hook->AppDomainDestroyed(pParam->adid); |
385 | _ASSERTE(SUCCEEDED(hr)); |
386 | } |
387 | } |
388 | } |
389 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
390 | { |
391 | _ASSERTE(!"Test Hook threw an exception." ); |
392 | } |
393 | PAL_ENDTRY |
394 | |
395 | return S_OK; |
396 | } |
397 | |
398 | STDMETHODIMP CLRTestHookManager::ImageMapped(LPCWSTR wszPath, LPCVOID pBaseAddress,DWORD flags) |
399 | { |
400 | STATIC_CONTRACT_NOTHROW; |
401 | |
402 | struct Param |
403 | { |
404 | CLRTestHookManager *pThis; |
405 | LPCWSTR wszPath; |
406 | LPCVOID pBaseAddress; |
407 | DWORD flags; |
408 | } param; |
409 | param.pThis = this; |
410 | param.wszPath = wszPath; |
411 | param.pBaseAddress = pBaseAddress; |
412 | param.flags = flags; |
413 | |
414 | PAL_TRY(Param *, pParam, ¶m) |
415 | { |
416 | //ignores the returned codes |
417 | for (LONG i = 0; i < pParam->pThis->m_nHooks; i++) |
418 | { |
419 | ICLRTestHook2* hook = pParam->pThis->m_pHooks[i].v2(); |
420 | if(hook) |
421 | { |
422 | HRESULT hr=hook->ImageMapped(pParam->wszPath,pParam->pBaseAddress,pParam->flags); |
423 | _ASSERTE(SUCCEEDED(hr)); |
424 | } |
425 | } |
426 | } |
427 | PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) |
428 | { |
429 | _ASSERTE(!"Test Hook threw an exception." ); |
430 | } |
431 | PAL_ENDTRY |
432 | |
433 | return S_OK; |
434 | |
435 | } |
436 | |
437 | HRESULT CLRTestHookManager::AppDomainCanBeUnloaded(DWORD adid, BOOL bUnsafePoint) |
438 | { |
439 | STATIC_CONTRACT_THROWS; |
440 | HRESULT hr=S_OK; |
441 | { |
442 | if (!ThreadCanBeAborted()) |
443 | return S_OK; |
444 | for (LONG i=0;i<m_nHooks;i++) |
445 | { |
446 | ICLRTestHook* hook=m_pHooks[i].v1(); |
447 | if(hook) |
448 | { |
449 | HRESULT hr2=hook->AppDomainCanBeUnloaded(adid,bUnsafePoint); |
450 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
451 | if (SUCCEEDED(hr)) |
452 | hr=hr2; |
453 | } |
454 | } |
455 | } |
456 | IfFailThrow(hr); |
457 | return hr; |
458 | } |
459 | |
460 | HRESULT CLRTestHookManager::StartingNativeImageBind(LPCWSTR wszAsmName, BOOL bIsCompilationProcess) |
461 | { |
462 | STATIC_CONTRACT_THROWS; |
463 | HRESULT hr=S_OK; |
464 | { |
465 | for (LONG i=0;i<m_nHooks;i++) |
466 | { |
467 | ICLRTestHook3* hook=m_pHooks[i].v3(); |
468 | if(hook) |
469 | { |
470 | HRESULT hr2=hook->StartingNativeImageBind(wszAsmName, bIsCompilationProcess); |
471 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
472 | if (SUCCEEDED(hr)) |
473 | hr=hr2; |
474 | } |
475 | } |
476 | } |
477 | |
478 | IfFailThrow(hr); |
479 | return hr; |
480 | } |
481 | |
482 | HRESULT CLRTestHookManager::CompletedNativeImageBind(LPVOID pFile,LPCUTF8 simpleName, BOOL hasNativeImage) |
483 | { |
484 | STATIC_CONTRACT_THROWS; |
485 | HRESULT hr=S_OK; |
486 | { |
487 | for (LONG i=0;i<m_nHooks;i++) |
488 | { |
489 | ICLRTestHook3* hook=m_pHooks[i].v3(); |
490 | if(hook) |
491 | { |
492 | HRESULT hr2=hook->CompletedNativeImageBind(pFile, simpleName, hasNativeImage); |
493 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
494 | if (SUCCEEDED(hr)) |
495 | hr=hr2; |
496 | } |
497 | } |
498 | } |
499 | |
500 | IfFailThrow(hr); |
501 | return hr; |
502 | } |
503 | |
504 | HRESULT CLRTestHookManager::AboutToLockImage(LPCWSTR wszPath, BOOL bIsCompilationProcess) |
505 | { |
506 | STATIC_CONTRACT_THROWS; |
507 | HRESULT hr=S_OK; |
508 | { |
509 | for (LONG i=0;i<m_nHooks;i++) |
510 | { |
511 | ICLRTestHook3* hook=m_pHooks[i].v3(); |
512 | if(hook) |
513 | { |
514 | HRESULT hr2=hook->AboutToLockImage(wszPath, bIsCompilationProcess); |
515 | _ASSERTE(SUCCEEDED(hr)||SUCCEEDED(hr2)); |
516 | if (SUCCEEDED(hr)) |
517 | hr=hr2; |
518 | } |
519 | } |
520 | } |
521 | |
522 | IfFailThrow(hr); |
523 | return hr; |
524 | } |
525 | |
526 | HRESULT CLRTestHookManager::EnableSlowPath (BOOL bEnable) |
527 | { |
528 | WRAPPER_NO_CONTRACT; |
529 | ThreadStore::TrapReturningThreads(bEnable); |
530 | return S_OK; |
531 | } |
532 | |
533 | ULONG CLRTestHookManager::AddRef() |
534 | { |
535 | return FastInterlockIncrement(&m_cRef); |
536 | } |
537 | |
538 | ULONG CLRTestHookManager::Release() |
539 | { |
540 | ULONG nRet= FastInterlockDecrement(&m_cRef); |
541 | // never goes away |
542 | return nRet; |
543 | } |
544 | |
545 | HRESULT CLRTestHookManager::QueryInterface(REFIID riid, void **ppv) |
546 | { |
547 | if (riid!=IID_IUnknown && riid!=IID_ICLRTestHookManager) |
548 | return E_NOINTERFACE; |
549 | AddRef(); |
550 | *ppv=(ICLRTestHookManager*)this; |
551 | return S_OK; |
552 | } |
553 | |
554 | |
555 | HRESULT CLRTestHookManager::CheckConfig() |
556 | { |
557 | CONTRACTL |
558 | { |
559 | THROWS; |
560 | GC_NOTRIGGER; |
561 | MODE_ANY; |
562 | } |
563 | CONTRACTL_END; |
564 | |
565 | HRESULT hr=S_OK; |
566 | if (g_pConfig) |
567 | { |
568 | LPWSTR szTestHooks=NULL; |
569 | hr=CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TestHooks,&szTestHooks); |
570 | if (SUCCEEDED(hr) && szTestHooks!=NULL && *szTestHooks!=W('\0')) |
571 | { |
572 | LPWSTR curr=szTestHooks; |
573 | do |
574 | { |
575 | LPWSTR next=wcschr(curr,W(';')); |
576 | if (next) |
577 | *(next++)=0; |
578 | LPWSTR delim=wcschr(curr,W(',')); |
579 | if (delim) |
580 | { |
581 | *(delim++)=W('\0'); |
582 | HMODULE hMod=WszLoadLibrary(curr); |
583 | _ASSERTE(hMod); |
584 | if (hMod!=NULL) |
585 | { |
586 | MAKE_MULTIBYTE_FROMWIDE(szFName,delim,CP_ACP); |
587 | CLRTESTHOOKPROC* fn=(CLRTESTHOOKPROC*)GetProcAddress(hMod,szFName); |
588 | _ASSERTE(fn); |
589 | if(fn) |
590 | fn(Start()); |
591 | } |
592 | } |
593 | curr=next; |
594 | } |
595 | while(curr!=NULL && *curr!=W('\0')); |
596 | |
597 | delete szTestHooks; |
598 | } |
599 | } |
600 | return hr; |
601 | } |
602 | |
603 | |
604 | HRESULT CLRTestHookManager::UnloadAppDomain(DWORD adid,DWORD flags) |
605 | { |
606 | return COR_E_CANNOTUNLOADAPPDOMAIN; |
607 | } |
608 | |
609 | VOID CLRTestHookManager::DoAppropriateWait( int cObjs, HANDLE *pObjs, INT32 iTimeout, BOOL bWaitAll, int* res) |
610 | { |
611 | CONTRACTL |
612 | { |
613 | THROWS; |
614 | GC_TRIGGERS; |
615 | MODE_ANY; |
616 | } |
617 | CONTRACTL_END; |
618 | |
619 | |
620 | Thread* thread=GetThread(); |
621 | DWORD result = WAIT_FAILED; |
622 | if(thread) |
623 | result=thread->DoAppropriateWait(cObjs,pObjs,bWaitAll,iTimeout,WaitMode_Alertable,NULL); |
624 | else |
625 | { |
626 | result = WaitForMultipleObjectsEx(cObjs,pObjs,bWaitAll,iTimeout,TRUE); |
627 | } |
628 | } |
629 | |
630 | |
631 | HRESULT CLRTestHookManager::GC(int generation) |
632 | { |
633 | CONTRACTL |
634 | { |
635 | THROWS; |
636 | GC_TRIGGERS; |
637 | MODE_ANY; |
638 | } |
639 | CONTRACTL_END; |
640 | |
641 | _ASSERTE(GetThread()==NULL || !GetThread()->PreemptiveGCDisabled()); |
642 | GCHeapUtilities::GetGCHeap()->GarbageCollect(generation); |
643 | FinalizerThread::FinalizerThreadWait(); |
644 | return S_OK; |
645 | } |
646 | |
647 | |
648 | HRESULT CLRTestHookManager::GetSimpleName(LPVOID domainfile,LPCUTF8* name) |
649 | { |
650 | HRESULT hr=S_OK; |
651 | EX_TRY |
652 | { |
653 | *name=((DomainFile*)domainfile)->GetSimpleName(); |
654 | } |
655 | EX_CATCH_HRESULT(hr); |
656 | return hr; |
657 | } |
658 | |
659 | |
660 | |
661 | INT_PTR CLRTestHookManager::GetCurrentThreadType() |
662 | { |
663 | WRAPPER_NO_CONTRACT; |
664 | return (INT_PTR) ClrFlsGetValue (TlsIdx_ThreadType); |
665 | } |
666 | |
667 | INT_PTR CLRTestHookManager::GetCurrentThreadLockCount (VOID) |
668 | { |
669 | LIMITED_METHOD_CONTRACT; |
670 | Thread* thread=GetThread(); |
671 | if(!thread) |
672 | return 0; |
673 | return thread->m_dwLockCount; |
674 | |
675 | }; |
676 | |
677 | |
678 | BOOL CLRTestHookManager::IsPreemptiveGC (VOID) |
679 | { |
680 | LIMITED_METHOD_CONTRACT; |
681 | Thread *thread = GetThread(); |
682 | // Preemptive GC is default |
683 | if (thread == NULL) |
684 | return TRUE; |
685 | else |
686 | return !thread->PreemptiveGCDisabled(); |
687 | }; |
688 | |
689 | |
690 | BOOL CLRTestHookManager::ThreadCanBeAborted (VOID) |
691 | { |
692 | LIMITED_METHOD_CONTRACT; |
693 | return (GetThread()==NULL || GetThread()->IsAbortPrevented() || GetThread()->IsAsyncPrevented())?FALSE:TRUE; |
694 | } |
695 | |
696 | HRESULT CLRTestHookManager::HasNativeImage(LPVOID domainfile,BOOL* pHasNativeImage) |
697 | { |
698 | STATIC_CONTRACT_THROWS; |
699 | HRESULT hr=S_OK; |
700 | EX_TRY |
701 | { |
702 | if (domainfile && ((DomainFile*)domainfile)->GetFile()) |
703 | { |
704 | *pHasNativeImage=((DomainFile*)domainfile)->GetFile()->HasNativeImage(); |
705 | } |
706 | else |
707 | *pHasNativeImage = 0; |
708 | } |
709 | EX_CATCH_HRESULT(hr); |
710 | return hr; |
711 | } |
712 | |
713 | |
714 | void CLRTestHookInfo::Set(ICLRTestHook* hook) |
715 | { |
716 | LIMITED_METHOD_CONTRACT; |
717 | if (SUCCEEDED(hook->QueryInterface(IID_ICLRTestHook3,(void**)&m_Hook.v3))) |
718 | { |
719 | m_Version=3; |
720 | return; |
721 | } |
722 | else if (SUCCEEDED(hook->QueryInterface(IID_ICLRTestHook2,(void**)&m_Hook.v2))) |
723 | { |
724 | m_Version=2; |
725 | return; |
726 | } |
727 | else |
728 | { |
729 | m_Version=1; |
730 | } |
731 | hook->AddRef(); |
732 | m_Hook.v1=hook; |
733 | } |
734 | |
735 | ICLRTestHook* CLRTestHookInfo::v1() |
736 | { |
737 | return m_Hook.v1; |
738 | } |
739 | |
740 | ICLRTestHook2* CLRTestHookInfo::v2() |
741 | { |
742 | LIMITED_METHOD_CONTRACT; |
743 | if(m_Version==2) |
744 | return m_Hook.v2; |
745 | return NULL; |
746 | } |
747 | |
748 | ICLRTestHook3* CLRTestHookInfo::v3() |
749 | { |
750 | if(m_Version>=3) |
751 | return m_Hook.v3; |
752 | return NULL; |
753 | } |
754 | |
755 | |
756 | |
757 | //to make sure CLRTestHook is ok |
758 | static CLRTestHook _hook; |
759 | |
760 | #endif |
761 | |
762 | |
763 | |