Modify affinity range config format for Windows
[platform/upstream/coreclr.git] / src / inc / utilcode.h
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 // UtilCode.h
6 //
7 // Utility functions implemented in UtilCode.lib.
8 //
9 //*****************************************************************************
10
11 #ifndef __UtilCode_h__
12 #define __UtilCode_h__
13
14 #include "crtwrap.h"
15 #include "winwrap.h"
16 #include <wchar.h>
17 #include <stdio.h>
18 #include <malloc.h>
19 #include <ole2.h>
20 #include <oleauto.h>
21 #include <limits.h>
22 #include "clrtypes.h"
23 #include "safewrap.h"
24 #include "volatile.h"
25 #include <daccess.h>
26 #include "clrhost.h"
27 #include "debugmacros.h"
28 #include "corhlprpriv.h"
29 #include "winnls.h"
30 #include "check.h"
31 #include "safemath.h"
32 #include "new.hpp"
33
34 #ifdef PAL_STDCPP_COMPAT
35 #include <type_traits>
36 #else
37 #include "clr_std/type_traits"
38 #endif
39
40 #include "contract.h"
41 #include "entrypoints.h"
42
43 #include "clrnt.h"
44
45 #include "random.h"
46
47 #define WINDOWS_KERNEL32_DLLNAME_A "kernel32"
48 #define WINDOWS_KERNEL32_DLLNAME_W W("kernel32")
49
50 #define CoreLibName_W W("System.Private.CoreLib")
51 #define CoreLibName_IL_W W("System.Private.CoreLib.dll")
52 #define CoreLibName_NI_W W("System.Private.CoreLib.ni.dll")
53 #define CoreLibName_TLB_W W("System.Private.CoreLib.tlb")
54 #define CoreLibName_A "System.Private.CoreLib"
55 #define CoreLibName_IL_A "System.Private.CoreLib.dll"
56 #define CoreLibName_NI_A "System.Private.CoreLib.ni.dll"
57 #define CoreLibName_TLB_A "System.Private.CoreLib.tlb"
58 #define CoreLibNameLen 22
59 #define CoreLibSatelliteName_A "System.Private.CoreLib.resources"
60 #define CoreLibSatelliteNameLen 32
61 #define LegacyCoreLibName_A "mscorlib"
62
63 class StringArrayList;
64
65 #if !defined(_DEBUG_IMPL) && defined(_DEBUG) && !defined(DACCESS_COMPILE)
66 #define _DEBUG_IMPL 1
67 #endif
68
69 #ifdef _TARGET_ARM_
70
71 // Under ARM we generate code only with Thumb encoding. In order to ensure we execute such code in the correct
72 // mode we must ensure the low-order bit is set in any code address we'll call as a sub-routine. In C++ this
73 // is handled automatically for us by the compiler. When generating and working with code generated
74 // dynamically we have to be careful to set or mask-out this bit as appropriate.
75 #ifndef THUMB_CODE
76 #define THUMB_CODE 1
77 #endif
78
79 // Given a WORD extract the bitfield [lowbit, highbit] (i.e. BitExtract(0xffff, 15, 0) == 0xffff).
80 inline WORD BitExtract(WORD wValue, DWORD highbit, DWORD lowbit)
81 {
82     _ASSERTE((highbit < 16) && (lowbit < 16) && (highbit >= lowbit));
83     return (wValue >> lowbit) & ((1 << ((highbit - lowbit) + 1)) - 1);
84 }
85
86 // Determine whether an ARM Thumb mode instruction is 32-bit or 16-bit based on the first WORD of the
87 // instruction.
88 inline bool Is32BitInstruction(WORD opcode)
89 {
90     return BitExtract(opcode, 15, 11) >= 0x1d;
91 }
92
93 template <typename ResultType, typename SourceType>
94 inline ResultType DataPointerToThumbCode(SourceType pCode)
95 {
96     return (ResultType)(((UINT_PTR)pCode) | THUMB_CODE);
97 }
98
99 template <typename ResultType, typename SourceType>
100 inline ResultType ThumbCodeToDataPointer(SourceType pCode)
101 {
102     return (ResultType)(((UINT_PTR)pCode) & ~THUMB_CODE);
103 }
104
105 #endif // _TARGET_ARM_
106
107 // Convert from a PCODE to the corresponding PINSTR.  On many architectures this will be the identity function;
108 // on ARM, this will mask off the THUMB bit.
109 inline TADDR PCODEToPINSTR(PCODE pc)
110 {
111 #ifdef _TARGET_ARM_
112     return ThumbCodeToDataPointer<TADDR,PCODE>(pc);
113 #else
114     return dac_cast<PCODE>(pc);
115 #endif
116 }
117
118 // Convert from a PINSTR to the corresponding PCODE.  On many architectures this will be the identity function;
119 // on ARM, this will raise the THUMB bit.
120 inline PCODE PINSTRToPCODE(TADDR addr)
121 {
122 #ifdef _TARGET_ARM_
123     return DataPointerToThumbCode<PCODE,TADDR>(addr);
124 #else
125     return dac_cast<PCODE>(addr);
126 #endif
127 }
128
129 typedef LPCSTR  LPCUTF8;
130 typedef LPSTR   LPUTF8;
131
132 #include "nsutilpriv.h"
133
134 #include "stdmacros.h"
135
136 //********** Macros. **********************************************************
137 #ifndef FORCEINLINE
138  #if _MSC_VER < 1200
139    #define FORCEINLINE inline
140  #else
141    #define FORCEINLINE __forceinline
142  #endif
143 #endif
144
145 #ifndef DEBUG_NOINLINE
146 #if defined(_DEBUG)
147 #define DEBUG_NOINLINE NOINLINE
148 #else
149 #define DEBUG_NOINLINE
150 #endif
151 #endif
152
153 #include <stddef.h> // for offsetof
154
155 #ifndef NumItems
156 // Number of elements in a fixed-size array
157 #define NumItems(s) (sizeof(s) / sizeof(s[0]))
158 #endif
159
160 #ifndef StrLen
161 // Number of characters in a string literal. Excludes terminating NULL.
162 #define StrLen(str) (NumItems(str) - 1)
163 #endif
164
165
166 #define IS_DIGIT(ch) ((ch >= W('0')) && (ch <= W('9')))
167 #define DIGIT_TO_INT(ch) (ch - W('0'))
168 #define INT_TO_DIGIT(i) ((WCHAR)(W('0') + i))
169
170 #define IS_HEXDIGIT(ch) (((ch >= W('a')) && (ch <= W('f'))) || \
171                          ((ch >= W('A')) && (ch <= W('F'))))
172 #define HEXDIGIT_TO_INT(ch) ((towlower(ch) - W('a')) + 10)
173 #define INT_TO_HEXDIGIT(i) ((WCHAR)(W('a') + (i - 10)))
174
175
176 // Helper will 4 byte align a value, rounding up.
177 #define ALIGN4BYTE(val) (((val) + 3) & ~0x3)
178
179 #ifdef  _DEBUG
180 #define DEBUGARG(x)         , x
181 #else
182 #define DEBUGARG(x)
183 #endif
184
185 #ifndef sizeofmember
186 // Returns the size of a class or struct member.
187 #define sizeofmember(c,m) (sizeof(((c*)0)->m))
188 #endif
189
190 //=--------------------------------------------------------------------------=
191 // Prefast helpers.
192 //
193
194 #include "safemath.h"
195
196
197 //=--------------------------------------------------------------------------=
198 // string helpers.
199
200 //
201 // given and ANSI String, copy it into a wide buffer.
202 // be careful about scoping when using this macro!
203 //
204 // how to use the below two macros:
205 //
206 //  ...
207 //  LPSTR pszA;
208 //  pszA = MyGetAnsiStringRoutine();
209 //  MAKE_WIDEPTR_FROMANSI(pwsz, pszA);
210 //  MyUseWideStringRoutine(pwsz);
211 //  ...
212 //
213 // similarily for MAKE_ANSIPTR_FROMWIDE.  note that the first param does not
214 // have to be declared, and no clean up must be done.
215 //
216
217 // We'll define an upper limit that allows multiplication by 4 (the max
218 // bytes/char in UTF-8) but still remains positive, and allows some room for pad.
219 // Under normal circumstances, we should never get anywhere near this limit.
220 #define MAKE_MAX_LENGTH 0x1fffff00
221
222 #ifndef MAKE_TOOLONGACTION
223 #define MAKE_TOOLONGACTION ThrowHR(COR_E_OVERFLOW)
224 #endif
225
226 #ifndef MAKE_TRANSLATIONFAILED
227 #define MAKE_TRANSLATIONFAILED ThrowWin32(ERROR_NO_UNICODE_TRANSLATION)
228 #endif
229
230 // This version throws on conversion errors (ie, no best fit character
231 // mapping to characters that look similar, and no use of the default char
232 // ('?') when printing out unrepresentable characters.  Use this method for
233 // most development in the EE, especially anything like metadata or class
234 // names.  See the BESTFIT version if you're printing out info to the console.
235 #define MAKE_MULTIBYTE_FROMWIDE(ptrname, widestr, codepage) \
236     int __l##ptrname = (int)wcslen(widestr);        \
237     if (__l##ptrname > MAKE_MAX_LENGTH)         \
238         MAKE_TOOLONGACTION;                     \
239     __l##ptrname = (int)((__l##ptrname + 1) * 2 * sizeof(char)); \
240     CQuickBytes __CQuickBytes##ptrname; \
241     __CQuickBytes##ptrname.AllocThrows(__l##ptrname); \
242     BOOL __b##ptrname; \
243     DWORD __cBytes##ptrname = WszWideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, widestr, -1, (LPSTR)__CQuickBytes##ptrname.Ptr(), __l##ptrname, NULL, &__b##ptrname); \
244     if (__b##ptrname || (__cBytes##ptrname == 0 && (widestr[0] != W('\0')))) { \
245         MAKE_TRANSLATIONFAILED; \
246     } \
247     LPSTR ptrname = (LPSTR)__CQuickBytes##ptrname.Ptr()
248
249 // This version does best fit character mapping and also allows the use
250 // of the default char ('?') for any Unicode character that isn't
251 // representable.  This is reasonable for writing to the console, but
252 // shouldn't be used for most string conversions.
253 #define MAKE_MULTIBYTE_FROMWIDE_BESTFIT(ptrname, widestr, codepage) \
254     int __l##ptrname = (int)wcslen(widestr);        \
255     if (__l##ptrname > MAKE_MAX_LENGTH)         \
256         MAKE_TOOLONGACTION;                     \
257     __l##ptrname = (int)((__l##ptrname + 1) * 2 * sizeof(char)); \
258     CQuickBytes __CQuickBytes##ptrname; \
259     __CQuickBytes##ptrname.AllocThrows(__l##ptrname); \
260     DWORD __cBytes##ptrname = WszWideCharToMultiByte(codepage, 0, widestr, -1, (LPSTR)__CQuickBytes##ptrname.Ptr(), __l##ptrname, NULL, NULL); \
261     if (__cBytes##ptrname == 0 && __l##ptrname != 0) { \
262         MAKE_TRANSLATIONFAILED; \
263     } \
264     LPSTR ptrname = (LPSTR)__CQuickBytes##ptrname.Ptr()
265
266 // Use for anything critical other than output to console, where weird
267 // character mappings are unacceptable.
268 #define MAKE_ANSIPTR_FROMWIDE(ptrname, widestr) MAKE_MULTIBYTE_FROMWIDE(ptrname, widestr, CP_ACP)
269
270 // Use for output to the console.
271 #define MAKE_ANSIPTR_FROMWIDE_BESTFIT(ptrname, widestr) MAKE_MULTIBYTE_FROMWIDE_BESTFIT(ptrname, widestr, CP_ACP)
272
273 #define MAKE_WIDEPTR_FROMANSI(ptrname, ansistr) \
274     CQuickBytes __qb##ptrname; \
275     int __l##ptrname; \
276     __l##ptrname = WszMultiByteToWideChar(CP_ACP, 0, ansistr, -1, 0, 0); \
277     if (__l##ptrname > MAKE_MAX_LENGTH) \
278         MAKE_TOOLONGACTION; \
279     LPWSTR ptrname = (LPWSTR) __qb##ptrname.AllocThrows((__l##ptrname+1)*sizeof(WCHAR));  \
280     if (WszMultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, ansistr, -1, ptrname, __l##ptrname) == 0) { \
281         MAKE_TRANSLATIONFAILED; \
282     }
283
284 #define MAKE_WIDEPTR_FROMANSI_NOTHROW(ptrname, ansistr) \
285     CQuickBytes __qb##ptrname; \
286     LPWSTR ptrname = 0; \
287     int __l##ptrname; \
288     __l##ptrname = WszMultiByteToWideChar(CP_ACP, 0, ansistr, -1, 0, 0); \
289     if (__l##ptrname <= MAKE_MAX_LENGTH) { \
290         ptrname = (LPWSTR) __qb##ptrname.AllocNoThrow((__l##ptrname+1)*sizeof(WCHAR));  \
291         if (ptrname) { \
292             if (WszMultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, ansistr, -1, ptrname, __l##ptrname) != 0) { \
293                 ptrname[__l##ptrname] = 0; \
294             } else { \
295                 ptrname = 0; \
296             } \
297         } \
298     }
299
300 #define MAKE_UTF8PTR_FROMWIDE(ptrname, widestr) CQuickBytes _##ptrname; _##ptrname.ConvertUnicode_Utf8(widestr); LPSTR ptrname = (LPSTR) _##ptrname.Ptr();
301
302 #define MAKE_UTF8PTR_FROMWIDE_NOTHROW(ptrname, widestr) \
303     CQuickBytes __qb##ptrname; \
304     int __l##ptrname = (int)wcslen(widestr); \
305     LPUTF8 ptrname = 0; \
306     if (__l##ptrname <= MAKE_MAX_LENGTH) { \
307         __l##ptrname = (int)((__l##ptrname + 1) * 2 * sizeof(char)); \
308         ptrname = (LPUTF8) __qb##ptrname.AllocNoThrow(__l##ptrname); \
309     } \
310     if (ptrname) { \
311         INT32 __lresult##ptrname=WszWideCharToMultiByte(CP_UTF8, 0, widestr, -1, ptrname, __l##ptrname-1, NULL, NULL); \
312         DWORD __dwCaptureLastError##ptrname = ::GetLastError(); \
313         if ((__lresult##ptrname==0) && (((LPCWSTR)widestr)[0] != W('\0'))) { \
314             if (__dwCaptureLastError##ptrname==ERROR_INSUFFICIENT_BUFFER) { \
315                 INT32 __lsize##ptrname=WszWideCharToMultiByte(CP_UTF8, 0, widestr, -1, NULL, 0, NULL, NULL); \
316                 ptrname = (LPSTR) __qb##ptrname .AllocNoThrow(__lsize##ptrname); \
317                 if (ptrname) { \
318                     if (WszWideCharToMultiByte(CP_UTF8, 0, widestr, -1, ptrname, __lsize##ptrname, NULL, NULL) != 0) { \
319                         ptrname[__l##ptrname] = 0; \
320                     } else { \
321                         ptrname = 0; \
322                     } \
323                 } \
324             } \
325             else { \
326                 ptrname = 0; \
327             } \
328         } \
329     } \
330
331 #define MAKE_WIDEPTR_FROMUTF8N(ptrname, utf8str, n8chrs) \
332     CQuickBytes __qb##ptrname; \
333     int __l##ptrname; \
334     __l##ptrname = WszMultiByteToWideChar(CP_UTF8, 0, utf8str, n8chrs, 0, 0); \
335     if (__l##ptrname > MAKE_MAX_LENGTH) \
336         MAKE_TOOLONGACTION; \
337     LPWSTR ptrname = (LPWSTR) __qb##ptrname .AllocThrows((__l##ptrname+1)*sizeof(WCHAR)); \
338     if (0==WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8str, n8chrs, ptrname, __l##ptrname)) { \
339         MAKE_TRANSLATIONFAILED; \
340     } \
341     ptrname[__l##ptrname] = 0;
342
343
344 #define MAKE_WIDEPTR_FROMUTF8(ptrname, utf8str) CQuickBytes _##ptrname;  _##ptrname.ConvertUtf8_Unicode(utf8str); LPCWSTR ptrname = (LPCWSTR) _##ptrname.Ptr();
345
346
347 #define MAKE_WIDEPTR_FROMUTF8N_NOTHROW(ptrname, utf8str, n8chrs) \
348     CQuickBytes __qb##ptrname; \
349     int __l##ptrname; \
350     LPWSTR ptrname = 0; \
351     __l##ptrname = WszMultiByteToWideChar(CP_UTF8, 0, utf8str, n8chrs, 0, 0); \
352     if (__l##ptrname <= MAKE_MAX_LENGTH) { \
353         ptrname = (LPWSTR) __qb##ptrname.AllocNoThrow((__l##ptrname+1)*sizeof(WCHAR));  \
354         if (ptrname) { \
355             if (WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8str, n8chrs, ptrname, __l##ptrname) != 0) { \
356                 ptrname[__l##ptrname] = 0; \
357             } else { \
358                 ptrname = 0; \
359             } \
360         } \
361     }
362
363 #define MAKE_WIDEPTR_FROMUTF8_NOTHROW(ptrname, utf8str)   MAKE_WIDEPTR_FROMUTF8N_NOTHROW(ptrname, utf8str, -1)
364
365 // This method takes the number of characters
366 #define MAKE_MULTIBYTE_FROMWIDEN(ptrname, widestr, _nCharacters, _pCnt, codepage)        \
367     CQuickBytes __qb##ptrname; \
368     int __l##ptrname; \
369     __l##ptrname = WszWideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, widestr, _nCharacters, NULL, 0, NULL, NULL);           \
370     if (__l##ptrname > MAKE_MAX_LENGTH) \
371         MAKE_TOOLONGACTION; \
372     ptrname = (LPUTF8) __qb##ptrname .AllocThrows(__l##ptrname+1); \
373     BOOL __b##ptrname; \
374     DWORD _pCnt = WszWideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, widestr, _nCharacters, ptrname, __l##ptrname, NULL, &__b##ptrname);  \
375     if (__b##ptrname || (_pCnt == 0 && _nCharacters > 0)) { \
376         MAKE_TRANSLATIONFAILED; \
377     } \
378     ptrname[__l##ptrname] = 0;
379
380 #define MAKE_MULTIBYTE_FROMWIDEN_BESTFIT(ptrname, widestr, _nCharacters, _pCnt, codepage)        \
381     CQuickBytes __qb##ptrname; \
382     int __l##ptrname; \
383     __l##ptrname = WszWideCharToMultiByte(codepage, 0, widestr, _nCharacters, NULL, 0, NULL, NULL);           \
384     if (__l##ptrname > MAKE_MAX_LENGTH) \
385         MAKE_TOOLONGACTION; \
386     ptrname = (LPUTF8) __qb##ptrname .AllocThrows(__l##ptrname+1); \
387     DWORD _pCnt = WszWideCharToMultiByte(codepage, 0, widestr, _nCharacters, ptrname, __l##ptrname, NULL, NULL);  \
388     if (_pCnt == 0 && _nCharacters > 0) { \
389         MAKE_TRANSLATIONFAILED; \
390     } \
391     ptrname[__l##ptrname] = 0;
392
393 #define MAKE_ANSIPTR_FROMWIDEN(ptrname, widestr, _nCharacters, _pCnt)        \
394        MAKE_MULTIBYTE_FROMWIDEN(ptrname, widestr, _nCharacters, _pCnt, CP_ACP)
395
396
397 inline
398 LPWSTR DuplicateString(
399     LPCWSTR wszString,
400     size_t  cchString)
401 {
402     STATIC_CONTRACT_NOTHROW;
403
404     LPWSTR wszDup = NULL;
405     if (wszString != NULL)
406     {
407         wszDup = new (nothrow) WCHAR[cchString + 1];
408         if (wszDup != NULL)
409         {
410             wcscpy_s(wszDup, cchString + 1, wszString);
411         }
412     }
413     return wszDup;
414 }
415
416 inline
417 LPWSTR DuplicateString(
418     LPCWSTR wszString)
419 {
420     STATIC_CONTRACT_NOTHROW;
421
422     if (wszString != NULL)
423     {
424         return DuplicateString(wszString, wcslen(wszString));
425     }
426     else
427     {
428         return NULL;
429     }
430 }
431
432 void DECLSPEC_NORETURN ThrowOutOfMemory();
433
434 inline
435 LPWSTR DuplicateStringThrowing(
436     LPCWSTR wszString,
437     size_t cchString)
438 {
439     STATIC_CONTRACT_THROWS;
440
441     if (wszString == NULL)
442         return NULL;
443
444     LPWSTR wszDup = DuplicateString(wszString, cchString);
445     if (wszDup == NULL)
446         ThrowOutOfMemory();
447
448     return wszDup;
449 }
450
451 inline
452 LPWSTR DuplicateStringThrowing(
453     LPCWSTR wszString)
454 {
455     STATIC_CONTRACT_THROWS;
456
457     if (wszString == NULL)
458         return NULL;
459
460     LPWSTR wszDup = DuplicateString(wszString);
461     if (wszDup == NULL)
462         ThrowOutOfMemory();
463
464     return wszDup;
465 }
466
467
468 //*****************************************************************************
469 // Placement new is used to new and object at an exact location.  The pointer
470 // is simply returned to the caller without actually using the heap.  The
471 // advantage here is that you cause the ctor() code for the object to be run.
472 // This is ideal for heaps of C++ objects that need to get init'd multiple times.
473 // Example:
474 //      void        *pMem = GetMemFromSomePlace();
475 //      Foo *p = new (pMem) Foo;
476 //      DoSomething(p);
477 //      p->~Foo();
478 //*****************************************************************************
479 #ifndef __PLACEMENT_NEW_INLINE
480 #define __PLACEMENT_NEW_INLINE
481 inline void *__cdecl operator new(size_t, void *_P)
482 {
483     LIMITED_METHOD_DAC_CONTRACT;
484
485     return (_P);
486 }
487 #endif // __PLACEMENT_NEW_INLINE
488
489
490 /********************************************************************************/
491 /* portability helpers */
492 #ifdef _WIN64
493 #define IN_WIN64(x)     x
494 #define IN_WIN32(x)
495 #else
496 #define IN_WIN64(x)
497 #define IN_WIN32(x)     x
498 #endif
499
500 #ifdef _TARGET_64BIT_
501 #define IN_TARGET_64BIT(x)     x
502 #define IN_TARGET_32BIT(x)
503 #else
504 #define IN_TARGET_64BIT(x)
505 #define IN_TARGET_32BIT(x)     x
506 #endif
507
508 void * __cdecl
509 operator new(size_t n);
510
511 _Ret_bytecap_(n) void * __cdecl
512 operator new[](size_t n);
513
514 void __cdecl
515 operator delete(void *p) NOEXCEPT;
516
517 void __cdecl
518 operator delete[](void *p) NOEXCEPT;
519
520 #ifdef _DEBUG_IMPL
521 HRESULT _OutOfMemory(LPCSTR szFile, int iLine);
522 #define OutOfMemory() _OutOfMemory(__FILE__, __LINE__)
523 #else
524 inline HRESULT OutOfMemory()
525 {
526     LIMITED_METHOD_CONTRACT;
527     return (E_OUTOFMEMORY);
528 }
529 #endif
530
531 //*****************************************************************************
532 // Handle accessing localizable resource strings
533 //*****************************************************************************
534 // NOTE: Should use locale names as much as possible.  LCIDs don't support
535 // custom cultures on Vista+.
536 // TODO: This should always use the names
537 #ifdef FEATURE_USE_LCID    
538 typedef LCID LocaleID;
539 typedef LCID LocaleIDValue;
540 #else
541 typedef LPCWSTR LocaleID;
542 typedef WCHAR LocaleIDValue[LOCALE_NAME_MAX_LENGTH];
543 #endif
544
545 // Notes about the culture callbacks:
546 // - The language we're operating in can change at *runtime*!
547 // - A process may operate in *multiple* languages.
548 //     (ex: Each thread may have it's own language)
549 // - If we don't care what language we're in (or have no way of knowing),
550 //     then return a 0-length name and UICULTUREID_DONTCARE for the culture ID.
551 // - GetCultureName() and the GetCultureId() must be in sync (refer to the
552 //     same language).
553 // - We have two functions separate functions for better performance.
554 //     - The name is used to resolve a directory for MsCorRC.dll.
555 //     - The id is used as a key to map to a dll hinstance.
556
557 // Callback to obtain both the culture name and the culture's parent culture name
558 typedef HRESULT (*FPGETTHREADUICULTURENAMES)(__inout StringArrayList* pCultureNames);
559 #ifdef FEATURE_USE_LCID
560 // Callback to return the culture ID.
561 const LCID UICULTUREID_DONTCARE = (LCID)-1;
562 #else
563 const LPCWSTR UICULTUREID_DONTCARE = NULL;
564 #endif
565
566 typedef int (*FPGETTHREADUICULTUREID)(LocaleIDValue*);
567
568 HMODULE CLRLoadLibrary(LPCWSTR lpLibFileName);
569
570 HMODULE CLRLoadLibraryEx(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
571
572 BOOL CLRFreeLibrary(HMODULE hModule);
573
574 // Prevent people from using LoadStringRC & LoadStringRCEx from inside the product since it
575 // causes issues with having the wrong version picked up inside the shim.
576 #define LoadStringRC __error("From inside the CLR, use UtilLoadStringRC; LoadStringRC is only meant to be exported.")
577 #define LoadStringRCEx __error("From inside the CLR, use UtilLoadStringRCEx; LoadStringRC is only meant to be exported.")
578
579 // Load a string using the resources for the current module.
580 STDAPI UtilLoadStringRC(UINT iResouceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax, int bQuiet=FALSE);
581
582 #ifdef FEATURE_USE_LCID
583 STDAPI UtilLoadStringRCEx(LCID lcid, UINT iResourceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax, int bQuiet, int *pcwchUsed);
584 #endif
585
586 // Specify callbacks so that UtilLoadStringRC can find out which language we're in.
587 // If no callbacks specified (or both parameters are NULL), we default to the
588 // resource dll in the root (which is probably english).
589 void SetResourceCultureCallbacks(
590     FPGETTHREADUICULTURENAMES fpGetThreadUICultureNames,
591     FPGETTHREADUICULTUREID fpGetThreadUICultureId
592 );
593
594 void GetResourceCultureCallbacks(
595         FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
596         FPGETTHREADUICULTUREID* fpGetThreadUICultureId
597 );
598
599 #if !defined(DACCESS_COMPILE)
600 // Get the MUI ID, on downlevel platforms where MUI is not supported it
601 // returns the default system ID.
602 extern int GetMUILanguageID(LocaleIDValue* pResult);
603 extern HRESULT GetMUILanguageNames(__inout StringArrayList* pCultureNames);
604
605 #endif // !defined(DACCESS_COMPILE)
606
607 //*****************************************************************************
608 // Use this class by privately deriving from noncopyable to disallow copying of 
609 // your class.
610 //*****************************************************************************
611 class noncopyable
612 {
613 protected:
614     noncopyable()
615     {}
616     ~noncopyable()
617     {}
618
619 private:
620     noncopyable(const noncopyable&);
621     const noncopyable& operator=(const noncopyable&);
622 };
623
624 //*****************************************************************************
625 // Must associate each handle to an instance of a resource dll with the int
626 // that it represents
627 //*****************************************************************************
628 typedef HINSTANCE HRESOURCEDLL;
629
630
631 class CCulturedHInstance
632 {
633     LocaleIDValue   m_LangId;
634     HRESOURCEDLL    m_hInst;
635     BOOL            m_fMissing;
636     
637 public:
638     CCulturedHInstance()
639     {
640         LIMITED_METHOD_CONTRACT;
641         m_hInst = NULL;
642         m_fMissing = FALSE;
643     }
644     
645     BOOL HasID(LocaleID id)
646     {
647         _ASSERTE(m_hInst != NULL || m_fMissing);
648         if (id == UICULTUREID_DONTCARE)
649             return FALSE;
650         
651 #ifdef FEATURE_USE_LCID
652         return id == m_LangId;
653 #else
654         return wcscmp(id, m_LangId) == 0;
655 #endif
656     }
657     
658     HRESOURCEDLL GetLibraryHandle()
659     {
660         return m_hInst;
661     }
662     
663     BOOL IsSet()
664     {
665         return m_hInst != NULL;
666     }
667
668     BOOL IsMissing()
669     {
670         return m_fMissing;
671     }
672
673     void SetMissing(LocaleID id)
674     {
675         _ASSERTE(m_hInst == NULL);
676         SetId(id);
677         m_fMissing = TRUE;
678     }
679     
680     void Set(LocaleID id, HRESOURCEDLL hInst)
681     {
682         _ASSERTE(m_hInst == NULL);
683         _ASSERTE(m_fMissing == FALSE);
684         SetId(id);
685         m_hInst = hInst;
686     }
687   private:
688     void SetId(LocaleID id)
689     {
690 #ifdef FEATURE_USE_LCID
691         m_LangId = id;
692 #else
693         if (id != UICULTUREID_DONTCARE)
694         {
695             wcsncpy_s(m_LangId, NumItems(m_LangId), id, NumItems(m_LangId));
696             m_LangId[NumItems(m_LangId)-1] = W('\0');
697         }
698         else
699         {
700             m_LangId[0] = W('\0');
701         }
702 #endif
703     }
704  };
705
706 #ifndef DACCESS_COMPILE
707 void AddThreadPreferredUILanguages(StringArrayList* pArray);
708 #endif
709 //*****************************************************************************
710 // CCompRC manages string Resource access for COM+. This includes loading
711 // the MsCorRC.dll for resources as well allowing each thread to use a
712 // a different localized version.
713 //*****************************************************************************
714 class CCompRC
715 {
716 public:
717
718     enum ResourceCategory
719     {
720         // must be present
721         Required,                   
722         
723         // present in Desktop CLR and Core CLR + debug pack, an error
724         // If missing, get a generic error message instead
725         Error,           
726         
727         // present in Desktop CLR and Core CLR + debug pack, normal operation (e.g tracing)
728         // if missing, get a generic "resource not found" message instead
729         Debugging,           
730
731         // present in Desktop CLR, optional for CoreCLR
732         DesktopCLR,       
733
734         // might not be present, non essential
735         Optional
736     };
737
738     CCompRC()
739     {
740         // This constructor will be fired up on startup. Make sure it doesn't
741         // do anything besides zero-out out values.
742         m_bUseFallback = FALSE;
743
744         m_fpGetThreadUICultureId = NULL;
745         m_fpGetThreadUICultureNames = NULL;
746         
747
748         m_pHash = NULL;
749         m_nHashSize = 0;
750         m_csMap = NULL;
751         m_pResourceFile = NULL;
752 #ifdef FEATURE_PAL
753         m_pResourceDomain = NULL;
754 #endif // FEATURE_PAL
755
756     }// CCompRC
757
758     HRESULT Init(LPCWSTR pResourceFile, BOOL bUseFallback = FALSE);
759     void Destroy();
760
761     BOOL ShouldUseFallback()
762     {
763         LIMITED_METHOD_CONTRACT;
764         return m_bUseFallback;
765     };
766
767     static void SetIsMscoree() {s_bIsMscoree = TRUE;}
768
769     HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL);    
770     HRESULT LoadString(ResourceCategory eCategory, LocaleID langId, UINT iResourceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed);
771
772     void SetResourceCultureCallbacks(
773         FPGETTHREADUICULTURENAMES fpGetThreadUICultureNames,
774         FPGETTHREADUICULTUREID fpGetThreadUICultureId
775     );
776
777     void GetResourceCultureCallbacks(
778         FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
779         FPGETTHREADUICULTUREID* fpGetThreadUICultureId
780     );
781
782     HRESULT LoadMUILibrary(HRESOURCEDLL * pHInst);
783
784     // Get the default resource location (mscorrc.dll for desktop, mscorrc.debug.dll for CoreCLR)
785     static CCompRC* GetDefaultResourceDll();
786     // Get the generic messages dll (Silverlight only, mscorrc.dll)
787     static CCompRC* GetFallbackResourceDll();
788     static void ShutdownDefaultResourceDll();
789     static void GetDefaultCallbacks(
790                     FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
791                     FPGETTHREADUICULTUREID* fpGetThreadUICultureId)
792     {
793         WRAPPER_NO_CONTRACT;
794         m_DefaultResourceDll.GetResourceCultureCallbacks(
795                     fpGetThreadUICultureNames,
796                     fpGetThreadUICultureId);
797     }
798
799     static void SetDefaultCallbacks(
800                 FPGETTHREADUICULTURENAMES fpGetThreadUICultureNames,
801                 FPGETTHREADUICULTUREID fpGetThreadUICultureId)
802     {
803         WRAPPER_NO_CONTRACT;
804         // Either both are NULL or neither are NULL
805         _ASSERTE((fpGetThreadUICultureNames != NULL) ==
806                  (fpGetThreadUICultureId != NULL));
807
808         m_DefaultResourceDll.SetResourceCultureCallbacks(
809                 fpGetThreadUICultureNames,
810                 fpGetThreadUICultureId);
811
812         m_FallbackResourceDll.SetResourceCultureCallbacks(
813                 fpGetThreadUICultureNames,
814                 fpGetThreadUICultureId);
815
816     }
817
818 #ifdef USE_FORMATMESSAGE_WRAPPER
819
820 DWORD
821 PALAPI
822 static 
823 FormatMessage(
824            IN DWORD dwFlags,
825            IN LPCVOID lpSource,
826            IN DWORD dwMessageId,
827            IN DWORD dwLanguageId,
828            OUT LPWSTR lpBuffer,
829            IN DWORD nSize,
830            IN va_list *Arguments);
831 #endif // USE_FORMATMESSAGE_WRAPPER
832
833
834 private:
835     HRESULT GetLibrary(LocaleID langId, HRESOURCEDLL* phInst);
836 #ifndef DACCESS_COMPILE
837     HRESULT LoadLibraryHelper(HRESOURCEDLL *pHInst,
838                               SString& rcPath);
839     HRESULT LoadLibraryThrows(HRESOURCEDLL * pHInst);
840     HRESULT LoadLibrary(HRESOURCEDLL * pHInst);
841     HRESULT LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName);
842 #endif
843
844     // We do not have global constructors any more
845     static LONG     m_dwDefaultInitialized;
846     static CCompRC  m_DefaultResourceDll;
847     static LPCWSTR  m_pDefaultResource;
848
849     // fallback resources if debug pack is not installed
850     static LONG     m_dwFallbackInitialized;
851     static CCompRC  m_FallbackResourceDll;
852     static LPCWSTR  m_pFallbackResource;
853
854     // We must map between a thread's int and a dll instance.
855     // Since we only expect 1 language almost all of the time, we'll special case
856     // that and then use a variable size map for everything else.
857     CCulturedHInstance m_Primary;
858     CCulturedHInstance * m_pHash;
859     int m_nHashSize;
860
861     CRITSEC_COOKIE m_csMap;
862
863     LPCWSTR m_pResourceFile;
864 #ifdef FEATURE_PAL
865     // Resource domain is an ANSI string identifying a native resources file
866     static LPCSTR  m_pDefaultResourceDomain;
867     static LPCSTR  m_pFallbackResourceDomain;
868     LPCSTR m_pResourceDomain;
869 #endif // FEATURE_PAL
870
871     // Main accessors for hash
872     HRESOURCEDLL LookupNode(LocaleID langId, BOOL &fMissing);
873     HRESULT AddMapNode(LocaleID langId, HRESOURCEDLL hInst, BOOL fMissing = FALSE);
874
875     FPGETTHREADUICULTUREID m_fpGetThreadUICultureId;
876     FPGETTHREADUICULTURENAMES m_fpGetThreadUICultureNames;
877
878     BOOL m_bUseFallback;
879     static BOOL s_bIsMscoree;
880 };
881
882 HRESULT UtilLoadResourceString(CCompRC::ResourceCategory eCategory, UINT iResouceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax);
883
884
885 int UtilMessageBox(
886                   HWND hWnd,        // Handle to Owner Window
887                   UINT uText,       // Resource Identifier for Text message
888                   UINT uCaption,    // Resource Identifier for Caption
889                   UINT uType,       // Style of MessageBox
890                   BOOL displayForNonInteractive,    // Display even if the process is running non interactive 
891                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
892                   ...);             // Additional Arguments
893
894 int UtilMessageBoxNonLocalized(
895                   HWND hWnd,        // Handle to Owner Window
896                   LPCWSTR lpText,    // Resource Identifier for Text message
897                   LPCWSTR lpTitle,   // Resource Identifier for Caption
898                   UINT uType,       // Style of MessageBox
899                   BOOL displayForNonInteractive,    // Display even if the process is running non interactive 
900                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
901                   ...);             // Additional Arguments
902
903 int UtilMessageBoxVA(
904                   HWND hWnd,        // Handle to Owner Window
905                   UINT uText,       // Resource Identifier for Text message
906                   UINT uCaption,    // Resource Identifier for Caption
907                   UINT uType,       // Style of MessageBox
908                   BOOL displayForNonInteractive,    // Display even if the process is running non interactive 
909                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
910                   va_list args);    // Additional Arguments
911
912 int UtilMessageBoxNonLocalizedVA(
913                   HWND hWnd,        // Handle to Owner Window
914                   LPCWSTR lpText,    // Text message
915                   LPCWSTR lpCaption, // Caption
916                   UINT uType,       // Style of MessageBox
917                   BOOL displayForNonInteractive,    // Display even if the process is running non interactive 
918                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
919                   BOOL * pInputFromUser,            // To distinguish between user pressing abort vs. assuming abort.
920                   va_list args);    // Additional Arguments
921
922 int UtilMessageBoxNonLocalizedVA(
923                   HWND hWnd,        // Handle to Owner Window
924                   LPCWSTR lpText,    // Text message
925                   LPCWSTR lpCaption, // Caption
926                   LPCWSTR lpDetails, // Details that may be shown in a collapsed extended area of the dialog (Vista or higher).
927                   UINT uType,       // Style of MessageBox
928                   BOOL displayForNonInteractive,    // Display even if the process is running non interactive 
929                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
930                   BOOL * pInputFromUser,            // To distinguish between user pressing abort vs. assuming abort.
931                   va_list args);    // Additional Arguments
932
933 int UtilMessageBoxCatastrophic(
934                   UINT uText,       // Text for MessageBox
935                   UINT uTitle,      // Title for MessageBox
936                   UINT uType,       // Style of MessageBox
937                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
938                   ...);
939
940 int UtilMessageBoxCatastrophicNonLocalized(
941                   LPCWSTR lpText,    // Text for MessageBox
942                   LPCWSTR lpTitle,   // Title for MessageBox
943                   UINT uType,       // Style of MessageBox
944                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
945                   ...);
946
947 int UtilMessageBoxCatastrophicVA(
948                   UINT uText,       // Text for MessageBox
949                   UINT uTitle,      // Title for MessageBox
950                   UINT uType,       // Style of MessageBox
951                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
952                   va_list args);    // Additional Arguments
953
954 int UtilMessageBoxCatastrophicNonLocalizedVA(
955                   LPCWSTR lpText,    // Text for MessageBox
956                   LPCWSTR lpTitle,   // Title for MessageBox
957                   UINT uType,       // Style of MessageBox
958                   BOOL ShowFileNameInTitle, // Flag to show FileName in Caption
959                   va_list args);    // Additional Arguments
960
961
962 // The HRESULT_FROM_WIN32 macro evaluates its arguments three times.
963 // <TODO>TODO: All HRESULT_FROM_WIN32(GetLastError()) should be replaced by calls to
964 //  this helper function avoid code bloat</TODO>
965 inline HRESULT HRESULT_FROM_GetLastError()
966 {
967     WRAPPER_NO_CONTRACT;
968     DWORD dw = GetLastError();
969     // Make sure we return a failure
970     if (dw == ERROR_SUCCESS)
971     {
972         _ASSERTE(!"We were expecting to get an error code, but a success code is being returned. Check this code path for Everett!");
973         return E_FAIL;
974     }
975     else
976         return HRESULT_FROM_WIN32(dw);
977 }
978
979 inline HRESULT HRESULT_FROM_GetLastErrorNA()
980 {
981     WRAPPER_NO_CONTRACT;
982     DWORD dw = GetLastError();
983     // Make sure we return a failure
984     if (dw == ERROR_SUCCESS)
985         return E_FAIL;
986     else
987         return HRESULT_FROM_WIN32(dw);
988 }
989
990 inline HRESULT BadError(HRESULT hr)
991 {
992     LIMITED_METHOD_CONTRACT;
993     _ASSERTE(!"Serious Error");
994     return (hr);
995 }
996
997 #define TESTANDRETURN(test, hrVal)              \
998 {                                               \
999     int ___test = (int)(test);                  \
1000     if (! ___test)                              \
1001         return hrVal;                           \
1002 }
1003
1004 #define TESTANDRETURNPOINTER(pointer)           \
1005     TESTANDRETURN(pointer!=NULL, E_POINTER)
1006
1007 #define TESTANDRETURNMEMORY(pointer)            \
1008     TESTANDRETURN(pointer!=NULL, E_OUTOFMEMORY)
1009
1010 #define TESTANDRETURNHR(hr)                     \
1011     TESTANDRETURN(SUCCEEDED(hr), hr)
1012
1013 #define TESTANDRETURNARG(argtest)               \
1014     TESTANDRETURN(argtest, E_INVALIDARG)
1015
1016 // Quick validity check for HANDLEs that are returned by Win32 APIs that
1017 // use INVALID_HANDLE_VALUE instead of NULL to indicate an error
1018 inline BOOL IsValidHandle(HANDLE h)
1019 {
1020     LIMITED_METHOD_CONTRACT;
1021     return ((h != NULL) && (h != INVALID_HANDLE_VALUE));
1022 }
1023
1024 // Count the bits in a value in order iBits time.
1025 inline int CountBits(int iNum)
1026 {
1027     LIMITED_METHOD_CONTRACT;
1028     int iBits;
1029     for (iBits=0;  iNum;  iBits++)
1030         iNum = iNum & (iNum - 1);
1031     return (iBits);
1032 }
1033
1034 #include "bitposition.h"
1035
1036 // Convert the currency to a decimal and canonicalize.
1037 inline void VarDecFromCyCanonicalize(CY cyIn, DECIMAL* dec)
1038 {
1039     WRAPPER_NO_CONTRACT;
1040
1041     (*(ULONG*)dec) = 0;
1042     DECIMAL_HI32(*dec) = 0;
1043     if (cyIn.int64 == 0) // For compatibility, a currency of 0 emits the Decimal "0.0000" (scale set to 4).
1044     {
1045         DECIMAL_SCALE(*dec) = 4;
1046         DECIMAL_LO32(*dec) = 0;
1047         DECIMAL_MID32(*dec) = 0;
1048         return;
1049     }
1050
1051     if (cyIn.int64 < 0) {
1052         DECIMAL_SIGN(*dec) = DECIMAL_NEG;
1053         cyIn.int64 = -cyIn.int64;
1054     }
1055
1056     BYTE scale = 4;
1057     ULONGLONG absoluteCy = (ULONGLONG)cyIn.int64;
1058     while (scale != 0 && ((absoluteCy % 10) == 0))
1059     {
1060         scale--;
1061         absoluteCy /= 10;
1062     }
1063     DECIMAL_SCALE(*dec) = scale;
1064     DECIMAL_LO32(*dec) = (ULONG)absoluteCy;
1065     DECIMAL_MID32(*dec) = (ULONG)(absoluteCy >> 32);
1066 }
1067
1068 //*****************************************************************************
1069 //
1070 // Paths functions. Use these instead of the CRT.
1071 //
1072 //*****************************************************************************
1073 // secure version! Specify the size of the each buffer in count of elements
1074 void    SplitPath(const WCHAR *path,
1075                   __inout_z __inout_ecount_opt(driveSizeInWords) WCHAR *drive, int driveSizeInWords,
1076                   __inout_z __inout_ecount_opt(dirSizeInWords) WCHAR *dir, int dirSizeInWords,
1077                   __inout_z __inout_ecount_opt(fnameSizeInWords) WCHAR *fname, size_t fnameSizeInWords,
1078                   __inout_z __inout_ecount_opt(extSizeInWords) WCHAR *ext, size_t extSizeInWords);
1079
1080 //*******************************************************************************
1081 // A much more sensible version that just points to each section of the string.
1082 //*******************************************************************************
1083 void    SplitPathInterior(
1084     __in      LPCWSTR wszPath,
1085     __out_opt LPCWSTR *pwszDrive,    __out_opt size_t *pcchDrive,
1086     __out_opt LPCWSTR *pwszDir,      __out_opt size_t *pcchDir,
1087     __out_opt LPCWSTR *pwszFileName, __out_opt size_t *pcchFileName,
1088     __out_opt LPCWSTR *pwszExt,      __out_opt size_t *pcchExt);
1089
1090
1091 void    MakePath(__out CQuickWSTR &path,
1092                  __in LPCWSTR drive,
1093                  __in LPCWSTR dir,
1094                  __in LPCWSTR fname,
1095                  __in LPCWSTR ext);
1096
1097 WCHAR * FullPath(__out_ecount (maxlen) WCHAR *UserBuf, const WCHAR *path, size_t maxlen);
1098
1099 //*****************************************************************************
1100 //
1101 // SString version of the path functions.
1102 //
1103 //*****************************************************************************
1104 void    SplitPath(__in SString const &path,
1105                   __inout_opt SString *drive,
1106                   __inout_opt SString *dir,
1107                   __inout_opt SString *fname,
1108                   __inout_opt SString *ext);
1109
1110 #if !defined(NO_CLRCONFIG)
1111
1112 //*****************************************************************************
1113 //
1114 // **** REGUTIL - Static helper functions for reading/writing to Windows registry.
1115 //
1116 //*****************************************************************************
1117
1118
1119 class REGUTIL
1120 {
1121 public:
1122 //*****************************************************************************
1123
1124     enum CORConfigLevel
1125     {
1126         COR_CONFIG_ENV          = 0x01,
1127         COR_CONFIG_USER         = 0x02,
1128         COR_CONFIG_MACHINE      = 0x04,
1129         COR_CONFIG_FUSION       = 0x08,
1130
1131         COR_CONFIG_REGISTRY     = (COR_CONFIG_USER|COR_CONFIG_MACHINE|COR_CONFIG_FUSION),
1132         COR_CONFIG_ALL          = (COR_CONFIG_ENV|COR_CONFIG_USER|COR_CONFIG_MACHINE),
1133     };
1134
1135     //
1136     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
1137     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
1138     // 
1139     static DWORD GetConfigDWORD_DontUse_(
1140         LPCWSTR        name,
1141         DWORD          defValue,
1142         CORConfigLevel level = COR_CONFIG_ALL,
1143         BOOL           fPrependCOMPLUS = TRUE);
1144
1145     //
1146     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
1147     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
1148     // 
1149     static HRESULT GetConfigDWORD_DontUse_(
1150         LPCWSTR name,
1151         DWORD defValue,
1152         __out DWORD * result,
1153         CORConfigLevel level = COR_CONFIG_ALL,
1154         BOOL fPrependCOMPLUS = TRUE);
1155     
1156     static ULONGLONG GetConfigULONGLONG_DontUse_(
1157         LPCWSTR        name,
1158         ULONGLONG      defValue,
1159         CORConfigLevel level = COR_CONFIG_ALL,
1160         BOOL           fPrependCOMPLUS = TRUE);
1161
1162     //
1163     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
1164     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
1165     // 
1166     static DWORD GetConfigFlag_DontUse_(
1167         LPCWSTR        name,
1168         DWORD          bitToSet,
1169         BOOL           defValue = FALSE);
1170
1171     //
1172     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
1173     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
1174     // 
1175     static LPWSTR GetConfigString_DontUse_(
1176         LPCWSTR name,
1177         BOOL fPrependCOMPLUS = TRUE,
1178         CORConfigLevel level = COR_CONFIG_ALL,
1179         BOOL fUsePerfCache = TRUE);
1180
1181     static void   FreeConfigString(__in __in_z LPWSTR name);
1182
1183 private:
1184     static LPWSTR EnvGetString(LPCWSTR name, BOOL fPrependCOMPLUS);
1185 public:
1186
1187     static BOOL UseRegistry();
1188
1189 private:
1190 //*****************************************************************************
1191 // Get either a DWORD or ULONGLONG. Always puts the result in a ULONGLONG that
1192 // you can safely cast to a DWORD if fGetDWORD is TRUE.
1193 //*****************************************************************************    
1194     static HRESULT GetConfigInteger(
1195         LPCWSTR name,
1196         ULONGLONG defValue,
1197         __out ULONGLONG * result,
1198         BOOL fGetDWORD = TRUE,
1199         CORConfigLevel level = COR_CONFIG_ALL,
1200         BOOL fPrependCOMPLUS = TRUE);
1201 public:
1202
1203
1204 //*****************************************************************************
1205 // (Optional) Initialize the config registry cache
1206 // (see ConfigCacheValueNameSeenPerhaps, below.)
1207 //*****************************************************************************
1208     static void InitOptionalConfigCache();
1209
1210 private:
1211
1212
1213 //*****************************************************************************
1214 // Return TRUE if the registry value name might have been seen in the registry
1215 // at startup;
1216 // return FALSE if the value was definitely not seen at startup.
1217 //
1218 // Perf Optimization for VSWhidbey:113373.
1219 //*****************************************************************************
1220     static BOOL RegCacheValueNameSeenPerhaps(
1221         LPCWSTR name);
1222 //*****************************************************************************
1223 // Return TRUE if the environment variable name might have been seen at startup;
1224 // return FALSE if the value was definitely not seen at startup.
1225 //*****************************************************************************
1226     static BOOL EnvCacheValueNameSeenPerhaps(
1227         LPCWSTR name);
1228
1229     static BOOL s_fUseRegCache; // Enable registry cache; if FALSE, CCVNSP
1230                                  // always returns TRUE.
1231     static BOOL s_fUseEnvCache; // Enable env cache.
1232
1233     static BOOL s_fUseRegistry; // Allow lookups in the registry
1234
1235     // Open the .NetFramework keys once and cache the handles
1236     static HKEY s_hMachineFrameworkKey;
1237     static HKEY s_hUserFrameworkKey;
1238 };
1239
1240 // need this here because CLRConfig depends on REGUTIL, and ConfigStringHolder depends on CLRConfig
1241 #include "clrconfig.h" 
1242
1243 //-----------------------------------------------------------------------------
1244 // Wrapper for configuration strings.
1245 // This serves as a holder to call FreeConfigString.
1246 class ConfigStringHolder
1247 {
1248 public:
1249     ConfigStringHolder() { m_wszString = NULL; }
1250     ~ConfigStringHolder()
1251     {
1252         Clear();
1253     }
1254
1255     //
1256     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
1257     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
1258     // 
1259     void Init_DontUse_(LPCWSTR wszName)
1260     {
1261         Clear();
1262         m_wszString = REGUTIL::GetConfigString_DontUse_(wszName);
1263     }
1264
1265     // Free resources.
1266     void Clear()
1267     {
1268         if (m_wszString != NULL)
1269         {
1270             REGUTIL::FreeConfigString(m_wszString);
1271             m_wszString = NULL;
1272         }
1273     }
1274
1275     // Get the string value. NULL if not set.
1276     LPCWSTR Value()
1277     {
1278         return m_wszString;
1279     }
1280
1281 private:
1282     LPWSTR m_wszString;
1283 };
1284
1285 #endif // defined(NO_CLRCONFIG)
1286
1287 #include "ostype.h"
1288
1289 #define CLRGetTickCount64() GetTickCount64()
1290
1291 //
1292 // Use this function to initialize the s_CodeAllocHint
1293 // during startup. base is runtime .dll base address,
1294 // size is runtime .dll virtual size.
1295 //
1296 void InitCodeAllocHint(SIZE_T base, SIZE_T size, int randomPageOffset);
1297
1298
1299 //
1300 // Use this function to reset the s_CodeAllocHint
1301 // after unloading an AppDomain
1302 //
1303 void ResetCodeAllocHint();
1304
1305 //
1306 // Returns TRUE if p is located in near clr.dll that allows us
1307 // to use rel32 IP-relative addressing modes.
1308 //
1309 BOOL IsPreferredExecutableRange(void * p);
1310
1311 //
1312 // Allocate free memory that will be used for executable code
1313 // Handles the special requirements that we have on 64-bit platforms
1314 // where we want the executable memory to be located near mscorwks
1315 //
1316 BYTE * ClrVirtualAllocExecutable(SIZE_T dwSize, 
1317                                  DWORD flAllocationType,
1318                                  DWORD flProtect);
1319
1320 //
1321 // Allocate free memory within the range [pMinAddr..pMaxAddr] using
1322 // ClrVirtualQuery to find free memory and ClrVirtualAlloc to allocate it.
1323 //
1324 BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr,
1325                                    const BYTE *pMaxAddr,
1326                                    SIZE_T dwSize, 
1327                                    DWORD flAllocationType,
1328                                    DWORD flProtect);
1329
1330 //
1331 // Allocate free memory with specific alignment                                   
1332 //
1333 LPVOID ClrVirtualAllocAligned(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, SIZE_T alignment);
1334                                    
1335 //******************************************************************************
1336 // Returns the number of processors that a process has been configured to run on
1337 //******************************************************************************
1338 class NumaNodeInfo 
1339 {
1340 private:
1341     static BOOL m_enableGCNumaAware;
1342     static BOOL InitNumaNodeInfoAPI();
1343
1344 public:
1345     static BOOL CanEnableGCNumaAware();
1346     static void InitNumaNodeInfo();
1347
1348 #if !defined(FEATURE_REDHAWK)
1349 public:         // functions
1350
1351     static LPVOID VirtualAllocExNuma(HANDLE hProc, LPVOID lpAddr, SIZE_T size,
1352                                      DWORD allocType, DWORD prot, DWORD node);
1353     static BOOL GetNumaProcessorNodeEx(PPROCESSOR_NUMBER proc_no, PUSHORT node_no);
1354 #endif
1355 };
1356
1357 struct CPU_Group_Info 
1358 {
1359     WORD        nr_active;      // at most 64
1360     WORD        reserved[1];
1361     WORD        begin;
1362     WORD        end;
1363     DWORD_PTR   active_mask;
1364     DWORD       groupWeight;
1365     DWORD       activeThreadWeight;
1366 };
1367
1368 class CPUGroupInfo
1369 {
1370 private:
1371     static LONG m_initialization;
1372     static WORD m_nGroups;
1373     static WORD m_nProcessors;
1374     static BOOL m_enableGCCPUGroups;
1375     static BOOL m_threadUseAllCpuGroups;
1376     static WORD m_initialGroup;
1377     static CPU_Group_Info *m_CPUGroupInfoArray;
1378     static bool s_hadSingleProcessorAtStartup;
1379
1380     static BOOL InitCPUGroupInfoArray();
1381     static BOOL InitCPUGroupInfoRange();
1382     static void InitCPUGroupInfo();
1383     static BOOL IsInitialized();
1384
1385 public:
1386     static void EnsureInitialized();
1387     static BOOL CanEnableGCCPUGroups();
1388     static BOOL CanEnableThreadUseAllCpuGroups();
1389     static WORD GetNumActiveProcessors();
1390     static void GetGroupForProcessor(WORD processor_number, 
1391                     WORD *group_number, WORD *group_processor_number);
1392     static DWORD CalculateCurrentProcessorNumber();
1393     //static void PopulateCPUUsageArray(void * infoBuffer, ULONG infoSize);
1394
1395 #if !defined(FEATURE_REDHAWK)
1396 public:
1397     static BOOL GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP relationship,
1398                    SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *slpiex, PDWORD count); 
1399     static BOOL SetThreadGroupAffinity(HANDLE h,
1400                     GROUP_AFFINITY *groupAffinity, GROUP_AFFINITY *previousGroupAffinity);
1401     static BOOL GetThreadGroupAffinity(HANDLE h, GROUP_AFFINITY *groupAffinity);
1402     static BOOL GetSystemTimes(FILETIME *idleTime, FILETIME *kernelTime, FILETIME *userTime);
1403     static void ChooseCPUGroupAffinity(GROUP_AFFINITY *gf);
1404     static void ClearCPUGroupAffinity(GROUP_AFFINITY *gf);
1405     static BOOL GetCPUGroupRange(WORD group_number, WORD* group_begin, WORD* group_size);
1406 #endif
1407
1408 public:
1409     static bool HadSingleProcessorAtStartup()
1410     {
1411         LIMITED_METHOD_CONTRACT;
1412         return s_hadSingleProcessorAtStartup;
1413     }
1414 };
1415
1416 int GetCurrentProcessCpuCount();
1417 DWORD_PTR GetCurrentProcessCpuMask();
1418
1419 uint32_t GetOsPageSize();
1420
1421
1422 //*****************************************************************************
1423 // Return != 0 if the bit at the specified index in the array is on and 0 if
1424 // it is off.
1425 //*****************************************************************************
1426 inline int GetBit(PTR_BYTE pcBits,int iBit)
1427 {
1428     LIMITED_METHOD_CONTRACT;
1429     return (pcBits[iBit>>3] & (1 << (iBit & 0x7)));
1430 }
1431
1432 #ifdef DACCESS_COMPILE
1433 inline int GetBit(BYTE const * pcBits,int iBit)
1434 {
1435     WRAPPER_NO_CONTRACT;
1436     return GetBit(dac_cast<PTR_BYTE>(pcBits), iBit);
1437 }
1438 #endif
1439
1440 //*****************************************************************************
1441 // Set the state of the bit at the specified index based on the value of bOn.
1442 //*****************************************************************************
1443 inline void SetBit(PTR_BYTE pcBits,int iBit,int bOn)
1444 {
1445     LIMITED_METHOD_CONTRACT;
1446     if (bOn)
1447         pcBits[iBit>>3] |= (1 << (iBit & 0x7));
1448     else
1449         pcBits[iBit>>3] &= ~(1 << (iBit & 0x7));
1450 }
1451
1452 #ifdef DACCESS_COMPILE
1453 inline void SetBit(BYTE * pcBits,int iBit,int bOn)
1454 {
1455     WRAPPER_NO_CONTRACT;
1456     SetBit(dac_cast<PTR_BYTE>(pcBits), iBit, bOn);
1457 }
1458 #endif
1459
1460 template<typename T>
1461 class SimpleListNode
1462 {
1463 public:
1464     SimpleListNode<T>(const T& _t)
1465     {
1466         data = _t;
1467         next = 0;
1468     }
1469
1470     T                  data;
1471     SimpleListNode<T>* next;
1472 };
1473
1474 template<typename T>
1475 class SimpleList
1476 {
1477 public:
1478     typedef SimpleListNode<T> NodeType;
1479
1480     SimpleList<T>()
1481     {
1482         head = NULL;
1483     }
1484
1485     void LinkHead(NodeType* pNode)
1486     {
1487         pNode->next = head;
1488                       head = pNode;
1489     }
1490
1491     NodeType* UnlinkHead()
1492     {
1493         NodeType* ret = head;
1494
1495         if (head)
1496         {
1497             head = head->next;
1498         }
1499         return ret;
1500     }
1501
1502     NodeType* Head()
1503     {
1504         return head;
1505     }
1506
1507 protected:
1508
1509     NodeType* head;
1510 };
1511
1512
1513 template < typename T, typename U >
1514 struct Pair
1515 {
1516 public:
1517     typedef Pair< T, U > this_type;
1518     typedef T first_type;
1519     typedef U second_type;
1520
1521     Pair()
1522     {}
1523
1524     Pair( T const & t, U const & u )
1525         : m_first( t )
1526         , m_second( u )
1527     { SUPPORTS_DAC; }
1528
1529     Pair( this_type const & obj )
1530         : m_first( obj.m_first )
1531         , m_second( obj.m_second )
1532     {}
1533
1534     this_type & operator=( this_type const & obj )
1535     {
1536         m_first = obj.m_first;
1537         m_second = obj.m_second;
1538         return *this;
1539     }
1540
1541     T & First()
1542     {
1543         return m_first;
1544     }
1545
1546     T const & First() const
1547     {
1548         return m_first;
1549     }
1550
1551     U & Second()
1552     {
1553         return m_second;
1554     }
1555
1556     U const & Second() const
1557     {
1558         return m_second;
1559     }
1560
1561     bool operator==(const Pair& rhs) const
1562     {
1563         return ((this->First()  == rhs.First()) &&
1564                 (this->Second() == rhs.Second()));
1565     }
1566
1567     bool operator!=(const Pair& rhs) const
1568     {
1569         return !(*this == rhs);
1570     }
1571
1572 private:
1573     first_type  m_first;
1574     second_type m_second;
1575 };
1576
1577
1578 template < typename T, typename U >
1579 Pair< T, U > MakePair( T const & t, U const & u )
1580 {
1581     SUPPORTS_DAC;
1582     return Pair< T, U >( t, u );
1583 }
1584
1585
1586 //*****************************************************************************
1587 // This class implements a dynamic array of structures for which the order of
1588 // the elements is unimportant.  This means that any item placed in the list
1589 // may be swapped to any other location in the list at any time.  If the order
1590 // of the items you place in the array is important, then use the CStructArray
1591 // class.
1592 //*****************************************************************************
1593
1594 template <class T,
1595           int iGrowInc,
1596           class ALLOCATOR>
1597 class CUnorderedArrayWithAllocator
1598 {
1599     int         m_iCount;               // # of elements used in the list.
1600     int         m_iSize;                // # of elements allocated in the list.
1601 public:
1602 #ifndef DACCESS_COMPILE
1603     T           *m_pTable;              // Pointer to the list of elements.
1604 #else
1605     TADDR        m_pTable;              // Pointer to the list of elements.
1606 #endif
1607
1608 public:
1609
1610 #ifndef DACCESS_COMPILE
1611
1612     CUnorderedArrayWithAllocator() :
1613         m_iCount(0),
1614         m_iSize(0),
1615         m_pTable(NULL)
1616     {
1617         LIMITED_METHOD_CONTRACT;
1618     }
1619     ~CUnorderedArrayWithAllocator()
1620     {
1621         LIMITED_METHOD_CONTRACT;
1622         // Free the chunk of memory.
1623         if (m_pTable != NULL)
1624             ALLOCATOR::Free(this, m_pTable);
1625     }
1626
1627     void Clear()
1628     {
1629         WRAPPER_NO_CONTRACT;
1630         m_iCount = 0;
1631         if (m_iSize > iGrowInc)
1632         {
1633             T* tmp = ALLOCATOR::AllocNoThrow(this, iGrowInc);
1634             if (tmp) {
1635                 ALLOCATOR::Free(this, m_pTable);
1636                 m_pTable = tmp;
1637                 m_iSize = iGrowInc;
1638             }
1639         }
1640     }
1641
1642     void Clear(int iFirst, int iCount)
1643     {
1644         WRAPPER_NO_CONTRACT;
1645         int     iSize;
1646
1647         if (iFirst + iCount < m_iCount)
1648             memmove(&m_pTable[iFirst], &m_pTable[iFirst + iCount], sizeof(T) * (m_iCount - (iFirst + iCount)));
1649
1650         m_iCount -= iCount;
1651
1652         iSize = ((m_iCount / iGrowInc) * iGrowInc) + ((m_iCount % iGrowInc != 0) ? iGrowInc : 0);
1653         if (m_iSize > iGrowInc && iSize < m_iSize)
1654         {
1655             T *tmp = ALLOCATOR::AllocNoThrow(this, iSize);
1656             if (tmp) {
1657                 memcpy (tmp, m_pTable, iSize * sizeof(T));
1658                 delete [] m_pTable;
1659                 m_pTable = tmp;
1660                 m_iSize = iSize;
1661             }
1662         }
1663         _ASSERTE(m_iCount <= m_iSize);
1664     }
1665
1666     T *Table()
1667     {
1668         LIMITED_METHOD_CONTRACT;
1669         return (m_pTable);
1670     }
1671
1672     T *Append()
1673     {
1674         CONTRACTL {
1675             NOTHROW;
1676         } CONTRACTL_END;
1677
1678         // The array should grow, if we can't fit one more element into the array.
1679         if (m_iSize <= m_iCount && GrowNoThrow() == NULL)
1680             return (NULL);
1681         return (&m_pTable[m_iCount++]);
1682     }
1683
1684     T *AppendThrowing()
1685     {
1686         CONTRACTL {
1687             THROWS;
1688         } CONTRACTL_END;
1689
1690         // The array should grow, if we can't fit one more element into the array.
1691         if (m_iSize <= m_iCount)
1692             Grow();
1693         return (&m_pTable[m_iCount++]);
1694     }
1695
1696     void Delete(const T &Entry)
1697     {
1698         LIMITED_METHOD_CONTRACT;
1699         --m_iCount;
1700         for (int i=0; i <= m_iCount; ++i)
1701             if (m_pTable[i] == Entry)
1702             {
1703                 m_pTable[i] = m_pTable[m_iCount];
1704                 return;
1705             }
1706
1707         // Just in case we didn't find it.
1708         ++m_iCount;
1709     }
1710
1711     void DeleteByIndex(int i)
1712     {
1713         LIMITED_METHOD_CONTRACT;
1714         --m_iCount;
1715         m_pTable[i] = m_pTable[m_iCount];
1716     }
1717
1718     void Swap(int i,int j)
1719     {
1720         LIMITED_METHOD_CONTRACT;
1721         T       tmp;
1722
1723         if (i == j)
1724             return;
1725         tmp = m_pTable[i];
1726         m_pTable[i] = m_pTable[j];
1727         m_pTable[j] = tmp;
1728     }
1729
1730 #else
1731
1732     TADDR Table()
1733     {
1734         LIMITED_METHOD_CONTRACT;
1735         SUPPORTS_DAC;
1736         return (m_pTable);
1737     }
1738
1739     void EnumMemoryRegions(void)
1740     {
1741         SUPPORTS_DAC;
1742         DacEnumMemoryRegion(m_pTable, m_iCount * sizeof(T));
1743     }
1744
1745 #endif // #ifndef DACCESS_COMPILE
1746
1747     USHORT Count()
1748     {
1749         LIMITED_METHOD_CONTRACT;
1750         SUPPORTS_DAC;
1751         _ASSERTE(FitsIn<USHORT>(m_iCount));
1752         return static_cast<USHORT>(m_iCount);
1753     }
1754
1755 private:
1756     T *Grow();
1757     T *GrowNoThrow();
1758 };
1759
1760
1761 #ifndef DACCESS_COMPILE
1762
1763 //*****************************************************************************
1764 // Increase the size of the array.
1765 //*****************************************************************************
1766 template <class T,
1767           int iGrowInc,
1768           class ALLOCATOR>
1769 T *CUnorderedArrayWithAllocator<T,iGrowInc,ALLOCATOR>::GrowNoThrow()  // NULL if can't grow.
1770 {
1771     WRAPPER_NO_CONTRACT;
1772     T       *pTemp;
1773
1774     // try to allocate memory for reallocation.
1775     if ((pTemp = ALLOCATOR::AllocNoThrow(this, m_iSize+iGrowInc)) == NULL)
1776         return (NULL);
1777     memcpy (pTemp, m_pTable, m_iSize*sizeof(T));
1778     ALLOCATOR::Free(this, m_pTable);
1779     m_pTable = pTemp;
1780     m_iSize += iGrowInc;
1781     _ASSERTE(m_iSize > 0);
1782     return (pTemp);
1783 }
1784
1785 template <class T,
1786           int iGrowInc,
1787           class ALLOCATOR>
1788 T *CUnorderedArrayWithAllocator<T,iGrowInc,ALLOCATOR>::Grow()  // exception if can't grow.
1789 {
1790     WRAPPER_NO_CONTRACT;
1791     T       *pTemp;
1792
1793     // try to allocate memory for reallocation.
1794     pTemp = ALLOCATOR::AllocThrowing(this, m_iSize+iGrowInc);
1795     memcpy (pTemp, m_pTable, m_iSize*sizeof(T));
1796     ALLOCATOR::Free(this, m_pTable);
1797     m_pTable = pTemp;
1798     m_iSize += iGrowInc;
1799     _ASSERTE(m_iSize > 0);
1800     return (pTemp);
1801 }
1802
1803 #endif // #ifndef DACCESS_COMPILE
1804
1805
1806 template <class T>
1807 class CUnorderedArray__Allocator
1808 {
1809 public:
1810
1811     static T *AllocThrowing (void*, int nElements)
1812     {
1813         return new T[nElements];
1814     }
1815
1816     static T *AllocNoThrow (void*, int nElements)
1817     {
1818         return new (nothrow) T[nElements];
1819     }
1820
1821     static void Free (void*, T *pTable)
1822     {
1823         delete [] pTable;
1824     }
1825 };
1826
1827
1828 template <class T,int iGrowInc>
1829 class CUnorderedArray : public CUnorderedArrayWithAllocator<T, iGrowInc, CUnorderedArray__Allocator<T> >
1830 {
1831 public:
1832
1833     CUnorderedArray ()
1834     {
1835         LIMITED_METHOD_CONTRACT;
1836     }
1837 };
1838
1839
1840 //Used by the debugger.  Included here in hopes somebody else might, too
1841 typedef CUnorderedArray<SIZE_T, 17> SIZE_T_UNORDERED_ARRAY;
1842
1843
1844 //*****************************************************************************
1845 // This class implements a dynamic array of structures for which the insert
1846 // order is important.  Inserts will slide all elements after the location
1847 // down, deletes slide all values over the deleted item.  If the order of the
1848 // items in the array is unimportant to you, then CUnorderedArray may provide
1849 // the same feature set at lower cost.
1850 //*****************************************************************************
1851 class CStructArray
1852 {
1853     BYTE        *m_pList;               // Pointer to the list of elements.
1854     int         m_iCount;               // # of elements used in the list.
1855     int         m_iSize;                // # of elements allocated in the list.
1856     int         m_iGrowInc;             // Growth increment.
1857     short       m_iElemSize;            // Size of an array element.
1858     bool        m_bFree;                // true if data is automatically maintained.
1859
1860 public:
1861     CStructArray(short iElemSize, short iGrowInc = 1) :
1862         m_pList(NULL),
1863         m_iCount(0),
1864         m_iSize(0),
1865         m_iGrowInc(iGrowInc),
1866         m_iElemSize(iElemSize),
1867         m_bFree(true)
1868     {
1869         LIMITED_METHOD_CONTRACT;
1870     }
1871     ~CStructArray()
1872     {
1873         WRAPPER_NO_CONTRACT;
1874         Clear();
1875     }
1876
1877     void *Insert(int iIndex);
1878     void *InsertThrowing(int iIndex);
1879     void *Append();
1880     void *AppendThrowing();
1881     int AllocateBlock(int iCount);
1882     void AllocateBlockThrowing(int iCount);
1883     void Delete(int iIndex);
1884     void *Ptr()
1885     {
1886         LIMITED_METHOD_CONTRACT;
1887         return (m_pList);
1888     }
1889     void *Get(int iIndex)
1890     {
1891         WRAPPER_NO_CONTRACT;
1892         _ASSERTE(iIndex < m_iCount);
1893         return ((void *) ((size_t) Ptr() + (iIndex * m_iElemSize)));
1894     }
1895     int Size()
1896     {
1897         LIMITED_METHOD_CONTRACT;
1898         return (m_iCount * m_iElemSize);
1899     }
1900     int Count()
1901     {
1902         LIMITED_METHOD_CONTRACT;
1903         return (m_iCount);
1904     }
1905     void Clear();
1906     void ClearCount()
1907     {
1908         LIMITED_METHOD_CONTRACT;
1909         m_iCount = 0;
1910     }
1911
1912     void InitOnMem(short iElemSize, void *pList, int iCount, int iSize, int iGrowInc=1)
1913     {
1914         LIMITED_METHOD_CONTRACT;
1915         m_iElemSize = iElemSize;
1916         m_iGrowInc = (short) iGrowInc;
1917         m_pList = (BYTE*)pList;
1918         m_iCount = iCount;
1919         m_iSize = iSize;
1920         m_bFree = false;
1921     }
1922
1923 private:
1924     void Grow(int iCount);
1925 };
1926
1927
1928 //*****************************************************************************
1929 // This template simplifies access to a CStructArray by removing void * and
1930 // adding some operator overloads.
1931 //*****************************************************************************
1932 template <class T>
1933 class CDynArray : public CStructArray
1934 {
1935 public:
1936     CDynArray(short iGrowInc=16) :
1937         CStructArray(sizeof(T), iGrowInc)
1938     {
1939         LIMITED_METHOD_CONTRACT;
1940     }
1941
1942     T *Insert(int iIndex)
1943     {
1944         WRAPPER_NO_CONTRACT;
1945         return ((T *)CStructArray::Insert((int)iIndex));
1946     }
1947
1948     T *InsertThrowing(int iIndex)
1949     {
1950         WRAPPER_NO_CONTRACT;
1951         return ((T *)CStructArray::InsertThrowing((int)iIndex));
1952     }
1953
1954     T *Append()
1955     {
1956         WRAPPER_NO_CONTRACT;
1957         return ((T *)CStructArray::Append());
1958     }
1959
1960     T *AppendThrowing()
1961     {
1962         WRAPPER_NO_CONTRACT;
1963         return ((T *)CStructArray::AppendThrowing());
1964     }
1965
1966     T *Ptr()
1967     {
1968         WRAPPER_NO_CONTRACT;
1969         return ((T *)CStructArray::Ptr());
1970     }
1971
1972     T *Get(int iIndex)
1973     {
1974         WRAPPER_NO_CONTRACT;
1975         return (Ptr() + iIndex);
1976     }
1977     T &operator[](int iIndex)
1978     {
1979         WRAPPER_NO_CONTRACT;
1980         return (*(Ptr() + iIndex));
1981     }
1982     int ItemIndex(T *p)
1983     {
1984         WRAPPER_NO_CONTRACT;
1985         return (((int)(LONG_PTR)p - (int)(LONG_PTR)Ptr()) / sizeof(T));
1986     }
1987     void Move(int iFrom, int iTo)
1988     {
1989         WRAPPER_NO_CONTRACT;
1990         T       tmp;
1991
1992         _ASSERTE(iFrom >= 0 && iFrom < Count() &&
1993                  iTo >= 0 && iTo < Count());
1994
1995         tmp = *(Ptr() + iFrom);
1996         if (iTo > iFrom)
1997             memmove(Ptr() + iFrom, Ptr() + iFrom + 1, (iTo - iFrom) * sizeof(T));
1998         else
1999             memmove(Ptr() + iTo + 1, Ptr() + iTo, (iFrom - iTo) * sizeof(T));
2000         *(Ptr() + iTo) = tmp;
2001     }
2002 };
2003
2004 // Some common arrays.
2005 typedef CDynArray<int> INTARRAY;
2006 typedef CDynArray<short> SHORTARRAY;
2007 typedef CDynArray<int> LONGARRAY;
2008 typedef CDynArray<USHORT> USHORTARRAY;
2009 typedef CDynArray<ULONG> ULONGARRAY;
2010 typedef CDynArray<BYTE> BYTEARRAY;
2011 typedef CDynArray<mdToken> TOKENARRAY;
2012
2013 template <class T> class CStackArray : public CStructArray
2014 {
2015 public:
2016     CStackArray(short iGrowInc=4) :
2017         CStructArray(sizeof(T), iGrowInc),
2018         m_curPos(0)
2019     {
2020         LIMITED_METHOD_CONTRACT;
2021     }
2022
2023     void Push(T p)
2024     {
2025         WRAPPER_NO_CONTRACT;
2026         // We should only inc m_curPos after we grow the array.
2027         T *pT = (T *)CStructArray::InsertThrowing(m_curPos);
2028         m_curPos ++;
2029         *pT = p;
2030     }
2031
2032     T * Pop()
2033     {
2034         WRAPPER_NO_CONTRACT;
2035         T * retPtr;
2036
2037         _ASSERTE(m_curPos > 0);
2038
2039         retPtr = (T *)CStructArray::Get(m_curPos-1);
2040         CStructArray::Delete(m_curPos--);
2041
2042         return (retPtr);
2043     }
2044
2045     int Count()
2046     {
2047         LIMITED_METHOD_CONTRACT;
2048         return(m_curPos);
2049     }
2050
2051 private:
2052     int m_curPos;
2053 };
2054
2055
2056 //*****************************************************************************
2057 // This template manages a list of free entries by their 0 based offset.  By
2058 // making it a template, you can use whatever size free chain will match your
2059 // maximum count of items.  -1 is reserved.
2060 //*****************************************************************************
2061 template <class T> class TFreeList
2062 {
2063 public:
2064     void Init(
2065         T           *rgList,
2066         int         iCount)
2067     {
2068         LIMITED_METHOD_CONTRACT;
2069         // Save off values.
2070         m_rgList = rgList;
2071         m_iCount = iCount;
2072         m_iNext = 0;
2073
2074         // Init free list.
2075         int i;
2076         for (i=0;  i<iCount - 1;  i++)
2077             m_rgList[i] = i + 1;
2078         m_rgList[i] = (T) -1;
2079     }
2080
2081     T GetFreeEntry()                        // Index of free item, or -1.
2082     {
2083         LIMITED_METHOD_CONTRACT;
2084         T           iNext;
2085
2086         if (m_iNext == (T) -1)
2087             return (-1);
2088
2089         iNext = m_iNext;
2090         m_iNext = m_rgList[m_iNext];
2091         return (iNext);
2092     }
2093
2094     void DelFreeEntry(T iEntry)
2095     {
2096         LIMITED_METHOD_CONTRACT;
2097         _ASSERTE(iEntry < m_iCount);
2098         m_rgList[iEntry] = m_iNext;
2099         m_iNext = iEntry;
2100     }
2101
2102     // This function can only be used when it is guaranteed that the free
2103     // array is contigous, for example, right after creation to quickly
2104     // get a range of items from the heap.
2105     void ReserveRange(int iCount)
2106     {
2107         LIMITED_METHOD_CONTRACT;
2108         _ASSERTE(iCount < m_iCount);
2109         _ASSERTE(m_iNext == 0);
2110         m_iNext = iCount;
2111     }
2112
2113 private:
2114     T           *m_rgList;              // List of free info.
2115     int         m_iCount;               // How many entries to manage.
2116     T           m_iNext;                // Next item to get.
2117 };
2118
2119
2120 //*****************************************************************************
2121 //*****************************************************************************
2122 template <class T> class CQuickSort
2123 {
2124 protected:
2125     T           *m_pBase;                   // Base of array to sort.
2126 private:
2127     SSIZE_T     m_iCount;                   // How many items in array.
2128     SSIZE_T     m_iElemSize;                // Size of one element.
2129 public:
2130     CQuickSort(
2131         T           *pBase,                 // Address of first element.
2132         SSIZE_T     iCount) :               // How many there are.
2133         m_pBase(pBase),
2134         m_iCount(iCount),
2135         m_iElemSize(sizeof(T))
2136     {
2137         LIMITED_METHOD_DAC_CONTRACT;
2138     }
2139
2140 //*****************************************************************************
2141 // Call to sort the array.
2142 //*****************************************************************************
2143     inline void Sort()
2144     {
2145         WRAPPER_NO_CONTRACT;
2146         SortRange(0, m_iCount - 1);
2147     }
2148
2149 protected:
2150 //*****************************************************************************
2151 // Override this function to do the comparison.
2152 //*****************************************************************************
2153     virtual FORCEINLINE int Compare(        // -1, 0, or 1
2154         T           *psFirst,               // First item to compare.
2155         T           *psSecond)              // Second item to compare.
2156     {
2157         LIMITED_METHOD_DAC_CONTRACT;
2158         return (memcmp(psFirst, psSecond, sizeof(T)));
2159 //      return (::Compare(*psFirst, *psSecond));
2160     }
2161
2162     virtual FORCEINLINE void Swap(
2163         SSIZE_T     iFirst,
2164         SSIZE_T     iSecond)
2165     {
2166         LIMITED_METHOD_DAC_CONTRACT;
2167         if (iFirst == iSecond) return;
2168         T sTemp( m_pBase[iFirst] );
2169         m_pBase[iFirst] = m_pBase[iSecond];
2170         m_pBase[iSecond] = sTemp;
2171     }
2172
2173 private:
2174     inline void SortRange(
2175         SSIZE_T     iLeft,
2176         SSIZE_T     iRight)
2177     {
2178         WRAPPER_NO_CONTRACT;
2179         SSIZE_T     iLast;
2180         SSIZE_T     i;                      // loop variable.
2181         
2182         for (;;)
2183         {
2184             // if less than two elements you're done.
2185             if (iLeft >= iRight)
2186                 return;
2187             
2188             // ASSERT that we now have valid indicies.  This is statically provable
2189             // since this private function is only called with valid indicies,
2190             // and iLeft and iRight only converge towards eachother.  However,
2191             // PreFast can't detect this because it doesn't know about our callers.
2192             COMPILER_ASSUME(iLeft >= 0 && iLeft < m_iCount);
2193             COMPILER_ASSUME(iRight >= 0 && iRight < m_iCount);
2194             
2195             // The mid-element is the pivot, move it to the left.
2196             Swap(iLeft, (iLeft + iRight) / 2);
2197             iLast = iLeft;
2198             
2199             // move everything that is smaller than the pivot to the left.
2200             for (i = iLeft + 1; i <= iRight; i++)
2201             {
2202                 if (Compare(&m_pBase[i], &m_pBase[iLeft]) < 0)
2203                 {
2204                     Swap(i, ++iLast);
2205                 }
2206             }
2207             
2208             // Put the pivot to the point where it is in between smaller and larger elements.
2209             Swap(iLeft, iLast);
2210             
2211             // Sort each partition.
2212             SSIZE_T iLeftLast = iLast - 1;
2213             SSIZE_T iRightFirst = iLast + 1;
2214             if (iLeftLast - iLeft < iRight - iRightFirst)
2215             {   // Left partition is smaller, sort it recursively
2216                 SortRange(iLeft, iLeftLast);
2217                 // Tail call to sort the right (bigger) partition
2218                 iLeft = iRightFirst;
2219                 //iRight = iRight;
2220                 continue;
2221             }
2222             else
2223             {   // Right partition is smaller, sort it recursively
2224                 SortRange(iRightFirst, iRight);
2225                 // Tail call to sort the left (bigger) partition
2226                 //iLeft = iLeft;
2227                 iRight = iLeftLast;
2228                 continue;
2229             }
2230         }
2231     }
2232 };
2233
2234 //*****************************************************************************
2235 // Faster and simpler version of the binary search below.
2236 //*****************************************************************************
2237 template <class T>
2238 const T * BinarySearch(const T * pBase, int iCount, const T & find)
2239 {
2240     WRAPPER_NO_CONTRACT;
2241
2242     int iFirst = 0;
2243     int iLast  = iCount - 1;
2244
2245     // It is faster to use linear search once we get down to a small number of elements.
2246     while (iLast - iFirst > 10)
2247     {
2248         int iMid = (iLast + iFirst) / 2;
2249         
2250         if (find < pBase[iMid])
2251             iLast = iMid - 1;
2252         else
2253             iFirst = iMid;
2254     }
2255
2256     for (int i = iFirst; i <= iLast; i++)
2257     {
2258         if (find == pBase[i])
2259             return &pBase[i];
2260
2261         if (find < pBase[i])
2262             break;
2263     }
2264
2265     return NULL;
2266 }
2267
2268 //*****************************************************************************
2269 // This template encapsulates a binary search algorithm on the given type
2270 // of data.
2271 //*****************************************************************************
2272 template <class T> class CBinarySearch
2273 {
2274 private:
2275     const T     *m_pBase;                   // Base of array to sort.
2276     int         m_iCount;                   // How many items in array.
2277
2278 public:
2279     CBinarySearch(
2280         const T     *pBase,                 // Address of first element.
2281         int         iCount) :               // Value to find.
2282         m_pBase(pBase),
2283         m_iCount(iCount)
2284     {
2285         LIMITED_METHOD_CONTRACT;
2286     }
2287
2288 //*****************************************************************************
2289 // Searches for the item passed to ctor.
2290 //*****************************************************************************
2291     const T *Find(                          // Pointer to found item in array.
2292         const T     *psFind,                // The key to find.
2293         int         *piInsert = NULL)       // Index to insert at.
2294     {
2295         WRAPPER_NO_CONTRACT;
2296         int         iMid, iFirst, iLast;    // Loop control.
2297         int         iCmp;                   // Comparison.
2298
2299         iFirst = 0;
2300         iLast = m_iCount - 1;
2301         while (iFirst <= iLast)
2302         {
2303             iMid = (iLast + iFirst) / 2;
2304             iCmp = Compare(psFind, &m_pBase[iMid]);
2305             if (iCmp == 0)
2306             {
2307                 if (piInsert != NULL)
2308                     *piInsert = iMid;
2309                 return (&m_pBase[iMid]);
2310             }
2311             else if (iCmp < 0)
2312                 iLast = iMid - 1;
2313             else
2314                 iFirst = iMid + 1;
2315         }
2316         if (piInsert != NULL)
2317             *piInsert = iFirst;
2318         return (NULL);
2319     }
2320
2321 //*****************************************************************************
2322 // Override this function to do the comparison if a comparison operator is
2323 // not valid for your data type (such as a struct).
2324 //*****************************************************************************
2325     virtual int Compare(                    // -1, 0, or 1
2326         const T     *psFirst,               // Key you are looking for.
2327         const T     *psSecond)              // Item to compare to.
2328     {
2329         LIMITED_METHOD_CONTRACT;
2330         return (memcmp(psFirst, psSecond, sizeof(T)));
2331 //      return (::Compare(*psFirst, *psSecond));
2332     }
2333 };
2334
2335 //*****************************************************************************
2336 // The information that the hash table implementation stores at the beginning
2337 // of every record that can be but in the hash table.
2338 //*****************************************************************************
2339 typedef DPTR(struct HASHENTRY) PTR_HASHENTRY;
2340 struct HASHENTRY
2341 {
2342     ULONG      iPrev;                  // Previous bucket in the chain.
2343     ULONG      iNext;                  // Next bucket in the chain.
2344 };
2345
2346 typedef DPTR(struct FREEHASHENTRY) PTR_FREEHASHENTRY;
2347 struct FREEHASHENTRY : HASHENTRY
2348 {
2349     ULONG      iFree;
2350 };
2351
2352 //*****************************************************************************
2353 // Used by the FindFirst/FindNextEntry functions.  These api's allow you to
2354 // do a sequential scan of all entries.
2355 //*****************************************************************************
2356 struct HASHFIND
2357 {
2358     ULONG      iBucket;            // The next bucket to look in.
2359     ULONG      iNext;
2360 };
2361
2362
2363 //*****************************************************************************
2364 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
2365 // The hashtable implementation that should be used instead is code:SHash.
2366 // If code:SHash does not work for you, talk to mailto:clrdeag.
2367 //*****************************************************************************
2368 // This is a class that implements a chain and bucket hash table.
2369 //
2370 // The data is actually supplied as an array of structures by the user of this class.
2371 // This allows the buckets to use small indices to point to the chain, instead of pointers.
2372 //
2373 // Each entry in the array contains a HASHENTRY structure immediately
2374 // followed by the key used to hash the structure.
2375 //
2376 // The HASHENTRY part of every structure is used to implement the chain of
2377 // entries in a single bucket.
2378 //
2379 // This implementation does not support rehashing the buckets if the table grows
2380 // to big.
2381 // @TODO: Fix this by adding an abstract function Hash() which must be implemented
2382 // by all clients.
2383 //
2384 //*****************************************************************************
2385 class CHashTable
2386 {
2387     friend class DebuggerRCThread; //RCthread actually needs access to
2388     //fields of derrived class DebuggerPatchTable
2389
2390 protected:
2391     TADDR       m_pcEntries;            // Pointer to the array of structs.
2392     ULONG      m_iEntrySize;           // Size of the structs.
2393
2394     ULONG      m_iBuckets;             // # of chains we are hashing into.
2395     PTR_ULONG  m_piBuckets;           // Ptr to the array of bucket chains.
2396
2397     INDEBUG(unsigned    m_maxSearch;)   // For evaluating perf characteristics
2398
2399     HASHENTRY *EntryPtr(ULONG iEntry)
2400     {
2401         LIMITED_METHOD_DAC_CONTRACT;
2402         return (PTR_HASHENTRY(m_pcEntries + (iEntry * m_iEntrySize)));
2403     }
2404
2405     ULONG     ItemIndex(HASHENTRY *p)
2406     {
2407         SUPPORTS_DAC;
2408         LIMITED_METHOD_CONTRACT;
2409         return (ULONG)((dac_cast<TADDR>(p) - m_pcEntries) / m_iEntrySize);
2410     }
2411
2412
2413 public:
2414
2415     CHashTable(
2416         ULONG      iBuckets) :         // # of chains we are hashing into.
2417         m_pcEntries((TADDR)NULL),
2418         m_iBuckets(iBuckets)
2419     {
2420         LIMITED_METHOD_CONTRACT;
2421
2422         m_piBuckets = NULL;
2423
2424         INDEBUG(m_maxSearch = 0;)
2425     }
2426
2427     CHashTable() :         // # of chains we are hashing into.
2428         m_pcEntries((TADDR)NULL),
2429         m_iBuckets(5)
2430     {
2431         LIMITED_METHOD_CONTRACT;
2432
2433         m_piBuckets = NULL;
2434
2435         INDEBUG(m_maxSearch = 0;)
2436     }
2437
2438 #ifndef DACCESS_COMPILE
2439
2440     ~CHashTable()
2441     {
2442         LIMITED_METHOD_CONTRACT;
2443         if (m_piBuckets != NULL)
2444         {
2445             delete [] m_piBuckets;
2446             m_piBuckets = NULL;
2447         }
2448     }
2449
2450 //*****************************************************************************
2451 // This is the second part of construction where we do all of the work that
2452 // can fail.  We also take the array of structs here because the calling class
2453 // presumably needs to allocate it in its NewInit.
2454 //*****************************************************************************
2455     HRESULT NewInit(                    // Return status.
2456         BYTE        *pcEntries,         // Array of structs we are managing.
2457         ULONG      iEntrySize);        // Size of the entries.
2458
2459 //*****************************************************************************
2460 // This can be called to change the pointer to the table that the hash table
2461 // is managing.  You might call this if (for example) you realloc the size
2462 // of the table and its pointer is different.
2463 //*****************************************************************************
2464     void SetTable(
2465         BYTE        *pcEntries)         // Array of structs we are managing.
2466     {
2467         LIMITED_METHOD_CONTRACT;
2468         m_pcEntries = (TADDR)pcEntries;
2469     }
2470
2471 //*****************************************************************************
2472 // Clear the hash table as if there were nothing in it.
2473 //*****************************************************************************
2474     void Clear()
2475     {
2476         LIMITED_METHOD_CONTRACT;
2477         _ASSERTE(m_piBuckets != NULL);
2478         memset(m_piBuckets, 0xff, m_iBuckets * sizeof(ULONG));
2479     }
2480
2481 //*****************************************************************************
2482 // Add the struct at the specified index in m_pcEntries to the hash chains.
2483 //*****************************************************************************
2484     BYTE *Add(                          // New entry.
2485         ULONG      iHash,              // Hash value of entry to add.
2486         ULONG      iIndex);            // Index of struct in m_pcEntries.
2487
2488 //*****************************************************************************
2489 // Delete the struct at the specified index in m_pcEntries from the hash chains.
2490 //*****************************************************************************
2491     void Delete(
2492         ULONG      iHash,              // Hash value of entry to delete.
2493         ULONG      iIndex);            // Index of struct in m_pcEntries.
2494
2495     void Delete(
2496         ULONG      iHash,              // Hash value of entry to delete.
2497         HASHENTRY   *psEntry);          // The struct to delete.
2498
2499 //*****************************************************************************
2500 // The item at the specified index has been moved, update the previous and
2501 // next item.
2502 //*****************************************************************************
2503     void Move(
2504         ULONG      iHash,              // Hash value for the item.
2505         ULONG      iNew);              // New location.
2506
2507 #endif // #ifndef DACCESS_COMPILE
2508
2509 //*****************************************************************************
2510 // Return a boolean indicating whether or not this hash table has been inited.
2511 //*****************************************************************************
2512     int IsInited()
2513     {
2514         LIMITED_METHOD_CONTRACT;
2515         return (m_piBuckets != NULL);
2516     }
2517
2518 //*****************************************************************************
2519 // Search the hash table for an entry with the specified key value.
2520 //*****************************************************************************
2521     BYTE *Find(                         // Index of struct in m_pcEntries.
2522         ULONG      iHash,              // Hash value of the item.
2523         SIZE_T     key);               // The key to match.
2524
2525 //*****************************************************************************
2526 // Search the hash table for the next entry with the specified key value.
2527 //*****************************************************************************
2528     ULONG FindNext(                    // Index of struct in m_pcEntries.
2529         SIZE_T     key,                // The key to match.
2530         ULONG      iIndex);            // Index of previous match.
2531
2532 //*****************************************************************************
2533 // Returns the first entry in the first hash bucket and inits the search
2534 // struct.  Use the FindNextEntry function to continue walking the list.  The
2535 // return order is not gauranteed.
2536 //*****************************************************************************
2537     BYTE *FindFirstEntry(               // First entry found, or 0.
2538         HASHFIND    *psSrch)            // Search object.
2539     {
2540         WRAPPER_NO_CONTRACT;
2541         if (m_piBuckets == 0)
2542             return (0);
2543         psSrch->iBucket = 1;
2544         psSrch->iNext = m_piBuckets[0];
2545         return (FindNextEntry(psSrch));
2546     }
2547
2548 //*****************************************************************************
2549 // Returns the next entry in the list.
2550 //*****************************************************************************
2551     BYTE *FindNextEntry(                // The next entry, or0 for end of list.
2552         HASHFIND    *psSrch);           // Search object.
2553
2554 #ifdef DACCESS_COMPILE
2555     void EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
2556                            ULONG numEntries);
2557 #endif
2558
2559 protected:
2560     virtual BOOL Cmp(SIZE_T key1, const HASHENTRY * pc2) = 0;
2561 };
2562
2563
2564 class CNewData
2565 {
2566 public:
2567     static BYTE *Alloc(int iSize, int iMaxSize)
2568     {
2569         WRAPPER_NO_CONTRACT;
2570         return (new BYTE[iSize]);
2571     }
2572     static void Free(BYTE *pPtr, int iSize)
2573     {
2574         LIMITED_METHOD_CONTRACT;
2575         delete [] pPtr;
2576     }
2577     static BYTE *Grow(BYTE *&pPtr, int iCurSize)
2578     {
2579         WRAPPER_NO_CONTRACT;
2580         BYTE *p;
2581         S_SIZE_T newSize = S_SIZE_T(iCurSize) + S_SIZE_T(GrowSize(iCurSize));
2582         //check for overflow
2583         if(newSize.IsOverflow())
2584             p = NULL;
2585         else
2586             p = new (nothrow) BYTE[newSize.Value()];
2587         if (p == 0) return (0);
2588         memcpy (p, pPtr, iCurSize);
2589         delete [] pPtr;
2590         pPtr = p;
2591         return pPtr;
2592     }
2593     static void Clean(BYTE * pData, int iSize)
2594     {
2595     }
2596     static int RoundSize(int iSize)
2597     {
2598         LIMITED_METHOD_CONTRACT;
2599         return (iSize);
2600     }
2601     static int GrowSize(int iCurSize)
2602     {
2603         LIMITED_METHOD_CONTRACT;
2604         int newSize = (3 * iCurSize) / 2;
2605         return (newSize < 256) ? 256 : newSize;
2606     }
2607 };
2608
2609 class CNewDataNoThrow
2610 {
2611 public:
2612     static BYTE *Alloc(int iSize, int iMaxSize)
2613     {
2614         WRAPPER_NO_CONTRACT;
2615         return (new (nothrow) BYTE[iSize]);
2616     }
2617     static void Free(BYTE *pPtr, int iSize)
2618     {
2619         LIMITED_METHOD_CONTRACT;
2620         delete [] pPtr;
2621     }
2622     static BYTE *Grow(BYTE *&pPtr, int iCurSize)
2623     {
2624         WRAPPER_NO_CONTRACT;
2625         BYTE *p;
2626         S_SIZE_T newSize = S_SIZE_T(iCurSize) + S_SIZE_T(GrowSize(iCurSize));
2627         //check for overflow
2628         if(newSize.IsOverflow())
2629             p = NULL;
2630         else
2631             p = new (nothrow) BYTE[newSize.Value()];
2632         if (p == 0) return (0);
2633         memcpy (p, pPtr, iCurSize);
2634         delete [] pPtr;
2635         pPtr = p;
2636         return pPtr;
2637     }
2638     static void Clean(BYTE * pData, int iSize)
2639     {
2640     }
2641     static int RoundSize(int iSize)
2642     {
2643         LIMITED_METHOD_CONTRACT;
2644         return (iSize);
2645     }
2646     static int GrowSize(int iCurSize)
2647     {
2648         LIMITED_METHOD_CONTRACT;
2649         int newSize = (3 * iCurSize) / 2;
2650         return (newSize < 256) ? 256 : newSize;
2651     }
2652 };
2653
2654
2655 //*****************************************************************************
2656 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
2657 // The hashtable implementation that should be used instead is code:SHash.
2658 // If code:SHash does not work for you, talk to mailto:clrdeag.
2659 //*****************************************************************************
2660 // CHashTable expects the data to be in a single array - this is provided by
2661 // CHashTableAndData.
2662 // The array is allocated using the MemMgr type. CNewData and
2663 // CNewDataNoThrow can be used for this.
2664 //*****************************************************************************
2665 template <class MemMgr>
2666 class CHashTableAndData : public CHashTable
2667 {
2668 public:
2669     ULONG      m_iFree;                // Index into m_pcEntries[] of next available slot
2670     ULONG      m_iEntries;             // size of m_pcEntries[]
2671
2672 public:
2673
2674     CHashTableAndData() :
2675         CHashTable()
2676     {
2677         LIMITED_METHOD_CONTRACT;
2678     }
2679
2680     CHashTableAndData(
2681         ULONG      iBuckets) :         // # of chains we are hashing into.
2682         CHashTable(iBuckets)
2683     {
2684         LIMITED_METHOD_CONTRACT;
2685     }
2686
2687 #ifndef DACCESS_COMPILE
2688
2689     ~CHashTableAndData()
2690     {
2691         WRAPPER_NO_CONTRACT;
2692         if (m_pcEntries != NULL)
2693             MemMgr::Free((BYTE*)m_pcEntries, MemMgr::RoundSize(m_iEntries * m_iEntrySize));
2694     }
2695
2696 //*****************************************************************************
2697 // This is the second part of construction where we do all of the work that
2698 // can fail.  We also take the array of structs here because the calling class
2699 // presumably needs to allocate it in its NewInit.
2700 //*****************************************************************************
2701     HRESULT NewInit(                    // Return status.
2702         ULONG      iEntries,           // # of entries.
2703         ULONG      iEntrySize,         // Size of the entries.
2704         int         iMaxSize);          // Max size of data.
2705
2706 //*****************************************************************************
2707 // Clear the hash table as if there were nothing in it.
2708 //*****************************************************************************
2709     void Clear()
2710     {
2711         WRAPPER_NO_CONTRACT;
2712         m_iFree = 0;
2713         InitFreeChain(0, m_iEntries);
2714         CHashTable::Clear();
2715     }
2716
2717 //*****************************************************************************
2718 // Grabs a slot for the new entry to be added.
2719 // The caller should fill in the non-HASHENTRY part of the returned slot
2720 //*****************************************************************************
2721     BYTE *Add(
2722         ULONG      iHash)              // Hash value of entry to add.
2723     {
2724         WRAPPER_NO_CONTRACT;
2725         FREEHASHENTRY *psEntry;
2726
2727         // Make the table bigger if necessary.
2728         if (m_iFree == UINT32_MAX && !Grow())
2729             return (NULL);
2730
2731         // Add the first entry from the free list to the hash chain.
2732         psEntry = (FREEHASHENTRY *) CHashTable::Add(iHash, m_iFree);
2733         m_iFree = psEntry->iFree;
2734
2735         // If we're recycling memory, give our memory-allocator a chance to re-init it.
2736
2737         // Each entry is prefixed with a header - we don't want to trash that.
2738         SIZE_T cbHeader = sizeof(FREEHASHENTRY);
2739         MemMgr::Clean((BYTE*) psEntry + cbHeader, (int) (m_iEntrySize - cbHeader));
2740
2741         return ((BYTE *) psEntry);
2742     }
2743
2744 //*****************************************************************************
2745 // Delete the struct at the specified index in m_pcEntries from the hash chains.
2746 //*****************************************************************************
2747     void Delete(
2748         ULONG      iHash,              // Hash value of entry to delete.
2749         ULONG      iIndex)             // Index of struct in m_pcEntries.
2750     {
2751         WRAPPER_NO_CONTRACT;
2752         CHashTable::Delete(iHash, iIndex);
2753         ((FREEHASHENTRY *) EntryPtr(iIndex))->iFree = m_iFree;
2754         m_iFree = iIndex;
2755     }
2756
2757     void Delete(
2758         ULONG      iHash,              // Hash value of entry to delete.
2759         HASHENTRY   *psEntry)           // The struct to delete.
2760     {
2761         WRAPPER_NO_CONTRACT;
2762         CHashTable::Delete(iHash, psEntry);
2763         ((FREEHASHENTRY *) psEntry)->iFree = m_iFree;
2764         m_iFree = ItemIndex(psEntry);
2765     }
2766
2767 #endif // #ifndef DACCESS_COMPILE
2768
2769     // This is a sad legacy workaround. The debugger's patch table (implemented as this
2770     // class) is shared across process. We publish the runtime offsets of
2771     // some key fields. Since those fields are private, we have to provide
2772     // accessors here. So if you're not using these functions, don't start.
2773     // We can hopefully remove them.
2774     // Note that we can't just make RCThread a friend of this class (we tried
2775     // originally) because the inheritence chain has a private modifier,
2776     // so DebuggerPatchTable::m_pcEntries is illegal.
2777     static SIZE_T helper_GetOffsetOfEntries()
2778     {
2779         LIMITED_METHOD_CONTRACT;
2780         return offsetof(CHashTableAndData, m_pcEntries);
2781     }
2782
2783     static SIZE_T helper_GetOffsetOfCount()
2784     {
2785         LIMITED_METHOD_CONTRACT;
2786         return offsetof(CHashTableAndData, m_iEntries);
2787     }
2788
2789 #ifdef DACCESS_COMPILE
2790     void EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
2791     {
2792         SUPPORTS_DAC;
2793         CHashTable::EnumMemoryRegions(flags, m_iEntries);
2794     }
2795 #endif
2796
2797 private:
2798     void InitFreeChain(ULONG iStart,ULONG iEnd);
2799     int Grow();
2800 };
2801
2802 #ifndef DACCESS_COMPILE
2803
2804 //*****************************************************************************
2805 // This is the second part of construction where we do all of the work that
2806 // can fail.  We also take the array of structs here because the calling class
2807 // presumably needs to allocate it in its NewInit.
2808 //*****************************************************************************
2809 template<class MemMgr>
2810 HRESULT CHashTableAndData<MemMgr>::NewInit(// Return status.
2811     ULONG      iEntries,               // # of entries.
2812     ULONG      iEntrySize,             // Size of the entries.
2813     int         iMaxSize)               // Max size of data.
2814 {
2815     WRAPPER_NO_CONTRACT;
2816     BYTE        *pcEntries;
2817     HRESULT     hr;
2818
2819
2820     // note that this function can throw because it depends on the <M>::Alloc
2821
2822     // Allocate the memory for the entries.
2823     if ((pcEntries = MemMgr::Alloc(MemMgr::RoundSize(iEntries * iEntrySize),
2824                                    MemMgr::RoundSize(iMaxSize))) == 0)
2825         return (E_OUTOFMEMORY);
2826     m_iEntries = iEntries;
2827
2828     // Init the base table.
2829     if (FAILED(hr = CHashTable::NewInit(pcEntries, iEntrySize)))
2830         MemMgr::Free(pcEntries, MemMgr::RoundSize(iEntries * iEntrySize));
2831     else
2832     {
2833         // Init the free chain.
2834         m_iFree = 0;
2835         InitFreeChain(0, iEntries);
2836     }
2837     return (hr);
2838 }
2839
2840 //*****************************************************************************
2841 // Initialize a range of records such that they are linked together to be put
2842 // on the free chain.
2843 //*****************************************************************************
2844 template<class MemMgr>
2845 void CHashTableAndData<MemMgr>::InitFreeChain(
2846     ULONG      iStart,                 // Index to start initializing.
2847     ULONG      iEnd)                   // Index to stop initializing
2848 {
2849     LIMITED_METHOD_CONTRACT;
2850     BYTE* pcPtr;
2851     _ASSERTE(iEnd > iStart);
2852
2853     pcPtr = (BYTE*)m_pcEntries + iStart * m_iEntrySize;
2854     for (++iStart; iStart < iEnd; ++iStart)
2855     {
2856         ((FREEHASHENTRY *) pcPtr)->iFree = iStart;
2857         pcPtr += m_iEntrySize;
2858     }
2859     ((FREEHASHENTRY *) pcPtr)->iFree = UINT32_MAX;
2860 }
2861
2862 //*****************************************************************************
2863 // Attempt to increase the amount of space available for the record heap.
2864 //*****************************************************************************
2865 template<class MemMgr>
2866 int CHashTableAndData<MemMgr>::Grow()   // 1 if successful, 0 if not.
2867 {
2868     WRAPPER_NO_CONTRACT;
2869     int         iCurSize;               // Current size in bytes.
2870     int         iEntries;               // New # of entries.
2871
2872     _ASSERTE(m_pcEntries != NULL);
2873     _ASSERTE(m_iFree == UINT32_MAX);
2874
2875     // Compute the current size and new # of entries.
2876     S_UINT32 iTotEntrySize = S_UINT32(m_iEntries) * S_UINT32(m_iEntrySize);
2877     if( iTotEntrySize.IsOverflow() )
2878     {
2879         _ASSERTE( !"CHashTableAndData overflow!" );
2880         return (0);
2881     }    
2882     iCurSize = MemMgr::RoundSize( iTotEntrySize.Value() );
2883     iEntries = (iCurSize + MemMgr::GrowSize(iCurSize)) / m_iEntrySize;
2884
2885     if ( (iEntries < 0) || ((ULONG)iEntries <= m_iEntries) )
2886     {
2887         _ASSERTE( !"CHashTableAndData overflow!" );
2888         return (0);
2889     }
2890
2891     // Try to expand the array.
2892     if (MemMgr::Grow(*(BYTE**)&m_pcEntries, iCurSize) == 0)
2893         return (0);
2894
2895     // Init the newly allocated space.
2896     InitFreeChain(m_iEntries, iEntries);
2897     m_iFree = m_iEntries;
2898     m_iEntries = iEntries;
2899     return (1);
2900 }
2901
2902 #endif // #ifndef DACCESS_COMPILE
2903
2904 //*****************************************************************************
2905 //*****************************************************************************
2906
2907 inline COUNT_T HashCOUNT_T(COUNT_T currentHash, COUNT_T data)
2908 {
2909     LIMITED_METHOD_DAC_CONTRACT;
2910     return ((currentHash << 5) + currentHash) ^ data;
2911 }
2912
2913 inline COUNT_T HashPtr(COUNT_T currentHash, PTR_VOID ptr)
2914 {
2915     WRAPPER_NO_CONTRACT;
2916     SUPPORTS_DAC;
2917     return HashCOUNT_T(currentHash, COUNT_T(SIZE_T(dac_cast<TADDR>(ptr))));
2918 }
2919
2920 inline DWORD HashThreeToOne(DWORD a, DWORD b, DWORD c)
2921 {
2922     LIMITED_METHOD_DAC_CONTRACT;
2923
2924     /*
2925     lookup3.c, by Bob Jenkins, May 2006, Public Domain.
2926
2927     These are functions for producing 32-bit hashes for hash table lookup.
2928     hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() 
2929     are externally useful functions.  Routines to test the hash are included 
2930     if SELF_TEST is defined.  You can use this free for any purpose.  It's in
2931     the public domain.  It has no warranty.
2932     */
2933
2934     #define rot32(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
2935     c ^= b; c -= rot32(b,14);
2936     a ^= c; a -= rot32(c,11);
2937     b ^= a; b -= rot32(a,25);
2938     c ^= b; c -= rot32(b,16);
2939     a ^= c; a -= rot32(c,4); 
2940     b ^= a; b -= rot32(a,14);
2941     c ^= b; c -= rot32(b,24);
2942
2943     return c;
2944 }
2945
2946 inline ULONG HashBytes(BYTE const *pbData, size_t iSize)
2947 {
2948     LIMITED_METHOD_CONTRACT;
2949     ULONG   hash = 5381;
2950
2951     BYTE const *pbDataEnd = pbData + iSize;
2952
2953     for (/**/ ; pbData < pbDataEnd; pbData++)
2954     {
2955         hash = ((hash << 5) + hash) ^ *pbData;
2956     }
2957     return hash;
2958 }
2959
2960 // Helper function for hashing a string char by char.
2961 inline ULONG HashStringA(LPCSTR szStr)
2962 {
2963     LIMITED_METHOD_CONTRACT;
2964     ULONG   hash = 5381;
2965     int     c;
2966
2967     while ((c = *szStr) != 0)
2968     {
2969         hash = ((hash << 5) + hash) ^ c;
2970         ++szStr;
2971     }
2972     return hash;
2973 }
2974
2975 inline ULONG HashString(LPCWSTR szStr)
2976 {
2977     LIMITED_METHOD_CONTRACT;
2978     ULONG   hash = 5381;
2979     int     c;
2980
2981     while ((c = *szStr) != 0)
2982     {
2983         hash = ((hash << 5) + hash) ^ c;
2984         ++szStr;
2985     }
2986     return hash;
2987 }
2988
2989 inline ULONG HashStringN(LPCWSTR szStr, SIZE_T cchStr)
2990 {
2991     LIMITED_METHOD_CONTRACT;
2992     ULONG   hash = 5381;
2993
2994     // hash the string two characters at a time
2995     ULONG *ptr = (ULONG *)szStr;
2996     
2997     // we assume that szStr is null-terminated
2998     _ASSERTE(cchStr <= wcslen(szStr));
2999     SIZE_T cDwordCount = (cchStr + 1) / 2;
3000
3001     for (SIZE_T i = 0; i < cDwordCount; i++)
3002     {
3003         hash = ((hash << 5) + hash) ^ ptr[i];
3004     }
3005
3006     return hash;
3007 }
3008
3009 // Case-insensitive string hash function.
3010 inline ULONG HashiStringA(LPCSTR szStr)
3011 {
3012     LIMITED_METHOD_CONTRACT;
3013     ULONG   hash = 5381;
3014     while (*szStr != 0)
3015     {
3016         hash = ((hash << 5) + hash) ^ toupper(*szStr);
3017         szStr++;
3018     }
3019     return hash;
3020 }
3021
3022 // Case-insensitive string hash function.
3023 inline ULONG HashiString(LPCWSTR szStr)
3024 {
3025     LIMITED_METHOD_CONTRACT;
3026     ULONG   hash = 5381;
3027     while (*szStr != 0)
3028     {
3029         hash = ((hash << 5) + hash) ^ towupper(*szStr);
3030         szStr++;
3031     }
3032     return hash;
3033 }
3034
3035 // Case-insensitive string hash function.
3036 inline ULONG HashiStringN(LPCWSTR szStr, DWORD count)
3037 {
3038     LIMITED_METHOD_CONTRACT;
3039     ULONG   hash = 5381;
3040     while (*szStr != 0 && count--)
3041     {
3042         hash = ((hash << 5) + hash) ^ towupper(*szStr);
3043         szStr++;
3044     }
3045     return hash;
3046 }
3047
3048 // Case-insensitive string hash function when all of the
3049 // characters in the string are known to be below 0x80.
3050 // Knowing this is much more efficient than calling
3051 // towupper above.
3052 inline ULONG HashiStringKnownLower80(LPCWSTR szStr) {
3053     LIMITED_METHOD_CONTRACT;
3054     ULONG hash = 5381;
3055     int c;
3056     int mask = ~0x20;
3057     while ((c = *szStr)!=0) {
3058         //If we have a lowercase character, ANDing off 0x20
3059         //(mask) will make it an uppercase character.
3060         if (c>='a' && c<='z') {
3061             c&=mask;
3062         }
3063         hash = ((hash << 5) + hash) ^ c;
3064         ++szStr;
3065     }
3066     return hash;
3067 }
3068
3069 inline ULONG HashiStringNKnownLower80(LPCWSTR szStr, DWORD count) {
3070     LIMITED_METHOD_CONTRACT;
3071     ULONG hash = 5381;
3072     int c;
3073     int mask = ~0x20;
3074     while ((c = *szStr) !=0 && count--) {
3075         //If we have a lowercase character, ANDing off 0x20
3076         //(mask) will make it an uppercase character.
3077         if (c>='a' && c<='z') {
3078             c&=mask;
3079         }
3080         hash = ((hash << 5) + hash) ^ c;
3081         ++szStr;
3082     }
3083     return hash;
3084 }
3085
3086 //*****************************************************************************
3087 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
3088 // The hashtable implementation that should be used instead is code:SHash.
3089 // If code:SHash does not work for you, talk to mailto:clrdeag.
3090 //*****************************************************************************
3091 // This class implements a closed hashing table.  Values are hashed to a bucket,
3092 // and if that bucket is full already, then the value is placed in the next
3093 // free bucket starting after the desired target (with wrap around).  If the
3094 // table becomes 75% full, it is grown and rehashed to reduce lookups.  This
3095 // class is best used in a reltively small lookup table where hashing is
3096 // not going to cause many collisions.  By not having the collision chain
3097 // logic, a lot of memory is saved.
3098 //
3099 // The user of the template is required to supply several methods which decide
3100 // how each element can be marked as free, deleted, or used.  It would have
3101 // been possible to write this with more internal logic, but that would require
3102 // either (a) more overhead to add status on top of elements, or (b) hard
3103 // coded types like one for strings, one for ints, etc... This gives you the
3104 // flexibility of adding logic to your type.
3105 //*****************************************************************************
3106 class CClosedHashBase
3107 {
3108     BYTE *EntryPtr(int iEntry)
3109     {
3110         LIMITED_METHOD_CONTRACT;
3111         return (m_rgData + (iEntry * m_iEntrySize));
3112     }
3113
3114     BYTE *EntryPtr(int iEntry, BYTE *rgData)
3115     {
3116         LIMITED_METHOD_CONTRACT;
3117         return (rgData + (iEntry * m_iEntrySize));
3118     }
3119
3120 public:
3121     enum ELEMENTSTATUS
3122     {
3123         FREE,                               // Item is not in use right now.
3124         DELETED,                            // Item is deleted.
3125         USED                                // Item is in use.
3126     };
3127
3128     CClosedHashBase(
3129         int         iBuckets,               // How many buckets should we start with.
3130         int         iEntrySize,             // Size of an entry.
3131         bool        bPerfect) :             // true if bucket size will hash with no collisions.
3132         m_bPerfect(bPerfect),
3133         m_iBuckets(iBuckets),
3134         m_iEntrySize(iEntrySize),
3135         m_iCount(0),
3136         m_iCollisions(0),
3137         m_rgData(0)
3138     {
3139         LIMITED_METHOD_CONTRACT;
3140         m_iSize = iBuckets + 7;
3141     }
3142
3143     virtual ~CClosedHashBase()
3144     {
3145         WRAPPER_NO_CONTRACT;
3146         Clear();
3147     }
3148
3149     virtual void Clear()
3150     {
3151         LIMITED_METHOD_CONTRACT;
3152         delete [] m_rgData;
3153         m_iCount = 0;
3154         m_iCollisions = 0;
3155         m_rgData = 0;
3156     }
3157
3158 //*****************************************************************************
3159 // Accessors for getting at the underlying data.  Be careful to use Count()
3160 // only when you want the number of buckets actually used.
3161 //*****************************************************************************
3162
3163     int Count()
3164     {
3165         LIMITED_METHOD_CONTRACT;
3166         return (m_iCount);
3167     }
3168
3169     int Collisions()
3170     {
3171         LIMITED_METHOD_CONTRACT;
3172         return (m_iCollisions);
3173     }
3174
3175     int Buckets()
3176     {
3177         LIMITED_METHOD_CONTRACT;
3178         return (m_iBuckets);
3179     }
3180
3181     void SetBuckets(int iBuckets, bool bPerfect=false)
3182     {
3183         LIMITED_METHOD_CONTRACT;
3184         _ASSERTE(m_rgData == 0);
3185         m_iBuckets = iBuckets;
3186         m_iSize = m_iBuckets + 7;
3187         m_bPerfect = bPerfect;
3188     }
3189
3190     BYTE *Data()
3191     {
3192         LIMITED_METHOD_CONTRACT;
3193         return (m_rgData);
3194     }
3195
3196 //*****************************************************************************
3197 // Add a new item to hash table given the key value.  If this new entry
3198 // exceeds maximum size, then the table will grow and be re-hashed, which
3199 // may cause a memory error.
3200 //*****************************************************************************
3201     BYTE *Add(                              // New item to fill out on success.
3202         void        *pData)                 // The value to hash on.
3203     {
3204         WRAPPER_NO_CONTRACT;
3205         // If we haven't allocated any memory, or it is too small, fix it.
3206         if (!m_rgData || ((m_iCount + 1) > (m_iSize * 3 / 4) && !m_bPerfect))
3207         {
3208             if (!ReHash())
3209                 return (0);
3210         }
3211
3212         return (DoAdd(pData, m_rgData, m_iBuckets, m_iSize, m_iCollisions, m_iCount));
3213     }
3214
3215 //*****************************************************************************
3216 // Delete the given value.  This will simply mark the entry as deleted (in
3217 // order to keep the collision chain intact).  There is an optimization that
3218 // consecutive deleted entries leading up to a free entry are themselves freed
3219 // to reduce collisions later on.
3220 //*****************************************************************************
3221     void Delete(
3222         void        *pData);                // Key value to delete.
3223
3224
3225 //*****************************************************************************
3226 //  Callback function passed to DeleteLoop.
3227 //*****************************************************************************
3228     typedef BOOL (* DELETELOOPFUNC)(        // Delete current item?
3229          BYTE *pEntry,                      // Bucket entry to evaluate
3230          void *pCustomizer);                // User-defined value
3231
3232 //*****************************************************************************
3233 // Iterates over all active values, passing each one to pDeleteLoopFunc.
3234 // If pDeleteLoopFunc returns TRUE, the entry is deleted. This is safer
3235 // and faster than using FindNext() and Delete().
3236 //*****************************************************************************
3237     void DeleteLoop(
3238         DELETELOOPFUNC pDeleteLoopFunc,     // Decides whether to delete item
3239         void *pCustomizer);                 // Extra value passed to deletefunc.
3240
3241
3242 //*****************************************************************************
3243 // Lookup a key value and return a pointer to the element if found.
3244 //*****************************************************************************
3245     BYTE *Find(                             // The item if found, 0 if not.
3246         void        *pData);                // The key to lookup.
3247
3248 //*****************************************************************************
3249 // Look for an item in the table.  If it isn't found, then create a new one and
3250 // return that.
3251 //*****************************************************************************
3252     BYTE *FindOrAdd(                        // The item if found, 0 if not.
3253         void        *pData,                 // The key to lookup.
3254         bool        &bNew);                 // true if created.
3255
3256 //*****************************************************************************
3257 // The following functions are used to traverse each used entry.  This code
3258 // will skip over deleted and free entries freeing the caller up from such
3259 // logic.
3260 //*****************************************************************************
3261     BYTE *GetFirst()                        // The first entry, 0 if none.
3262     {
3263         WRAPPER_NO_CONTRACT;
3264         int         i;                      // Loop control.
3265
3266         // If we've never allocated the table there can't be any to get.
3267         if (m_rgData == 0)
3268             return (0);
3269
3270         // Find the first one.
3271         for (i=0;  i<m_iSize;  i++)
3272         {
3273             if (Status(EntryPtr(i)) != FREE && Status(EntryPtr(i)) != DELETED)
3274                 return (EntryPtr(i));
3275         }
3276         return (0);
3277     }
3278
3279     BYTE *GetNext(BYTE *Prev)               // The next entry, 0 if done.
3280     {
3281         WRAPPER_NO_CONTRACT;
3282         int         i;                      // Loop control.
3283
3284         for (i = (int)(((size_t) Prev - (size_t) &m_rgData[0]) / m_iEntrySize) + 1; i<m_iSize;  i++)
3285         {
3286             if (Status(EntryPtr(i)) != FREE && Status(EntryPtr(i)) != DELETED)
3287                 return (EntryPtr(i));
3288         }
3289         return (0);
3290     }
3291
3292 private:
3293 //*****************************************************************************
3294 // Hash is called with a pointer to an element in the table.  You must override
3295 // this method and provide a hash algorithm for your element type.
3296 //*****************************************************************************
3297     virtual unsigned int Hash(             // The key value.
3298         void const  *pData)=0;              // Raw data to hash.
3299
3300 //*****************************************************************************
3301 // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate
3302 // direction of miscompare.  In this system everything is always equal or not.
3303 //*****************************************************************************
3304     virtual unsigned int Compare(          // 0, -1, or 1.
3305         void const  *pData,                 // Raw key data on lookup.
3306         BYTE        *pElement)=0;           // The element to compare data against.
3307
3308 //*****************************************************************************
3309 // Return true if the element is free to be used.
3310 //*****************************************************************************
3311     virtual ELEMENTSTATUS Status(           // The status of the entry.
3312         BYTE        *pElement)=0;           // The element to check.
3313
3314 //*****************************************************************************
3315 // Sets the status of the given element.
3316 //*****************************************************************************
3317     virtual void SetStatus(
3318         BYTE        *pElement,              // The element to set status for.
3319         ELEMENTSTATUS eStatus)=0;           // New status.
3320
3321 //*****************************************************************************
3322 // Returns the internal key value for an element.
3323 //*****************************************************************************
3324     virtual void *GetKey(                   // The data to hash on.
3325         BYTE        *pElement)=0;           // The element to return data ptr for.
3326
3327 //*****************************************************************************
3328 // This helper actually does the add for you.
3329 //*****************************************************************************
3330     BYTE *DoAdd(void *pData, BYTE *rgData, int &iBuckets, int iSize,
3331                 int &iCollisions, int &iCount);
3332
3333 //*****************************************************************************
3334 // This function is called either to init the table in the first place, or
3335 // to rehash the table if we ran out of room.
3336 //*****************************************************************************
3337     bool ReHash();                          // true if successful.
3338
3339 //*****************************************************************************
3340 // Walk each item in the table and mark it free.
3341 //*****************************************************************************
3342     void InitFree(BYTE *ptr, int iSize)
3343     {
3344         WRAPPER_NO_CONTRACT;
3345         int         i;
3346         for (i=0;  i<iSize;  i++, ptr += m_iEntrySize)
3347             SetStatus(ptr, FREE);
3348     }
3349
3350 private:
3351     bool        m_bPerfect;                 // true if the table size guarantees
3352                                             //  no collisions.
3353     int         m_iBuckets;                 // How many buckets do we have.
3354     int         m_iEntrySize;               // Size of an entry.
3355     int         m_iSize;                    // How many elements can we have.
3356     int         m_iCount;                   // How many items cannot be used (NON free, i.e. USED+DELETED).
3357     int         m_iCollisions;              // How many have we had.
3358     BYTE        *m_rgData;                  // Data element list.
3359 };
3360
3361 //*****************************************************************************
3362 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
3363 // The hashtable implementation that should be used instead is code:SHash.
3364 // If code:SHash does not work for you, talk to mailto:clrdeag.
3365 //*****************************************************************************
3366 template <class T> class CClosedHash : public CClosedHashBase
3367 {
3368 public:
3369     CClosedHash(
3370         int         iBuckets,               // How many buckets should we start with.
3371         bool        bPerfect=false) :       // true if bucket size will hash with no collisions.
3372         CClosedHashBase(iBuckets, sizeof(T), bPerfect)
3373     {
3374         WRAPPER_NO_CONTRACT;
3375     }
3376
3377     T &operator[](int iIndex)
3378     {
3379         WRAPPER_NO_CONTRACT;
3380         return ((T &) *(Data() + (iIndex * sizeof(T))));
3381     }
3382
3383
3384 //*****************************************************************************
3385 // Add a new item to hash table given the key value.  If this new entry
3386 // exceeds maximum size, then the table will grow and be re-hashed, which
3387 // may cause a memory error.
3388 //*****************************************************************************
3389     T *Add(                                 // New item to fill out on success.
3390         void        *pData)                 // The value to hash on.
3391     {
3392         WRAPPER_NO_CONTRACT;
3393         return ((T *) CClosedHashBase::Add(pData));
3394     }
3395
3396 //*****************************************************************************
3397 // Lookup a key value and return a pointer to the element if found.
3398 //*****************************************************************************
3399     T *Find(                                // The item if found, 0 if not.
3400         void        *pData)                 // The key to lookup.
3401     {
3402         WRAPPER_NO_CONTRACT;
3403         return ((T *) CClosedHashBase::Find(pData));
3404     }
3405
3406 //*****************************************************************************
3407 // Look for an item in the table.  If it isn't found, then create a new one and
3408 // return that.
3409 //*****************************************************************************
3410     T *FindOrAdd(                           // The item if found, 0 if not.
3411         void        *pData,                 // The key to lookup.
3412         bool        &bNew)                  // true if created.
3413     {
3414         WRAPPER_NO_CONTRACT;
3415         return ((T *) CClosedHashBase::FindOrAdd(pData, bNew));
3416     }
3417
3418
3419 //*****************************************************************************
3420 // The following functions are used to traverse each used entry.  This code
3421 // will skip over deleted and free entries freeing the caller up from such
3422 // logic.
3423 //*****************************************************************************
3424     T *GetFirst()                           // The first entry, 0 if none.
3425     {
3426         WRAPPER_NO_CONTRACT;
3427         return ((T *) CClosedHashBase::GetFirst());
3428     }
3429
3430     T *GetNext(T *Prev)                     // The next entry, 0 if done.
3431     {
3432         WRAPPER_NO_CONTRACT;
3433         return ((T *) CClosedHashBase::GetNext((BYTE *) Prev));
3434     }
3435 };
3436
3437
3438 //*****************************************************************************
3439 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
3440 // The hashtable implementation that should be used instead is code:SHash.
3441 // If code:SHash does not work for you, talk to mailto:clrdeag.
3442 //*****************************************************************************
3443 // Closed hash with typed parameters.  The derived class is the second
3444 //  parameter to the template.  The derived class must implement:
3445 //    unsigned long Hash(const T *pData);
3446 //    unsigned long Compare(const T *p1, T *p2);
3447 //    ELEMENTSTATUS Status(T *pEntry);
3448 //    void SetStatus(T *pEntry, ELEMENTSTATUS s);
3449 //    void* GetKey(T *pEntry);
3450 //*****************************************************************************
3451 template<class T, class H>class CClosedHashEx : public CClosedHash<T>
3452 {
3453 public:
3454     CClosedHashEx(
3455         int         iBuckets,               // How many buckets should we start with.
3456         bool        bPerfect=false) :       // true if bucket size will hash with no collisions.
3457         CClosedHash<T> (iBuckets, bPerfect)
3458     {
3459         WRAPPER_NO_CONTRACT;
3460     }
3461
3462     unsigned int Hash(const void *pData)
3463     {
3464         WRAPPER_NO_CONTRACT;
3465         return static_cast<H*>(this)->Hash((const T*)pData);
3466     }
3467
3468     unsigned int Compare(const void *p1, BYTE *p2)
3469     {
3470         WRAPPER_NO_CONTRACT;
3471         return static_cast<H*>(this)->Compare((const T*)p1, (T*)p2);
3472     }
3473
3474     typename CClosedHash<T>::ELEMENTSTATUS Status(BYTE *p)
3475     {
3476         WRAPPER_NO_CONTRACT;
3477         return static_cast<H*>(this)->Status((T*)p);
3478     }
3479
3480     void SetStatus(BYTE *p, typename CClosedHash<T>::ELEMENTSTATUS s)
3481     {
3482         WRAPPER_NO_CONTRACT;
3483         static_cast<H*>(this)->SetStatus((T*)p, s);
3484     }
3485
3486     void* GetKey(BYTE *p)
3487     {
3488         WRAPPER_NO_CONTRACT;
3489         return static_cast<H*>(this)->GetKey((T*)p);
3490     }
3491 };
3492
3493
3494 //*****************************************************************************
3495 // IMPORTANT: This data structure is deprecated, please do not add any new uses.
3496 // The hashtable implementation that should be used instead is code:SHash.
3497 // If code:SHash does not work for you, talk to mailto:clrdeag.
3498 //*****************************************************************************
3499 // This template is another form of a closed hash table.  It handles collisions
3500 // through a linked chain.  To use it, derive your hashed item from HASHLINK
3501 // and implement the virtual functions required.  1.5 * ibuckets will be
3502 // allocated, with the extra .5 used for collisions.  If you add to the point
3503 // where no free nodes are available, the entire table is grown to make room.
3504 // The advantage to this system is that collisions are always directly known,
3505 // there either is one or there isn't.
3506 //*****************************************************************************
3507 struct HASHLINK
3508 {
3509     ULONG       iNext;                  // Offset for next entry.
3510 };
3511
3512 template <class T> class CChainedHash
3513 {
3514     friend class VerifyLayoutsMD;
3515 public:
3516     CChainedHash(int iBuckets=32) :
3517         m_rgData(0),
3518         m_iBuckets(iBuckets),
3519         m_iCount(0),
3520         m_iMaxChain(0),
3521         m_iFree(0)
3522     {
3523         LIMITED_METHOD_CONTRACT;
3524         m_iSize = iBuckets + (iBuckets / 2);
3525     }
3526
3527     ~CChainedHash()
3528     {
3529         LIMITED_METHOD_CONTRACT;
3530         if (m_rgData)
3531             delete [] m_rgData;
3532     }
3533
3534     void SetBuckets(int iBuckets)
3535     {
3536         LIMITED_METHOD_CONTRACT;
3537         _ASSERTE(m_rgData == 0);
3538         // if iBuckets==0, then we'll allocate a zero size array and AV on dereference.
3539         _ASSERTE(iBuckets > 0);
3540         m_iBuckets = iBuckets;
3541         m_iSize = iBuckets + (iBuckets / 2);
3542     }
3543
3544     T *Add(void const *pData)
3545     {
3546         WRAPPER_NO_CONTRACT;
3547         ULONG       iHash;
3548         int         iBucket;
3549         T           *pItem;
3550
3551         // Build the list if required.
3552         if (m_rgData == 0 || m_iFree == 0xffffffff)
3553         {
3554             if (!ReHash())
3555                 return (0);
3556         }
3557
3558         // Hash the item and pick a bucket.
3559         iHash = Hash(pData);
3560         iBucket = iHash % m_iBuckets;
3561
3562         // Use the bucket if it is free.
3563         if (InUse(&m_rgData[iBucket]) == false)
3564         {
3565             pItem = &m_rgData[iBucket];
3566             pItem->iNext = 0xffffffff;
3567         }
3568         // Else take one off of the free list for use.
3569         else
3570         {
3571             ULONG       iEntry;
3572
3573             // Pull an item from the free list.
3574             iEntry = m_iFree;
3575             pItem = &m_rgData[m_iFree];
3576             m_iFree = pItem->iNext;
3577
3578             // Link the new node in after the bucket.
3579             pItem->iNext = m_rgData[iBucket].iNext;
3580             m_rgData[iBucket].iNext = iEntry;
3581         }
3582         ++m_iCount;
3583         return (pItem);
3584     }
3585
3586     T *Find(void const *pData, bool bAddIfNew=false)
3587     {
3588         WRAPPER_NO_CONTRACT;
3589         ULONG       iHash;
3590         int         iBucket;
3591         T           *pItem;
3592
3593         // Check states for lookup.
3594         if (m_rgData == 0)
3595         {
3596             // If we won't be adding, then we are through.
3597             if (bAddIfNew == false)
3598                 return (0);
3599
3600             // Otherwise, create the table.
3601             if (!ReHash())
3602                 return (0);
3603         }
3604
3605         // Hash the item and pick a bucket.
3606         iHash = Hash(pData);
3607         iBucket = iHash % m_iBuckets;
3608
3609         // If it isn't in use, then there it wasn't found.
3610         if (!InUse(&m_rgData[iBucket]))
3611         {
3612             if (bAddIfNew == false)
3613                 pItem = 0;
3614             else
3615             {
3616                 pItem = &m_rgData[iBucket];
3617                 pItem->iNext = 0xffffffff;
3618                 ++m_iCount;
3619             }
3620         }
3621         // Scan the list for the one we want.
3622         else
3623         {
3624             ULONG iChain = 0;
3625             for (pItem=(T *) &m_rgData[iBucket];  pItem;  pItem=GetNext(pItem))
3626             {
3627                 if (Cmp(pData, pItem) == 0)
3628                     break;
3629                 ++iChain;
3630             }
3631
3632             if (!pItem && bAddIfNew)
3633             {
3634                 ULONG       iEntry;
3635
3636                 // Record maximum chain length.
3637                 if (iChain > m_iMaxChain)
3638                     m_iMaxChain = iChain;
3639
3640                 // Now need more room.
3641                 if (m_iFree == 0xffffffff)
3642                 {
3643                     if (!ReHash())
3644                         return (0);
3645                 }
3646
3647                 // Pull an item from the free list.
3648                 iEntry = m_iFree;
3649                 pItem = &m_rgData[m_iFree];
3650                 m_iFree = pItem->iNext;
3651
3652                 // Link the new node in after the bucket.
3653                 pItem->iNext = m_rgData[iBucket].iNext;
3654                 m_rgData[iBucket].iNext = iEntry;
3655                 ++m_iCount;
3656             }
3657         }
3658         return (pItem);
3659     }
3660
3661     int Count()
3662     {
3663         LIMITED_METHOD_CONTRACT;
3664         return (m_iCount);
3665     }
3666
3667     int Buckets()
3668     {
3669         LIMITED_METHOD_CONTRACT;
3670         return (m_iBuckets);
3671     }
3672
3673     ULONG MaxChainLength()
3674     {
3675         LIMITED_METHOD_CONTRACT;
3676         return (m_iMaxChain);
3677     }
3678
3679     virtual void Clear()
3680     {
3681         LIMITED_METHOD_CONTRACT;
3682         // Free up the memory.
3683         if (m_rgData)
3684         {
3685             delete [] m_rgData;
3686             m_rgData = 0;
3687         }
3688
3689         m_rgData = 0;
3690         m_iFree = 0;
3691         m_iCount = 0;
3692         m_iMaxChain = 0;
3693     }
3694
3695     virtual bool InUse(T *pItem)=0;
3696     virtual void SetFree(T *pItem)=0;
3697     virtual ULONG Hash(void const *pData)=0;
3698     virtual int Cmp(void const *pData, void *pItem)=0;
3699 private:
3700     inline T *GetNext(T *pItem)
3701     {
3702         LIMITED_METHOD_CONTRACT;
3703         if (pItem->iNext != 0xffffffff)
3704             return ((T *) &m_rgData[pItem->iNext]);
3705         return (0);
3706     }
3707
3708     bool ReHash()
3709     {
3710         WRAPPER_NO_CONTRACT;
3711         T           *rgTemp;
3712         int         iNewSize;
3713
3714         // If this is a first time allocation, then just malloc it.
3715         if (!m_rgData)
3716         {
3717             if ((m_rgData = new (nothrow) T[m_iSize]) == 0)
3718                 return (false);
3719
3720             int i;
3721             for (i=0;  i<m_iSize;  i++)
3722                 SetFree(&m_rgData[i]);
3723
3724             m_iFree = m_iBuckets;
3725             for (i=m_iBuckets;  i<m_iSize;  i++)
3726                 ((T *) &m_rgData[i])->iNext = i + 1;
3727             ((T *) &m_rgData[m_iSize - 1])->iNext = 0xffffffff;
3728             return (true);
3729         }
3730
3731         // Otherwise we need more room on the free chain, so allocate some.
3732         iNewSize = m_iSize + (m_iSize / 2);
3733
3734         // Allocate/realloc memory.
3735         if ((rgTemp = new (nothrow) T[iNewSize]) == 0)
3736             return (false);
3737
3738         memcpy (rgTemp,m_rgData,m_iSize*sizeof(T));
3739         delete [] m_rgData;
3740
3741         // Init new entries, save the new free chain, and reset internals.
3742         m_iFree = m_iSize;
3743         for (int i=m_iFree;  i<iNewSize;  i++)
3744         {
3745             SetFree(&rgTemp[i]);
3746             ((T *) &rgTemp[i])->iNext = i + 1;
3747         }
3748         ((T *) &rgTemp[iNewSize - 1])->iNext = 0xffffffff;
3749
3750         m_rgData = rgTemp;
3751         m_iSize = iNewSize;
3752         return (true);
3753     }
3754
3755 private:
3756     T           *m_rgData;              // Data to store items in.
3757     int         m_iBuckets;             // How many buckets we want.
3758     int         m_iSize;                // How many are allocated.
3759     int         m_iCount;               // How many are we using.
3760     ULONG       m_iMaxChain;            // Max chain length.
3761     ULONG       m_iFree;                // Free chain.
3762 };
3763
3764
3765 //*****************************************************************************
3766 //
3767 //********** String helper functions.
3768 //
3769 //*****************************************************************************
3770
3771 //*****************************************************************************
3772 // Checks if string length exceeds the specified limit
3773 //*****************************************************************************
3774 inline BOOL IsStrLongerThan(__in __in_z char* pstr, unsigned N)
3775 {
3776     LIMITED_METHOD_CONTRACT;
3777     unsigned i = 0;
3778     if(pstr)
3779     {
3780         for(i=0; (i < N)&&(pstr[i]); i++);
3781     }
3782     return (i >= N);
3783 }
3784
3785
3786 //*****************************************************************************
3787 // Class to parse a list of simple assembly names and then find a match
3788 //*****************************************************************************
3789
3790 class AssemblyNamesList
3791 {
3792     struct AssemblyName
3793     {
3794         LPUTF8          m_assemblyName;
3795         AssemblyName   *m_next;         // Next name
3796     };
3797
3798     AssemblyName       *m_pNames;       // List of names
3799
3800 public:
3801
3802     bool IsInList(LPCUTF8 assemblyName);
3803
3804     bool IsEmpty()
3805     {
3806         LIMITED_METHOD_CONTRACT;
3807         return m_pNames == 0;
3808     }
3809
3810     AssemblyNamesList(__in LPWSTR list);
3811     ~AssemblyNamesList();
3812 };
3813
3814 //*****************************************************************************
3815 // Class to parse a list of method names and then find a match
3816 //*****************************************************************************
3817
3818 struct CORINFO_SIG_INFO;
3819
3820 class MethodNamesListBase
3821 {
3822     struct MethodName
3823     {
3824         LPUTF8      methodName;     // NULL means wildcard
3825         LPUTF8      className;      // NULL means wildcard
3826         int         numArgs;        // number of args for the method, -1 is wildcard
3827         MethodName *next;           // Next name
3828     };
3829
3830     MethodName     *pNames;         // List of names
3831
3832     bool IsInList(LPCUTF8 methodName, LPCUTF8 className, int numArgs);
3833
3834 public:
3835     void Init()
3836     {
3837         LIMITED_METHOD_CONTRACT;
3838         pNames = 0;
3839     }
3840
3841     void Init(__in __in_z LPWSTR list)
3842     {
3843         WRAPPER_NO_CONTRACT;
3844         pNames = 0;
3845         Insert(list);
3846     }
3847
3848     void Destroy();
3849
3850     void Insert(__in __in_z LPWSTR list);
3851
3852     bool IsInList(LPCUTF8 methodName, LPCUTF8 className, PCCOR_SIGNATURE sig = NULL);
3853     bool IsInList(LPCUTF8 methodName, LPCUTF8 className, CORINFO_SIG_INFO* pSigInfo);
3854     bool IsEmpty()
3855     {
3856         LIMITED_METHOD_CONTRACT;
3857         return pNames == 0;
3858     }
3859 };
3860
3861 class MethodNamesList : public MethodNamesListBase
3862 {
3863 public:
3864     MethodNamesList()
3865     {
3866         WRAPPER_NO_CONTRACT;
3867         Init();
3868     }
3869
3870     MethodNamesList(__in LPWSTR list)
3871     {
3872         WRAPPER_NO_CONTRACT;
3873         Init(list);
3874     }
3875
3876     ~MethodNamesList()
3877     {
3878         WRAPPER_NO_CONTRACT;
3879         Destroy();
3880     }
3881 };
3882
3883 #if !defined(NO_CLRCONFIG)
3884
3885 /**************************************************************************/
3886 /* simple wrappers around the REGUTIL and MethodNameList routines that make
3887    the lookup lazy */
3888
3889 /* to be used as static variable - no constructor/destructor, assumes zero
3890    initialized memory */
3891
3892 class ConfigDWORD
3893 {
3894 public:
3895     //
3896     // NOTE: The following function is deprecated; use the CLRConfig class instead. 
3897     // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
3898     // 
3899     inline DWORD val_DontUse_(__in __in_z LPCWSTR keyName, DWORD defaultVal=0)
3900     {
3901         WRAPPER_NO_CONTRACT;
3902         // make sure that the memory was zero initialized
3903         _ASSERTE(m_inited == 0 || m_inited == 1);
3904
3905         if (!m_inited) init_DontUse_(keyName, defaultVal);
3906         return m_value;
3907     }
3908     inline DWORD val(const CLRConfig::ConfigDWORDInfo & info)
3909     {
3910         WRAPPER_NO_CONTRACT;
3911         // make sure that the memory was zero initialized
3912         _ASSERTE(m_inited == 0 || m_inited == 1);
3913
3914         if (!m_inited) init(info);
3915         return m_value;
3916     }
3917
3918 private:
3919     void init_DontUse_(__in __in_z LPCWSTR keyName, DWORD defaultVal=0);
3920     void init(const CLRConfig::ConfigDWORDInfo & info);
3921
3922 private:
3923     DWORD  m_value;
3924     BYTE m_inited;
3925 };
3926
3927 /**************************************************************************/
3928 class ConfigString
3929 {
3930 public:
3931     inline LPWSTR val(const CLRConfig::ConfigStringInfo & info)
3932     {
3933         WRAPPER_NO_CONTRACT;
3934         // make sure that the memory was zero initialized
3935         _ASSERTE(m_inited == 0 || m_inited == 1);
3936
3937         if (!m_inited) init(info);
3938         return m_value;
3939     }
3940
3941     bool isInitialized()
3942     {
3943         WRAPPER_NO_CONTRACT;
3944
3945         // make sure that the memory was zero initialized
3946         _ASSERTE(m_inited == 0 || m_inited == 1);
3947
3948         return m_inited == 1;
3949     }
3950
3951 private:
3952     void init(const CLRConfig::ConfigStringInfo & info);
3953
3954 private:
3955     LPWSTR m_value;
3956     BYTE m_inited;
3957 };
3958
3959 /**************************************************************************/
3960 class ConfigMethodSet
3961 {
3962 public:
3963     bool isEmpty()
3964     {
3965         WRAPPER_NO_CONTRACT;
3966         _ASSERTE(m_inited == 1);
3967         return m_list.IsEmpty();
3968     }
3969
3970     bool contains(LPCUTF8 methodName, LPCUTF8 className, PCCOR_SIGNATURE sig = NULL);
3971     bool contains(LPCUTF8 methodName, LPCUTF8 className, CORINFO_SIG_INFO* pSigInfo);
3972
3973     inline void ensureInit(const CLRConfig::ConfigStringInfo & info)
3974     {
3975         WRAPPER_NO_CONTRACT;
3976         // make sure that the memory was zero initialized
3977         _ASSERTE(m_inited == 0 || m_inited == 1);
3978
3979         if (!m_inited) init(info);
3980     }
3981
3982 private:
3983     void init(const CLRConfig::ConfigStringInfo & info);
3984
3985 private:
3986     MethodNamesListBase m_list;
3987
3988     BYTE m_inited;
3989 };
3990
3991 #endif // !defined(NO_CLRCONFIG)
3992
3993 //*****************************************************************************
3994 // Convert a pointer to a string into a GUID.
3995 //*****************************************************************************
3996 HRESULT LPCSTRToGuid(                   // Return status.
3997     LPCSTR      szGuid,                 // String to convert.
3998     GUID        *psGuid);               // Buffer for converted GUID.
3999
4000 //*****************************************************************************
4001 // Convert a GUID into a pointer to a string
4002 //*****************************************************************************
4003 int GuidToLPWSTR(                  // Return status.
4004     GUID        Guid,                  // [IN] The GUID to convert.
4005     __out_ecount (cchGuid) LPWSTR szGuid, // [OUT] String into which the GUID is stored
4006     DWORD       cchGuid);              // [IN] Size in wide chars of szGuid
4007
4008 //*****************************************************************************
4009 // Parse a Wide char string into a GUID
4010 //*****************************************************************************
4011 BOOL LPWSTRToGuid(
4012     GUID      * Guid,                         // [OUT] The GUID to fill in
4013     __in_ecount(cchGuid)   LPCWSTR szGuid,    // [IN] String to parse
4014     DWORD       cchGuid);                     // [IN] Count in wchars in string
4015
4016 typedef VPTR(class RangeList) PTR_RangeList;
4017
4018 class RangeList
4019 {
4020   public:
4021     VPTR_BASE_CONCRETE_VTABLE_CLASS(RangeList)
4022
4023 #ifndef DACCESS_COMPILE
4024     RangeList();
4025     ~RangeList();
4026 #else
4027     RangeList()
4028     {
4029         LIMITED_METHOD_CONTRACT;
4030     }
4031 #endif
4032
4033     // Wrappers to make the virtual calls DAC-safe.
4034     BOOL AddRange(const BYTE *start, const BYTE *end, void *id)
4035     {
4036         return this->AddRangeWorker(start, end, id);
4037     }
4038     
4039     void RemoveRanges(void *id, const BYTE *start = NULL, const BYTE *end = NULL)
4040     {
4041         return this->RemoveRangesWorker(id, start, end);
4042     }
4043     
4044     BOOL IsInRange(TADDR address, TADDR *pID = NULL)
4045     {
4046         SUPPORTS_DAC;
4047     
4048         return this->IsInRangeWorker(address, pID);
4049     }
4050
4051 #ifndef DACCESS_COMPILE
4052
4053     // You can overload these two for synchronization (as LockedRangeList does)
4054     virtual BOOL AddRangeWorker(const BYTE *start, const BYTE *end, void *id);
4055     // If both "start" and "end" are NULL, then this method deletes all ranges with
4056     // the given id (i.e. the original behaviour).  Otherwise, it ignores the given
4057     // id and deletes all ranges falling in the region [start, end).
4058     virtual void RemoveRangesWorker(void *id, const BYTE *start = NULL, const BYTE *end = NULL);
4059 #else
4060     virtual BOOL AddRangeWorker(const BYTE *start, const BYTE *end, void *id)
4061     {
4062         return TRUE;
4063     }
4064     virtual void RemoveRangesWorker(void *id, const BYTE *start = NULL, const BYTE *end = NULL) { }
4065 #endif // !DACCESS_COMPILE
4066
4067     virtual BOOL IsInRangeWorker(TADDR address, TADDR *pID = NULL);
4068
4069 #ifdef DACCESS_COMPILE
4070     void EnumMemoryRegions(enum CLRDataEnumMemoryFlags flags);
4071 #endif
4072
4073     enum
4074     {
4075         RANGE_COUNT = 10
4076     };
4077
4078    
4079   private:
4080     struct Range
4081     {
4082         TADDR start;
4083         TADDR end;
4084         TADDR id;
4085     };
4086
4087     struct RangeListBlock
4088     {
4089         Range                ranges[RANGE_COUNT];
4090         DPTR(RangeListBlock) next;
4091
4092 #ifdef DACCESS_COMPILE
4093         void EnumMemoryRegions(enum CLRDataEnumMemoryFlags flags);
4094 #endif
4095
4096     };
4097
4098     void InitBlock(RangeListBlock *block);
4099
4100     RangeListBlock       m_starterBlock;
4101     DPTR(RangeListBlock) m_firstEmptyBlock;
4102     TADDR                m_firstEmptyRange;
4103 };
4104
4105
4106 //
4107 // A private function to do the equavilent of a CoCreateInstance in
4108 // cases where we can't make the real call. Use this when, for
4109 // instance, you need to create a symbol reader in the Runtime but
4110 // we're not CoInitialized. Obviously, this is only good for COM
4111 // objects for which CoCreateInstance is just a glorified
4112 // find-and-load-me operation.
4113 //
4114
4115 HRESULT FakeCoCreateInstanceEx(REFCLSID       rclsid,
4116                                LPCWSTR        wszDllPath,
4117                                REFIID         riid,
4118                                void **        ppv,
4119                                HMODULE *      phmodDll);
4120
4121 // Provided for backward compatibility and for code that doesn't need the HMODULE of the
4122 // DLL that was loaded to create the COM object.  See comment at implementation of
4123 // code:FakeCoCreateInstanceEx for more details.
4124 inline HRESULT FakeCoCreateInstance(REFCLSID   rclsid,
4125                                     REFIID     riid,
4126                                     void **    ppv)
4127 {
4128     CONTRACTL
4129     {
4130         NOTHROW;
4131     }
4132     CONTRACTL_END;
4133
4134     return FakeCoCreateInstanceEx(rclsid, NULL, riid, ppv, NULL);
4135 };
4136
4137 //*****************************************************************************
4138 // Gets the directory based on the location of the module. This routine
4139 // is called at COR setup time. Set is called during EEStartup and by the
4140 // MetaData dispenser.
4141 //*****************************************************************************
4142 HRESULT GetInternalSystemDirectory(__out_ecount_part_opt(*pdwLength,*pdwLength) LPWSTR buffer, __inout DWORD* pdwLength);
4143 LPCWSTR GetInternalSystemDirectory(__out_opt DWORD * pdwLength = NULL);
4144
4145 //*****************************************************************************
4146 // This function validates the given Method/Field/Standalone signature. (util.cpp)
4147 //*****************************************************************************
4148 struct IMDInternalImport;
4149 HRESULT validateTokenSig(
4150     mdToken             tk,                     // [IN] Token whose signature needs to be validated.
4151     PCCOR_SIGNATURE     pbSig,                  // [IN] Signature.
4152     ULONG               cbSig,                  // [IN] Size in bytes of the signature.
4153     DWORD               dwFlags,                // [IN] Method flags.
4154     IMDInternalImport*  pImport);               // [IN] Internal MD Import interface ptr
4155
4156 //*****************************************************************************
4157 // Determine the version number of the runtime that was used to build the
4158 // specified image. The pMetadata pointer passed in is the pointer to the
4159 // metadata contained in the image.
4160 //*****************************************************************************
4161 HRESULT GetImageRuntimeVersionString(PVOID pMetaData, LPCSTR* pString);
4162
4163 //*****************************************************************************
4164 // The registry keys and values that contain the information regarding
4165 // the default registered unmanaged debugger.
4166 //*****************************************************************************
4167 SELECTANY const WCHAR kDebugApplicationsPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications");
4168 SELECTANY const WCHAR kDebugApplicationsKey[] = W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications");
4169
4170 SELECTANY const WCHAR kUnmanagedDebuggerKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug");
4171 SELECTANY const WCHAR kUnmanagedDebuggerValue[] = W("Debugger");
4172 SELECTANY const WCHAR kUnmanagedDebuggerAutoValue[] = W("Auto");
4173 SELECTANY const WCHAR kUnmanagedDebuggerAutoExclusionListKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList");
4174
4175 BOOL GetRegistryLongValue(HKEY    hKeyParent,              // Parent key.
4176                           LPCWSTR szKey,                   // Key name to look at.
4177                           LPCWSTR szName,                  // Name of value to get.
4178                           long    *pValue,                 // Put value here, if found.
4179                           BOOL    fReadNonVirtualizedKey); // Whether to read 64-bit hive on WOW64
4180
4181 HRESULT GetCurrentModuleFileName(SString& pBuffer);
4182
4183 //*****************************************************************************
4184 // Retrieve information regarding what registered default debugger
4185 //*****************************************************************************
4186 void GetDebuggerSettingInfo(SString &debuggerKeyValue, BOOL *pfAuto);
4187 HRESULT GetDebuggerSettingInfoWorker(__out_ecount_part_opt(*pcchDebuggerString, *pcchDebuggerString) LPWSTR wszDebuggerString, DWORD * pcchDebuggerString, BOOL * pfAuto);
4188
4189 void TrimWhiteSpace(__inout_ecount(*pcch)  LPCWSTR *pwsz, __inout LPDWORD pcch);
4190
4191
4192 //*****************************************************************************
4193 // Convert a UTF8 string to Unicode, into a CQuickArray<WCHAR>.
4194 //*****************************************************************************
4195 HRESULT Utf2Quick(
4196     LPCUTF8     pStr,                   // The string to convert.
4197     CQuickArray<WCHAR> &rStr,           // The QuickArray<WCHAR> to convert it into.
4198     int         iCurLen = 0);           // Initial characters in the array to leave (default 0).
4199
4200 //*****************************************************************************
4201 //  Extract the movl 64-bit unsigned immediate from an IA64 bundle
4202 //  (Format X2)
4203 //*****************************************************************************
4204 UINT64 GetIA64Imm64(UINT64 * pBundle);
4205 UINT64 GetIA64Imm64(UINT64 qword0, UINT64 qword1);
4206
4207 //*****************************************************************************
4208 //  Deposit the movl 64-bit unsigned immediate into an IA64 bundle
4209 //  (Format X2)
4210 //*****************************************************************************
4211 void PutIA64Imm64(UINT64 * pBundle, UINT64 imm64);
4212
4213 //*****************************************************************************
4214 //  Extract the IP-Relative signed 25-bit immediate from an IA64 bundle
4215 //  (Formats B1, B2 or B3)
4216 //  Note that due to branch target alignment requirements
4217 //       the lowest four bits in the result will always be zero.
4218 //*****************************************************************************
4219 INT32 GetIA64Rel25(UINT64 * pBundle, UINT32 slot);
4220 INT32 GetIA64Rel25(UINT64 qword0, UINT64 qword1, UINT32 slot);
4221
4222 //*****************************************************************************
4223 //  Deposit the IP-Relative signed 25-bit immediate into an IA64 bundle
4224 //  (Formats B1, B2 or B3)
4225 //  Note that due to branch target alignment requirements
4226 //       the lowest four bits are required to be zero.
4227 //*****************************************************************************
4228 void PutIA64Rel25(UINT64 * pBundle, UINT32 slot, INT32 imm25);
4229
4230 //*****************************************************************************
4231 //  Extract the IP-Relative signed 64-bit immediate from an IA64 bundle
4232 //  (Formats X3 or X4)
4233 //*****************************************************************************
4234 INT64 GetIA64Rel64(UINT64 * pBundle);
4235 INT64 GetIA64Rel64(UINT64 qword0, UINT64 qword1);
4236
4237 //*****************************************************************************
4238 //  Deposit the IP-Relative signed 64-bit immediate into a IA64 bundle
4239 //  (Formats X3 or X4)
4240 //*****************************************************************************
4241 void PutIA64Rel64(UINT64 * pBundle, INT64 imm64);
4242
4243 //*****************************************************************************
4244 //  Extract the 32-bit immediate from movw/movt Thumb2 sequence
4245 //*****************************************************************************
4246 UINT32 GetThumb2Mov32(UINT16 * p);
4247
4248 //*****************************************************************************
4249 //  Deposit the 32-bit immediate into movw/movt Thumb2 sequence
4250 //*****************************************************************************
4251 void PutThumb2Mov32(UINT16 * p, UINT32 imm32);
4252
4253 //*****************************************************************************
4254 //  Extract the 24-bit rel offset from bl instruction
4255 //*****************************************************************************
4256 INT32 GetThumb2BlRel24(UINT16 * p);
4257
4258 //*****************************************************************************
4259 //  Extract the 24-bit rel offset from bl instruction
4260 //*****************************************************************************
4261 void PutThumb2BlRel24(UINT16 * p, INT32 imm24);
4262
4263 //*****************************************************************************
4264 //  Extract the PC-Relative offset from a b or bl instruction 
4265 //*****************************************************************************
4266 INT32 GetArm64Rel28(UINT32 * pCode);
4267
4268 //*****************************************************************************
4269 //  Extract the PC-Relative page address from an adrp instruction
4270 //*****************************************************************************
4271 INT32 GetArm64Rel21(UINT32 * pCode);
4272
4273 //*****************************************************************************
4274 //  Extract the page offset from an add instruction
4275 //*****************************************************************************
4276 INT32 GetArm64Rel12(UINT32 * pCode);
4277
4278 //*****************************************************************************
4279 //  Deposit the PC-Relative offset 'imm28' into a b or bl instruction 
4280 //*****************************************************************************
4281 void PutArm64Rel28(UINT32 * pCode, INT32 imm28);
4282
4283 //*****************************************************************************
4284 //  Deposit the PC-Relative page address 'imm21' into an adrp instruction
4285 //*****************************************************************************
4286 void PutArm64Rel21(UINT32 * pCode, INT32 imm21);
4287
4288 //*****************************************************************************
4289 //  Deposit the page offset 'imm12' into an add instruction
4290 //*****************************************************************************
4291 void PutArm64Rel12(UINT32 * pCode, INT32 imm12);
4292
4293 //*****************************************************************************
4294 // Returns whether the offset fits into bl instruction
4295 //*****************************************************************************
4296 inline bool FitsInThumb2BlRel24(INT32 imm24)
4297 {
4298     return ((imm24 << 7) >> 7) == imm24;
4299 }
4300
4301 //*****************************************************************************
4302 // Returns whether the offset fits into an Arm64 b or bl instruction
4303 //*****************************************************************************
4304 inline bool FitsInRel28(INT32 val32)
4305 {
4306     return (val32 >= -0x08000000) && (val32 < 0x08000000);
4307 }
4308
4309 //*****************************************************************************
4310 // Returns whether the offset fits into an Arm64 adrp instruction
4311 //*****************************************************************************
4312 inline bool FitsInRel21(INT32 val32)
4313 {
4314     return (val32 >= 0) && (val32 <= 0x001FFFFF);
4315 }
4316
4317 //*****************************************************************************
4318 // Returns whether the offset fits into an Arm64 add instruction
4319 //*****************************************************************************
4320 inline bool FitsInRel12(INT32 val32)
4321 {
4322     return (val32 >= 0) && (val32 <= 0x00000FFF);
4323 }
4324
4325 //*****************************************************************************
4326 // Returns whether the offset fits into an Arm64 b or bl instruction
4327 //*****************************************************************************
4328 inline bool FitsInRel28(INT64 val64)
4329 {
4330     return (val64 >= -0x08000000LL) && (val64 < 0x08000000LL);
4331 }
4332
4333 //*****************************************************************************
4334 // Splits a command line into argc/argv lists, using the VC7 parsing rules.
4335 // This functions interface mimics the CommandLineToArgvW api.
4336 // If function fails, returns NULL.
4337 // If function suceeds, call delete [] on return pointer when done.
4338 //*****************************************************************************
4339 LPWSTR *SegmentCommandLine(LPCWSTR lpCmdLine, DWORD *pNumArgs);
4340
4341 //
4342 // TEB access can be dangerous when using fibers because a fiber may
4343 // run on multiple threads.  If the TEB pointer is retrieved and saved
4344 // and then a fiber is moved to a different thread, when it accesses
4345 // the saved TEB pointer, it will be looking at the TEB state for a
4346 // different fiber.
4347 //
4348 // These accessors serve the purpose of retrieving information from the
4349 // TEB in a manner that ensures that the current fiber will not switch
4350 // threads while the access is occuring.
4351 //
4352 class ClrTeb
4353 {
4354 public:
4355 #if defined(FEATURE_PAL)
4356
4357     // returns pointer that uniquely identifies the fiber
4358     static void* GetFiberPtrId()
4359     {
4360         LIMITED_METHOD_CONTRACT;
4361         // not fiber for FEATURE_PAL - use the regular thread ID
4362         return (void *)(size_t)GetCurrentThreadId();
4363     }
4364
4365     static void* InvalidFiberPtrId()
4366     {
4367         return NULL;
4368     }
4369
4370     static void* GetStackBase()
4371     {
4372         return PAL_GetStackBase();
4373     }
4374
4375     static void* GetStackLimit()
4376     {
4377         return PAL_GetStackLimit();
4378     }
4379
4380 #else // !FEATURE_PAL
4381
4382     // returns pointer that uniquely identifies the fiber
4383     static void* GetFiberPtrId()
4384     {
4385         LIMITED_METHOD_CONTRACT;
4386         // stackbase is the unique fiber identifier
4387         return NtCurrentTeb()->NtTib.StackBase;
4388     }
4389
4390     static void* GetStackBase()
4391     {
4392         LIMITED_METHOD_CONTRACT;
4393         return NtCurrentTeb()->NtTib.StackBase;
4394     }
4395
4396     static void* GetStackLimit()
4397     {
4398         LIMITED_METHOD_CONTRACT;
4399         return NtCurrentTeb()->NtTib.StackLimit;
4400     }
4401
4402     // Please don't start to use this method unless you absolutely have to.
4403     // The reason why this is added is for WIN64 to support LEGACY PE-style TLS
4404     // variables.  On X86 it is supported by the JIT compilers themselves.  On
4405     // WIN64 we build more logic into the JIT helper for accessing fields.
4406     static void* GetLegacyThreadLocalStoragePointer()
4407     {
4408         LIMITED_METHOD_CONTRACT;
4409         return NtCurrentTeb()->ThreadLocalStoragePointer;
4410     }
4411
4412     static void* GetOleReservedPtr()
4413     {
4414         LIMITED_METHOD_CONTRACT;
4415         return NtCurrentTeb()->ReservedForOle;
4416     }
4417
4418     static void* GetProcessEnvironmentBlock()
4419     {
4420         LIMITED_METHOD_CONTRACT;
4421         return NtCurrentTeb()->ProcessEnvironmentBlock;
4422     }
4423
4424
4425     static void* InvalidFiberPtrId()
4426     {
4427         return (void*) 1;
4428     }
4429 #endif // !FEATURE_PAL
4430 };
4431
4432 #if !defined(DACCESS_COMPILE)
4433
4434 // check if current thread is a GC thread (concurrent or server)
4435 inline BOOL IsGCSpecialThread ()
4436 {
4437     STATIC_CONTRACT_NOTHROW;
4438     STATIC_CONTRACT_GC_NOTRIGGER;
4439     STATIC_CONTRACT_MODE_ANY;
4440     STATIC_CONTRACT_CANNOT_TAKE_LOCK;
4441
4442     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_GC);
4443 }
4444
4445 // check if current thread is a Gate thread
4446 inline BOOL IsGateSpecialThread ()
4447 {
4448     STATIC_CONTRACT_NOTHROW;
4449     STATIC_CONTRACT_GC_NOTRIGGER;
4450     STATIC_CONTRACT_MODE_ANY;
4451
4452     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Gate);
4453 }
4454
4455 // check if current thread is a Timer thread
4456 inline BOOL IsTimerSpecialThread ()
4457 {
4458     STATIC_CONTRACT_NOTHROW;
4459     STATIC_CONTRACT_GC_NOTRIGGER;
4460     STATIC_CONTRACT_MODE_ANY;
4461
4462     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Timer);
4463 }
4464
4465 // check if current thread is a debugger helper thread
4466 inline BOOL IsDbgHelperSpecialThread ()
4467 {
4468     STATIC_CONTRACT_NOTHROW;
4469     STATIC_CONTRACT_GC_NOTRIGGER;
4470     STATIC_CONTRACT_MODE_ANY;
4471
4472     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_DbgHelper);
4473 }
4474
4475 // check if current thread is a debugger helper thread
4476 inline BOOL IsETWRundownSpecialThread ()
4477 {
4478     STATIC_CONTRACT_NOTHROW;
4479     STATIC_CONTRACT_GC_NOTRIGGER;
4480     STATIC_CONTRACT_MODE_ANY;
4481
4482     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_ETWRundownThread);
4483 }
4484
4485 // check if current thread is a generic instantiation lookup compare thread
4486 inline BOOL IsGenericInstantiationLookupCompareThread ()
4487 {
4488     STATIC_CONTRACT_NOTHROW;
4489     STATIC_CONTRACT_GC_NOTRIGGER;
4490     STATIC_CONTRACT_MODE_ANY;
4491
4492     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_GenericInstantiationCompare);
4493 }
4494
4495 // check if current thread is a thread which is performing shutdown
4496 inline BOOL IsShutdownSpecialThread ()
4497 {
4498     STATIC_CONTRACT_NOTHROW;
4499     STATIC_CONTRACT_GC_NOTRIGGER;
4500     STATIC_CONTRACT_MODE_ANY;
4501
4502     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Shutdown);
4503 }
4504
4505 inline BOOL IsThreadPoolIOCompletionSpecialThread ()
4506 {
4507     STATIC_CONTRACT_NOTHROW;
4508     STATIC_CONTRACT_GC_NOTRIGGER;
4509     STATIC_CONTRACT_MODE_ANY;
4510
4511     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Threadpool_IOCompletion);
4512 }
4513
4514 inline BOOL IsThreadPoolWorkerSpecialThread ()
4515 {
4516     STATIC_CONTRACT_NOTHROW;
4517     STATIC_CONTRACT_GC_NOTRIGGER;
4518     STATIC_CONTRACT_MODE_ANY;
4519
4520     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Threadpool_Worker);
4521 }
4522
4523 inline BOOL IsWaitSpecialThread ()
4524 {
4525     STATIC_CONTRACT_NOTHROW;
4526     STATIC_CONTRACT_GC_NOTRIGGER;
4527     STATIC_CONTRACT_MODE_ANY;
4528
4529     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Wait);
4530 }
4531
4532 // check if current thread is a thread which is performing shutdown
4533 inline BOOL IsSuspendEEThread ()
4534 {
4535     STATIC_CONTRACT_NOTHROW;
4536     STATIC_CONTRACT_GC_NOTRIGGER;
4537     STATIC_CONTRACT_MODE_ANY;
4538
4539     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_DynamicSuspendEE);
4540 }
4541
4542 inline BOOL IsFinalizerThread ()
4543 {
4544     STATIC_CONTRACT_NOTHROW;
4545     STATIC_CONTRACT_GC_NOTRIGGER;
4546     STATIC_CONTRACT_MODE_ANY;
4547
4548     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_Finalizer);
4549 }
4550
4551 inline BOOL IsShutdownHelperThread ()
4552 {
4553     STATIC_CONTRACT_NOTHROW;
4554     STATIC_CONTRACT_GC_NOTRIGGER;
4555     STATIC_CONTRACT_MODE_ANY;
4556
4557     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_ShutdownHelper);
4558 }
4559
4560 inline BOOL IsProfilerAttachThread ()
4561 {
4562     STATIC_CONTRACT_NOTHROW;
4563     STATIC_CONTRACT_GC_NOTRIGGER;
4564     STATIC_CONTRACT_MODE_ANY;
4565
4566     return !!(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ThreadType_ProfAPI_Attach);
4567 }
4568
4569 // set specical type for current thread
4570 inline void ClrFlsSetThreadType (TlsThreadTypeFlag flag)
4571 {
4572     STATIC_CONTRACT_NOTHROW;
4573     STATIC_CONTRACT_GC_NOTRIGGER;
4574     STATIC_CONTRACT_MODE_ANY;
4575
4576     ClrFlsSetValue (TlsIdx_ThreadType, (LPVOID)(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) |flag));
4577 }
4578
4579 // clear specical type for current thread
4580 inline void ClrFlsClearThreadType (TlsThreadTypeFlag flag)
4581 {
4582     STATIC_CONTRACT_NOTHROW;
4583     STATIC_CONTRACT_GC_NOTRIGGER;
4584     STATIC_CONTRACT_MODE_ANY;
4585
4586     ClrFlsSetValue (TlsIdx_ThreadType, (LPVOID)(((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & ~flag));
4587 }
4588
4589 #endif //!DACCESS_COMPILE
4590
4591 #ifdef DACCESS_COMPILE
4592 #define SET_THREAD_TYPE_STACKWALKER(pThread)
4593 #define CLEAR_THREAD_TYPE_STACKWALKER()
4594 #else   // DACCESS_COMPILE
4595 #define SET_THREAD_TYPE_STACKWALKER(pThread)   ClrFlsSetValue(TlsIdx_StackWalkerWalkingThread, pThread)
4596 #define CLEAR_THREAD_TYPE_STACKWALKER() ClrFlsSetValue(TlsIdx_StackWalkerWalkingThread, NULL)
4597 #endif  // DACCESS_COMPILE
4598
4599 HRESULT SetThreadName(HANDLE hThread, PCWSTR lpThreadDescription);
4600
4601 inline BOOL IsStackWalkerThread()
4602 {
4603     STATIC_CONTRACT_NOTHROW;
4604     STATIC_CONTRACT_GC_NOTRIGGER;
4605     STATIC_CONTRACT_MODE_ANY;
4606     STATIC_CONTRACT_CANNOT_TAKE_LOCK;
4607
4608 #if defined(DACCESS_COMPILE)
4609     return FALSE;
4610 #else
4611     return ClrFlsGetValue (TlsIdx_StackWalkerWalkingThread) != NULL;
4612 #endif
4613 }
4614
4615 inline BOOL IsGCThread ()
4616 {
4617     STATIC_CONTRACT_NOTHROW;
4618     STATIC_CONTRACT_GC_NOTRIGGER;
4619     STATIC_CONTRACT_MODE_ANY;
4620     STATIC_CONTRACT_SUPPORTS_DAC;
4621
4622 #if !defined(DACCESS_COMPILE)
4623     return IsGCSpecialThread () || IsSuspendEEThread ();
4624 #else
4625     return FALSE;
4626 #endif
4627 }
4628
4629 class ClrFlsThreadTypeSwitch
4630 {
4631 public:
4632     ClrFlsThreadTypeSwitch (TlsThreadTypeFlag flag)
4633     {
4634         STATIC_CONTRACT_NOTHROW;
4635         STATIC_CONTRACT_GC_NOTRIGGER;
4636         STATIC_CONTRACT_MODE_ANY;
4637
4638 #ifndef DACCESS_COMPILE
4639         m_flag = flag;
4640         m_fPreviouslySet = (((size_t)ClrFlsGetValue (TlsIdx_ThreadType)) & flag);
4641
4642         // In debug builds, remember the full group of flags that were set at the time
4643         // the constructor was called.  This will be used in ASSERTs in the destructor
4644         INDEBUG(m_nPreviousFlagGroup = (size_t)ClrFlsGetValue (TlsIdx_ThreadType));
4645         
4646         if (!m_fPreviouslySet)
4647         {
4648             ClrFlsSetThreadType(flag);
4649         }
4650 #endif // DACCESS_COMPILE
4651     }
4652
4653     ~ClrFlsThreadTypeSwitch ()
4654     {
4655         STATIC_CONTRACT_NOTHROW;
4656         STATIC_CONTRACT_GC_NOTRIGGER;
4657         STATIC_CONTRACT_MODE_ANY;
4658
4659 #ifndef DACCESS_COMPILE
4660         // This holder should only be used to set (and thus restore) ONE thread type flag
4661         // at a time. If more than that one flag was modified since this holder was
4662         // instantiated, then this holder still restores only the flag it knows about. To
4663         // prevent confusion, assert if some other flag was modified, so the user doesn't
4664         // expect the holder to restore the entire original set of flags.
4665         // 
4666         // The expression below says that the only difference between the previous flag
4667         // group and the current flag group should be m_flag (or no difference at all, if
4668         // m_flag's state didn't actually change).
4669         _ASSERTE(((m_nPreviousFlagGroup ^ (size_t) ClrFlsGetValue(TlsIdx_ThreadType)) | (size_t) m_flag) == (size_t) m_flag);
4670
4671         if (m_fPreviouslySet)
4672         {
4673             ClrFlsSetThreadType(m_flag);
4674         }
4675         else
4676         {
4677             ClrFlsClearThreadType(m_flag);
4678         }
4679 #endif // DACCESS_COMPILE
4680     }
4681
4682 private:
4683     TlsThreadTypeFlag m_flag;
4684     BOOL m_fPreviouslySet;
4685     INDEBUG(size_t m_nPreviousFlagGroup);
4686 };
4687
4688 class ClrFlsValueSwitch
4689 {
4690 public:
4691     ClrFlsValueSwitch (PredefinedTlsSlots slot, PVOID value)
4692     {
4693         STATIC_CONTRACT_NOTHROW;
4694         STATIC_CONTRACT_GC_NOTRIGGER;
4695         STATIC_CONTRACT_MODE_ANY;
4696
4697 #ifndef DACCESS_COMPILE
4698         m_slot = slot;
4699         m_PreviousValue = ClrFlsGetValue(slot);
4700         ClrFlsSetValue(slot, value);
4701 #endif // DACCESS_COMPILE
4702     }
4703
4704     ~ClrFlsValueSwitch ()
4705     {
4706         STATIC_CONTRACT_NOTHROW;
4707         STATIC_CONTRACT_GC_NOTRIGGER;
4708         STATIC_CONTRACT_MODE_ANY;
4709
4710 #ifndef DACCESS_COMPILE
4711         ClrFlsSetValue(m_slot, m_PreviousValue);
4712 #endif // DACCESS_COMPILE
4713     }
4714
4715 private:
4716     PVOID m_PreviousValue;
4717     PredefinedTlsSlots m_slot;
4718 };
4719
4720 //*********************************************************************************
4721
4722 // When we're hosted, operations called by the host (such as Thread::YieldTask)
4723 // may not cause calls back into the host, as the host needs not be reentrant.
4724 // Use the following holder for code in which calls into the host are forbidden.
4725 // (If a call into the host is attempted nevertheless, an assert will fire.)
4726
4727 class ForbidCallsIntoHostOnThisThread
4728 {
4729 private:
4730     static Volatile<PVOID> s_pvOwningFiber;
4731
4732     FORCEINLINE static BOOL Enter(BOOL)
4733     {
4734         WRAPPER_NO_CONTRACT;
4735         return InterlockedCompareExchangePointer(
4736             &s_pvOwningFiber, ClrTeb::GetFiberPtrId(), NULL) == NULL;
4737     }
4738
4739     FORCEINLINE static void Leave(BOOL)
4740     {
4741         LIMITED_METHOD_CONTRACT;
4742         s_pvOwningFiber = NULL;
4743     }
4744
4745 public:
4746     typedef ConditionalStateHolder<BOOL, ForbidCallsIntoHostOnThisThread::Enter, ForbidCallsIntoHostOnThisThread::Leave> Holder;
4747
4748     FORCEINLINE static BOOL CanThisThreadCallIntoHost()
4749     {
4750         WRAPPER_NO_CONTRACT;
4751         return s_pvOwningFiber != ClrTeb::GetFiberPtrId();
4752     }
4753 };
4754
4755 typedef ForbidCallsIntoHostOnThisThread::Holder ForbidCallsIntoHostOnThisThreadHolder;
4756
4757 FORCEINLINE BOOL CanThisThreadCallIntoHost()
4758 {
4759     WRAPPER_NO_CONTRACT;
4760     return ForbidCallsIntoHostOnThisThread::CanThisThreadCallIntoHost();
4761 }
4762
4763 //*********************************************************************************
4764
4765 #include "contract.inl"
4766
4767 namespace util
4768 {
4769     //  compare adapters
4770     //  
4771     
4772     template < typename T >
4773     struct less
4774     {
4775         bool operator()( T const & first, T const & second ) const
4776         {
4777             return first < second;
4778         }
4779     };
4780
4781     template < typename T >
4782     struct greater
4783     {
4784         bool operator()( T const & first, T const & second ) const
4785         {
4786             return first > second;
4787         }
4788     };
4789     
4790
4791     //  sort adapters
4792     //
4793
4794     template< typename Iter, typename Pred >
4795     void sort( Iter begin, Iter end, Pred pred );
4796
4797     template< typename T, typename Pred >
4798     void sort( T * begin, T * end, Pred pred )
4799     {
4800         struct sort_helper : CQuickSort< T >
4801         {
4802             sort_helper( T * begin, T * end, Pred pred )
4803                 : CQuickSort< T >( begin, end - begin )
4804                 , m_pred( pred )
4805             {}
4806             
4807             virtual int Compare( T * first, T * second )
4808             {
4809                 return m_pred( *first, *second ) ? -1
4810                             : ( m_pred( *second, *first ) ? 1 : 0 );
4811             }
4812
4813             Pred m_pred;
4814         };
4815
4816         sort_helper sort_obj( begin, end, pred );
4817         sort_obj.Sort();
4818     }
4819     
4820
4821     template < typename Iter >
4822     void sort( Iter begin, Iter end );
4823
4824     template < typename T >
4825     void sort( T * begin, T * end )
4826     {
4827         util::sort( begin, end, util::less< T >() );
4828     }
4829
4830     
4831     // binary search adapters
4832     //
4833
4834     template < typename Iter, typename T, typename Pred >
4835     Iter lower_bound( Iter begin, Iter end, T const & val, Pred pred );
4836
4837     template < typename T, typename Pred >
4838     T * lower_bound( T * begin, T * end, T const & val, Pred pred )
4839     {
4840         for (; begin != end; )
4841         {
4842             T * mid = begin + ( end - begin ) / 2;
4843             if ( pred( *mid, val ) )
4844                 begin = ++mid;
4845             else
4846                 end = mid;
4847         }
4848
4849         return begin;
4850     }
4851
4852
4853     template < typename Iter, typename T >
4854     Iter lower_bound( Iter begin, Iter end, T const & val );
4855
4856     template < typename T >
4857     T * lower_bound( T * begin, T * end, T const & val )
4858     {
4859         return util::lower_bound( begin, end, val, util::less< T >() );
4860     }
4861 }
4862
4863
4864 /* ------------------------------------------------------------------------ *
4865  * Overloaded operators for the executable heap
4866  * ------------------------------------------------------------------------ */
4867
4868 #ifndef FEATURE_PAL
4869
4870 struct CExecutable { int x; };
4871 extern const CExecutable executable;
4872
4873 void * __cdecl operator new(size_t n, const CExecutable&);
4874 void * __cdecl operator new[](size_t n, const CExecutable&);
4875 void * __cdecl operator new(size_t n, const CExecutable&, const NoThrow&);
4876 void * __cdecl operator new[](size_t n, const CExecutable&, const NoThrow&);
4877
4878
4879 //
4880 // Executable heap delete to match the executable heap new above.
4881 //
4882 template<class T> void DeleteExecutable(T *p)
4883 {
4884     if (p != NULL)
4885     {
4886         p->T::~T();
4887
4888         ClrHeapFree(ClrGetProcessExecutableHeap(), 0, p);
4889     }
4890 }
4891
4892 #endif // FEATURE_PAL
4893
4894 INDEBUG(BOOL DbgIsExecutable(LPVOID lpMem, SIZE_T length);)
4895
4896 BOOL NoGuiOnAssert();
4897 #ifdef _DEBUG
4898 VOID TerminateOnAssert();
4899 #endif // _DEBUG
4900
4901 class HighCharHelper {
4902 public:
4903     static inline BOOL IsHighChar(int c) {
4904         return (BOOL)HighCharTable[c];
4905     }
4906
4907 private:
4908     static const BYTE HighCharTable[];
4909 };
4910
4911
4912 BOOL ThreadWillCreateGuardPage(SIZE_T sizeReservedStack, SIZE_T sizeCommitedStack);
4913
4914 FORCEINLINE void HolderSysFreeString(BSTR str) { CONTRACT_VIOLATION(ThrowsViolation); SysFreeString(str); }
4915
4916 typedef Wrapper<BSTR, DoNothing, HolderSysFreeString> BSTRHolder;
4917
4918 // HMODULE_TGT represents a handle to a module in the target process.  In non-DAC builds this is identical
4919 // to HMODULE (HINSTANCE), which is the base address of the module.  In DAC builds this must be a target address,
4920 // and so is represented by TADDR. 
4921
4922 #ifdef DACCESS_COMPILE
4923 typedef TADDR HMODULE_TGT;
4924 #else
4925 typedef HMODULE HMODULE_TGT;
4926 #endif
4927
4928 BOOL IsIPInModule(HMODULE_TGT hModule, PCODE ip);
4929
4930 //----------------------------------------------------------------------------------------
4931 // The runtime invokes InitUtilcode() in its dllmain and passes along all of the critical
4932 // callback pointers. For the desktop CLR, all DLLs loaded by the runtime must also call
4933 // InitUtilcode with the same callbacks as the runtime used. To achieve this, the runtime
4934 // calls a special initialization routine exposed by the loaded module with the callbacks,
4935 // which in turn calls InitUtilcode.
4936 //
4937 // This structure collects all of the critical callback info passed in InitUtilcode().
4938 // Note that one of them is GetCLRFunction() which is itself a gofer for many other
4939 // callbacks. If a callback fetch be safely deferred until we have TLS and stack probe
4940 // functionality running, it should be added to that function rather than this structure.
4941 // Things like IEE are here because that callback has to be set up before GetCLRFunction()
4942 // can be safely called.
4943 //----------------------------------------------------------------------------------------
4944 struct CoreClrCallbacks
4945 {
4946     typedef IExecutionEngine* (* pfnIEE_t)();
4947     typedef HRESULT (* pfnGetCORSystemDirectory_t)(SString& pbuffer);
4948     typedef void* (* pfnGetCLRFunction_t)(LPCSTR functionName);
4949
4950     HINSTANCE                   m_hmodCoreCLR;
4951     pfnIEE_t                    m_pfnIEE;
4952     pfnGetCORSystemDirectory_t  m_pfnGetCORSystemDirectory;
4953     pfnGetCLRFunction_t         m_pfnGetCLRFunction;
4954 };
4955
4956
4957 // For DAC, we include this functionality only when EH SxS is enabled.
4958
4959 //----------------------------------------------------------------------------------------
4960 // CoreCLR must invoke this before CRT initialization to ensure utilcode has all the callback
4961 // pointers it needs.
4962 //----------------------------------------------------------------------------------------
4963 VOID InitUtilcode(const CoreClrCallbacks &cccallbacks);
4964 CoreClrCallbacks const & GetClrCallbacks();
4965
4966 //----------------------------------------------------------------------------------------
4967 // Stuff below is for utilcode.lib eyes only.
4968 //----------------------------------------------------------------------------------------
4969
4970 // Stores callback pointers provided by InitUtilcode().
4971 extern CoreClrCallbacks g_CoreClrCallbacks;
4972
4973 // Throws up a helpful dialog if InitUtilcode() wasn't called.
4974 #ifdef _DEBUG
4975 void OnUninitializedCoreClrCallbacks();
4976 #define VALIDATECORECLRCALLBACKS() if (g_CoreClrCallbacks.m_hmodCoreCLR == NULL) OnUninitializedCoreClrCallbacks()
4977 #else  //_DEBUG
4978 #define VALIDATECORECLRCALLBACKS()
4979 #endif //_DEBUG
4980
4981
4982 #ifdef FEATURE_CORRUPTING_EXCEPTIONS
4983
4984 // Corrupting Exception limited support for outside the VM folder
4985 BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE);
4986
4987 #endif // FEATURE_CORRUPTING_EXCEPTIONS
4988
4989 namespace UtilCode
4990 {
4991     // These are type-safe versions of Interlocked[Compare]Exchange
4992     // They avoid invoking struct cast operations via reinterpreting
4993     // the struct's address as a LONG* or LONGLONG* and dereferencing it.
4994     // 
4995     // If we had a global ::operator & (unary), we would love to use that
4996     // to ensure we were not also accidentally getting a structs's provided
4997     // operator &. TODO: probe with a static_assert?
4998
4999     template <typename T, int SIZE = sizeof(T)>
5000     struct InterlockedCompareExchangeHelper;
5001
5002     template <typename T>
5003     struct InterlockedCompareExchangeHelper<T, sizeof(LONG)>
5004     {
5005         static inline T InterlockedExchange(
5006             T volatile * target,
5007             T            value)
5008         {
5009             static_assert_no_msg(sizeof(T) == sizeof(LONG));
5010             LONG res = ::InterlockedExchange(
5011                 reinterpret_cast<LONG volatile *>(target),
5012                 *reinterpret_cast<LONG *>(/*::operator*/&(value)));
5013             return *reinterpret_cast<T*>(&res);
5014         }
5015
5016         static inline T InterlockedCompareExchange(
5017             T volatile * destination,
5018             T            exchange,
5019             T            comparand)
5020         {
5021             static_assert_no_msg(sizeof(T) == sizeof(LONG));
5022             LONG res = ::InterlockedCompareExchange(
5023                 reinterpret_cast<LONG volatile *>(destination),
5024                 *reinterpret_cast<LONG*>(/*::operator*/&(exchange)),
5025                 *reinterpret_cast<LONG*>(/*::operator*/&(comparand)));
5026             return *reinterpret_cast<T*>(&res);
5027         }
5028     };
5029  
5030     template <typename T>
5031     struct InterlockedCompareExchangeHelper<T, sizeof(LONGLONG)>
5032     {
5033         static inline T InterlockedExchange(
5034             T volatile * target,
5035             T            value)
5036         {
5037             static_assert_no_msg(sizeof(T) == sizeof(LONGLONG));
5038             LONGLONG res = ::InterlockedExchange64(
5039                 reinterpret_cast<LONGLONG volatile *>(target),
5040                 *reinterpret_cast<LONGLONG *>(/*::operator*/&(value)));
5041             return *reinterpret_cast<T*>(&res);
5042         }
5043
5044         static inline T InterlockedCompareExchange(
5045             T volatile * destination,
5046             T            exchange,
5047             T            comparand)
5048         {
5049             static_assert_no_msg(sizeof(T) == sizeof(LONGLONG));
5050             LONGLONG res = ::InterlockedCompareExchange64(
5051                 reinterpret_cast<LONGLONG volatile *>(destination),
5052                 *reinterpret_cast<LONGLONG*>(/*::operator*/&(exchange)),
5053                 *reinterpret_cast<LONGLONG*>(/*::operator*/&(comparand)));
5054             return *reinterpret_cast<T*>(&res);
5055         }
5056     };
5057 }
5058  
5059 template <typename T>
5060 inline T InterlockedExchangeT(
5061     T volatile * target,
5062     T            value)
5063 {
5064     return ::UtilCode::InterlockedCompareExchangeHelper<T>::InterlockedExchange(
5065         target, value);
5066 }
5067
5068 template <typename T>
5069 inline T InterlockedCompareExchangeT(
5070     T volatile * destination,
5071     T            exchange,
5072     T            comparand)
5073 {
5074     return ::UtilCode::InterlockedCompareExchangeHelper<T>::InterlockedCompareExchange(
5075         destination, exchange, comparand);
5076 }
5077
5078 // Pointer variants for Interlocked[Compare]ExchangePointer
5079 // If the underlying type is a const type, we have to remove its constness
5080 // since Interlocked[Compare]ExchangePointer doesn't take const void * arguments.
5081 template <typename T>
5082 inline T* InterlockedExchangeT(
5083     T* volatile * target,
5084     T*            value)
5085 {
5086     //STATIC_ASSERT(value == 0);
5087     typedef typename std::remove_const<T>::type * non_const_ptr_t;
5088     return reinterpret_cast<T*>(InterlockedExchangePointer(
5089         reinterpret_cast<PVOID volatile *>(const_cast<non_const_ptr_t volatile *>(target)),
5090         reinterpret_cast<PVOID>(const_cast<non_const_ptr_t>(value))));
5091 }
5092
5093 template <typename T>
5094 inline T* InterlockedCompareExchangeT(
5095     T* volatile * destination,
5096     T*            exchange,
5097     T*            comparand)
5098 {
5099     //STATIC_ASSERT(exchange == 0);
5100     typedef typename std::remove_const<T>::type * non_const_ptr_t;
5101     return reinterpret_cast<T*>(InterlockedCompareExchangePointer(
5102         reinterpret_cast<PVOID volatile *>(const_cast<non_const_ptr_t volatile *>(destination)),
5103         reinterpret_cast<PVOID>(const_cast<non_const_ptr_t>(exchange)), 
5104         reinterpret_cast<PVOID>(const_cast<non_const_ptr_t>(comparand))));
5105 }
5106
5107 // NULL pointer variants of the above to avoid having to cast NULL
5108 // to the appropriate pointer type.
5109 template <typename T>
5110 inline T* InterlockedExchangeT(
5111     T* volatile *   target,
5112     int             value) // When NULL is provided as argument.
5113 {
5114     //STATIC_ASSERT(value == 0);
5115     return InterlockedExchangeT(target, reinterpret_cast<T*>(value));
5116 }
5117
5118 template <typename T>
5119 inline T* InterlockedCompareExchangeT(
5120     T* volatile *   destination,
5121     int             exchange,  // When NULL is provided as argument.
5122     T*              comparand)
5123 {
5124     //STATIC_ASSERT(exchange == 0);
5125     return InterlockedCompareExchangeT(destination, reinterpret_cast<T*>(exchange), comparand);
5126 }
5127
5128 template <typename T>
5129 inline T* InterlockedCompareExchangeT(
5130     T* volatile *   destination,
5131     T*              exchange,
5132     int             comparand) // When NULL is provided as argument.
5133 {
5134     //STATIC_ASSERT(comparand == 0);
5135     return InterlockedCompareExchangeT(destination, exchange, reinterpret_cast<T*>(comparand));
5136 }
5137
5138 // NULL pointer variants of the above to avoid having to cast NULL
5139 // to the appropriate pointer type.
5140 template <typename T>
5141 inline T* InterlockedExchangeT(
5142     T* volatile *  target,
5143     std::nullptr_t value) // When nullptr is provided as argument.
5144 {
5145     //STATIC_ASSERT(value == 0);
5146     return InterlockedExchangeT(target, static_cast<T*>(value));
5147 }
5148
5149 template <typename T>
5150 inline T* InterlockedCompareExchangeT(
5151     T* volatile *  destination,
5152     std::nullptr_t exchange,  // When nullptr is provided as argument.
5153     T*             comparand)
5154 {
5155     //STATIC_ASSERT(exchange == 0);
5156     return InterlockedCompareExchangeT(destination, static_cast<T*>(exchange), comparand);
5157 }
5158
5159 template <typename T>
5160 inline T* InterlockedCompareExchangeT(
5161     T* volatile *  destination,
5162     T*             exchange,
5163     std::nullptr_t comparand) // When nullptr is provided as argument.
5164 {
5165     //STATIC_ASSERT(comparand == 0);
5166     return InterlockedCompareExchangeT(destination, exchange, static_cast<T*>(comparand));
5167 }
5168
5169 #undef InterlockedExchangePointer
5170 #define InterlockedExchangePointer Use_InterlockedExchangeT
5171 #undef InterlockedCompareExchangePointer
5172 #define InterlockedCompareExchangePointer Use_InterlockedCompareExchangeT
5173
5174 // Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL",
5175 // then this would return "C:\Dir1\Dir2\" (note the trailing backslash).
5176 HRESULT GetHModuleDirectory(HMODULE hMod, SString& wszPath);
5177 HRESULT CopySystemDirectory(const SString& pPathString, SString& pbuffer);
5178
5179 HMODULE LoadLocalizedResourceDLLForSDK(_In_z_ LPCWSTR wzResourceDllName, _In_opt_z_ LPCWSTR modulePath=NULL, bool trySelf=true);
5180 // This is a slight variation that can be used for anything else
5181 typedef void* (__cdecl *LocalizedFileHandler)(LPCWSTR);
5182 void* FindLocalizedFile(_In_z_ LPCWSTR wzResourceDllName, LocalizedFileHandler lfh, _In_opt_z_ LPCWSTR modulePath=NULL);
5183
5184
5185
5186 // Helper to support termination due to heap corruption
5187 // It's not supported on Win2K, so we have to manually delay load it
5188 void EnableTerminationOnHeapCorruption();
5189
5190
5191
5192 namespace Clr { namespace Util
5193 {
5194     // This api returns a pointer to a null-terminated string that contains the local appdata directory
5195     // or it returns NULL in the case that the directory could not be found. The return value from this function
5196     // is not actually checked for existence. 
5197     HRESULT GetLocalAppDataDirectory(LPCWSTR *ppwzLocalAppDataDirectory);
5198     HRESULT SetLocalAppDataDirectory(LPCWSTR pwzLocalAppDataDirectory);
5199
5200 namespace Reg
5201 {
5202     HRESULT ReadStringValue(HKEY hKey, LPCWSTR wszSubKey, LPCWSTR wszName, SString & ssValue);
5203     __success(return == S_OK)
5204     HRESULT ReadStringValue(HKEY hKey, LPCWSTR wszSubKey, LPCWSTR wszName, __deref_out __deref_out_z LPWSTR* pwszValue);
5205 }
5206
5207 #ifdef FEATURE_COMINTEROP
5208 namespace Com
5209 {
5210     HRESULT FindInprocServer32UsingCLSID(REFCLSID rclsid, SString & ssInprocServer32Name);
5211 }
5212 #endif // FEATURE_COMINTEROP
5213
5214 namespace Win32
5215 {
5216     static const WCHAR LONG_FILENAME_PREFIX_W[] = W("\\\\?\\");
5217     static const CHAR LONG_FILENAME_PREFIX_A[] = "\\\\?\\";
5218
5219     void GetModuleFileName(
5220         HMODULE hModule,
5221         SString & ssFileName,
5222         bool fAllowLongFileNames = false);
5223
5224     __success(return == S_OK)
5225     HRESULT GetModuleFileName(
5226         HMODULE hModule,
5227         __deref_out_z LPWSTR * pwszFileName,
5228         bool fAllowLongFileNames = false);
5229
5230     void GetFullPathName(
5231         SString const & ssFileName,
5232         SString & ssPathName,
5233         DWORD * pdwFilePartIdx,
5234         bool fAllowLongFileNames = false);
5235 }
5236
5237 }}
5238
5239 #if defined(FEATURE_APPX) && !defined(DACCESS_COMPILE)
5240     // Forward declaration of AppX::IsAppXProcess
5241     namespace AppX { bool IsAppXProcess(); }
5242
5243     // LOAD_WITH_ALTERED_SEARCH_PATH is unsupported in AppX processes.
5244     inline DWORD GetLoadWithAlteredSearchPathFlag()
5245     {
5246         WRAPPER_NO_CONTRACT;
5247         return AppX::IsAppXProcess() ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH;
5248     }
5249 #else // FEATURE_APPX && !DACCESS_COMPILE
5250     // LOAD_WITH_ALTERED_SEARCH_PATH can be used unconditionally.
5251     inline DWORD GetLoadWithAlteredSearchPathFlag()
5252     {
5253         LIMITED_METHOD_CONTRACT;
5254         #ifdef LOAD_WITH_ALTERED_SEARCH_PATH
5255             return LOAD_WITH_ALTERED_SEARCH_PATH;
5256         #else
5257             return 0;
5258         #endif
5259     }
5260 #endif // FEATURE_APPX && !DACCESS_COMPILE
5261
5262 // clr::SafeAddRef and clr::SafeRelease helpers.
5263 namespace clr
5264 {
5265     //=================================================================================================================
5266     template <typename ItfT>
5267     static inline 
5268     typename std::enable_if< std::is_pointer<ItfT>::value, ItfT >::type
5269     SafeAddRef(ItfT pItf)
5270     {
5271         STATIC_CONTRACT_LIMITED_METHOD;
5272         if (pItf != nullptr)
5273         {
5274             pItf->AddRef();
5275         }
5276         return pItf;
5277     }
5278
5279     //=================================================================================================================
5280     template <typename ItfT>
5281     typename std::enable_if< std::is_pointer<ItfT>::value && std::is_reference<ItfT>::value, ULONG >::type
5282     SafeRelease(ItfT pItf)
5283     {
5284         STATIC_CONTRACT_LIMITED_METHOD;
5285         ULONG res = 0;
5286         if (pItf != nullptr)
5287         {
5288             res = pItf->Release();
5289             pItf = nullptr;
5290         }
5291         return res;
5292     }
5293
5294     //=================================================================================================================
5295     template <typename ItfT>
5296     typename std::enable_if< std::is_pointer<ItfT>::value && !std::is_reference<ItfT>::value, ULONG >::type
5297     SafeRelease(ItfT pItf)
5298     {
5299         STATIC_CONTRACT_LIMITED_METHOD;
5300         ULONG res = 0;
5301         if (pItf != nullptr)
5302         {
5303             res = pItf->Release();
5304         }
5305         return res;
5306     }
5307 }
5308
5309 // clr::SafeDelete
5310 namespace clr
5311 {
5312     //=================================================================================================================
5313     template <typename PtrT>
5314     static inline 
5315     typename std::enable_if< std::is_pointer<PtrT>::value, PtrT >::type
5316     SafeDelete(PtrT & ptr)
5317     {
5318         STATIC_CONTRACT_LIMITED_METHOD;
5319         if (ptr != nullptr)
5320         {
5321             delete ptr;
5322             ptr = nullptr;
5323         }
5324     }
5325 }
5326
5327 // ======================================================================================
5328 // Spinning support (used by VM and by MetaData via file:..\Utilcode\UTSem.cpp)
5329
5330 struct SpinConstants
5331 {
5332     DWORD dwInitialDuration;
5333     DWORD dwMaximumDuration;
5334     DWORD dwBackoffFactor;
5335     DWORD dwRepetitions;
5336     DWORD dwMonitorSpinCount;
5337 };
5338
5339 extern SpinConstants g_SpinConstants;
5340
5341 // ======================================================================================
5342
5343 void* GetCLRFunction(LPCSTR FunctionName);
5344
5345 #endif // __UtilCode_h__