mainwnt.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 262 行

C
262
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Win32 main routines for executables and DLLs.
*
****************************************************************************/


#include "variety.h"
#include <windows.h>

#include <stdio.h>
#include <io.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef _M_IX86
 #include <i86.h>
#endif

#include "iomode.h"
#include "strdup.h"
#include "liballoc.h"
#include "libwin32.h"
#include "stacklow.h"
#include "sigtab.h"
#include "ntex.h"
#include "rtdata.h"
#include "initfini.h"
#include "rtinit.h"
#include "widechar.h"
#include "initarg.h"

DWORD __TlsIndex = NO_INDEX;

_WCRTLINK int *__threadid( void )
{
    return( (int *) &(__THREADDATAPTR->thread_id) );
}

thread_data             *__FirstThreadData = NULL;

static struct thread_data *__SingleThread()
{
    return( __FirstThreadData );
}

static void __NullAccessRtn( int handle )
{
    handle = handle;
}

static void __NullExitRtn() {}

static void __NullAccIOBRtn(void) {}
static void __NullAccHeapRtn(void) {}
static void __NullAccTDListRtn(void) {}

_WCRTDATA struct thread_data    *(*__GetThreadPtr)() = &__SingleThread;
void    (*_AccessFileH)(int)     = &__NullAccessRtn;
void    (*_ReleaseFileH)(int)    = &__NullAccessRtn;
void    (*_AccessIOB)(void)      = &__NullAccIOBRtn;
void    (*_ReleaseIOB)(void)     = &__NullAccIOBRtn;
void    (*_AccessNHeap)(void)    = &__NullAccHeapRtn;
void    (*_AccessFHeap)(void)    = &__NullAccHeapRtn;
void    (*_ReleaseNHeap)(void)   = &__NullAccHeapRtn;
void    (*_ReleaseFHeap)(void)   = &__NullAccHeapRtn;
void    (*_AccessTDList)(void)   = &__NullAccTDListRtn;
void    (*_ReleaseTDList)(void)  = &__NullAccTDListRtn;
void    (*_AccessFList)(void)    = &__NullAccIOBRtn;
void    (*_ReleaseFList)(void)   = &__NullAccIOBRtn;
void    (*_ThreadExitRtn)(void)  = &__NullExitRtn;

void __sig_null_rtn(void) {}
_WCRTLINK void  (*__sig_init_rtn)(void) = __sig_null_rtn;
_WCRTLINK void  (*__sig_fini_rtn)(void) = __sig_null_rtn;

#ifdef _M_IX86
 #pragma aux _end "*"
#endif
extern  char            _end;

extern  char            *_Envptr;

int                     __Is_DLL;       /* TRUE => DLL, else not a DLL */
static char             *_cmd_ptr;
static wchar_t          *_wcmd_ptr;

// called once at DLL_PROCESS_ATTACH or by __NTMainInit

int __NTInit( int is_dll, thread_data *tdata, HANDLE hdll )
{
    DWORD       ver;
    WORD        os_ver;

    __Is_DLL = is_dll;                                  /* 15-feb-93 */
    // tdata is guaranteed to never be NULL. If starting up for an EXE,
    // it's pointing on the stack (alloca). If this is run on behalf of
    // a DLL startup, it's already NULL checked by the caller.
    __FirstThreadData = tdata;
    __initPOSIXHandles();

    _Envptr = GetEnvironmentStrings();

    /*
     * Force reference to environ so that __setenvp is linked in; hence,
     * __ParsePosixHandleStr will be called.
     */
    environ = NULL;

    ver = GetVersion();
    os_ver = LOWORD( ver );
    _RWD_osmajor = os_ver & 0xff;
    _RWD_osminor = (os_ver >> 8) & 0xff;
    _RWD_osbuild = HIWORD( ver );
    _RWD_osver = _RWD_osbuild;
    _RWD_winmajor = _RWD_osmajor;
    _RWD_winminor = _RWD_osminor;
    _RWD_winver = (_RWD_winmajor << 8) | _RWD_winminor;

    {
        static char     fn[_MAX_PATH];
        GetModuleFileNameA( NULL, fn, sizeof( fn ) );
        _LpPgmName = fn;
    }
    {
        static wchar_t  wfn[_MAX_PATH];
        __lib_GetModuleFileNameW( NULL, wfn, sizeof( wfn ) );
        _LpwPgmName = wfn;
    }

    {
        char    *cmd;
        _cmd_ptr = cmd = __clib_strdup( GetCommandLineA() );
        if( *cmd == '"' ) {
            cmd++;
            while( *cmd != '"' && *cmd != 0 ) {
                cmd++;
            }
            if( *cmd ) cmd++;
        } else {
            while( !isspace( *cmd ) && *cmd != 0 ) {
                cmd++;
            }
        }
        while( isspace( *cmd ) ) {
            cmd++;
        }
        _LpCmdLine = cmd;
    }
    {
        wchar_t *wcmd;
        wcmd = GetCommandLineW();       /* Win95 supports GetCommandLineW */
        if( wcmd ) {
            _wcmd_ptr = wcmd = __clib_wcsdup( wcmd );
            if( *wcmd == '"' ) {
                wcmd++;
                while( *wcmd != '"' && *wcmd != 0 ) {
                    wcmd++;
                }
                if( *wcmd ) wcmd++;
            } else {
                while( !isspace( *wcmd ) && *wcmd != 0 ) {
                    wcmd++;
                }
            }
            while( isspace( *wcmd ) ) {
                wcmd++;
            }
        } else {
            wcmd = L"";
        }
        _LpwCmdLine = wcmd;
    }

    if( is_dll ) {
        {
            static char    fn[_MAX_PATH];
            GetModuleFileNameA( hdll, fn, sizeof( fn ) );
            _LpDllName = fn;
        }
        {
            static wchar_t wfn[_MAX_PATH];
            __lib_GetModuleFileNameW( hdll, wfn, sizeof( wfn ) );
            _LpwDllName = wfn;
        }
    }

    return( TRUE );
}

void __NTFini( void )
{
    // calls to free memory have to be done before semaphores closed
    if( _cmd_ptr ) {
        lib_free( _cmd_ptr );
        _cmd_ptr = NULL;
    }
    if( _wcmd_ptr ) {
        lib_free( _wcmd_ptr );
        _wcmd_ptr = NULL;
    }
    if( _Envptr != NULL ) {
        FreeEnvironmentStrings( _Envptr );
        _Envptr = NULL;
    }
}

void __NTMainInit( REGISTRATION_RECORD *rr, thread_data *tdata )
{
    __DefaultExceptionHandler();
    __NTInit( FALSE, tdata, GetModuleHandle(NULL) );
    __init_stack_limits( &_STACKLOW, &_STACKTOP );
    __NewExceptionFilter( rr );
    __InitRtns( INIT_PRIORITY_LIBRARY+1 );
    __sig_init_rtn();
    __InitRtns( 255 );
}

_WCRTLINK void (*__process_fini)(unsigned,unsigned) = 0;

_WCRTLINK void __exit( unsigned ret_code )
{
    __NTFini(); // must be done before following finalizers get called
    if( __Is_DLL ) {
        if( __process_fini != 0 ) {
            (*__process_fini)( 0, FINI_PRIORITY_EXIT-1 );
        }
    } else {
        __DoneExceptionFilter();
        __FiniRtns( 0, FINI_PRIORITY_EXIT-1 );
        (*_ThreadExitRtn)();
    }
    // Also gets done by __FreeThreadDataList which is activated from FiniSema4s
    // for multi-threaded apps
    __FirstThreadData = NULL;
    ExitProcess( ret_code );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?