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.

294 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1993-2001 Microsoft Corporation
  3. Module Name:
  4. error.cpp
  5. Abstract:
  6. This file implements the error handeling functions for the
  7. entire DRWTSN32 application. This includes error popups,
  8. debug prints, and assertions.
  9. Author:
  10. Wesley Witt (wesw) 1-May-1993
  11. Environment:
  12. User Mode
  13. --*/
  14. #include "pch.cpp"
  15. void
  16. __cdecl
  17. FatalError(
  18. HRESULT Error,
  19. _TCHAR * pszFormat,
  20. ...
  21. )
  22. /*++
  23. Routine Description:
  24. This function is called when there is nothing else to do, hence
  25. the name FatalError. It puts up a popup and then terminates.
  26. Arguments:
  27. Same as printf.
  28. Return Value:
  29. None.
  30. --*/
  31. {
  32. PTSTR pszErrMsg = NULL;
  33. PTSTR pszInternalMsgFormat = NULL;
  34. _TCHAR szArgumentsBuffer[1024 * 2] = {0};
  35. _TCHAR szMsg[1024 * 8] = {0};
  36. DWORD dwCount;
  37. va_list arg_ptr;
  38. va_start(arg_ptr, pszFormat);
  39. _vsntprintf(szArgumentsBuffer, sizeof(szArgumentsBuffer) / sizeof(_TCHAR), pszFormat, arg_ptr);
  40. va_end(arg_ptr);
  41. dwCount = FormatMessage(
  42. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  43. FORMAT_MESSAGE_IGNORE_INSERTS,
  44. NULL,
  45. Error,
  46. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  47. (PTSTR) &pszErrMsg,
  48. 0,
  49. NULL
  50. );
  51. _sntprintf(szMsg, sizeof(szMsg) / sizeof(_TCHAR), LoadRcString(IDS_ERROR_FORMAT_STRING),
  52. szArgumentsBuffer, Error);
  53. if (dwCount) {
  54. if ( (_tcslen(szMsg) + _tcslen(pszErrMsg) +1) * sizeof(_TCHAR) < sizeof(szMsg)) {
  55. _tcscat(szMsg, pszErrMsg);
  56. }
  57. }
  58. MessageBox(NULL, szMsg, LoadRcString(IDS_FATAL_ERROR), MB_TASKMODAL | MB_SETFOREGROUND | MB_OK);
  59. if (pszErrMsg) {
  60. LocalFree(pszErrMsg);
  61. }
  62. ExitProcess(0);
  63. }
  64. void
  65. __cdecl
  66. NonFatalError(
  67. PTSTR pszFormat,
  68. ...
  69. )
  70. /*++
  71. Routine Description:
  72. This function is used to generate a popup with some kind of
  73. warning message inside.
  74. Arguments:
  75. Same as printf.
  76. Return Value:
  77. None.
  78. --*/
  79. {
  80. PTSTR pszErrMsg = NULL;
  81. PTSTR pszInternalMsgFormat = NULL;
  82. _TCHAR szArgumentsBuffer[1024 * 2] = {0};
  83. _TCHAR szMsg[1024 * 8] = {0};
  84. DWORD dwCount;
  85. va_list arg_ptr;
  86. DWORD dwError;
  87. dwError = GetLastError();
  88. va_start(arg_ptr, pszFormat);
  89. _vsntprintf(szArgumentsBuffer, sizeof(szArgumentsBuffer) / sizeof(_TCHAR), pszFormat, arg_ptr);
  90. va_end(arg_ptr);
  91. if (ERROR_SUCCESS == dwError) {
  92. // Don't bother getting an error message
  93. _tcscpy(szMsg, szArgumentsBuffer);
  94. } else {
  95. // We have a real error
  96. dwCount = FormatMessage(
  97. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  98. FORMAT_MESSAGE_IGNORE_INSERTS,
  99. NULL,
  100. dwError,
  101. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  102. (PTSTR) &pszErrMsg,
  103. 0,
  104. NULL
  105. );
  106. _sntprintf(szMsg, sizeof(szMsg) / sizeof(_TCHAR), LoadRcString(IDS_ERROR_FORMAT_STRING),
  107. szArgumentsBuffer, dwError);
  108. if (dwCount) {
  109. if ( (_tcslen(szMsg) + _tcslen(pszErrMsg) +1) * sizeof(_TCHAR) < sizeof(szMsg)) {
  110. _tcscat(szMsg, pszErrMsg);
  111. }
  112. }
  113. }
  114. MessageBox(NULL, szMsg, LoadRcString(IDS_NONFATAL_ERROR),
  115. MB_TASKMODAL | MB_SETFOREGROUND | MB_OK);
  116. if (pszErrMsg) {
  117. LocalFree(pszErrMsg);
  118. }
  119. }
  120. void
  121. __cdecl
  122. dprintf(
  123. _TCHAR *format,
  124. ...
  125. )
  126. /*++
  127. Routine Description:
  128. This function is a var-args version of OutputDebugString.
  129. Arguments:
  130. Same as printf.
  131. Return Value:
  132. None.
  133. --*/
  134. {
  135. _TCHAR buf[1024];
  136. va_list arg_ptr;
  137. va_start(arg_ptr, format);
  138. _vsntprintf(buf, sizeof(buf) / sizeof(_TCHAR), format, arg_ptr);
  139. va_end(arg_ptr);
  140. OutputDebugString( buf );
  141. return;
  142. }
  143. void
  144. AssertError(
  145. PTSTR pszExpression,
  146. PTSTR pszFile,
  147. DWORD dwLineNumber
  148. )
  149. /*++
  150. Routine Description:
  151. Display an assertion failure message box which gives the user a choice
  152. as to whether the process should be aborted, the assertion ignored or
  153. a break exception generated.
  154. Arguments:
  155. Expression - Supplies a string representation of the failed assertion.
  156. File - Supplies a pointer to the file name where the assertion
  157. failed.
  158. LineNumber - Supplies the line number in the file where the assertion
  159. failed.
  160. Return Value:
  161. None.
  162. --*/
  163. {
  164. int nResponse;
  165. _TCHAR szModuleBuffer[ MAX_PATH ];
  166. DWORD dwLength;
  167. _TCHAR szBuffer[ 4096 ];
  168. DWORD dwError;
  169. LPTSTR lpszMsgBuf = NULL;
  170. dwError = GetLastError();
  171. //
  172. // Get the last error string
  173. //
  174. FormatMessage(
  175. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  176. FORMAT_MESSAGE_IGNORE_INSERTS,
  177. NULL,
  178. dwError,
  179. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  180. (LPTSTR) &lpszMsgBuf,
  181. 0,
  182. NULL);
  183. //
  184. // Get the asserting module's file name.
  185. //
  186. dwLength = GetModuleFileName( NULL, szModuleBuffer, sizeof(szModuleBuffer) / sizeof(_TCHAR));
  187. _sntprintf(szBuffer, sizeof(szBuffer) / sizeof(_TCHAR),
  188. _T("Assertion Failed : <%s> in file %s at line %u\n\nModule Name: %s\nLast system error: %u\n%s"),
  189. pszExpression, pszFile, dwLineNumber, szModuleBuffer, dwError, lpszMsgBuf);
  190. LocalFree( lpszMsgBuf );
  191. nResponse = MessageBox(NULL, szBuffer, _T("DrWatson Assertion"),
  192. MB_TASKMODAL | MB_ABORTRETRYIGNORE | MB_ICONERROR | MB_TASKMODAL);
  193. switch( nResponse ) {
  194. case IDABORT:
  195. //
  196. // Terminate the process.
  197. //
  198. ExitProcess( (UINT) -1 );
  199. break;
  200. case IDIGNORE:
  201. //
  202. // Ignore the failed assertion.
  203. //
  204. break;
  205. case IDRETRY:
  206. //
  207. // Break into a debugger.
  208. //
  209. DebugBreak();
  210. break;
  211. default:
  212. //
  213. // Break into a debugger because of a catastrophic failure.
  214. //
  215. DebugBreak( );
  216. break;
  217. }
  218. }