Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. convert.h
  5. Abstract:
  6. Header over convert.c
  7. This seems like an appropriate place to explain Godot's stack strategy. Basically,
  8. every time we do an allocation on the stack when _GODOTSAFESTACK is defined (which
  9. is currently always), we do not want to take size and perf hit of over 500 SEH blocks
  10. and we also do not have the time to try to special case each API to try to find out
  11. parameter sizes or do stack probes.
  12. At the same time, we cannot be crazy go lucky like VSANSI and simply allow the _alloca
  13. call to throw an EXCEPTION_STACK_OVERFLOW, since it is unrealistic to expect callers to
  14. wrap every API call in SEH blocks (just as it is for us!). Even if it were realistic,
  15. we cannot afford to punish users who do not writ bulletproof code. Failure is okay, but
  16. crashes are not.
  17. Therefore, in order to satify both our size/perf requirement and our safety requirement,
  18. we preface every call to _alloca with a call to our StackAllocCheck function. This function
  19. will attempt to call _alloca in a try...except block and will properly fix up the stack
  20. on failure. This keeps us from bloating up with hundreds of SEH blocks yet still allows
  21. us to have a bit more safety.
  22. Note that this is NOT a 100% solution, since it is vaguely possible that a multithreaded
  23. application has a (slim) chance of succeeding the StackAllockCheck function but then
  24. failing before the official (unguarded) call to _alloca due to another thread's call to
  25. _alloca, initiated by the user's code (it would never be one of our calls since all of
  26. *ours* use this safe method). There is no real defense against this, but it is a very
  27. unlikely type of problem.
  28. Revision History:
  29. 17 Mar 2001 v-michka Created.
  30. 15 Apr 2001 v-michka Put in lots of fun heap/stack stuff
  31. --*/
  32. #ifndef CONVERT_H
  33. #define CONVERT_H
  34. #define _GODOTSAFESTACK
  35. // Is this non null and not a user atom?
  36. #define FSTRING_VALID(x) ((ULONG_PTR)(x) > 0xffff)
  37. // Our function for making sure stack allocations are valid
  38. BOOL StackAllocCheck(size_t size);
  39. // _alloca, on certain platforms, returns a raw pointer to the
  40. // stack rather than NULL on allocations of size zero. Since this
  41. // is sub-optimal for code that subsequently calls functions like
  42. // strlen on the allocated block of memory, these wrappers are
  43. // provided for use.
  44. ///////////////////////////////////////////////////////////////////////////
  45. //
  46. // _STACKALLOC
  47. // Do an allocation from the stack. Must be a macro for obvious reasons!
  48. //
  49. //
  50. #define _STACKALLOC_SAFE(siz, mem) \
  51. if(StackAllocCheck(siz)) \
  52. mem = (void *)((siz)?(_alloca(siz)):NULL); \
  53. else \
  54. mem = NULL;
  55. #define _STACKALLOC_UNSAFE(siz, mem) \
  56. mem = ((siz)?(_alloca(siz)):NULL)
  57. #ifdef _GODOTSAFESTACK
  58. #define _STACKALLOC(siz, mem) _STACKALLOC_SAFE(siz, mem)
  59. #else
  60. #define _STACKALLOC(siz, mem) _STACKALLOC_UNSAFE(siz, mem)
  61. #endif
  62. ///////////////////////////////////////////////////////////////////////////
  63. //
  64. // GODOT_TO_ACP_STACKALLOC
  65. // Convert from Unicode to ANSI if needed, otherwise copy as if it were an Atom
  66. //
  67. //
  68. #define GODOT_TO_ACP_STACKALLOC_SAFE(src, dst) \
  69. if (FSTRING_VALID((LPWSTR)src)) \
  70. { \
  71. size_t cch = gwcslen((LPWSTR)(src)) + 1; \
  72. _STACKALLOC_SAFE(cch*g_mcs, (LPSTR)dst); \
  73. if(dst) \
  74. WideCharToMultiByte(g_acp, 0, (LPWSTR)(src), cch, (LPSTR)(dst), cch*g_mcs, NULL, NULL); \
  75. else \
  76. (LPSTR)(dst) = (LPSTR)(src); \
  77. } \
  78. else \
  79. (LPSTR)(dst) = (LPSTR)(src)
  80. #define GODOT_TO_ACP_STACKALLOC_UNSAFE(src, dst) \
  81. if (FSTRING_VALID((LPWSTR)src)) \
  82. { \
  83. size_t cch = gwcslen((LPWSTR)(src)) + 1; \
  84. _STACKALLOC_UNSAFE(cch*g_mcs, (LPSTR)dst); \
  85. if(dst) \
  86. WideCharToMultiByte(g_acp, 0, (LPWSTR)(src), cch, (LPSTR)(dst), cch*g_mcs, NULL, NULL); \
  87. else \
  88. (LPSTR)(dst) = (LPSTR)(src); \
  89. } \
  90. else \
  91. (LPSTR)(dst) = (LPSTR)(src)
  92. #ifdef _GODOTSAFESTACK
  93. #define GODOT_TO_ACP_STACKALLOC(src, dst) GODOT_TO_ACP_STACKALLOC_SAFE(src, dst)
  94. #else
  95. #define GODOT_TO_ACP_STACKALLOC(src, dst) GODOT_TO_ACP_STACKALLOC_UNSAFE(src, dst)
  96. #endif
  97. ///////////////////////////////////////////////////////////////////////////
  98. //
  99. // GODOT_TO_CPG_STACKALLOC
  100. // Convert from Unicode to ANSI if needed, otherwise copy as if it were an Atom
  101. //
  102. //
  103. #define GODOT_TO_CPG_STACKALLOC_SAFE(src, dst, cpg, mcs) \
  104. if (FSTRING_VALID(src)) \
  105. { \
  106. size_t cch = gwcslen((LPWSTR)(src)) + 1; \
  107. _STACKALLOC_SAFE(cch*mcs, (LPSTR)dst); \
  108. if(dst) \
  109. WideCharToMultiByte(cpg, 0, (LPWSTR)(src), cch, (LPSTR)(dst), cch*mcs, NULL, NULL); \
  110. else \
  111. (LPSTR)(dst) = (LPSTR)(src); \
  112. } \
  113. else \
  114. (LPSTR)(dst) = (LPSTR)(src)
  115. #define GODOT_TO_CPG_STACKALLOC_UNSAFE(src, dst, cpg, mcs) \
  116. if (FSTRING_VALID(src)) \
  117. { \
  118. size_t cch = gwcslen((LPWSTR)(src)) + 1; \
  119. _STACKALLOC_UNSAFE(cch*mcs, (LPSTR)dst); \
  120. if(dst) \
  121. WideCharToMultiByte(cpg, 0, (LPWSTR)(src), cch, (LPSTR)(dst), cch*mcs, NULL, NULL); \
  122. else \
  123. (LPSTR)(dst) = (LPSTR)(src); \
  124. } \
  125. else \
  126. (LPSTR)(dst) = (LPSTR)(src)
  127. #ifdef _GODOTSAFESTACK
  128. #define GODOT_TO_CPG_STACKALLOC(src, dst, cpg, mcs) GODOT_TO_CPG_STACKALLOC_SAFE(src, dst, cpg, mcs)
  129. #else
  130. #define GODOT_TO_CPG_STACKALLOC(src, dst, cpg, mcs) GODOT_TO_CPG_STACKALLOC_UNSAFE(src, dst, cpg, mcs)
  131. #endif
  132. ///////////////////////////////////////////////////////////////////////////
  133. //
  134. // Various enums, macros and functions for heap allocation stuff
  135. //
  136. //
  137. typedef enum
  138. {
  139. arBadParam = 1,
  140. arFailed = 2,
  141. arAlloc = 3,
  142. arNoAlloc = 4
  143. } ALLOCRETURN;
  144. ///////////////////////////////////////////////////////////////////////////
  145. //
  146. // Our generic heap wrappers
  147. //
  148. //
  149. #define GodotHeapAlloc(mem) ((mem) ? (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem)) : NULL)
  150. #define GodotHeapFree(mem) ((mem) ? (HeapFree(GetProcessHeap(), 0, mem)) : FALSE)
  151. #define GodotHeapReAlloc(old, mem) ((mem) ? (HeapReAlloc(GetProcessHeap(), 0, old, mem)) : NULL)
  152. ///////////////////////////////////////////////////////////////////////////
  153. //
  154. // wrappers/foward declares around our heap alloc/conversion
  155. // functions to handle common cases
  156. //
  157. //
  158. #define GodotToAcpOnHeap(lpwz, lpsz) GodotToCpgCchOnHeap(lpwz, -1, lpsz, g_acp, g_mcs)
  159. #define GodotToCpgOnHeap(lpwz, lpsz, cpg, mcs) GodotToCpgCchOnHeap(lpwz, -1, lpsz, cpg, mcs)
  160. #define GodotToUnicodeOnHeap(lpsz, lpwz) GodotToUnicodeCpgCchOnHeap(lpsz, -1, lpwz, g_acp)
  161. #define GodotToUnicodeCpgOnHeap(lpsz, lpwz, cpg, mcs) GodotToUnicodeCpgCchOnHeap(lpwz, -1, lpsz, cpg)
  162. ALLOCRETURN GodotToCpgCchOnHeap(LPCWSTR lpwz, int cchMax, LPSTR * lpsz, UINT cpg, UINT mcs);
  163. ALLOCRETURN GodotToUnicodeCpgCchOnHeap(LPCSTR lpsz, int cchMax, LPWSTR * lpwz, UINT cpg);
  164. ///////////////////////////////////////////////////////////////////////////
  165. //
  166. // Additional Forward declares
  167. //
  168. //
  169. void DevModeAfromW(LPDEVMODEA lpdma, LPDEVMODEW lpdmw);
  170. void DevModeWfromA(LPDEVMODEW lpdmw, LPDEVMODEA lpdma);
  171. HGLOBAL HDevModeAfromW(HGLOBAL * lphdmw, BOOL fFree);
  172. HGLOBAL HDevModeWfromA(HGLOBAL * lphdma, BOOL fFree);
  173. HGLOBAL HDevNamesAfromW(HGLOBAL * lphdnw, BOOL fFree);
  174. HGLOBAL HDevNamesWfromA(HGLOBAL * lphdna, BOOL fFree);
  175. void LogFontAfromW(LPLOGFONTA lplfa, LPLOGFONTW lplfw);
  176. void LogFontWfromA(LPLOGFONTW lplfw, LPLOGFONTA lplfa);
  177. void Win32FindDataWfromA(PWIN32_FIND_DATAW w32fdw, PWIN32_FIND_DATAA w32fda);
  178. void TextMetricWfromA(LPTEXTMETRICW lptmw, LPTEXTMETRICA lptma);
  179. void NewTextMetricWfromA(LPNEWTEXTMETRICW lpntmw, LPNEWTEXTMETRICA lpntma);
  180. void NewTextMetricExWfromA(NEWTEXTMETRICEXW * lpntmew, NEWTEXTMETRICEXA * lpntmea);
  181. BOOL MenuItemInfoAfromW(LPMENUITEMINFOA lpmiia, LPCMENUITEMINFOW lpmiiw);
  182. int GrszToGrwz(const CHAR* szFrom, WCHAR* wzTo, int cchTo);
  183. int SzToWzCch(const CHAR *sz, WCHAR *wz, int cch);
  184. #endif // CONVERT_H