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