/********************************************************************* * msvcrt_get_thread_data * * Return the thread local storage structure. */ thread_data_t *msvcrt_get_thread_data(void) { thread_data_t *ptr; DWORD err = GetLastError(); /* need to preserve last error */ if (!(ptr = TlsGetValue( msvcrt_tls_index ))) { if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) _amsg_exit( _RT_THREAD ); if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD ); ptr->random_seed = 1; } SetLastError( err ); return ptr; }
void __cdecl _endthread ( void ) { _ptiddata ptd; /* pointer to thread's _tiddata struct */ /* * Call fp termination, if necessary */ if ( _FPmtterm != NULL ) (*_FPmtterm)(); if ( (ptd = _getptd()) == NULL ) _amsg_exit(_RT_THREAD); /* * Close the thread handle (if there was one) */ if ( ptd->_thandle != (unsigned long)(-1L) ) (void) CloseHandle( (HANDLE)(ptd->_thandle) ); /* * Free up the _tiddata structure & its subordinate buffers * _freeptd() will also clear the value for this thread * of the TLS variable __tlsindex. */ _freeptd(ptd); /* * Terminate the thread */ ExitThread(0); }
static void __cdecl pre_cpp_init(void) { #ifdef _RTC atexit(_RTC_Terminate); #endif /* _RTC */ /* * Get the arguments for the call to main. Note this must be * done explicitly, rather than as part of the dll's * initialization, to implement optional expansion of wild * card chars in filename args */ startinfo.newmode = _newmode; #ifdef WPRFLAG argret = __wgetmainargs(&argc, &argv, &envp, _dowildcard, &startinfo); #else /* WPRFLAG */ argret = __getmainargs(&argc, &argv, &envp, _dowildcard, &startinfo); #endif /* WPRFLAG */ #ifndef _SYSCRT if (argret < 0) { _amsg_exit(_RT_SPACEARG); } #endif /* _SYSCRT */ }
PTHREADDATA GetThreadData(void) { PTHREADDATA ThreadData; DWORD LastError; LastError = GetLastError(); ThreadData = TlsGetValue(TlsIndex); if (ThreadData == NULL) { ThreadData = (PTHREADDATA)calloc(1, sizeof(THREADDATA)); if (ThreadData != NULL) { TlsSetValue(TlsIndex, (LPVOID)ThreadData); InitThreadData(ThreadData); } else { _amsg_exit(_RT_THREAD); /* write message and die */ } } SetLastError(LastError); return ThreadData; }
void __cdecl _heap_abort ( void ) { _amsg_exit(_RT_HEAP); /* heap error */ /*** PROCESS TERMINATED ***/ }
_ptiddata __cdecl _getptd ( void ) { _ptiddata ptd = _getptd_noexit(); if (!ptd) { _amsg_exit(_RT_THREAD); /* write message and die */ } return ptd; }
thread_data_t *msvcrt_get_thread_data(void) { thread_data_t *ptr; DWORD err = GetLastError(); /* need to preserve last error */ if (!(ptr = TlsGetValue( msvcrt_tls_index ))) { if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) _amsg_exit( _RT_THREAD ); if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD ); ptr->tid = GetCurrentThreadId(); ptr->handle = INVALID_HANDLE_VALUE; ptr->random_seed = 1; ptr->locinfo = MSVCRT_locale->locinfo; ptr->mbcinfo = MSVCRT_locale->mbcinfo; } SetLastError( err ); return ptr; }
void fn0040127B(word32 ebx, word32 esi, word32 edi) { fn00401561(); Eq_5 * ebp_10 = fn00401770(ebx, esi, edi, dwLoc0C, 4202984, 0x0C); ebp_10->dw0000 = 0; Eq_25 * esp_105 = fp - 8; word32 edx_17 = fs->ptr0018->dw0004; word32 edi_18 = 0; do { __lock(); word32 eax_24; __cmpxchg(globals->dw403368, edx_17, 0, out eax_24); if (eax_24 == 0) goto l00401151; } while (eax_24 != edx_17); edi_18 = 1; l00401151: if (globals->dw40336C == 1) { Mem185[fp - 0x0C:word32] = 31; _amsg_exit(); esp_105 = fp + 0xFFFFFFF4; l0040119D: if (globals->dw40336C == 1) { Eq_25 * esp_174 = esp_105 - 4; esp_174->dw0000 = 4202652; esp_174->dw0000 = 4202644; _initterm(); globals->dw40336C = 2; esp_105 = esp_174; } if (edi_18 == 0) globals->dw403368 = 0; if (globals->ptr403378 != null) { Eq_167 * esp_152 = esp_105 - 4; esp_152->dw0000 = 4207480; word32 eax_154 = fn00401470(dwArg00); esp_105 = esp_152 + 4; if (eax_154 != 0) { esp_152->dw0000 = 0; esp_152->t0004.dw0000 = 2; esp_152->t0004.dw0000 = 0; esp_105 = esp_152 - 8; Mem165[4207480:word32](); }
void __cdecl __initstdio(void) { int i; #ifndef CRTDLL /* * If the user has not supplied a definition of _nstream, set it * to _NSTREAM_. If the user has supplied a value that is too small * set _nstream to the minimum acceptable value (_IOB_ENTRIES). */ if ( _nstream == 0 ) _nstream = _NSTREAM_; else if ( _nstream < _IOB_ENTRIES ) _nstream = _IOB_ENTRIES; #endif /* CRTDLL */ /* * Allocate the __piob array. Try for _nstream entries first. If this * fails then reset _nstream to _IOB_ENTRIES and try again. If it * still fails, bail out with an RTE. */ if ( (__piob = (void **)_calloc_crt( _nstream, sizeof(void *) )) == NULL ) { _nstream = _IOB_ENTRIES; if ( (__piob = (void **)_calloc_crt( _nstream, sizeof(void *) )) == NULL ) _amsg_exit( _RT_STDIOINIT ); } /* * Initialize the first _IOB_ENTRIES to point to the corresponding * entries in _iob[]. */ for ( i = 0 ; i < _IOB_ENTRIES ; i++ ) __piob[i] = (void *)&_iob[i]; for ( i = 0 ; i < 3 ; i++ ) { if ( (_osfhnd(i) == (long)INVALID_HANDLE_VALUE) || (_osfhnd(i) == 0L) ) { _iob[i]._file = -1; } } }
static unsigned long WINAPI _threadstart ( void * ptd ) { /* * Stash the pointer to the per-thread data stucture in TLS */ if ( !TlsSetValue(__tlsindex, ptd) ) _amsg_exit(_RT_THREAD); /* * Call fp initialization, if necessary */ if ( _FPmtinit != NULL ) (*_FPmtinit)(); /* * Guard call to user code with a _try - _except statement to * implement runtime errors and signal support */ __try { ( (void(__cdecl *)(void *))(((_ptiddata)ptd)->_initaddr) ) ( ((_ptiddata)ptd)->_initarg ); _endthread(); } __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) ) { /* * Should never reach here */ _exit( GetExceptionCode() ); } /* end of _try - _except */ /* * Never executed! */ return(0L); }
void __cdecl _lock ( int locknum ) { PCRITICAL_SECTION pcs; /* * Create/open the lock, if necessary */ if ( _locktable[locknum] == NULL ) { if ( (pcs = _malloc_crt(sizeof(CRITICAL_SECTION))) == NULL ) _amsg_exit(_RT_LOCK); _mlock(_LOCKTAB_LOCK); /*** WARNING: Recursive lock call ***/ if ( _locktable[locknum] == NULL ) { InitializeCriticalSection(pcs); _locktable[locknum] = pcs; } else { _free_crt(pcs); } _munlock(_LOCKTAB_LOCK); } /* * Enter the critical section. */ EnterCriticalSection( _locktable[locknum] ); }
__declspec(noinline) int __tmainCRTStartup (void) { _TCHAR *lpszCommandLine = NULL; STARTUPINFO StartupInfo; WINBOOL inDoubleQuote = FALSE; memset (&StartupInfo, 0, sizeof (STARTUPINFO)); if (mingw_app_type) GetStartupInfo (&StartupInfo); { 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 == __initializing) { _amsg_exit (31); } else if (__native_startup_state == __uninitialized) { __native_startup_state = __initializing; _initterm ((_PVFV *)(void *)__xi_a, (_PVFV *)(void *) __xi_z); } else has_cctor = 1; if (__native_startup_state == __initializing) { _initterm (__xc_a, __xc_z); __native_startup_state = __initialized; } _ASSERTE(__native_startup_state == __initialized); if (! nested) (VOID)InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); if (__dyn_tls_init_callback != NULL) __dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL); _pei386_runtime_relocator (); __mingw_oldexcpt_handler = SetUnhandledExceptionFilter (_gnu_exception_handler); #ifdef _WIN64 __mingw_init_ehandler (); #endif __mingw_prepare_except_for_msvcr80_and_higher (); _fpreset (); if (mingw_app_type) { #ifdef WPRFLAG lpszCommandLine = (_TCHAR *) _wcmdln; #else lpszCommandLine = (char *) _acmdln; #endif while (*lpszCommandLine > SPACECHAR || (*lpszCommandLine&&inDoubleQuote)) { if (*lpszCommandLine == DQUOTECHAR) inDoubleQuote = !inDoubleQuote; #ifdef _MBCS if (_ismbblead (*lpszCommandLine)) { if (lpszCommandLine) /* FIXME: Why this check? Should I check for *lpszCommandLine != 0 too? */ lpszCommandLine++; } #endif ++lpszCommandLine; } while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) lpszCommandLine++; __mingw_winmain_hInstance = (HINSTANCE) &__ImageBase; __mingw_winmain_lpCmdLine = lpszCommandLine; __mingw_winmain_nShowCmd = StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT; } duplicate_ppstrings (argc, &argv); #ifdef WPRFLAG __winitenv = envp; /* C++ initialization. gcc inserts this call automatically for a function called main, but not for wmain. */ __main (); mainret = wmain (argc, argv, envp); #else __initenv = envp; mainret = main (argc, argv, envp); #endif if (!managedapp) exit (mainret); if (has_cctor == 0) _cexit (); } return mainret; }
// address: 0x4126d0 int main(int argc, char *argv[], char *envp[]) { __size32 eax; // r24 eax = _amsg_exit(); return eax; }
/*** *_setargv, __setargv - set up "argc" and "argv" for C programs * *Purpose: * Read the command line and create the argv array for C * programs. * *Entry: * Arguments are retrieved from the program command line, * pointed to by _acmdln. * *Exit: * "argv" points to a null-terminated list of pointers to ASCIZ * strings, each of which is an argument from the command line. * "argc" is the number of arguments. The strings are copied from * the environment segment into space allocated on the heap/stack. * The list of pointers is also located on the heap or stack. * _pgmptr points to the program name. * *Exceptions: * Terminates with out of memory error if no memory to allocate. * *******************************************************************************/ #ifdef WILDCARD #ifdef WPRFLAG void __cdecl __wsetargv ( #else /* WPRFLAG */ void __cdecl __setargv ( #endif /* WPRFLAG */ #else /* WILDCARD */ #ifdef WPRFLAG void __cdecl _wsetargv ( #else /* WPRFLAG */ void __cdecl _setargv ( #endif /* WPRFLAG */ #endif /* WILDCARD */ void ) { _TSCHAR *p; _TSCHAR *cmdstart; /* start of command line to parse */ int numargs, numchars; static _TSCHAR _pgmname[ MAX_PATH ]; #if !defined (CRTDLL) && defined (_MBCS) /* If necessary, initialize the multibyte ctype table. */ if ( __mbctype_initialized == 0 ) __initmbctable(); #endif /* !defined (CRTDLL) && defined (_MBCS) */ /* Get the program name pointer from Win32 Base */ GetModuleFileName( NULL, _pgmname, sizeof( _pgmname ) / sizeof(_TSCHAR)); #ifdef WPRFLAG _wpgmptr = _pgmname; #else /* WPRFLAG */ _pgmptr = _pgmname; #endif /* WPRFLAG */ /* if there's no command line at all (won't happen from cmd.exe, but possibly another program), then we use _pgmptr as the command line to parse, so that argv[0] is initialized to the program name */ #ifdef WPRFLAG cmdstart = (*_wcmdln == NULCHAR) ? _wpgmptr : _wcmdln; #else /* WPRFLAG */ cmdstart = (*_acmdln == NULCHAR) ? _pgmptr : _acmdln; #endif /* WPRFLAG */ /* first find out how much space is needed to store args */ #ifdef WPRFLAG wparse_cmdline(cmdstart, NULL, NULL, &numargs, &numchars); #else /* WPRFLAG */ parse_cmdline(cmdstart, NULL, NULL, &numargs, &numchars); #endif /* WPRFLAG */ /* allocate space for argv[] vector and strings */ p = _malloc_crt(numargs * sizeof(_TSCHAR *) + numchars * sizeof(_TSCHAR)); if (p == NULL) _amsg_exit(_RT_SPACEARG); /* store args and argv ptrs in just allocated block */ #ifdef WPRFLAG wparse_cmdline(cmdstart, (wchar_t **)p, (wchar_t *)(((char *)p) + numargs * sizeof(wchar_t *)), &numargs, &numchars); #else /* WPRFLAG */ parse_cmdline(cmdstart, (char **)p, p + numargs * sizeof(char *), &numargs, &numchars); #endif /* WPRFLAG */ /* set argv and argc */ __argc = numargs - 1; #ifdef WPRFLAG __wargv = (wchar_t **)p; #else /* WPRFLAG */ __argv = (char **)p; #endif /* WPRFLAG */ #ifdef WILDCARD /* call _[w]cwild to expand wildcards in arg vector */ #ifdef WPRFLAG if (_wcwild()) #else /* WPRFLAG */ if (_cwild()) #endif /* WPRFLAG */ _amsg_exit(_RT_SPACEARG); /* out of space */ #endif /* WILDCARD */ }
// address: 0x4014ec void _start() { __size16 ax; // r0 __size16 cx; // r1 unsigned char dl; // r10 __size32 eax; // r24 __size32 *ebp; // r29 __size32 ebx; // r27 __size32 ecx; // r25 __size32 edi; // r31 int edx; // r26 __size32 esi; // r30 int esp; // r28 void *esp_1; // r28{8} void *esp_2; // r28{44} void *esp_3; // r28{191} int local0; // m[esp - 4] int local1; // m[esp - 24] int local2; // m[esp - 20] unsigned int local3; // m[esp - 12] int local4; // m[esp - 8] void *local5; // esp_3{191} esi = proc1(local1, local2, esi); /* Warning: also results in ebx, edi */ esp_1 = proc2(16, ebx, esi, edi); /* Warning: also results in ebp */ local5 = esp_1; ebx = 0; *(__size32*)(ebp - 4) = 0; eax = *24; esi = *(eax + 4); *(__size32*)(ebp - 28) = 0; edi = 0x403374; for(;;) { esp_3 = local5; *(__size32*)(esp_3 - 4) = 0; *(__size32*)(esp_3 - 8) = esi; *(__size32*)(esp_3 - 12) = 0x403374; eax = InterlockedCompareExchange(); /* Warning: also results in edx */ if (eax == 0) { goto L24; } if (eax == esi) { break; } *(__size32*)(esp_3 - 16) = 1000; esp_2 = Sleep(*(esp_3 - 16)); local5 = esp_2; } *(__size32*)(ebp - 28) = 1; L24: esi = 1; if (global61 != 1) { if (global61 != 0) { global68 = 1; L16: if (global61 == 1) { *(__size32*)(esp_3 - 16) = 0x4020cc; *(__size32*)(esp_3 - 20) = 0x4020c4; edx = _initterm(); global61 = 2; } if (*(ebp - 28) == 0) { *(__size32*)(esp_3 - 16) = 0; *(__size32*)(esp_3 - 20) = 0x403374; edx = InterlockedExchange(*(esp_3 - 20), *(esp_3 - 16)); } esp = esp_3 - 12; if (*0x403380 != 0) { *(__size32*)(esp_3 - 16) = 0x403380; eax = proc5(*(esp_3 - 16), dl, edx, 0); /* Warning: also results in ax, cx, dl, edx */ ecx = *(esp_3 - 16); esp = esp_3 - 12; if (eax != 0) { *(__size32*)(esp_3 - 16) = 0; *(__size32*)(esp_3 - 20) = 2; *(__size32*)(esp_3 - 24) = 0; (*global53)(local1, local2, pc, 0x4021d8, 16, ax, cx, dl, eax, ecx, edx, 0, ebp, 1, 0x403374, LOGICALFLAGS32(eax), LOGICALFLAGS32(eax), LOGICALFLAGS32(eax)); } } *(__size32*)0x23cc = global75; local0 = global75; local4 = global76; local3 = global77; eax = proc6(*(esp - 12), *(esp - 8), 0x23cc, ebx, esi, edi); /* Warning: also results in ebx */ global79 = eax; if (*0x403024 == ebx) { local0 = eax; exit(*(esp - 4)); } if (*0x403034 == ebx) { _cexit(); } *(__size32*)(ebp - 4) = -2; } else { global61 = 1; *(__size32*)(esp_3 - 16) = 0x4020dc; *(__size32*)(esp_3 - 20) = 0x4020d0; eax = _initterm_e(); /* Warning: also results in edx */ esp = esp_3 - 12; if (eax == 0) { goto L16; } else { *(__size32*)(ebp - 4) = -2; } } } else { *(__size32*)(esp_3 - 16) = 31; edx = _amsg_exit(); goto L16; } proc8(ebp); return; }
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; }
void __cdecl _ioinit ( void ) { STARTUPINFO StartupInfo; int cfi_len; int fh; int i; ioinfo *pio; char *posfile; UNALIGNED long *posfhnd; long stdfh; DWORD htype; /* * Allocate and initialize the first array of ioinfo structs. This * array is pointed to by __pioinfo[0] */ if ( (pio = _malloc_crt( IOINFO_ARRAY_ELTS * sizeof(ioinfo) )) == NULL ) { _amsg_exit( _RT_LOWIOINIT ); } __pioinfo[0] = pio; _nhandle = IOINFO_ARRAY_ELTS; for ( ; pio < __pioinfo[0] + IOINFO_ARRAY_ELTS ; pio++ ) { pio->osfile = 0; pio->osfhnd = (long)INVALID_HANDLE_VALUE; pio->pipech = 10; /* linefeed/newline char */ #if defined(_MT) && !defined(DLL_FOR_WIN32S) pio->lockinitflag = 0; /* uninitialized lock */ #endif } /* * Process inherited file handle information, if any */ GetStartupInfo( &StartupInfo ); if ( (StartupInfo.cbReserved2 != 0) && (StartupInfo.lpReserved2 != NULL) ) { /* * Get the number of handles inherited. */ cfi_len = *(UNALIGNED int *)(StartupInfo.lpReserved2); /* * Set pointers to the start of the passed file info and OS * HANDLE values. */ posfile = (char *)(StartupInfo.lpReserved2) + sizeof( int ); posfhnd = (UNALIGNED long *)(posfile + cfi_len); /* * Ensure cfi_len does not exceed the number of supported * handles! */ cfi_len = __min( cfi_len, _NHANDLE_ ); /* * Allocate sufficient arrays of ioinfo structs to hold inherited * file information. */ for ( i = 1 ; _nhandle < cfi_len ; i++ ) { /* * Allocate another array of ioinfo structs */ if ( (pio = _malloc_crt( IOINFO_ARRAY_ELTS * sizeof(ioinfo) )) == NULL ) { /* * No room for another array of ioinfo structs, reduce * the number of inherited handles we process. */ cfi_len = _nhandle; break; } /* * Update __pioinfo[] and _nhandle */ __pioinfo[i] = pio; _nhandle += IOINFO_ARRAY_ELTS; for ( ; pio < __pioinfo[i] + IOINFO_ARRAY_ELTS ; pio++ ) { pio->osfile = 0; pio->osfhnd = (long)INVALID_HANDLE_VALUE; pio->pipech = 10; #if defined(_MT) && !defined(DLL_FOR_WIN32S) pio->lockinitflag = 0; #endif } } /* * Validate and copy the passed file information */ for ( fh = 0 ; fh < cfi_len ; fh++, posfile++, posfhnd++ ) { /* * Copy the passed file info iff it appears to describe * an open, valid file. */ if ( (*posfhnd != (long)INVALID_HANDLE_VALUE) && (*posfile & FOPEN) && (GetFileType( (HANDLE)(*posfhnd) ) != FILE_TYPE_UNKNOWN) ) { pio = _pioinfo( fh ); pio->osfhnd = *posfhnd; pio->osfile = *posfile; } } } /* * If valid HANDLE-s for standard input, output and error were not * inherited, try to obtain them directly from the OS. Also, set the * appropriate bits in the osfile fields. */ for ( fh = 0 ; fh < 3 ; fh++ ) { pio = __pioinfo[0] + fh; if ( pio->osfhnd == (long)INVALID_HANDLE_VALUE ) { /* * mark the handle as open in text mode. */ pio->osfile = (char)(FOPEN | FTEXT); if ( ((stdfh = (long)GetStdHandle( stdhndl(fh) )) != (long)INVALID_HANDLE_VALUE) && ((htype = GetFileType( (HANDLE)stdfh )) != FILE_TYPE_UNKNOWN) ) { /* * obtained a valid HANDLE from GetStdHandle */ pio->osfhnd = stdfh; /* * finish setting osfile: determine if it is a character * device or pipe. */ if ( (htype & 0xFF) == FILE_TYPE_CHAR ) pio->osfile |= FDEV; else if ( (htype & 0xFF) == FILE_TYPE_PIPE ) pio->osfile |= FPIPE; } else { /* * if there is no valid HANDLE, treat the CRT handle as * being open in text mode on a device (with * INVALID_HANDLE_VALUE underlying it). */ pio->osfile |= FDEV; } } else { /* * handle was passed to us by parent process. make * sure it is text mode. */ pio->osfile |= FTEXT; } } /* * Set the number of supported HANDLE-s to _nhandle */ (void)SetHandleCount( (unsigned)_nhandle ); }
void __cdecl _fptrap( void ) { _amsg_exit(_RT_FLOAT); }
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; }
int __tmainCRTStartup( void ) { unsigned int osplatform = 0; unsigned int winver = 0; unsigned int winmajor = 0; unsigned int winminor = 0; unsigned int osver = 0; int initret; int mainret = 0; OSVERSIONINFOA* posvi; int managedapp; #ifdef _WINMAIN_ _TUCHAR* lpszCommandLine; STARTUPINFO StartupInfo; __try { /* Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so the very general exception handler below is appropriate */ GetStartupInfo(&StartupInfo); } __except (EXCEPTION_EXECUTE_HANDLER) { return 255; } #endif /* _WINMAIN_ */ /* * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid * triggering the /GS buffer overrun detection. That can't be * used here, since the guard cookie isn't available until we * initialize it from here! */ posvi = (OSVERSIONINFOA*)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA)); if (!posvi) { fast_error_exit(_RT_HEAP); return 255; } /* * Get the full Win32 version */ posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); if (!GetVersionExA(posvi)) { HeapFree(GetProcessHeap(), 0, posvi); return 255; } osplatform = posvi->dwPlatformId; winmajor = posvi->dwMajorVersion; winminor = posvi->dwMinorVersion; /* * The somewhat bizarre calculations of _osver and _winver are * required for backward compatibility (used to use GetVersion) */ osver = (posvi->dwBuildNumber) & 0x07fff; HeapFree(GetProcessHeap(), 0, posvi); if (osplatform != VER_PLATFORM_WIN32_NT) { osver |= 0x08000; } winver = (winmajor << 8) + winminor; _set_osplatform(osplatform); _set_winver(winver); _set_winmajor(winmajor); _set_winminor(winminor); _set_osver(osver); /* * Determine if this is a managed application */ managedapp = check_managed_app(); if (!_heap_init(1)) { /* initialize heap */ fast_error_exit(_RT_HEAPINIT); /* write message and die */ } if (!_mtinit()) { /* initialize multi-thread */ fast_error_exit(_RT_THREAD); /* write message and die */ } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); /* * Initialize the Runtime Checks stuff */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ /* * Guard the remainder of the initialization code and the call * to user's main, or WinMain, function in a __try/__except * statement. */ __try { if (_ioinit() < 0) { /* initialize lowio */ _amsg_exit(_RT_LOWIOINIT); } /* get wide cmd line info */ _tcmdln = (_TSCHAR*)GetCommandLineT(); /* get wide environ info */ _tenvptr = (_TSCHAR*)GetEnvironmentStringsT(); if (_tsetargv() < 0) { _amsg_exit(_RT_SPACEARG); } if (_tsetenvp() < 0) { _amsg_exit(_RT_SPACEENV); } initret = _cinit(TRUE); /* do C data initialize */ if (initret != 0) { _amsg_exit(initret); } #ifdef _WINMAIN_ lpszCommandLine = _twincmdln(); mainret = _tWinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT ); #else /* _WINMAIN_ */ _tinitenv = _tenviron; mainret = _tmain(__argc, _targv, _tenviron); #endif /* _WINMAIN_ */ if (!managedapp) { exit(mainret); } _cexit(); } __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) { /* * Should never reach here */ mainret = GetExceptionCode(); if (!managedapp) { _exit(mainret); } _c_exit(); } /* end of try - except */ return mainret; }
/* * routine in DLL to do initialization (in this case, C++ constructors) */ extern void __cdecl _initterm(_PVFV *, _PVFV *); #ifdef _WINMAIN_ #ifdef WPRFLAG int wWinMainCRTStartup( #else /* WPRFLAG */ int WinMainCRTStartup( #endif /* WPRFLAG */ #else /* _WINMAIN_ */ #ifdef WPRFLAG int wmainCRTStartup( #else /* WPRFLAG */ int mainCRTStartup( #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ void ) { int argc = 0; /* three standard arguments to main */ _TSCHAR **argv = NULL; _TSCHAR **envp = NULL; int argret = 0; #ifdef _WINMAIN_ _TUCHAR *lpszCommandLine; STARTUPINFO StartupInfo; #endif /* _WINMAIN_ */ #ifdef WPRFLAG int envp_count = 0; #endif //_startupinfo startinfo; /* * Determine if this is a managed application */ //managedapp = check_managed_app(); /* * Set __app_type properly */ #ifdef _WINMAIN_ //__set_app_type(_GUI_APP); #else /* _WINMAIN_ */ //__set_app_type(_CONSOLE_APP); #endif /* _WINMAIN_ */ #ifdef _WINMAIN_ #ifdef WPRFLAG dbgmsg("wWinMainCRTStartup()"); #else dbgmsg("WinMainCRTStartup()"); #endif #else #ifdef WPRFLAG dbgmsg("wmainCRTStartup()"); #else dbgmsg("mainCRTStartup()"); #endif #endif /* * Mark this module as an EXE file so that atexit/_onexit * will do the right thing when called, including for C++ * d-tors. */ __onexitbegin = __onexitend = (_PVFV *)(-1); dbgmsg("OK1b"); /* * Propogate the _fmode and _commode variables to the DLL * (crash in crtdll.dll...?) */ //*_IMP___FMODE = _fmode; dbgmsg("OK1c"); //*_IMP___COMMODE = _commode; dbgmsg("OK1d"); #ifdef _M_IX86 /* * Set the local copy of the Pentium FDIV adjustment flag * (not supported by crtdll.dll) */ //_adjust_fdiv = * _imp___adjust_fdiv; #endif /* _M_IX86 */ dbgmsg("OK2"); /* * Run the RTC initialization code for this DLL */ #ifdef _RTC _RTC_Initialize(); #endif /* _RTC */ /* * Call _setargv(), which will trigger a call to __setargv() if * SETARGV.OBJ is linked with the EXE. If SETARGV.OBJ is not * linked with the EXE, a dummy _setargv() will be called. */ #ifdef WPRFLAG //_wsetargv(); #else /* WPRFLAG */ //_setargv(); #endif /* WPRFLAG */ /* * If the user has supplied a _matherr routine then set * __pusermatherr to point to it. */ // if ( !__defaultmatherr ) // __setusermatherr(_matherr); #ifdef _M_IX86 //_setdefaultprecision(); #endif /* _M_IX86 */ /* * Do runtime startup initializers. * * Note: the only possible entry we'll be executing here is for * __lconv_init, pulled in from charmax.obj only if the EXE was * compiled with -J. All other .CRT$XI* initializers are only * run as part of the CRT itself, and so for the CRT DLL model * are not found in the EXE. For that reason, we call _initterm, * not _initterm_e, because __lconv_init will never return failure, * and _initterm_e is not exported from the CRT DLL. * * Note further that, when using the CRT DLL, executing the * .CRT$XI* initializers is only done for an EXE, not for a DLL * using the CRT DLL. That is to make sure the -J setting for * the EXE is not overriden by that of any DLL. */ //_initterm( __xi_a, __xi_z ); #ifdef _RTC atexit(_RTC_Terminate); #endif /* _RTC */ /* * Get the arguments for the call to main. Note this must be * done explicitly, rather than as part of the dll's * initialization, to implement optional expansion of wild * card chars in filename args */ dbgmsg("OK3"); //startinfo.newmode = 0; #ifdef WPRFLAG _wcmdln = GetCommandLineW(); argv = (_TSCHAR**)CommandLineToArgvW(_wcmdln, &argc); if (argv == NULL) FatalAppExitA(0, "This application requires Windows NT."); _wpgmptr = (wchar_t*)argv[0]; __wargv = (wchar_t**)argv; __argc = argc; _wenviron[0] = GetEnvironmentStringsW(); while ((_wenviron[envp_count][0] != 0) & (envp_count < MAX_WENVIRON_COUNT)) { _wenviron[envp_count+1] = _wenviron[envp_count]+ wcslen(_wenviron[envp_count])+1; envp_count++; } if ((argv == NULL) | (envp_count >= MAX_WENVIRON_COUNT)) argret = -1; if (argret < 0) _amsg_exit(_RT_SPACEARG); _wenviron[envp_count] = NULL; envp = (_TSCHAR**)_wenviron; #else /* WPRFLAG */ argret = __GetMainArgs(&argc, &argv, &envp, 0, NULL /*&startinfo*/); if (argv == NULL) _amsg_exit(_RT_SPACEARG); __argc = argc; __argv = argv; _environ = envp; _pgmptr = argv[0]; #endif dbgmsg("OK4"); /* * do C++ constructors (initializers) specific to this EXE */ //_initterm( __xc_a, __xc_z ); #ifdef _WINMAIN_ /* * Skip past program name (first token in command line). * Check for and handle quoted program name. */ #ifdef WPRFLAG /* OS may not support "W" flavors */ if (_wcmdln == NULL) FatalAppExitA(0, "This application requires Windows NT."); lpszCommandLine = (wchar_t *)_wcmdln; #else /* WPRFLAG */ lpszCommandLine = (unsigned char *)_acmdln; #endif /* WPRFLAG */ if ( *lpszCommandLine == DQUOTECHAR ) { /* * Scan, and skip over, subsequent characters until * another double-quote or a null is encountered. */ while ( *++lpszCommandLine && (*lpszCommandLine != DQUOTECHAR) ); /* * If we stopped on a double-quote (usual case), skip * over it. */ if ( *lpszCommandLine == DQUOTECHAR ) lpszCommandLine++; } while (*lpszCommandLine > SPACECHAR) lpszCommandLine++; if (*lpszCommandLine >= SPACECHAR) lpszCommandLine++; dbgmsg("OK5"); /* * Skip past any white space preceeding the second token. */ while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) { lpszCommandLine++; } StartupInfo.dwFlags = 0; GetStartupInfo( &StartupInfo ); #ifdef WPRFLAG __winitenv = (wchar_t**)envp; exit(wWinMain( #else /* WPRFLAG */ __initenv = envp; exit(WinMain( #endif /* WPRFLAG */ GetModuleHandleA(NULL), NULL, (LPTSTR)lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT )); #else /* _WINMAIN_ */ #ifdef WPRFLAG dbgmsg("OK6"); exit(wmain(argc, (wchar_t**)argv, (wchar_t**)envp)); #else /* WPRFLAG */ dbgmsg("OK6"); exit(main(argc, argv, envp)); #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ }
int __tmainCRTStartup( void ) { #ifdef _WINMAIN_ _TUCHAR* lpszCommandLine; STARTUPINFO StartupInfo; BOOL inDoubleQuote = FALSE; __try { /* Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so the very general exception handler below is appropriate */ GetStartupInfo(&StartupInfo); } __except (EXCEPTION_EXECUTE_HANDLER) { return 255; } #endif /* _WINMAIN_ */ /* * Guard the initialization code and the call to user's main, or * WinMain, function in a __try/__except statement. */ __try { /* * 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. * * Do runtime startup initializers. * * Note: the only possible entry we'll be executing here is for * __lconv_init, pulled in from charmax.obj only if the EXE was * compiled with -J. All other .CRT$XI* initializers are only * run as part of the CRT itself, and so for the CRT DLL model * are not found in the EXE. For that reason, we call _initterm, * not _initterm_e, because __lconv_init will never return failure, * and _initterm_e is not exported from the CRT DLL. * * Note further that, when using the CRT DLL, executing the * .CRT$XI* initializers is only done for an EXE, not for a DLL * using the CRT DLL. That is to make sure the -J setting for * the EXE is not overriden by that of any DLL. */ 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 == __initializing) { _amsg_exit(_RT_CRT_INIT_CONFLICT); } else if (__native_startup_state == __uninitialized) { __native_startup_state = __initializing; #ifndef _SYSCRT if (_initterm_e(__xi_a, __xi_z) != 0) { return 255; } #else /* _SYSCRT */ _initterm((_PVFV*)(void*)__xi_a, (_PVFV*)(void*)__xi_z); #endif /* _SYSCRT */ } else { has_cctor = 1; } /* * do C++ constructors (initializers) specific to this EXE */ if (__native_startup_state == __initializing) { _initterm(__xc_a, __xc_z); __native_startup_state = __initialized; } _ASSERTE(__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 primary * thread used to start the process, by calling __dyn_tls_init * through a callback defined in tlsdyn.obj. */ if (__dyn_tls_init_callback != NULL && _IsNonwritableInCurrentImage((PBYTE)&__dyn_tls_init_callback)) { __dyn_tls_init_callback(NULL, DLL_THREAD_ATTACH, NULL); } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); #ifdef _WINMAIN_ /* * Skip past program name (first token in command line). * Check for and handle quoted program name. */ #ifdef WPRFLAG /* OS may not support "W" flavors */ if (_wcmdln == NULL) { return 255; } lpszCommandLine = (wchar_t*)_wcmdln; #else /* WPRFLAG */ lpszCommandLine = (unsigned char*)_acmdln; #endif /* WPRFLAG */ while (*lpszCommandLine > SPACECHAR || (*lpszCommandLine && inDoubleQuote)) { /* * Flip the count from 1 to 0 or 0 to 1 if current character * is DOUBLEQUOTE */ if (*lpszCommandLine == DQUOTECHAR) { inDoubleQuote = !inDoubleQuote; } #ifdef _MBCS if (_ismbblead(*lpszCommandLine)) { if (lpszCommandLine) { lpszCommandLine++; } } #endif /* _MBCS */ ++lpszCommandLine; } /* * Skip past any white space preceeding the second token. */ while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) { lpszCommandLine++; } #ifdef WPRFLAG mainret = wWinMain( #else /* WPRFLAG */ mainret = WinMain( #endif /* WPRFLAG */ (HINSTANCE)&__ImageBase, NULL, lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT ); #else /* _WINMAIN_ */ #ifdef WPRFLAG __winitenv = envp; mainret = wmain(argc, argv, envp); #else /* WPRFLAG */ __initenv = envp; mainret = main(argc, argv, envp); #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ /* * Note that if the exe is managed app, we don't really need to * call exit or _c_exit. .cctor should be able to take care of * this. */ if (!managedapp) exit(mainret); if (has_cctor == 0) _cexit(); } __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) { /* * Should never reach here */ mainret = GetExceptionCode(); /* * Note that if the exe is managed app, we don't really need to * call exit or _c_exit. .cctor should be able to take care of * this. */ if (!managedapp) { _exit(mainret); } if (has_cctor == 0) { _cexit(); } } /* end of try - except */ return mainret; }