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.

264 lines
6.3 KiB

  1. /*****************************************************************************
  2. *
  3. * assert.c - Assertion stuff
  4. *
  5. *****************************************************************************/
  6. #include "map.h"
  7. #ifdef DEBUG
  8. #include <stdarg.h>
  9. #include <shlwapi.h>
  10. #ifndef ARRAYSIZE
  11. #define ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))
  12. #endif
  13. /*****************************************************************************
  14. *
  15. * SquirtSqflPtszV
  16. *
  17. * Squirt a message with a trailing crlf.
  18. *
  19. *****************************************************************************/
  20. void EXTERNAL
  21. SquirtSqflPtszV(SQFL sqfl, LPCTSTR ptsz, ...)
  22. {
  23. if (sqfl == 0 || (sqfl & sqflCur)) {
  24. va_list ap;
  25. TCHAR tsz[1024];
  26. va_start(ap, ptsz);
  27. wvnsprintf(tsz, ARRAYSIZE(tsz), ptsz, ap);
  28. va_end(ap);
  29. OutputDebugString(tsz);
  30. OutputDebugString(TEXT("\r\n"));
  31. }
  32. }
  33. /*****************************************************************************
  34. *
  35. * AssertPtszPtszLn
  36. *
  37. * Something bad happened.
  38. *
  39. *****************************************************************************/
  40. int EXTERNAL
  41. AssertPtszPtszLn(LPCTSTR ptszExpr, LPCTSTR ptszFile, int iLine)
  42. {
  43. SquirtSqflPtszV(sqflAlways, TEXT("Assertion failed: `%s' at %s(%d)"),
  44. ptszExpr, ptszFile, iLine);
  45. DebugBreak();
  46. return 0;
  47. }
  48. /*****************************************************************************
  49. *
  50. * Procedure call tracing is gross because the C preprocessor is lame.
  51. *
  52. * Oh, if only we had support for m4...
  53. *
  54. *****************************************************************************/
  55. /*****************************************************************************
  56. *
  57. * ArgsPszV
  58. *
  59. * Collect arguments to a procedure.
  60. *
  61. * psz -> ASCIIZ format string
  62. * ... = argument list
  63. *
  64. * The characters in the format string are listed in EmitPal.
  65. *
  66. *****************************************************************************/
  67. void EXTERNAL
  68. ArgsPalPszV(PARGLIST pal, LPCSTR psz, ...)
  69. {
  70. va_list ap;
  71. va_start(ap, psz);
  72. if (psz) {
  73. PPV ppv;
  74. pal->pszFormat = psz;
  75. for (ppv = pal->rgpv; *psz; psz++) {
  76. *ppv++ = va_arg(ap, PV);
  77. }
  78. } else {
  79. pal->pszFormat = "";
  80. }
  81. }
  82. /*****************************************************************************
  83. *
  84. * EmitPal
  85. *
  86. * OutputDebugString the information, given a pal. No trailing
  87. * carriage return is emitted.
  88. *
  89. * pal -> place where info was saved
  90. *
  91. * Format characters:
  92. *
  93. * p - 32-bit flat pointer
  94. * x - 32-bit hex integer
  95. * s - TCHAR string
  96. * A - ANSI string
  97. * W - UNICODE string
  98. * G - GUID
  99. * u - unsigned integer
  100. * C - clipboard format
  101. *
  102. *****************************************************************************/
  103. void INTERNAL
  104. EmitPal(PARGLIST pal)
  105. {
  106. char sz[MAX_PATH];
  107. int i;
  108. OutputDebugStringA(pal->pszProc);
  109. OutputDebugString(TEXT("("));
  110. for (i = 0; pal->pszFormat[i]; i++) {
  111. if (i) {
  112. OutputDebugString(TEXT(", "));
  113. }
  114. switch (pal->pszFormat[i]) {
  115. case 'p': /* 32-bit flat pointer */
  116. case 'x': /* 32-bit hex */
  117. wnsprintfA(sz, ARRAYSIZE(sz), "%08x", pal->rgpv[i]);
  118. OutputDebugStringA(sz);
  119. break;
  120. case 's': /* TCHAR string */
  121. if (pal->rgpv[i]) {
  122. OutputDebugString(pal->rgpv[i]);
  123. }
  124. break;
  125. case 'A': /* ANSI string */
  126. if (pal->rgpv[i]) {
  127. OutputDebugStringA(pal->rgpv[i]);
  128. }
  129. break;
  130. #if 0
  131. case 'W': /* UNICODE string */
  132. #ifdef UNICODE
  133. OutputDebugStringW(pal->rgpv[i]);
  134. #else
  135. OleStrToStrN(sz, cA(sz), pal->rgpv[i], -1);
  136. OutputDebugStringA(sz);
  137. #endif
  138. break;
  139. #endif
  140. case 'G': /* GUID */
  141. wnsprintfA(sz, ARRAYSIZE(sz), "%08x", *(LPDWORD)pal->rgpv[i]);
  142. OutputDebugStringA(sz);
  143. break;
  144. case 'u': /* 32-bit unsigned decimal */
  145. wnsprintfA(sz, ARRAYSIZE(sz), "%u", pal->rgpv[i]);
  146. OutputDebugStringA(sz);
  147. break;
  148. case 'C':
  149. if (GetClipboardFormatNameA(PtrToInt(pal->rgpv[i]), sz, cA(sz))) {
  150. } else {
  151. wnsprintfA(sz, ARRAYSIZE(sz), "[%04x]", pal->rgpv[i]);
  152. }
  153. OutputDebugStringA(sz);
  154. break;
  155. default: AssertF(0); /* Invalid */
  156. }
  157. }
  158. OutputDebugString(TEXT(")"));
  159. }
  160. /*****************************************************************************
  161. *
  162. * EnterSqflPtsz
  163. *
  164. * Mark entry to a procedure. Arguments were already collected by
  165. * ArgsPszV.
  166. *
  167. * sqfl -> squirty flags
  168. * pszProc -> procedure name
  169. * pal -> place to save the name and get the format/args
  170. *
  171. *****************************************************************************/
  172. void EXTERNAL
  173. EnterSqflPszPal(SQFL sqfl, LPCSTR pszProc, PARGLIST pal)
  174. {
  175. pal->pszProc = pszProc;
  176. if (sqfl == 0 || (sqfl & sqflCur)) {
  177. EmitPal(pal);
  178. OutputDebugString(TEXT("\r\n"));
  179. }
  180. }
  181. /*****************************************************************************
  182. *
  183. * ExitSqflPalHresPpv
  184. *
  185. * Mark exit from a procedure.
  186. *
  187. * pal -> argument list
  188. * hres -> exit result
  189. * ppv -> optional OUT pointer;
  190. * 1 means that hres is a boolean
  191. * 2 means that hres is nothing at all
  192. *
  193. *****************************************************************************/
  194. void EXTERNAL
  195. ExitSqflPalHresPpv(SQFL sqfl, PARGLIST pal, HRESULT hres, PPV ppvObj)
  196. {
  197. DWORD le = GetLastError();
  198. if (ppvObj == ppvVoid) {
  199. } else if (ppvObj == ppvBool) {
  200. if (hres == 0) {
  201. sqfl |= sqflError;
  202. }
  203. } else {
  204. if (FAILED(hres)) {
  205. AssertF(fLimpFF(ppvObj, *ppvObj == 0));
  206. sqfl |= sqflError;
  207. }
  208. }
  209. if (sqfl == 0 || (sqfl & sqflCur)) {
  210. EmitPal(pal);
  211. OutputDebugString(TEXT(" -> "));
  212. if (ppvObj != ppvVoid) {
  213. TCHAR tszBuf[32];
  214. wnsprintf(tszBuf, ARRAYSIZE(tszBuf), TEXT("%08x"), hres);
  215. OutputDebugString(tszBuf);
  216. if (ppvObj != ppvBool) {
  217. if (ppvObj) {
  218. wnsprintf(tszBuf, ARRAYSIZE(tszBuf), TEXT(" [%08x]"), *ppvObj);
  219. OutputDebugString(tszBuf);
  220. }
  221. } else if (hres == 0) {
  222. wnsprintf(tszBuf, ARRAYSIZE(tszBuf), TEXT(" [%d]"), le);
  223. OutputDebugString(tszBuf);
  224. }
  225. }
  226. OutputDebugString(TEXT("\r\n"));
  227. }
  228. /*
  229. * This redundant test prevents a breakpoint on SetLastError()
  230. * from being hit constantly.
  231. */
  232. if (le != GetLastError()) {
  233. SetLastError(le);
  234. }
  235. }
  236. #endif