Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343//// invalid_parameter.cpp//// Copyright (c) Microsoft Corporation. All rights reserved.//// The invalid parameter handlers and related functionality//#include <corecrt_internal.h>#include <corecrt_internal_ptd_propagation.h>
static __crt_state_management::dual_state_global<_invalid_parameter_handler> __acrt_invalid_parameter_handler;
#if defined _M_X64 && !defined _UCRT_ENCLAVE_BUILD
static void __cdecl capture_current_context(CONTEXT* const context_record) throw() { ULONG64 ControlPc; ULONG64 EstablisherFrame; ULONG64 ImageBase; PRUNTIME_FUNCTION FunctionEntry; PVOID HandlerData;
RtlCaptureContext(context_record);
ControlPc = context_record->Rip; FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, nullptr);
if (FunctionEntry != nullptr) { RtlVirtualUnwind( UNW_FLAG_NHANDLER, ImageBase, ControlPc, FunctionEntry, context_record, &HandlerData, &EstablisherFrame, nullptr); } }
#endif // _M_X64 && !_UCRT_ENCLAVE_BUILD
#if defined _CRT_GLOBAL_STATE_ISOLATION
// The legacy Windows CRT (msvcrt) does not terminate the process when an // invalid parameter is passed to a library function. Turning on this // validation for Windows components would be a big app compat problem. // // For OS components the default behavior will be to ignore the invalid parameters // and that is accomplished by providing an empty IPH. static void __cdecl invalid_parameter_handler_continue( wchar_t const * const, // pszExpression wchar_t const * const, // pszFunction wchar_t const * const, // pszFile unsigned int, // nLine uintptr_t // pReserved ) throw() { }
#endif
extern "C" void __cdecl __acrt_initialize_invalid_parameter_handler(void* const encoded_null){#if defined _CRT_GLOBAL_STATE_ISOLATION const _invalid_parameter_handler encoded_os_iph = __crt_fast_encode_pointer(invalid_parameter_handler_continue);#endif const _invalid_parameter_handler iph[] = { reinterpret_cast<_invalid_parameter_handler>(encoded_null)#if defined _CRT_GLOBAL_STATE_ISOLATION ,encoded_os_iph#endif };
__acrt_invalid_parameter_handler.initialize_from_array(iph);}
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//// _invalid_parameter////-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+extern "C" void __cdecl _invalid_parameter_internal( wchar_t const* const expression, wchar_t const* const function_name, wchar_t const* const file_name, unsigned int const line_number, uintptr_t const reserved, __crt_cached_ptd_host& ptd ){ __acrt_ptd * const raw_ptd = ptd.get_raw_ptd_noexit(); if (raw_ptd && raw_ptd->_thread_local_iph) { raw_ptd->_thread_local_iph(expression, function_name, file_name, line_number, reserved); return; }
_invalid_parameter_handler const global_handler = __crt_fast_decode_pointer(__acrt_invalid_parameter_handler.value(ptd)); if (global_handler) { global_handler(expression, function_name, file_name, line_number, reserved); return; }
_invoke_watson(expression, function_name, file_name, line_number, reserved);}
extern "C" void __cdecl _invalid_parameter( wchar_t const* const expression, wchar_t const* const function_name, wchar_t const* const file_name, unsigned int const line_number, uintptr_t const reserved ){ __crt_cached_ptd_host ptd; return _invalid_parameter_internal(expression, function_name, file_name, line_number, reserved, ptd);}
extern "C" void __cdecl _invalid_parameter_noinfo(){ _invalid_parameter(nullptr, nullptr, nullptr, 0, 0);}
// This is used by inline code in the C++ Standard Library and the SafeInt// library. Because it is __declspec(noreturn), the compiler can better// optimize use of the invalid parameter handler for inline code.extern "C" __declspec(noreturn) void __cdecl _invalid_parameter_noinfo_noreturn(){ _invalid_parameter(nullptr, nullptr, nullptr, 0, 0); _invoke_watson (nullptr, nullptr, nullptr, 0, 0);}
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//// _invoke_watson////-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#if (defined _M_IX86 || defined _M_X64) && !defined _UCRT_ENCLAVE_BUILD
extern "C" void __cdecl __acrt_call_reportfault( int const debugger_hook_code, DWORD const _exception_code, DWORD const _exception_flags ) { // Notify the debugger if attached. if (debugger_hook_code != _CRT_DEBUGGER_IGNORE) { _CRT_DEBUGGER_HOOK(debugger_hook_code); }
// Fake an exception to call report fault: EXCEPTION_RECORD ExceptionRecord{}; CONTEXT ContextRecord{}; EXCEPTION_POINTERS ExceptionPointers = {&ExceptionRecord, &ContextRecord};
#ifdef _M_IX86 #if defined(__GNUC__) || defined(__clang__) __asm__ __volatile__( "movl %%eax, %[CxEax]\n\t" "movl %%ecx, %[CxEcx]\n\t" "movl %%edx, %[CxEdx]\n\t" "movl %%ebx, %[CxEbx]\n\t" "movl %%esi, %[CxEsi]\n\t" "movl %%edi, %[CxEdi]\n\t" : [CxEax] "=m" (ContextRecord.Eax), [CxEcx] "=m" (ContextRecord.Ecx), [CxEdx] "=m" (ContextRecord.Edx), [CxEbx] "=m" (ContextRecord.Ebx), [CxEsi] "=m" (ContextRecord.Esi), [CxEdi] "=m" (ContextRecord.Edi)); __asm__ __volatile__( "movw %%ss, %[CxSegSs]\n\t" "movw %%cs, %[CxSegCs]\n\t" "movw %%ds, %[CxSegDs]\n\t" "movw %%es, %[CxSegEs]\n\t" "movw %%fs, %[CxSegFs]\n\t" "movw %%gs, %[CxSegGs]\n\t" : [CxSegSs] "=m" (ContextRecord.SegSs), [CxSegCs] "=m" (ContextRecord.SegCs), [CxSegDs] "=m" (ContextRecord.SegDs), [CxSegEs] "=m" (ContextRecord.SegEs), [CxSegFs] "=m" (ContextRecord.SegFs), [CxSegGs] "=m" (ContextRecord.SegGs)); __asm__ __volatile__( "pushfl\n\t" "popl %[CxEFlags]\n\t" : [CxEFlags] "=m" (ContextRecord.EFlags)); #else // ^^^ __GNUC__ ^^^ // vvv !__GNUC__ vvv // __asm { mov dword ptr [ContextRecord.Eax ], eax mov dword ptr [ContextRecord.Ecx ], ecx mov dword ptr [ContextRecord.Edx ], edx mov dword ptr [ContextRecord.Ebx ], ebx mov dword ptr [ContextRecord.Esi ], esi mov dword ptr [ContextRecord.Edi ], edi mov word ptr [ContextRecord.SegSs], ss mov word ptr [ContextRecord.SegCs], cs mov word ptr [ContextRecord.SegDs], ds mov word ptr [ContextRecord.SegEs], es mov word ptr [ContextRecord.SegFs], fs mov word ptr [ContextRecord.SegGs], gs pushfd pop [ContextRecord.EFlags] } #endif // !__GNUC__
ContextRecord.ContextFlags = CONTEXT_CONTROL;
ContextRecord.Eip = (ULONG)_ReturnAddress(); ContextRecord.Esp = (ULONG)_AddressOfReturnAddress(); ContextRecord.Ebp = *((ULONG *)_AddressOfReturnAddress()-1);
#else // ^^^ _M_IX86 ^^^ // vvv _M_X64 vvv //
capture_current_context(&ContextRecord); ContextRecord.Rip = (ULONGLONG)_ReturnAddress(); ContextRecord.Rsp = (ULONGLONG)_AddressOfReturnAddress()+8;
#endif // _M_X64
ExceptionRecord.ExceptionCode = _exception_code; ExceptionRecord.ExceptionFlags = _exception_flags; ExceptionRecord.ExceptionAddress = _ReturnAddress();
BOOL const was_debugger_present = IsDebuggerPresent();
// Raises an exception that bypasses all exception handlers:#pragma warning(suppress:__WARNING_SETUNHANDLEDEXCEPTIONFILTER_USE) // 28725 Use Watson instead of this SetUnhandledExceptionFilter. SetUnhandledExceptionFilter(nullptr); DWORD const handler_result = UnhandledExceptionFilter(&ExceptionPointers);
// If no handler was found and no debugger was previously attached, then // execution must stop into the debugger hook: if (handler_result == EXCEPTION_CONTINUE_SEARCH && !was_debugger_present && debugger_hook_code != _CRT_DEBUGGER_IGNORE) { _CRT_DEBUGGER_HOOK(debugger_hook_code); } }
extern "C" __declspec(noreturn) void __cdecl _invoke_watson( wchar_t const* const expression, wchar_t const* const function_name, wchar_t const* const file_name, unsigned int const line_number, uintptr_t const reserved ) { UNREFERENCED_PARAMETER(expression ); UNREFERENCED_PARAMETER(function_name); UNREFERENCED_PARAMETER(file_name ); UNREFERENCED_PARAMETER(line_number ); UNREFERENCED_PARAMETER(reserved );
if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)) { __fastfail(FAST_FAIL_INVALID_ARG); }
// Otherwise, raise a fast-fail exception and termintae the process: __acrt_call_reportfault( _CRT_DEBUGGER_INVALIDPARAMETER, STATUS_INVALID_CRUNTIME_PARAMETER, EXCEPTION_NONCONTINUABLE);
TerminateProcess(GetCurrentProcess(), STATUS_INVALID_CRUNTIME_PARAMETER); UNREACHABLE; }
#else // ^^^ (_M_IX86 || _M_X64) && !_UCRT_ENCLAVE_BUILD ^^^ // vvv Newer Architectures vvv //
extern "C" __declspec(noreturn) void __cdecl _invoke_watson( wchar_t const* const expression, wchar_t const* const function_name, wchar_t const* const file_name, unsigned int const line_number, uintptr_t const reserved ) { UNREFERENCED_PARAMETER(expression ); UNREFERENCED_PARAMETER(function_name); UNREFERENCED_PARAMETER(file_name ); UNREFERENCED_PARAMETER(line_number ); UNREFERENCED_PARAMETER(reserved );
__fastfail(FAST_FAIL_INVALID_ARG); }
#endif
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//// Handler Accessors////-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+extern "C" _invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler const new_handler){ _invalid_parameter_handler const old_handler = __crt_fast_decode_pointer(__acrt_invalid_parameter_handler.value()); __acrt_invalid_parameter_handler.value() = __crt_fast_encode_pointer(new_handler); return old_handler;}
extern "C" _invalid_parameter_handler __cdecl _get_invalid_parameter_handler(){ return __crt_fast_decode_pointer(__acrt_invalid_parameter_handler.value());}
extern "C" _invalid_parameter_handler __cdecl _set_thread_local_invalid_parameter_handler(_invalid_parameter_handler const new_handler){ __acrt_ptd* const ptd = __acrt_getptd();
_invalid_parameter_handler const old_handler = ptd->_thread_local_iph; ptd->_thread_local_iph = new_handler; return old_handler;}
extern "C" _invalid_parameter_handler __cdecl _get_thread_local_invalid_parameter_handler(){ __acrt_ptd* const ptd = __acrt_getptd_noexit(); if (!ptd) { return nullptr; }
return ptd->_thread_local_iph;}