static BOOL WINAPI ctrlevent_capture ( DWORD CtrlType ) { _PHNDLR ctrl_action; _PHNDLR *pctrl_action; int sigcode; _mlock(_SIGNAL_LOCK); __try { /* * Identify the type of event and fetch the corresponding action * description. */ if ( CtrlType == CTRL_C_EVENT ) { pctrl_action = &ctrlc_action; ctrl_action = (_PHNDLR) _decode_pointer(*pctrl_action); sigcode = SIGINT; } else { pctrl_action = &ctrlbreak_action; ctrl_action = (_PHNDLR) _decode_pointer(*pctrl_action); sigcode = SIGBREAK; } if ( !(ctrl_action == SIG_DFL) && !(ctrl_action == SIG_IGN) ) /* * Reset the action to be SIG_DFL */ *pctrl_action = (_PHNDLR) _encoded_null(); } __finally { _munlock(_SIGNAL_LOCK); } if ( ctrl_action == SIG_DFL ) /* * return FALSE, indicating the event has NOT been handled */ return FALSE; if ( ctrl_action != SIG_IGN ) { (*ctrl_action)(sigcode); } /* * Return TRUE, indicating the event has been handled (which may * mean it's being ignored) */ return TRUE; }
_CRTIMP void __cdecl _invalid_parameter( const wchar_t *pszExpression, const wchar_t *pszFunction, const wchar_t *pszFile, unsigned int nLine, uintptr_t pReserved ) { _invalid_parameter_handler pHandler = __pInvalidArgHandler; pszExpression; pszFunction; pszFile; pHandler = (_invalid_parameter_handler) _decode_pointer(pHandler); if (pHandler != NULL) { pHandler(pszExpression, pszFunction, pszFile, nLine, pReserved); return; } // No user handler is defined. Notify the debugger if attached. _CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_INVALIDPARAMETER); _invoke_watson(pszExpression, pszFunction, pszFile, nLine, pReserved); }
_CRTIMP int __cdecl _set_error_mode( int em ) { int retval = 0; #if defined (CRTDLL) && !defined (_SYSCRT) if (_set_errmode_server != _encoded_null()) { return ((_set_error_mode_function) _decode_pointer(_set_errmode_server))(em); } #endif /* defined (CRTDLL) && !defined (_SYSCRT) */ switch (em) { case _OUT_TO_DEFAULT: case _OUT_TO_STDERR: case _OUT_TO_MSGBOX: retval = __error_mode; __error_mode = em; break; case _REPORT_ERRMODE: retval = __error_mode; break; default: _VALIDATE_RETURN(("Invalid error_mode", 0), EINVAL, -1); } return retval; }
_onexit_t __cdecl _onexit ( _onexit_t func ) { _PVFV * onexitbegin; _PVFV * onexitend; _onexit_t retval; onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin); if (onexitbegin == (_PVFV *)-1) { /* EXE */ #ifdef _M_IX86 return (*_imp___onexit)(func); #else /* _M_IX86 */ return (*__imp__onexit)(func); #endif /* _M_IX86 */ } /* * Note that we decode/encode the onexit array pointers on the * client side, not the CRT DLL side, to ease backwards compatibility. * That means we have to take a lock on this side, making the lock * found in __dllonexit redundant. */ _lock(_EXIT_LOCK1); __try { onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin); onexitend = (_PVFV *)_decode_pointer(__onexitend); retval = __dllonexit(func, &onexitbegin, &onexitend); __onexitbegin = (_PVFV *)_encode_pointer(onexitbegin); __onexitend = (_PVFV *)_encode_pointer(onexitend); } __finally { _unlock(_EXIT_LOCK1); } return retval; }
_CRTIMP void __cdecl __set_flsgetvalue() { #ifndef _M_AMD64 if (!FLS_GETVALUE) { TlsSetValue(__getvalueindex, _decode_pointer(gpFlsGetValue)); } #endif /* _M_AMD64 */ }
_CRTIMP int __cdecl __get_app_type() { #if defined (CRTDLL) && !defined (_SYSCRT) if (__get_app_type_server != _encoded_null()) { return ((_get_app_type_function) _decode_pointer(__get_app_type_server))(); } #endif /* defined (CRTDLL) && !defined (_SYSCRT) */ return __app_type; }
_CRTIMP _invalid_parameter_handler __cdecl _get_invalid_parameter_handler( ) { _invalid_parameter_handler pOld = NULL; pOld = __pInvalidArgHandler; pOld = (_invalid_parameter_handler) _decode_pointer((PVOID)pOld); return pOld; }
_CRTIMP void __cdecl __set_app_type( int at ) { #if defined (CRTDLL) && !defined (_SYSCRT) if (__set_app_type_server != _encoded_null()) { ((_set_app_type_function) _decode_pointer(__set_app_type_server))(at); } #endif /* defined (CRTDLL) && !defined (_SYSCRT) */ __app_type = at; }
_onexit_t __cdecl mingw_onexit(_onexit_t func) { _PVFV *onexitbegin; _PVFV *onexitend; _onexit_t retval; onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); if (onexitbegin == (_PVFV *) -1) return (* __MINGW_IMP_SYMBOL(_onexit)) (func); _lock (_EXIT_LOCK1); onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); onexitend = (_PVFV *) _decode_pointer (__onexitend); retval = __dllonexit (func, &onexitbegin, &onexitend); __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); __onexitend = (_PVFV *) _encode_pointer (onexitend); _unlock (_EXIT_LOCK1); return retval; }
_CRTIMP _invalid_parameter_handler __cdecl _set_invalid_parameter_handler( _invalid_parameter_handler pNew ) { _invalid_parameter_handler pOld = NULL; pOld = __pInvalidArgHandler; pOld = (_invalid_parameter_handler) _decode_pointer((PVOID)pOld); pNew = (_invalid_parameter_handler) _encode_pointer((PVOID)pNew); __pInvalidArgHandler = pNew; return pOld; }
errno_t __cdecl rand_s ( unsigned int* _RandomValue ) { PGENRANDOM pfnRtlGenRandom = _decode_pointer(g_pfnRtlGenRandom); _VALIDATE_RETURN_ERRCODE(_RandomValue != NULL, EINVAL); *_RandomValue = 0; // Review : better value to initialize it to? if (pfnRtlGenRandom == NULL) { PGENRANDOM encoded; void* enull; // Advapi32.dll is unloaded when the App exits. HMODULE hAdvApi32 = LoadLibrary("ADVAPI32.DLL"); if (!hAdvApi32) { _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), EINVAL); } pfnRtlGenRandom = (PGENRANDOM) GetProcAddress(hAdvApi32, _TO_STR(RtlGenRandom)); if (pfnRtlGenRandom == NULL) { _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), _get_errno_from_oserr(GetLastError())); } encoded = (PGENRANDOM) _encode_pointer(pfnRtlGenRandom); enull = _encoded_null(); #ifdef _M_IX86 if ((void*)(LONG_PTR)InterlockedExchange( (LONG*)&g_pfnRtlGenRandom, (LONG)(LONG_PTR)encoded) != enull) #else /* _M_IX86 */ if (InterlockedExchangePointer( (void**)&g_pfnRtlGenRandom, (void*)encoded) != enull) #endif /* _M_IX86 */ { /* A different thread has already loaded advapi32.dll. */ FreeLibrary(hAdvApi32); } } if (!(*pfnRtlGenRandom)(_RandomValue, (ULONG)sizeof(unsigned int))) { errno = ENOMEM; return errno; } return 0; }
_PHNDLR __cdecl signal( int signum, _PHNDLR sigact ) { struct _XCPT_ACTION *pxcptact; _PHNDLR oldsigact; int Error=0; _ptiddata ptd; BOOL SetConsoleCtrlError = FALSE; /* * Check for values of sigact supported on other platforms but not * on this one. Also, make sure sigact is not SIG_DIE */ if ( (sigact == SIG_ACK) || (sigact == SIG_SGE) ) goto sigreterror; /* * Take care of all signals which do not correspond to exceptions * in the host OS. Those are: * * SIGINT * SIGBREAK * SIGABRT * SIGTERM * */ if ( (signum == SIGINT) || (signum == SIGBREAK) || (signum == SIGABRT) || (signum == SIGABRT_COMPAT) || (signum == SIGTERM) ) { _mlock( _SIGNAL_LOCK ); __try { /* * if SIGINT or SIGBREAK, make sure the handler is installed * to capture ^C and ^Break events. */ if ( ((signum == SIGINT) || (signum == SIGBREAK)) && !ConsoleCtrlHandler_Installed ) { if ( SetConsoleCtrlHandler(ctrlevent_capture, TRUE) == TRUE ) { ConsoleCtrlHandler_Installed = TRUE; } else { _doserrno = GetLastError(); SetConsoleCtrlError=TRUE; } } switch (signum) { case SIGINT: oldsigact = (_PHNDLR) _decode_pointer(ctrlc_action); if(sigact!=SIG_GET) { ctrlc_action = (_PHNDLR) _encode_pointer(sigact); } break; case SIGBREAK: oldsigact = (_PHNDLR) _decode_pointer(ctrlbreak_action); if(sigact!=SIG_GET) { ctrlbreak_action = (_PHNDLR) _encode_pointer(sigact); } break; case SIGABRT: case SIGABRT_COMPAT: oldsigact = (_PHNDLR) _decode_pointer(abort_action); if(sigact!=SIG_GET) { abort_action = (_PHNDLR) _encode_pointer(sigact); } break; case SIGTERM: oldsigact = (_PHNDLR) _decode_pointer(term_action); if(sigact!=SIG_GET) { term_action = (_PHNDLR) _encode_pointer(sigact); } break; } } __finally { _munlock( _SIGNAL_LOCK ); } if (SetConsoleCtrlError) { goto sigreterror; } goto sigretok; }
WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { if (dwReason == DLL_PROCESS_DETACH) { if (__proc_attached > 0) __proc_attached--; else return FALSE; } if (dwReason == DLL_PROCESS_ATTACH) { void *lock_free = NULL; void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; int nested = FALSE; while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, fiberid, 0)) != 0) { if (lock_free == fiberid) { nested = TRUE; break; } Sleep(1000); } if (__native_startup_state != __uninitialized) { _amsg_exit(31); } else { __native_startup_state = __initializing; _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z); _initterm (__xc_a,__xc_z); __native_startup_state = __initialized; } if (! nested) { (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); } if (__dyn_tls_init_callback != NULL) { __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved); } __proc_attached++; } else if (dwReason == DLL_PROCESS_DETACH) { void *lock_free = NULL; while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0) { Sleep(1000); } if(__native_startup_state!=__initialized) { _amsg_exit (31); } else { _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); if (onexitbegin) { _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend); while (--onexitend >= onexitbegin) if (*onexitend != NULL) (**onexitend) (); free (onexitbegin); __onexitbegin = __onexitend = (_PVFV *) NULL; } __native_startup_state = __uninitialized; (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); } } return TRUE; }
BOOL WINAPI _CRT_INIT( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { /* * If this is a process detach notification, check that there has * been a prior (successful) process attachment. */ if ( dwReason == DLL_PROCESS_DETACH ) { if ( __proc_attached > 0 ) __proc_attached--; else /* * no prior process attach. just return failure. */ return FALSE; } #ifdef _M_IX86 /* * Set the local copy of the Pentium FDIV adjustment flag */ _adjust_fdiv = * _imp___adjust_fdiv; #endif /* _M_IX86 */ /* * do C++ constructors (initializers) specific to this DLL */ if ( dwReason == DLL_PROCESS_ATTACH ) { /* * There is a possiblity that the module where this object is * linked into is a mixed module. In all the cases we gurantee * that native initialization will occur before managed * initialization. Also in anycase this code should never be * called when some other code is initializing native code, * that's why we exit in that case. * * The case that is illegal is when managed code is executed for * the first time in loader lock. But there can be case when dll is * loaded in LoadLibrary and CLR could be already loaded in this * case it is perfectly OK to execute .cctor. */ void *lock_free=0; void *fiberid=((PNT_TIB)NtCurrentTeb())->StackBase; int nested=FALSE; while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, fiberid, 0))!=0) { if(lock_free==fiberid) { nested=TRUE; break; } /* some other thread is running native startup/shutdown during a cctor/domain unload. Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h */ /* wait for the other thread to complete init before we return */ Sleep(1000); } if (__native_startup_state != __uninitialized) { _amsg_exit( _RT_CRT_INIT_CONFLICT); } else { /* * Set the native startup state to initializing. */ __native_startup_state = __initializing; /* * Invoke C initializers. */ #ifndef _SYSCRT if (_initterm_e( __xi_a, __xi_z ) != 0) return FALSE; #else /* _SYSCRT */ _initterm((_PVFV *)(void *)__xi_a, (_PVFV *)(void *)__xi_z); #endif /* _SYSCRT */ /* * Invoke C++ constructors */ _initterm(__xc_a,__xc_z); /* * Set the native initialization state to initialized. */ __native_startup_state = __initialized; } if(!nested) { /* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */ #pragma warning(push) #pragma warning(disable:4312) InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0); #pragma warning(pop) } /* * If we have any dynamically initialized __declspec(thread) * variables, then invoke their initialization for the thread on * which the DLL is being loaded, by calling __dyn_tls_init through * a callback defined in tlsdyn.obj. We can't rely on the OS * calling __dyn_tls_init with DLL_PROCESS_ATTACH because, on * Win2K3 and before, that call happens before the CRT is * initialized. */ if (__dyn_tls_init_callback != NULL && _IsNonwritableInCurrentImage((PBYTE)&__dyn_tls_init_callback)) { __dyn_tls_init_callback(hDllHandle, DLL_THREAD_ATTACH, lpreserved); } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); /* * Increment the process attached flag. */ __proc_attached++; } else if ( dwReason == DLL_PROCESS_DETACH ) { /* * Any basic clean-up code that goes here must be * duplicated below in _DllMainCRTStartup for the * case where the user's DllMain() routine fails on a * Process Attach notification. This does not include * calling user C++ destructors, etc. */ /* * do _onexit/atexit() terminators * (if there are any) * * These terminators MUST be executed in * reverse order (LIFO)! * * NOTE: * This code assumes that __onexitbegin * points to the first valid onexit() * entry and that __onexitend points * past the last valid entry. If * __onexitbegin == __onexitend, the * table is empty and there are no * routines to call. */ void *lock_free=0; while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, (PVOID)1, 0))!=0) { /* some other thread is running native startup/shutdown during a cctor/domain unload. Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h */ /* wait for the other thread to complete init before we return */ Sleep(1000); } if(__native_startup_state!=__initialized) { /* somehow we are in a very bad state running shutdown when we have not started */ _amsg_exit( _RT_CRT_INIT_CONFLICT); } else { _PVFV * onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin); if (onexitbegin) { _PVFV * onexitend = (_PVFV *)_decode_pointer(__onexitend); while ( --onexitend >= onexitbegin ) /* * if current table entry is not * NULL, call thru it. */ if ( *onexitend != NULL ) (**onexitend)(); /* * free the block holding onexit table to * avoid memory leaks. Also zero the ptr * variables so that they are clearly cleaned up. */ _free_crt ( onexitbegin ) ; __onexitbegin = __onexitend = (_PVFV *)_encoded_null(); } __native_startup_state = __uninitialized; /* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */ #pragma warning(push) #pragma warning(disable:4312) InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0); #pragma warning(pop) } } return TRUE; }