utils.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,074 行 · 第 1/5 页

C
2,074
字号
/****************************************************************************
*
*                            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:  Setup utility functions.
*
****************************************************************************/


#if !defined( __UNIX__ )
    #include <dos.h>
    #include <direct.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <utime.h>
#include <fcntl.h>
#include <ctype.h>
#include <setjmp.h>
#include <limits.h>
#include <process.h>
#include "gui.h"
#include "text.h"
#include "setupinf.h"
#include "setup.h"
#include "genvbl.h"
#include "gendlg.h"
#include "guiutil.h"
#include "utils.h"
#include "setupio.h"
#include "wpack.h"

#include "errno.h"

typedef struct def_var {
    char                *variable;
    char                *value;
    struct def_var      *link;
} DEF_VAR;

extern void     BumpStatus( long );

extern int      ReadInternal( char * );

bool            ConfigModified = FALSE;
static enum { SRC_UNKNOWN, SRC_CD, SRC_DISK } SrcInstState;

extern bool     CancelSetup;
extern vhandle  UnInstall;
extern vhandle  PreviousInstall;
int             SkipDialogs;
char            *VariablesFile;
DEF_VAR         *ExtraVariables;
int             Invisible;

#ifdef PATCH
extern int      InitIO( void );
extern int      Decode( arccmd *);

static int      DecodeError;
extern int      IsPatch;
#endif

extern bool ModifyEnvironment( bool uninstall )
/*********************************************/
{
    bool                ret;

    ret = TRUE;
#ifdef _UI
    uninstall = uninstall;
#else
    ret = CreatePMInfo( uninstall );
    if( !ret ) {                   // create folder and icons
        gui_message_return  gui_ret;

        if( VarGetIntVal( UnInstall ) != 0 ) {
            gui_ret = MsgBox( NULL, "IDS_PMREMNOGOOD", GUI_YES_NO );
        } else {
            gui_ret = MsgBox( NULL, "IDS_PMADDNOGOOD", GUI_YES_NO );
        }
        if( gui_ret == GUI_RET_YES ) {
            ret = TRUE;
        }
    }
#endif
    return( ret );
}

extern bool ModifyStartup( bool uninstall )
/*****************************************/
{
    bool                ret;

#if !defined( _UI )
    WriteProfileStrings( uninstall );  // will write to the win.ini file.
#endif

//    if( !uninstall ) {
#if defined( __NT__ )
#ifndef __AXP__
    if( GetVariableIntVal( "IsWin95" ) != 0 ) {
        ret = ModifyAutoExec();
    } else {
#endif
        ret = ModifyConfiguration();
#ifndef __AXP__
    }
#endif
#else
    ret = ModifyAutoExec();
#endif
//    }
    return( ret );
}

typedef struct {
    unsigned long long  free_space;
    unsigned long       cluster_size;
    unsigned            use_target_for_tmp_file : 1;
    unsigned            fixed : 1;
    unsigned            diskette : 1;
} drive_info;

static drive_info       Drives[32];

#if defined( __DOS__ )

int __far critical_error_handler( unsigned deverr,
                  unsigned errcode,
                  unsigned far *devhdr )
{
    deverr=deverr;errcode=errcode;devhdr=devhdr;
    return( _HARDERR_FAIL );
}

#endif

typedef __far (HANDLER)( unsigned deverr,
                  unsigned errcode,
                  unsigned far *devhdr );
static void NoHardErrors()
{
#if defined( __OS2__ )
    DosError( FERR_DISABLEHARDERR );
#elif defined( __DOS__ )
    _harderr( (HANDLER *)critical_error_handler );
#elif defined( __WINDOWS__ ) || defined( __NT__ )
    SetErrorMode( SEM_FAILCRITICALERRORS );
#endif
}

#ifdef __NT__
bool NTSpawnWait( char *cmd, DWORD *exit_code, HANDLE in, HANDLE out, HANDLE err )
{
    STARTUPINFO             start;
    PROCESS_INFORMATION      info;

    memset( &start, 0, sizeof( start ) );
    start.cb = sizeof( start );
    start.hStdInput = in;
    start.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
    start.hStdError = GetStdHandle( STD_ERROR_HANDLE );
    if( in || out || err ) {
        start.dwFlags = STARTF_USESTDHANDLES;
    }
    if( cmd[ 0 ] == '-' ) {
        cmd++;
        start.wShowWindow = FALSE;
        start.dwFlags |= STARTF_USESHOWWINDOW;
    }
    if( !CreateProcess( NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP+CREATE_NEW_CONSOLE,
            NULL, NULL, &start, &info ) ) {
        return( FALSE );
    } else {
        WaitForSingleObject( info.hProcess, INFINITE );
        while( !GetExitCodeProcess( info.hProcess, exit_code ) ||
            *exit_code == STILL_ACTIVE ) {
            if( StatusCancelled() )
                return( FALSE );
        }
    }
    CloseHandle( info.hProcess );
    CloseHandle( info.hThread );
    return( TRUE );
}
#endif

#ifdef __WINDOWS__
#include "toolhelp.h"
static bool WinSpawnWait( char *cmd )
{
    struct {
        WORD        segEnv;
        LPCSTR      lpzCmdLine;
        UINT FAR *lpShow;
        UINT FAR *lpReserved;
    } parm;
    UINT        show[2];
    HINSTANCE   inst;
    HINSTANCE   toolhelp;
    BOOL WINAPI (*taskfirst)(TASKENTRY FAR *);
    BOOL WINAPI (*tasknext)(TASKENTRY FAR *);
    TASKENTRY   task;
    BOOL        stillthere;
    BOOL        ok;
    char        buff[_MAX_PATH];

    show[0] = 2;
    show[1] = SW_SHOW;
    memset( &parm, 0, sizeof( parm ) );
    parm.lpzCmdLine = "";
    parm.lpShow = show;
    inst = LoadModule( cmd, &parm );
    if( inst < HINSTANCE_ERROR ) return( FALSE );
    ReplaceVars( buff, "%ToolHelp%" );
    if( buff[0] == '\0' ) return( FALSE );
    toolhelp = LoadModule( buff, &parm );
    if( toolhelp < HINSTANCE_ERROR ) return( FALSE );
    taskfirst = (BOOL WINAPI(*)(TASKENTRY FAR*))GetProcAddress( toolhelp, "TaskFirst" );
    if( taskfirst == NULL ) return( FALSE );
    tasknext = (BOOL WINAPI(*)(TASKENTRY FAR*))GetProcAddress( toolhelp, "TaskNext" );
    if( tasknext == NULL ) return( FALSE );
    task.dwSize = sizeof( task );
    do {
        stillthere = FALSE;
        ok = taskfirst( &task );
        while( ok ) {
            if( task.hInst == inst )
                stillthere = TRUE;
            ok = tasknext( &task );
            StatusCancelled(); // yield
        }
    } while( stillthere );
    return( TRUE );
}
#endif

#ifdef __OS2__
static bool OS2SpawnWait( char *cmd, int *rc )
{
    RESULTCODES res;
    PID     dummy;
    char    *p;

    p = strchr( cmd, ' ' );
    if( p != NULL )
        *p = '\0';
    if( DosExecPgm( NULL, 0, EXEC_ASYNCRESULT, cmd, NULL, &res, cmd ) != 0 )
        return( FALSE );

    if( p != NULL )
        *p = ' ';
    for( ;; ) {
        *rc = DosWaitChild( DCWA_PROCESS, DCWW_NOWAIT, &res,
                    &dummy, res.codeTerminate );
        if( *rc != ERROR_CHILD_NOT_COMPLETE ) {
            *rc = res.codeResult;
            break;
        }
        StatusCancelled();
    }
    return( TRUE );
}
#endif

static bool DoSpawnCmd( char *cmd )
{
    bool        rc;

#if defined( __WINDOWS__ )
    {
    rc = WinSpawnWait( cmd );
    }
#elif defined( __NT__ )
    {
    DWORD exit_code;
    if( NTSpawnWait( cmd, &exit_code, 0, 0, 0 ) ) {
        rc = exit_code == 0;
    } else {
        rc = FALSE;
    }
    }
#elif defined( __OS2__ )
    {
    int     code;
    OS2SpawnWait( cmd, &code );
    rc = code == 0;
    }
#elif defined( _UI )
    {
    system( cmd );
    rc = TRUE;
    }
#endif
    GUIWndDirty( NULL );
    return( rc );
}


void DoSpawn( when_time when )
{
    char buff[2*_MAX_PATH];
    int         i, num_spawns;

    num_spawns = SimNumSpawns();
    for( i = 0; i < num_spawns; ++i ) {
        if( when != SimWhen( i ) )
            continue;
        if( !SimEvalSpawnCondition( i ) )
            continue;
        SimGetSpawnCommand( buff, i );
        if( buff[0] == '\0' )
            continue;
        DoSpawnCmd( buff );
    }
}


#define TMPFILENAME "_watcom_.tmp"
static void GetTmpFileName( char drive, char *buff )
{
    buff[0] = drive;
    strcpy( buff+1, ":\\" TMPFILENAME );
}

#if defined( WINNT ) || defined( WIN )
static void GetTmpFileNameUNC( char *path, char *buff )
{
    if( path == NULL || buff == NULL ) {
        return;
    }
    if( path[ 0 ] == '\\' && path[ 1 ] == '\\' ) {
        strcpy( buff, path );
        if( buff[ strlen( buff ) - 1 ] != '\\' ) {
            strcat( buff, "\\" );
        }
        strcat( buff, TMPFILENAME );
    } else {
        buff[0] = *path;
        strcpy( buff+1, ":\\" TMPFILENAME );
    }
}
#endif

static void GetTmpFileNameInTarget( unsigned drive, char *buff )
{
    int         i;
    int         max_targets = SimNumTargets();
    int         len;

    for( i = 0; i < max_targets; ++i ) {
        SimTargetDir( i, buff );
        if( tolower( buff[0] ) == tolower( drive ) && buff[1] == ':' ) {
            len = strlen( buff );
            if( len != 0 && buff[len-1] != '\\' ) {
                strcat( buff, "\\" );
            }
            strcat( buff, TMPFILENAME );
            return;
        }
    }
    GetTmpFileName( drive, buff );
}

void ResetDriveInfo()
{
    int         i;

    for( i = 0; i < sizeof( Drives ) / sizeof( Drives[0] ); ++i ) {
        Drives[ i ].cluster_size = 0;
    }
}

static int GetDriveNum( int drive )
{
    drive = toupper( drive ) - 'A' + 1;
    if( drive < 1 || drive > 26 ) drive = 0;
        return( drive );
}

static unsigned GetDriveInfo( int drive, bool removable )
{
    drive_info  *info;
    char        drive_char = drive;

    drive = GetDriveNum( drive );
    info = &Drives[drive];
    if( ( info->cluster_size == 0 || removable /* recheck - could have been replaced */ ) ) {

⌨️ 快捷键说明

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