Exemple #1
0
/*********************************************************************
 *		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;
}
Exemple #2
0
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);

}
Exemple #3
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 */
}
Exemple #4
0
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;
}
Exemple #5
0
void __cdecl _heap_abort (
	void
	)
{
	_amsg_exit(_RT_HEAP);		/* heap error */
	/*** PROCESS TERMINATED ***/
}
Exemple #6
0
_ptiddata __cdecl _getptd (
        void
        )
{
        _ptiddata ptd = _getptd_noexit();
        if (!ptd) {
            _amsg_exit(_RT_THREAD); /* write message and die */
        }
        return ptd;
}
Exemple #7
0
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;
}
Exemple #8
0
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]();
			}
Exemple #9
0
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;
            }
        }
}
Exemple #10
0
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);
}
Exemple #11
0
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] );

}
Exemple #12
0
__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;
}
Exemple #13
0
// address: 0x4126d0
int main(int argc, char *argv[], char *envp[]) {
    __size32 eax; 		// r24

    eax = _amsg_exit();
    return eax;
}
Exemple #14
0
/***
*_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 */
}
Exemple #15
0
// 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;
}
Exemple #16
0
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;
}
Exemple #17
0
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);
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
/*
 * 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_ */
}
Exemple #22
0
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;
}