Leaked source code of windows server 2003
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.

270 lines
7.1 KiB

  1. /***
  2. *validate.cpp - Routines to validate the data structures.
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Routines to validate the Exception Handling data structures.
  8. *
  9. * Entry points:
  10. *
  11. * Error reporting:
  12. * * EHRuntimeError - reports the error with
  13. * a popup or print to stderr, then quits.
  14. *
  15. * Pointer validation:
  16. * * _ValidateRead - Confirms that a pointer is valid for reading
  17. * * _ValidateWrite - Confirms that a pointer is valid for writing
  18. * * _ValidateExecute - Confirms that a pointer is valid to jump to
  19. *
  20. * Data structure dumpers:
  21. * * DumpTypeDescriptor
  22. * * DumpFuncInfo
  23. * * DumpThrowInfo
  24. *
  25. * Execution tracing (only in /DENABLE_EHTRACE builds):
  26. * * EHTraceOutput
  27. *
  28. *Revision History:
  29. * ??-??-93 BS Module created
  30. * 10-17-94 BWT Disable code for PPC.
  31. * 04-25-95 DAK Add Kernel EH Support
  32. * 05-17-99 PML Remove all Macintosh support.
  33. * 10-22-99 PML Add EHTRACE support
  34. * 12-07-01 BWT Remove NTSUBSET
  35. *
  36. ****/
  37. #include <windows.h>
  38. #include <eh.h>
  39. #include <ehassert.h>
  40. #pragma hdrstop
  41. #if defined(DEBUG)
  42. int __cdecl
  43. dprintf( char *format, ... )
  44. {
  45. static char buffer[512];
  46. int size = vsprintf( buffer, format, (char*)(&format+1) );
  47. OutputDebugString( buffer );
  48. return size;
  49. }
  50. #endif
  51. BOOL
  52. _ValidateRead( const void *data, UINT size )
  53. {
  54. BOOL bValid = TRUE;
  55. if ( IsBadReadPtr( data, size ) ) {
  56. dprintf( "_ValidateRead( %p, %d ): Invalid Pointer!", data, size );
  57. // terminate(); // terminate does not return.
  58. bValid = FALSE;
  59. }
  60. return bValid;
  61. }
  62. BOOL
  63. _ValidateWrite( void *data, UINT size )
  64. {
  65. BOOL bValid = TRUE;
  66. if ( IsBadWritePtr( data, size ) ) {
  67. dprintf( "_ValidateWrite( %p, %d ): Invalid Pointer!", data, size );
  68. // terminate(); // terminate does not return.
  69. bValid = FALSE;
  70. }
  71. return bValid;
  72. }
  73. BOOL
  74. _ValidateExecute( FARPROC code )
  75. {
  76. BOOL bValid = TRUE;
  77. if ( IsBadCodePtr( code ) ) {
  78. dprintf( "_ValidateExecute( %p ): Invalid Function Address!", code );
  79. // terminate(); // terminate does not return
  80. bValid = FALSE;
  81. }
  82. return bValid;
  83. }
  84. #if defined(DEBUG) && defined(_M_IX86)
  85. //
  86. // dbRNListHead - returns current value of FS:0.
  87. //
  88. // For debugger use only, since debugger doesn't seem to be able to view the
  89. // teb.
  90. //
  91. EHRegistrationNode *dbRNListHead(void)
  92. {
  93. EHRegistrationNode *pRN;
  94. __asm {
  95. mov eax, dword ptr FS:[0]
  96. mov pRN, eax
  97. }
  98. return pRN;
  99. }
  100. #endif
  101. #ifdef ENABLE_EHTRACE
  102. #include <stdio.h>
  103. #include <stdarg.h>
  104. //
  105. // Current EH tracing depth, stack for saving levels during __finally block
  106. // or __except filter.
  107. //
  108. int __ehtrace_level;
  109. int __ehtrace_level_stack_depth;
  110. int __ehtrace_level_stack[128];
  111. //
  112. // EHTraceOutput - Dump formatted string to OutputDebugString
  113. //
  114. void __cdecl EHTraceOutput(const char *format, ...)
  115. {
  116. va_list arglist;
  117. char buf[1024];
  118. sprintf(buf, "%p ", &format);
  119. OutputDebugString(buf);
  120. va_start(arglist, format);
  121. _vsnprintf(buf, sizeof(buf), format, arglist);
  122. OutputDebugString(buf);
  123. }
  124. //
  125. // EHTraceIndent - Return string for current EH tracing depth
  126. //
  127. const char*EHTraceIndent(int level)
  128. {
  129. static char indentbuf[128 + 1];
  130. // Reset global level to recover from stack unwinds
  131. __ehtrace_level = level;
  132. int depth = max(0, level - 1);
  133. if (depth > (sizeof(indentbuf) - 1) / 2) {
  134. depth = (sizeof(indentbuf) - 1) / 2;
  135. }
  136. for (int i = 0; i < depth; ++i) {
  137. indentbuf[2 * i] = '|';
  138. indentbuf[2 * i + 1] = ' ';
  139. }
  140. indentbuf[2 * depth] = '\0';
  141. return indentbuf;
  142. }
  143. //
  144. // EHTraceFunc - Chop down __FUNCTION__ to simple name
  145. //
  146. const char *EHTraceFunc(const char *func)
  147. {
  148. static char namebuf[128];
  149. const char *p = func + strlen(func) - 1;
  150. if (*p != ')') {
  151. // Name already simple (no arg list found)
  152. return func;
  153. }
  154. // Skip backwards past the argument list
  155. int parendepth = 1;
  156. while (p > func && parendepth > 0) {
  157. switch (*--p) {
  158. case '(':
  159. --parendepth;
  160. break;
  161. case ')':
  162. ++parendepth;
  163. break;
  164. }
  165. }
  166. // Find beginning of name
  167. // TODO: Won't work for funcs which return func-ptrs
  168. const char *pEnd = p;
  169. while (p > func && p[-1] != ' ') {
  170. --p;
  171. }
  172. size_t len = min(pEnd - p, sizeof(namebuf) - 1);
  173. memcpy(namebuf, p, len);
  174. namebuf[len] = '\0';
  175. return namebuf;
  176. }
  177. //
  178. // EHTracePushLevel - Push current trace depth on stack to allow temporary
  179. // resetting of level with __finally block or __except filter.
  180. //
  181. void EHTracePushLevel(int new_level)
  182. {
  183. if (__ehtrace_level_stack_depth < sizeof(__ehtrace_level_stack) / sizeof(__ehtrace_level_stack[0])) {
  184. __ehtrace_level_stack[__ehtrace_level_stack_depth] = __ehtrace_level;
  185. }
  186. ++__ehtrace_level_stack_depth;
  187. __ehtrace_level = new_level;
  188. }
  189. //
  190. // EHTracePopLevel - Pop saved trace depth from stack on completion of
  191. // __finally block or __except filter, and optionally restore global depth.
  192. //
  193. void EHTracePopLevel(bool restore)
  194. {
  195. --__ehtrace_level_stack_depth;
  196. if (restore &&
  197. __ehtrace_level_stack_depth < sizeof(__ehtrace_level_stack) / sizeof(__ehtrace_level_stack[0]))
  198. {
  199. __ehtrace_level = __ehtrace_level_stack[__ehtrace_level_stack_depth];
  200. }
  201. }
  202. //
  203. // EHTraceExceptFilter - Dump trace info for __except filter. Trace level must
  204. // have been pushed before entry with EHTracePushLevel, so any functions called
  205. // for the 'expr' argument are dumped at the right level.
  206. //
  207. int EHTraceExceptFilter(const char *func, int expr)
  208. {
  209. EHTraceOutput("In : %s%s: __except filter returns %d (%s)\n",
  210. EHTraceIndent(__ehtrace_level), EHTraceFunc(func), expr,
  211. expr < 0 ? "EXCEPTION_CONTINUE_EXECUTION" :
  212. expr > 0 ? "EXCEPTION_EXECUTE_HANDLER" :
  213. "EXCEPTION_CONTINUE_SEARCH");
  214. EHTracePopLevel(expr <= 0);
  215. return expr;
  216. }
  217. //
  218. // EHTraceHandlerReturn - Dump trace info for exception handler return
  219. //
  220. void EHTraceHandlerReturn(const char *func, int level, EXCEPTION_DISPOSITION result)
  221. {
  222. EHTraceOutput( "Exit : %s%s: Handler returning %d (%s)\n", \
  223. EHTraceIndent(level), EHTraceFunc(func), result,
  224. result == ExceptionContinueExecution ? "ExceptionContinueExecution" :
  225. result == ExceptionContinueSearch ? "ExceptionContinueSearch" :
  226. result == ExceptionNestedException ? "ExceptionNestedException" :
  227. result == ExceptionCollidedUnwind ? "ExceptionCollidedUnwind" :
  228. "unknown" );
  229. }
  230. #endif /* ENABLE_EHTRACE */