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.

318 lines
9.9 KiB

  1. /***
  2. *crt0msg.c - startup error messages
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Prints out banner for runtime error messages.
  8. *
  9. *Revision History:
  10. * 06-27-89 PHG Module created, based on asm version
  11. * 04-09-90 GJF Added #include <cruntime.h>. Made calling type
  12. * _CALLTYPE1. Also, fixed the copyright.
  13. * 04-10-90 GJF Fixed compiler warnings (-W3).
  14. * 06-04-90 GJF Revised to be more compatible with old scheme.
  15. * nmsghdr.c merged in.
  16. * 10-08-90 GJF New-style function declarators.
  17. * 10-11-90 GJF Added _RT_ABORT, _RT_FLOAT, _RT_HEAP.
  18. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  19. * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
  20. * 02-04-91 SRW Changed to call WriteFile (_WIN32_)
  21. * 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
  22. * 04-10-91 PNT Added _MAC_ conditional
  23. * 09-09-91 GJF Added _RT_ONEXIT error.
  24. * 09-18-91 GJF Added 3 math errors, also corrected comments for
  25. * errors that were changed in rterr.h, cmsgs.h.
  26. * 03-31-92 DJM POSIX support.
  27. * 10-23-92 GJF Added _RT_PUREVIRT.
  28. * 04-05-93 JWM Added _GET_RTERRMSG().
  29. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  30. * 04-29-93 GJF Removed rterrs[] entries for _RT_STACK, _RT_INTDIV,
  31. * _RT_NONCONT and _RT_INVALDISP.
  32. * 09-06-94 CFW Remove Cruiser support.
  33. * 09-06-94 GJF Revised to use MessageBox for GUI apps.
  34. * 01-10-95 JCF Remove __app_type and __error_mode check for _MAC_.
  35. * 02-14-95 CFW write -> _write, error messages to debug reporting.
  36. * 02-15-95 CFW Make all CRT message boxes look alike.
  37. * 02-24-95 CFW Use __crtMessageBoxA.
  38. * 02-27-95 CFW Change __crtMessageBoxA params.
  39. * 03-07-95 GJF Added _RT_STDIOINIT.
  40. * 03-21-95 CFW Add _CRT_ASSERT report type.
  41. * 06-06-95 CFW Remove _MB_SERVICE_NOTIFICATION.
  42. * 06-19-95 CFW Avoid STDIO calls.
  43. * 06-20-95 GJF Added _RT_LOWIOINIT.
  44. * 04-23-96 GJF Added _RT_HEAPINIT. Also, revised _NMSG_WRITE to
  45. * allow for ioinit() having not been invoked.
  46. * 05-05-97 GJF Changed call to WriteFile, in _NMSG_WRITE, so that
  47. * it does not reference _pioinfo. Also, a few cosmetic
  48. * changes.
  49. * 01-04-99 GJF Changes for 64-bit size_t.
  50. * 05-17-99 PML Remove all Macintosh support.
  51. * 01-24-99 PML Fix buffer overrun in _NMSG_WRITE.
  52. * 05-10-00 GB Fix call of _CrtDbgReport for _RT_BANNER in _NMSG_WRITE
  53. * 03-28-01 PML Protect against GetModuleFileName overflow (vs7#231284)
  54. * 12-07-01 BWT Protect against NULL handle for stderr (ntbug: 504230)
  55. * 06-05-02 BWT Switch from alloca to static buffer for error message
  56. * and remove POSIX.
  57. *
  58. *******************************************************************************/
  59. #include <cruntime.h>
  60. #include <internal.h>
  61. #include <stddef.h>
  62. #include <stdlib.h>
  63. #include <stdio.h>
  64. #include <string.h>
  65. #include <rterr.h>
  66. #include <cmsgs.h>
  67. #include <awint.h>
  68. #include <windows.h>
  69. #include <dbgint.h>
  70. /* struct used to lookup and access runtime error messages */
  71. struct rterrmsgs {
  72. int rterrno; /* error number */
  73. char *rterrtxt; /* text of error message */
  74. };
  75. /* runtime error messages */
  76. static struct rterrmsgs rterrs[] = {
  77. /* 2 */
  78. { _RT_FLOAT, _RT_FLOAT_TXT },
  79. /* 8 */
  80. { _RT_SPACEARG, _RT_SPACEARG_TXT },
  81. /* 9 */
  82. { _RT_SPACEENV, _RT_SPACEENV_TXT },
  83. /* 10 */
  84. { _RT_ABORT, _RT_ABORT_TXT },
  85. /* 16 */
  86. { _RT_THREAD, _RT_THREAD_TXT },
  87. /* 17 */
  88. { _RT_LOCK, _RT_LOCK_TXT },
  89. /* 18 */
  90. { _RT_HEAP, _RT_HEAP_TXT },
  91. /* 19 */
  92. { _RT_OPENCON, _RT_OPENCON_TXT },
  93. /* 22 */
  94. /* { _RT_NONCONT, _RT_NONCONT_TXT }, */
  95. /* 23 */
  96. /* { _RT_INVALDISP, _RT_INVALDISP_TXT }, */
  97. /* 24 */
  98. { _RT_ONEXIT, _RT_ONEXIT_TXT },
  99. /* 25 */
  100. { _RT_PUREVIRT, _RT_PUREVIRT_TXT },
  101. /* 26 */
  102. { _RT_STDIOINIT, _RT_STDIOINIT_TXT },
  103. /* 27 */
  104. { _RT_LOWIOINIT, _RT_LOWIOINIT_TXT },
  105. /* 28 */
  106. { _RT_HEAPINIT, _RT_HEAPINIT_TXT },
  107. /* 120 */
  108. { _RT_DOMAIN, _RT_DOMAIN_TXT },
  109. /* 121 */
  110. { _RT_SING, _RT_SING_TXT },
  111. /* 122 */
  112. { _RT_TLOSS, _RT_TLOSS_TXT },
  113. /* 252 */
  114. { _RT_CRNL, _RT_CRNL_TXT },
  115. /* 255 */
  116. { _RT_BANNER, _RT_BANNER_TXT }
  117. };
  118. /* number of elements in rterrs[] */
  119. #define _RTERRCNT ( sizeof(rterrs) / sizeof(struct rterrmsgs) )
  120. /* For C, _FF_DBGMSG is inactive, so _adbgmsg is
  121. set to null
  122. For FORTRAN, _adbgmsg is set to point to
  123. _FF_DBGMSG in dbginit initializer in dbgmsg.asm */
  124. void (*_adbgmsg)(void) = NULL;
  125. /***
  126. *_FF_MSGBANNER - writes out first part of run-time error messages
  127. *
  128. *Purpose:
  129. * This routine writes "\r\nrun-time error " to standard error.
  130. *
  131. * For FORTRAN $DEBUG error messages, it also uses the _FF_DBGMSG
  132. * routine whose address is stored in the _adbgmsg variable to print out
  133. * file and line number information associated with the run-time error.
  134. * If the value of _adbgmsg is found to be null, then the _FF_DBGMSG
  135. * routine won't be called from here (the case for C-only programs).
  136. *
  137. *Entry:
  138. * No arguments.
  139. *
  140. *Exit:
  141. * Nothing returned.
  142. *
  143. *Exceptions:
  144. * None handled.
  145. *
  146. *******************************************************************************/
  147. void __cdecl _FF_MSGBANNER (
  148. void
  149. )
  150. {
  151. if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
  152. _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
  153. {
  154. _NMSG_WRITE(_RT_CRNL); /* new line to begin error message */
  155. if (_adbgmsg != 0)
  156. _adbgmsg(); /* call __FF_DBGMSG for FORTRAN */
  157. _NMSG_WRITE(_RT_BANNER); /* run-time error message banner */
  158. }
  159. }
  160. /***
  161. *__NMSGWRITE(message) - write a given message to handle 2 (stderr)
  162. *
  163. *Purpose:
  164. * This routine writes the message associated with rterrnum
  165. * to stderr.
  166. *
  167. *Entry:
  168. * int rterrnum - runtime error number
  169. *
  170. *Exit:
  171. * no return value
  172. *
  173. *Exceptions:
  174. * none
  175. *
  176. *******************************************************************************/
  177. void __cdecl _NMSG_WRITE (
  178. int rterrnum
  179. )
  180. {
  181. int tblindx;
  182. DWORD bytes_written; /* bytes written */
  183. for ( tblindx = 0 ; tblindx < _RTERRCNT ; tblindx++ )
  184. if ( rterrnum == rterrs[tblindx].rterrno )
  185. break;
  186. if ( rterrnum == rterrs[tblindx].rterrno )
  187. {
  188. #ifdef _DEBUG
  189. /*
  190. * Report error.
  191. *
  192. * If _CRT_ERROR has _CRTDBG_REPORT_WNDW on, and user chooses
  193. * "Retry", call the debugger.
  194. *
  195. * Otherwise, continue execution.
  196. *
  197. */
  198. if (rterrnum != _RT_CRNL && rterrnum != _RT_BANNER)
  199. {
  200. if (1 == _CrtDbgReport(_CRT_ERROR, NULL, 0, NULL, rterrs[tblindx].rterrtxt))
  201. _CrtDbgBreak();
  202. }
  203. #endif
  204. if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
  205. _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
  206. {
  207. HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE);
  208. if (hStdErr) {
  209. WriteFile( hStdErr,
  210. rterrs[tblindx].rterrtxt,
  211. (unsigned long)strlen(rterrs[tblindx].rterrtxt),
  212. &bytes_written,
  213. NULL );
  214. }
  215. }
  216. else if (rterrnum != _RT_CRNL)
  217. {
  218. #define MSGTEXTPREFIX "Runtime Error!\n\nProgram: "
  219. static char outmsg[sizeof(MSGTEXTPREFIX) + _MAX_PATH + 2 + 500];
  220. // runtime error msg + progname + 2 newline + runtime error text.
  221. char * progname = &outmsg[sizeof(MSGTEXTPREFIX)];
  222. char * pch = progname;
  223. strcpy(outmsg, MSGTEXTPREFIX);
  224. progname[MAX_PATH] = '\0';
  225. if (!GetModuleFileName(NULL, progname, MAX_PATH))
  226. strcpy(progname, "<program name unknown>");
  227. #define MAXLINELEN 60
  228. if (strlen(pch) + 1 > MAXLINELEN)
  229. {
  230. pch += strlen(progname) + 1 - MAXLINELEN;
  231. strncpy(pch, "...", 3);
  232. }
  233. strcat(outmsg, "\n\n");
  234. strcat(outmsg, rterrs[tblindx].rterrtxt);
  235. __crtMessageBoxA(outmsg,
  236. "Microsoft Visual C++ Runtime Library",
  237. MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
  238. }
  239. }
  240. }
  241. /***
  242. *_GET_RTERRMSG(message) - returns ptr to error text for given runtime error
  243. *
  244. *Purpose:
  245. * This routine returns the message associated with rterrnum
  246. *
  247. *Entry:
  248. * int rterrnum - runtime error number
  249. *
  250. *Exit:
  251. * no return value
  252. *
  253. *Exceptions:
  254. * none
  255. *
  256. *******************************************************************************/
  257. char * __cdecl _GET_RTERRMSG (
  258. int rterrnum
  259. )
  260. {
  261. int tblindx;
  262. for ( tblindx = 0 ; tblindx < _RTERRCNT ; tblindx++ )
  263. if ( rterrnum == rterrs[tblindx].rterrno )
  264. break;
  265. if ( rterrnum == rterrs[tblindx].rterrno )
  266. return rterrs[tblindx].rterrtxt;
  267. else
  268. return NULL;
  269. }