/*** *errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string. * *Purpose: * The strerror_s runtime takes an error number for input and * copies the corresponding error message string in the destination * buffer. If the buffer is too small, the message is truncated. * *Entry: * TCHAR * buffer - Destination buffer. * size_t sizeInTChars - Size of the destination buffer. * int errnum - Integer error number (corresponding to an errno value). * *Exit: * The error code. * *Exceptions: * Input parameters are validated. Refer to the validation section of the function. * *******************************************************************************/ #ifdef _UNICODE errno_t __cdecl _wcserror_s( #else /* _UNICODE */ errno_t __cdecl strerror_s( #endif /* _UNICODE */ TCHAR* buffer, size_t sizeInTChars, int errnum ) { errno_t e = 0; /* validation section */ _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL); _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL); /* we use mbstowcs_s or strncpy_s because we want to truncate the error string * if the destination is not big enough */ #ifdef _UNICODE e = _ERRCHECK_EINVAL_ERANGE(mbstowcs_s(NULL, buffer, sizeInTChars, _get_sys_err_msg(errnum), _TRUNCATE)); /* ignore the truncate information */ if (e == STRUNCATE) { e = 0; } #else /* _UNICODE */ _ERRCHECK(strncpy_s(buffer, sizeInTChars, _get_sys_err_msg(errnum), sizeInTChars - 1)); #endif /* _UNICODE */ return e; }
void __cdecl _wperror ( const wchar_t *wmessage ) { int fh = 2; size_t size = 0; char *amessage; const char *sysmessage; /* convert WCS string into ASCII string */ if ( wmessage && *wmessage ) { _ERRCHECK_EINVAL_ERANGE(wcstombs_s( &size, NULL, 0, wmessage, INT_MAX)); if ( size==0 || (amessage = (char *)_calloc_crt(size, sizeof(char))) == NULL ) return; if ( _ERRCHECK_EINVAL_ERANGE(wcstombs_s(NULL, amessage, size, wmessage, _TRUNCATE)) != 0) { _free_crt(amessage); return; } } else amessage = NULL; _lock_fh( fh ); /* acquire file handle lock */ __try { if ( amessage ) { _write_nolock(fh,(char *)amessage,(unsigned)strlen(amessage)); _write_nolock(fh,": ",2); } _free_crt(amessage); /* note: freeing NULL is legal and benign */ sysmessage = _get_sys_err_msg( errno ); _write_nolock(fh, sysmessage,(unsigned)strlen(sysmessage)); _write_nolock(fh,"\n",1); } __finally { _unlock_fh( fh ); /* release file handle lock */ } }
// prefast (6262): This func uses lots of stack because we want to tolerate very large reports, and we can't use malloc here. int __cdecl _VCrtDbgReportA( int nRptType, void * returnAddress, char const* szFile, int nLine, char const* szModule, char const* szFormat, va_list arglist ) { int retval=0; int handled=FALSE; char szLineMessage[DBGRPT_MAX_MSG]{0}; char szOutMessage [DBGRPT_MAX_MSG]{0}; wchar_t szOutMessage2[DBGRPT_MAX_MSG]{0}; char szUserMessage[DBGRPT_MAX_MSG]{0}; if (nRptType < 0 || nRptType >= _CRT_ERRCNT) return -1; /* * handle the (hopefully rare) case of * * 1) ASSERT while already dealing with an ASSERT * or * 2) two threads asserting at the same time */ __try { if (_CRT_ASSERT == nRptType && _InterlockedIncrement(&_crtAssertBusy) > 0) { /* use only 'safe' functions -- must not assert in here! */ _ERRCHECK(_itoa_s(nLine, szLineMessage, DBGRPT_MAX_MSG, 10)); OutputDebugStringA("Second Chance Assertion Failed: File "); OutputDebugStringA(szFile ? szFile : "<file unknown>"); OutputDebugStringA(", Line "); OutputDebugStringA(szLineMessage); OutputDebugStringA("\n"); _CrtDbgBreak(); retval=-1; __leave; } // Leave space for ASSERTINTRO1 and "\r\n" if (szFormat) { int szlen = 0; _ERRCHECK_SPRINTF(szlen = _vsnprintf_s(szUserMessage, DBGRPT_MAX_MSG, DBGRPT_MAX_MSG - 2- max(sizeof(ASSERTINTRO1),sizeof(ASSERTINTRO2)), szFormat, arglist)); if (szlen < 0) { _ERRCHECK(strcpy_s(szUserMessage, DBGRPT_MAX_MSG, DBGRPT_TOOLONGMSG)); } } if (_CRT_ASSERT == nRptType) { _ERRCHECK(strcpy_s(szLineMessage, DBGRPT_MAX_MSG, szFormat ? ASSERTINTRO1 : ASSERTINTRO2)); } _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, szUserMessage)); if (_CRT_ASSERT == nRptType) { if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_FILE) { _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, "\r")); } _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, "\n")); } if (szFile) { int szlen = 0; _ERRCHECK_SPRINTF(szlen = _snprintf_s(szOutMessage, DBGRPT_MAX_MSG, DBGRPT_MAX_MSG - 1, "%s(%d) : %s", szFile, nLine, szLineMessage)); if (szlen < 0) { _ERRCHECK(strcpy_s(szOutMessage, DBGRPT_MAX_MSG, DBGRPT_TOOLONGMSG)); } } else { _ERRCHECK(strcpy_s(szOutMessage, DBGRPT_MAX_MSG, szLineMessage)); } { size_t ret = 0; errno_t e = 0; _ERRCHECK_EINVAL_ERANGE(e = mbstowcs_s(&ret, szOutMessage2, DBGRPT_MAX_MSG, szOutMessage, _TRUNCATE)); if(e != 0) { _ERRCHECK(wcscpy_s(szOutMessage2, DBGRPT_MAX_MSG, _CRT_WIDE(DBGRPT_INVALIDMSG))); } } /* User hook may handle report. We have to check the ANSI Hook2 List & then the UNICODE Hook2 List. Then we have check any ANSI individual Hook set through SetReportHook */ if (_pReportHookList || _pReportHookListW) { __crt_report_hook_node<char> *pnode=nullptr; __crt_report_hook_node<wchar_t> *pnodeW=nullptr; __acrt_lock(__acrt_debug_lock); __try { for (pnode = _pReportHookList; pnode; pnode = pnode->next) { int hook_retval=0; if (pnode->hook(nRptType, szOutMessage, &hook_retval)) { handled=TRUE; retval=hook_retval; __leave; } } for (pnodeW = _pReportHookListW; pnodeW; pnodeW = pnodeW->next) { int hook_retval=0; if (pnodeW->hook(nRptType, szOutMessage2, &hook_retval)) { handled=TRUE; retval=hook_retval; __leave; } } } __finally { __acrt_unlock(__acrt_debug_lock); } } if (handled) __leave; if (_pfnReportHook) { int hook_retval=0; if (_pfnReportHook(nRptType, szOutMessage, &hook_retval)) { retval = hook_retval; __leave; } } if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_FILE) { if (_CrtDbgFile[nRptType] != _CRTDBG_INVALID_HFILE) { DWORD bytes_written = 0; WriteFile(_CrtDbgFile[nRptType], szOutMessage, static_cast<DWORD>(strlen(szOutMessage)), &bytes_written, nullptr); } } if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_DEBUG) { OutputDebugStringA(szOutMessage); } if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_WNDW) { szLineMessage[0] = 0; if (nLine) { _ERRCHECK(_itoa_s(nLine, szLineMessage, DBGRPT_MAX_MSG, 10)); } retval = __acrt_MessageWindowA(nRptType, returnAddress, szFile, (nLine ? szLineMessage : nullptr), szModule, szUserMessage); } }