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 | |
9 | #ifndef __CLRHOST_H__ |
10 | #define __CLRHOST_H__ |
11 | |
12 | #include "windows.h" // worth to include before mscoree.h so we are guaranteed to pick few definitions |
13 | #ifdef CreateSemaphore |
14 | #undef CreateSemaphore |
15 | #endif |
16 | #include "mscoree.h" |
17 | #include "clrinternal.h" |
18 | #include "switches.h" |
19 | #include "holder.h" |
20 | #include "new.hpp" |
21 | #include "staticcontract.h" |
22 | #include "predeftlsslot.h" |
23 | #include "safemath.h" |
24 | #include "debugreturn.h" |
25 | |
26 | #if !defined(_DEBUG_IMPL) && defined(_DEBUG) && !defined(DACCESS_COMPILE) |
27 | #define _DEBUG_IMPL 1 |
28 | #endif |
29 | |
30 | #define BEGIN_PRESERVE_LAST_ERROR \ |
31 | { \ |
32 | DWORD __dwLastError = ::GetLastError(); \ |
33 | DEBUG_ASSURE_NO_RETURN_BEGIN(PRESERVE_LAST_ERROR); \ |
34 | { |
35 | |
36 | #define END_PRESERVE_LAST_ERROR \ |
37 | } \ |
38 | DEBUG_ASSURE_NO_RETURN_END(PRESERVE_LAST_ERROR); \ |
39 | ::SetLastError(__dwLastError); \ |
40 | } |
41 | |
42 | // |
43 | // TRASH_LASTERROR macro sets bogus last error in debug builds to help find places that fail to save it |
44 | // |
45 | #ifdef _DEBUG |
46 | |
47 | #define LAST_ERROR_TRASH_VALUE 42424 /* = 0xa5b8 */ |
48 | |
49 | #define TRASH_LASTERROR \ |
50 | SetLastError(LAST_ERROR_TRASH_VALUE) |
51 | |
52 | #else // _DEBUG |
53 | |
54 | #define TRASH_LASTERROR |
55 | |
56 | #endif // _DEBUG |
57 | |
58 | IExecutionEngine *GetExecutionEngine(); |
59 | IEEMemoryManager *GetEEMemoryManager(); |
60 | |
61 | LPVOID ClrVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); |
62 | BOOL ClrVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType); |
63 | SIZE_T ClrVirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength); |
64 | BOOL ClrVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); |
65 | LPVOID ClrDebugAlloc (size_t size, LPCSTR pszFile, int iLineNo); |
66 | HANDLE ClrGetProcessHeap(); |
67 | HANDLE ClrHeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); |
68 | BOOL ClrHeapDestroy(HANDLE hHeap); |
69 | LPVOID ClrHeapAlloc(HANDLE hHeap, DWORD dwFlags, S_SIZE_T dwBytes); |
70 | BOOL ClrHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); |
71 | BOOL ClrHeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem); |
72 | HANDLE ClrGetProcessExecutableHeap(); |
73 | |
74 | |
75 | #ifdef FAILPOINTS_ENABLED |
76 | extern int RFS_HashStack(); |
77 | #endif |
78 | |
79 | |
80 | void ClrFlsAssociateCallback(DWORD slot, PTLS_CALLBACK_FUNCTION callback); |
81 | |
82 | typedef LPVOID* (*CLRFLSGETBLOCK)(); |
83 | extern CLRFLSGETBLOCK __ClrFlsGetBlock; |
84 | |
85 | // Combining getter/setter into a single call |
86 | inline void ClrFlsIncrementValue(DWORD slot, int increment) |
87 | { |
88 | STATIC_CONTRACT_NOTHROW; |
89 | STATIC_CONTRACT_GC_NOTRIGGER; |
90 | STATIC_CONTRACT_MODE_ANY; |
91 | STATIC_CONTRACT_CANNOT_TAKE_LOCK; |
92 | STATIC_CONTRACT_SO_TOLERANT; |
93 | |
94 | _ASSERTE(increment != 0); |
95 | |
96 | void **block = (*__ClrFlsGetBlock)(); |
97 | size_t value; |
98 | |
99 | if (block != NULL) |
100 | { |
101 | value = (size_t) block[slot]; |
102 | |
103 | _ASSERTE((increment > 0) || (value + increment < value)); |
104 | block[slot] = (void *) (value + increment); |
105 | } |
106 | else |
107 | { |
108 | BEGIN_PRESERVE_LAST_ERROR; |
109 | |
110 | ANNOTATION_VIOLATION(SOToleranceViolation); |
111 | |
112 | IExecutionEngine * pEngine = GetExecutionEngine(); |
113 | value = (size_t) pEngine->TLS_GetValue(slot); |
114 | |
115 | _ASSERTE((increment > 0) || (value + increment < value)); |
116 | pEngine->TLS_SetValue(slot, (void *) (value + increment)); |
117 | |
118 | END_PRESERVE_LAST_ERROR; |
119 | } |
120 | } |
121 | |
122 | |
123 | inline void * ClrFlsGetValue (DWORD slot) |
124 | { |
125 | STATIC_CONTRACT_NOTHROW; |
126 | STATIC_CONTRACT_GC_NOTRIGGER; |
127 | STATIC_CONTRACT_MODE_ANY; |
128 | STATIC_CONTRACT_CANNOT_TAKE_LOCK; |
129 | STATIC_CONTRACT_SO_TOLERANT; |
130 | |
131 | void **block = (*__ClrFlsGetBlock)(); |
132 | if (block != NULL) |
133 | { |
134 | return block[slot]; |
135 | } |
136 | else |
137 | { |
138 | ANNOTATION_VIOLATION(SOToleranceViolation); |
139 | |
140 | void * value = GetExecutionEngine()->TLS_GetValue(slot); |
141 | return value; |
142 | } |
143 | } |
144 | |
145 | |
146 | inline BOOL ClrFlsCheckValue(DWORD slot, void ** pValue) |
147 | { |
148 | STATIC_CONTRACT_NOTHROW; |
149 | STATIC_CONTRACT_GC_NOTRIGGER; |
150 | STATIC_CONTRACT_MODE_ANY; |
151 | STATIC_CONTRACT_SO_TOLERANT; |
152 | |
153 | #ifdef _DEBUG |
154 | *pValue = ULongToPtr(0xcccccccc); |
155 | #endif //_DEBUG |
156 | void **block = (*__ClrFlsGetBlock)(); |
157 | if (block != NULL) |
158 | { |
159 | *pValue = block[slot]; |
160 | return TRUE; |
161 | } |
162 | else |
163 | { |
164 | ANNOTATION_VIOLATION(SOToleranceViolation); |
165 | BOOL result = GetExecutionEngine()->TLS_CheckValue(slot, pValue); |
166 | return result; |
167 | } |
168 | } |
169 | |
170 | inline void ClrFlsSetValue(DWORD slot, void *pData) |
171 | { |
172 | STATIC_CONTRACT_NOTHROW; |
173 | STATIC_CONTRACT_GC_NOTRIGGER; |
174 | STATIC_CONTRACT_MODE_ANY; |
175 | STATIC_CONTRACT_CANNOT_TAKE_LOCK; |
176 | STATIC_CONTRACT_SO_TOLERANT; |
177 | |
178 | void **block = (*__ClrFlsGetBlock)(); |
179 | if (block != NULL) |
180 | { |
181 | block[slot] = pData; |
182 | } |
183 | else |
184 | { |
185 | BEGIN_PRESERVE_LAST_ERROR; |
186 | |
187 | ANNOTATION_VIOLATION(SOToleranceViolation); |
188 | GetExecutionEngine()->TLS_SetValue(slot, pData); |
189 | |
190 | END_PRESERVE_LAST_ERROR; |
191 | } |
192 | } |
193 | |
194 | typedef LPVOID (*FastAllocInProcessHeapFunc)(DWORD dwFlags, SIZE_T dwBytes); |
195 | extern FastAllocInProcessHeapFunc __ClrAllocInProcessHeap; |
196 | inline LPVOID ClrAllocInProcessHeap(DWORD dwFlags, S_SIZE_T dwBytes) |
197 | { |
198 | STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY; |
199 | if (dwBytes.IsOverflow()) |
200 | { |
201 | return NULL; |
202 | } |
203 | |
204 | #ifndef SELF_NO_HOST |
205 | return __ClrAllocInProcessHeap(dwFlags, dwBytes.Value()); |
206 | #else |
207 | #undef HeapAlloc |
208 | #undef GetProcessHeap |
209 | static HANDLE ProcessHeap = NULL; |
210 | if (ProcessHeap == NULL) |
211 | ProcessHeap = GetProcessHeap(); |
212 | return ::HeapAlloc(ProcessHeap,dwFlags,dwBytes.Value()); |
213 | #define HeapAlloc(hHeap, dwFlags, dwBytes) Dont_Use_HeapAlloc(hHeap, dwFlags, dwBytes) |
214 | #define GetProcessHeap() Dont_Use_GetProcessHeap() |
215 | #endif |
216 | } |
217 | |
218 | typedef BOOL (*FastFreeInProcessHeapFunc)(DWORD dwFlags, LPVOID lpMem); |
219 | extern FastFreeInProcessHeapFunc __ClrFreeInProcessHeap; |
220 | inline BOOL ClrFreeInProcessHeap(DWORD dwFlags, LPVOID lpMem) |
221 | { |
222 | STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY; |
223 | #ifndef SELF_NO_HOST |
224 | return __ClrFreeInProcessHeap(dwFlags, lpMem); |
225 | #else |
226 | #undef HeapFree |
227 | #undef GetProcessHeap |
228 | static HANDLE ProcessHeap = NULL; |
229 | if (ProcessHeap == NULL) |
230 | ProcessHeap = GetProcessHeap(); |
231 | return (BOOL)(BYTE)::HeapFree(ProcessHeap, dwFlags, lpMem); |
232 | #define HeapFree(hHeap, dwFlags, lpMem) Dont_Use_HeapFree(hHeap, dwFlags, lpMem) |
233 | #define GetProcessHeap() Dont_Use_GetProcessHeap() |
234 | #endif |
235 | } |
236 | |
237 | // Critical section support for CLR DLLs other than the the EE. |
238 | // Include the header defining each Crst type and its corresponding level (relative rank). This is |
239 | // auto-generated from a tool that takes a high-level description of each Crst type and its dependencies. |
240 | #include "crsttypes.h" |
241 | |
242 | // critical section api |
243 | CRITSEC_COOKIE ClrCreateCriticalSection(CrstType type, CrstFlags flags); |
244 | HRESULT ClrDeleteCriticalSection(CRITSEC_COOKIE cookie); |
245 | void ClrEnterCriticalSection(CRITSEC_COOKIE cookie); |
246 | void ClrLeaveCriticalSection(CRITSEC_COOKIE cookie); |
247 | |
248 | // event api |
249 | EVENT_COOKIE ClrCreateAutoEvent(BOOL bInitialState); |
250 | EVENT_COOKIE ClrCreateManualEvent(BOOL bInitialState); |
251 | void ClrCloseEvent(EVENT_COOKIE event); |
252 | BOOL ClrSetEvent(EVENT_COOKIE event); |
253 | BOOL ClrResetEvent(EVENT_COOKIE event); |
254 | DWORD ClrWaitEvent(EVENT_COOKIE event, DWORD dwMilliseconds, BOOL bAlertable); |
255 | |
256 | // semaphore api |
257 | SEMAPHORE_COOKIE ClrCreateSemaphore(DWORD dwInitial, DWORD dwMax); |
258 | void ClrCloseSemaphore(SEMAPHORE_COOKIE semaphore); |
259 | BOOL ClrReleaseSemaphore(SEMAPHORE_COOKIE semaphore, LONG lReleaseCount, LONG *lpPreviousCount); |
260 | DWORD ClrWaitSemaphore(SEMAPHORE_COOKIE semaphore, DWORD dwMilliseconds, BOOL bAlertable); |
261 | |
262 | // mutex api |
263 | MUTEX_COOKIE ClrCreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName); |
264 | void ClrCloseMutex(MUTEX_COOKIE mutex); |
265 | BOOL ClrReleaseMutex(MUTEX_COOKIE mutex); |
266 | DWORD ClrWaitForMutex(MUTEX_COOKIE mutex,DWORD dwMilliseconds,BOOL bAlertable); |
267 | DWORD ClrSleepEx(DWORD dwMilliseconds, BOOL bAlertable); |
268 | |
269 | // Rather than use the above APIs directly, it is recommended that holder classes |
270 | // be used. This guarantees that the locks will be vacated when the scope is popped, |
271 | // either on exception or on return. |
272 | |
273 | typedef Holder<CRITSEC_COOKIE, ClrEnterCriticalSection, ClrLeaveCriticalSection, NULL> CRITSEC_Holder; |
274 | |
275 | // Use this holder to manage CRITSEC_COOKIE allocation to ensure it will be released if anything goes wrong |
276 | FORCEINLINE void VoidClrDeleteCriticalSection(CRITSEC_COOKIE cs) { if (cs != NULL) ClrDeleteCriticalSection(cs); } |
277 | typedef Wrapper<CRITSEC_COOKIE, DoNothing<CRITSEC_COOKIE>, VoidClrDeleteCriticalSection, NULL> CRITSEC_AllocationHolder; |
278 | |
279 | class Event { |
280 | public: |
281 | Event () |
282 | : m_event(NULL) |
283 | {STATIC_CONTRACT_LEAF;} |
284 | ~Event () |
285 | { |
286 | STATIC_CONTRACT_WRAPPER; |
287 | CloseEvent(); |
288 | } |
289 | |
290 | void CreateAutoEvent(BOOL bInitialState) |
291 | { |
292 | STATIC_CONTRACT_WRAPPER; |
293 | m_event = ClrCreateAutoEvent(bInitialState); |
294 | } |
295 | void CreateManualEvent(BOOL bInitialState) |
296 | { |
297 | STATIC_CONTRACT_WRAPPER; |
298 | m_event = ClrCreateManualEvent(bInitialState); |
299 | } |
300 | void CloseEvent() |
301 | { |
302 | STATIC_CONTRACT_WRAPPER; |
303 | if (m_event != NULL) |
304 | ClrCloseEvent(m_event); |
305 | m_event = NULL; |
306 | } |
307 | |
308 | BOOL Set() |
309 | { |
310 | STATIC_CONTRACT_WRAPPER; |
311 | return ClrSetEvent(m_event); |
312 | } |
313 | BOOL Reset() |
314 | { |
315 | STATIC_CONTRACT_WRAPPER; |
316 | return ClrResetEvent(m_event); |
317 | } |
318 | DWORD Wait(DWORD dwMilliseconds, BOOL bAlertable) |
319 | { |
320 | STATIC_CONTRACT_WRAPPER; |
321 | return ClrWaitEvent(m_event, dwMilliseconds, bAlertable); |
322 | } |
323 | |
324 | private: |
325 | EVENT_COOKIE m_event; |
326 | }; |
327 | |
328 | class Semaphore { |
329 | public: |
330 | Semaphore () |
331 | : m_semaphore(NULL) |
332 | {STATIC_CONTRACT_LEAF;} |
333 | ~Semaphore () |
334 | { |
335 | STATIC_CONTRACT_WRAPPER; |
336 | Close(); |
337 | } |
338 | |
339 | void Create(DWORD dwInitial, DWORD dwMax) |
340 | { |
341 | STATIC_CONTRACT_WRAPPER; |
342 | m_semaphore = ClrCreateSemaphore(dwInitial, dwMax); |
343 | } |
344 | void Close() |
345 | { |
346 | STATIC_CONTRACT_WRAPPER; |
347 | if (m_semaphore != NULL) |
348 | ClrCloseSemaphore(m_semaphore); |
349 | m_semaphore = NULL; |
350 | } |
351 | |
352 | BOOL Release(LONG lReleaseCount, LONG* lpPreviousCount) |
353 | { |
354 | STATIC_CONTRACT_WRAPPER; |
355 | return ClrReleaseSemaphore(m_semaphore, lReleaseCount, lpPreviousCount); |
356 | } |
357 | DWORD Wait(DWORD dwMilliseconds, BOOL bAlertable) |
358 | { |
359 | STATIC_CONTRACT_WRAPPER; |
360 | return ClrWaitSemaphore(m_semaphore, dwMilliseconds, bAlertable); |
361 | } |
362 | |
363 | private: |
364 | SEMAPHORE_COOKIE m_semaphore; |
365 | }; |
366 | |
367 | HMODULE GetCLRModule (); |
368 | |
369 | #ifndef FEATURE_NO_HOST |
370 | /* |
371 | Here we start the list of functions we want to deprecate. |
372 | We use a define to generate a linker error. |
373 | We must insure to include the header file that has the definition we are about |
374 | to deprecate before we use the #define otherwise we will run into a linker error |
375 | when legitimately undef'ing the function |
376 | */ |
377 | |
378 | // |
379 | // following are windows deprecates |
380 | // |
381 | #include <windows.h> |
382 | |
383 | /* |
384 | If you are reading this, you have probably tracked down the fact that memory Alloc, |
385 | etc. don't work inside your DLL because you are using src\inc & src\utilcode |
386 | services. |
387 | You need to use the ClrXXX equivalent functions to properly guarantee your code |
388 | works correctly wrt hosting and others execution engine requirements. |
389 | Check the list of Clr functions above |
390 | */ |
391 | |
392 | #define GetProcessHeap() \ |
393 | Dont_Use_GetProcessHeap() |
394 | |
395 | #define VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) \ |
396 | Dont_Use_VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) |
397 | |
398 | #define VirtualFree(lpAddress, dwSize, dwFreeType) \ |
399 | Dont_Use_VirtualFree(lpAddress, dwSize, dwFreeType) |
400 | |
401 | #define VirtualQuery(lpAddress, lpBuffer, dwLength) \ |
402 | Dont_Use_VirtualQuery(lpAddress, lpBuffer, dwLength) |
403 | |
404 | #define VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect) \ |
405 | Dont_Use_VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect) |
406 | |
407 | #define HeapCreate(flOptions, dwInitialSize, dwMaximumSize) \ |
408 | Dont_Use_HeapCreate(flOptions, dwInitialSize, dwMaximumSize) |
409 | |
410 | #define HeapDestroy(hHeap) \ |
411 | Dont_Use_HeapDestroy(hHeap) |
412 | |
413 | #define HeapAlloc(hHeap, dwFlags, dwBytes) \ |
414 | Dont_Use_HeapAlloc(hHeap, dwFlags, dwBytes) |
415 | |
416 | #define HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes) \ |
417 | Dont_Use_HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes) |
418 | |
419 | #define HeapFree(hHeap, dwFlags, lpMem) \ |
420 | Dont_Use_HeapFree(hHeap, dwFlags, lpMem) |
421 | |
422 | #define HeapValidate(hHeap, dwFlags, lpMem) \ |
423 | Dont_Use_HeapValidate(hHeap, dwFlags, lpMem) |
424 | |
425 | #define LocalAlloc(uFlags, uBytes) \ |
426 | Dont_Use_LocalAlloc(uFlags, uBytes) |
427 | |
428 | #define LocalFree(hMem) \ |
429 | Dont_Use_LocalFree(hMem) |
430 | |
431 | #define LocalReAlloc(hMem, uBytes, uFlags) \ |
432 | Dont_Use_LocalReAlloc(hMem, uBytes, uFlags) |
433 | |
434 | #define GlobalAlloc(uFlags, dwBytes) \ |
435 | Dont_Use_GlobalAlloc(uFlags, dwBytes) |
436 | |
437 | #define GlobalFree(hMem) \ |
438 | Dont_Use_GlobalFree(hMem) |
439 | |
440 | //#define ExitThread Dont_Use_ExitThread |
441 | |
442 | #define ExitProcess Dont_Use_ExitProcess |
443 | |
444 | /* |
445 | If you are reading this, you have probably tracked down the fact that TlsAlloc, |
446 | etc. don't work inside your DLL because you are using src\inc & src\utilcode |
447 | services. |
448 | |
449 | This is because the CLR can operate in a fiberized environment under host control. |
450 | When this is the case, logical thread local storage must be fiber-relative rather |
451 | than thread-relative. |
452 | |
453 | Although the OS provides FLS routines on .NET Server, it does not yet provide |
454 | those services on WinXP or Win2K. So you cannot just use fiber routines from |
455 | the OS. |
456 | |
457 | Instead, you must use the ClrFls_ routines described above. However, there are |
458 | some important differences between these EE-provided services and the OS TLS |
459 | services that you are used to: |
460 | |
461 | 1) There is no TlsAlloc/FlsAlloc equivalent. You must statically describe |
462 | your needs via the PredefinedTlsSlots below. If you have dynamic requirements, |
463 | you should give yourself a single static slot and then build your dynamic |
464 | requirements on top of this. The lack of a dynamic API is a deliberate |
465 | choice on my part, rather than lack of time. |
466 | |
467 | 2) You can provide a cleanup routine, which we will call on your behalf. However, |
468 | this can be called on a different thread than the "thread" (fiber or thread) |
469 | which holds the data. It can be called after that thread has actually been |
470 | terminated. It can be called before you see a DLL_THREAD_DETACH on your |
471 | physical thread. The circumstances vary based on whether the process is hosted |
472 | and based on whether TS_WeOwn is set on the internal Thread object. Make |
473 | no assumptions here. |
474 | */ |
475 | #define TlsAlloc() \ |
476 | Dont_Use_TlsAlloc() |
477 | |
478 | #define TlsSetValue(dwTlsIndex, lpTlsValue) \ |
479 | Dont_Use_TlsSetValue(dwTlsIndex, lpTlsValue) |
480 | |
481 | #define TlsGetValue(dwTlsIndex) \ |
482 | Dont_Use_TlsGetValue(dwTlsIndex) |
483 | |
484 | #define TlsFree(dwTlsIndex) \ |
485 | Dont_Use_TlsFree(dwTlsIndex) |
486 | |
487 | |
488 | /* |
489 | If you are reading this, you have probably tracked down the fact that synchronization objects |
490 | and critical sections don't work inside your DLL because you are using src\inc & src\utilcode services. |
491 | Please refer to the ClrXXX functions described above to make proper use of synchronization obejct, etc. |
492 | |
493 | Also it's extremely useful to look at the Holder classes defined above. |
494 | Those classes provide a nice encapsulation for synchronization object that allows automatic release of locks. |
495 | */ |
496 | #define InitializeCriticalSection(lpCriticalSection) \ |
497 | Dont_Use_InitializeCriticalSection(lpCriticalSection) |
498 | |
499 | #define InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount) \ |
500 | Dont_Use_InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount) |
501 | |
502 | #define DeleteCriticalSection(lpCriticalSection) \ |
503 | Dont_Use_DeleteCriticalSection(lpCriticalSection) |
504 | |
505 | #define EnterCriticalSection(lpCriticalSection) \ |
506 | Dont_Use_EnterCriticalSection(lpCriticalSection) |
507 | |
508 | #define TryEnterCriticalSection(lpCriticalSection) \ |
509 | Dont_Use_TryEnterCriticalSection(lpCriticalSection) |
510 | |
511 | #define LeaveCriticalSection(lpCriticalSection) \ |
512 | Dont_Use_LeaveCriticalSection(lpCriticalSection) |
513 | |
514 | #ifdef CreateEvent |
515 | #undef CreateEvent |
516 | #endif |
517 | #define CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName) \ |
518 | Dont_Use_CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName) |
519 | |
520 | #ifdef OpenEvent |
521 | #undef OpenEvent |
522 | #endif |
523 | #define OpenEvent(dwDesiredAccess, bInheritHandle, lpName) \ |
524 | Dont_Use_OpenEvent(dwDesiredAccess, bInheritHandle, lpName) |
525 | |
526 | #define ResetEvent(hEvent) \ |
527 | Dont_Use_ResetEvent(hEvent) |
528 | |
529 | #define SetEvent(hEvent) \ |
530 | Dont_Use_SetEvent(hEvent) |
531 | |
532 | #define PulseEvent(hEvent) \ |
533 | Dont_Use_PulseEvent(hEvent) |
534 | |
535 | #ifdef CreateSemaphore |
536 | #undef CreateSemaphore |
537 | #endif |
538 | #define CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName) \ |
539 | Dont_Use_CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName) |
540 | |
541 | #ifdef OpenSemaphore |
542 | #undef OpenSemaphore |
543 | #endif |
544 | #define OpenSemaphore(dwDesiredAccess, bInheritHandle, lpName) \ |
545 | Dont_Use_OpenSemaphore(dwDesiredAccess, bInheritHandle, lpName) |
546 | |
547 | #define ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount) \ |
548 | Dont_Use_ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount) |
549 | |
550 | #ifdef Sleep |
551 | #undef Sleep |
552 | #endif |
553 | #define Sleep(dwMilliseconds) \ |
554 | Dont_Use_Sleep(dwMilliseconds) |
555 | |
556 | #ifdef SleepEx |
557 | #undef SleepEx |
558 | #endif |
559 | #define SleepEx(dwMilliseconds,bAlertable) \ |
560 | Dont_Use_SleepEx(dwMilliseconds,bAlertable) |
561 | |
562 | // |
563 | // following are clib deprecates |
564 | // |
565 | #include <stdlib.h> |
566 | #include <malloc.h> |
567 | |
568 | #ifdef malloc |
569 | #undef malloc |
570 | #endif |
571 | |
572 | #define _CRT_EXCEPTION_NO_MALLOC |
573 | #define malloc(size) \ |
574 | Dont_Use_malloc(size) |
575 | |
576 | #ifdef realloc |
577 | #undef realloc |
578 | #endif |
579 | #define realloc(memblock, size) \ |
580 | Dont_Use_realloc(memblock, size) |
581 | |
582 | #ifdef free |
583 | #undef free |
584 | #endif |
585 | #define free(memblock) \ |
586 | Dont_Use_free(memblock) |
587 | |
588 | #endif //!FEATURE_NO_HOST |
589 | |
590 | extern void IncCantAllocCount(); |
591 | extern void DecCantAllocCount(); |
592 | |
593 | class CantAllocHolder |
594 | { |
595 | public: |
596 | CantAllocHolder () |
597 | { |
598 | IncCantAllocCount (); |
599 | } |
600 | ~CantAllocHolder() |
601 | { |
602 | DecCantAllocCount (); |
603 | } |
604 | }; |
605 | |
606 | // At places where want to allocate stress log, we need to first check if we are allowed to do so. |
607 | // If ClrTlsInfo doesn't exist for this thread, we take it as can alloc |
608 | inline bool IsInCantAllocRegion () |
609 | { |
610 | size_t count = 0; |
611 | if (ClrFlsCheckValue(TlsIdx_CantAllocCount, (LPVOID *)&count)) |
612 | { |
613 | _ASSERTE (count >= 0); |
614 | return count > 0; |
615 | } |
616 | return false; |
617 | } |
618 | // for stress log the rule is more restrict, we have to check the global counter too |
619 | extern BOOL IsInCantAllocStressLogRegion(); |
620 | |
621 | #include "genericstackprobe.inl" |
622 | |
623 | #endif |
624 | |