setup.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 463 行
C
463 行
/****************************************************************************
*
* 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 program mainline.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <string.h>
#include <unistd.h>
#include "gui.h"
#include "setup.h"
#include "setupinf.h"
#include "setupio.h"
#include "gendlg.h"
#include "genvbl.h"
#include "utils.h"
#ifdef PATCH
extern void InitIO( void ); /* fns. from wpack */
extern void FiniIO( void ); /* fns. from wpack */
extern void SetupTextTable( void );
#endif
extern void DoSpawn( when_time );
extern void SetupTitle();
extern void DeleteObsoleteFiles();
extern void ResetDiskInfo(void);
#ifdef PATCH
int IsPatch = 0;
#endif
extern int SkipDialogs;
extern bool CancelSetup;
extern vhandle UnInstall;
typedef enum {
Stack_Push,
Stack_Pop,
Stack_IsEmpty } DIR_PARAM_STACK_OPS;
static bool SetupOperations()
/***************************/
{
bool ok;
bool uninstall;
ok = ok;
// are we doing an UnInstall?
uninstall = VarGetIntVal( UnInstall );
if( GetVariableIntVal( "IsUpgrade" ) == 1 ) {
if( !CheckUpgrade() ) {
return( FALSE );
}
}
DoSpawn( WHEN_BEFORE );
#ifdef PATCH
if( GetVariableIntVal( "Patch" ) == 1 ) {
IsPatch = 1;
if( !PatchFiles() ) {
return( FALSE );
}
}
#endif
// Copy the files
if( GetVariableIntVal( "DoCopyFiles" ) == 1 ) {
if( !CopyAllFiles() ) {
return( FALSE );
}
}
DoSpawn( WHEN_AFTER );
// Modify AUTOEXEC.BAT and CONFIG.SYS
if( GetVariableIntVal( "DoModifyAuto" ) == 1 ) {
if( !ModifyStartup( uninstall ) ) {
return( FALSE );
}
}
// Create program group (folder)
if( GetVariableIntVal( "DoCreateIcons" ) == 1 ||
GetVariableIntVal( "DoCreateHelpIcons" ) == 1 ) {
if( !ModifyEnvironment( uninstall ) ) {
return( FALSE );
}
}
DoSpawn( WHEN_END );
return( TRUE );
}
#define MAX_DIAGS 20
#ifdef __WINDOWS__
bool CheckForSetup32( int argc, char **argv )
{
DWORD version = GetVersion();
int winver;
char *buff;
size_t mem_needed;
int i;
char new_exe[_MAX_PATH];
char drive[_MAX_DRIVE];
char path[_MAX_PATH];
char name[_MAX_FNAME];
char ext[_MAX_EXT];
char *os;
winver = LOBYTE( LOWORD( version ) ) * 100 + HIBYTE( LOWORD( version ) );
os = getenv( "OS" );
if( winver >= 390 || ( os != NULL && stricmp( os, "Windows_NT" ) == 0 ) ) {
_splitpath( argv[0], drive, path, name, ext );
_makepath( new_exe, drive, path, "SETUP32", ext );
mem_needed = strlen( new_exe );
for( i = 1; i < argc; i++ ) {
mem_needed += strlen( argv[ i ] ); // command line arguments
}
mem_needed += i; //spaces between arguments + terminating null
buff = malloc( mem_needed );
if( buff == NULL ) {
return( FALSE );
}
strcpy( buff, new_exe );
if( access( buff, F_OK ) == 0 ) {
for( i = 1; i < argc; i++ ) {
strcat( buff, " " );
strcat( buff, argv[ i ] );
}
WinExec( buff, SW_SHOW );
return( TRUE );
}
}
return( FALSE );
}
#endif
#if defined( __NT__ )
static bool CheckWin95Uninstall( int argc, char **argv )
{
// The Windows 95 version of setup gets installed as the
// uninstall utility. So that it can erase itself, the setup
// program gets copied to the Windows directory, and run from
// there. The version in the Windows directory gets erased by
// the WININIT program.
int len;
char buff[ 2 * _MAX_PATH ];
char drive[ _MAX_DRIVE ];
char dir[ _MAX_DIR ];
char name[ _MAX_FNAME ];
if( argc > 1 && stricmp( argv[ 1 ], "-u" ) == 0 ) {
// copy setup program to unsetup.exe in system directory
GetWindowsDirectory( buff, _MAX_PATH );
strcat( buff, "\\UnSetup.exe" );
if( DoCopyFile( argv[ 0 ], buff, FALSE ) == CFE_NOERROR ) {
// add entry to wininit.ini to erase unsetup.exe
WritePrivateProfileString( "rename", "NUL", buff, "wininit.ini" );
// setup.inf should be in same directory as setup.exe
len = strlen( buff );
buff[ len ] = ' ';
buff[ len + 1 ] = '\"';
_splitpath( argv[ 0 ], drive, dir, name, NULL );
_makepath( &buff[ len + 2 ], drive, dir, name, "inf" );
strcat( buff, "\"" );
// execute unsetup
WinExec( buff, SW_SHOW );
return( TRUE );
}
}
return( FALSE );
}
#endif
bool DirParamStack( char **inf_name,
char **tmp_path,
DIR_PARAM_STACK_OPS function)
/*************************************************/
{
// Not really a stack; stores only one "node"
static char * old_inf_name = NULL;
static char * old_tmp_path = NULL;
if( function == Stack_Push ) {
// Push values on "stack"
old_inf_name = *inf_name;
old_tmp_path = *tmp_path;
*inf_name = GUIMemAlloc( _MAX_PATH );
if( *inf_name == NULL ) {
return FALSE;
}
*tmp_path = GUIMemAlloc( _MAX_PATH );
if( *tmp_path == NULL ) {
GUIMemFree( *inf_name );
return FALSE;
}
return TRUE;
} else if( function == Stack_Pop ) {
// Pop
GUIMemFree( *inf_name );
GUIMemFree( *tmp_path );
*inf_name = old_inf_name;
*tmp_path = old_tmp_path;
old_inf_name = NULL;
old_tmp_path = NULL;
return TRUE;
} else {
// IsEmpty
return( old_inf_name == NULL );
}
}
extern bool DoMainLoop( dlg_state * state )
/*****************************************/
{
char *diag_list[MAX_DIAGS+1];
char *diags;
char *dstdir;
int dstlen;
bool got_disk_sizes = FALSE;
int i;
char newdst[_MAX_PATH];
char *next;
bool ret = FALSE;
SetupTitle();
#ifdef PATCH
// initialize decompression facility
SetupTextTable();
// InitIO();
#endif
// display initial dialog
diags = GetVariableStrVal( "DialogOrder" );
if( stricmp( diags, "" ) == 0 ) diags = "Welcome";
i = 0;
for( ;; ) {
diag_list[i] = diags;
next = strchr( diags, ',' );
if( next == NULL ) break;
*next = '\0';
diags = next + 1;
++i;
}
diag_list[i+1] = NULL;
/* process installation dialogs */
i = 0;
for( ;; ) {
if( i < 0 ) break;
if( diag_list[i] == NULL ) {
if( GetVariableIntVal( "DoCopyFiles" ) == 1 ) {
if( !CheckDrive( TRUE ) ) {
i = 0;
}
}
if( GetVariableByName( "SetupPath" ) != NO_VAR ) {
ret = TRUE;
break;
}
if( diag_list[i] == NULL ) {
StatusShow( TRUE );
ret = SetupOperations();
StatusShow( FALSE );
if( ret ) DoDialog( "Finished" );
break;
}
}
if( stricmp( diag_list[i], "GetDiskSizesHere" ) == 0 ) {
if( *state == DLG_NEXT ) {
dstdir = GetVariableStrVal( "DstDir" );
dstlen = strlen( dstdir );
if( dstlen != 0 &&
( dstdir[dstlen-1] == '\\' || dstdir[dstlen-1] == '/' ) ) {
strcpy( newdst, dstdir );
if( dstlen == 3 && dstdir[1] == ':' ) {
newdst[dstlen] = '.';
newdst[dstlen+1] = '\0';
} else {
newdst[dstlen-1] = '\0';
}
SetVariableByName( "DstDir", newdst );
}
SimSetNeedGetDiskSizes();
ResetDiskInfo();
got_disk_sizes = TRUE;
}
} else {
*state = DoDialog( diag_list[i] );
GUIWndDirty( NULL );
StatusCancelled();
}
if( *state == DLG_CAN ) {
if( MsgBox( NULL, "IDS_QUERYABORT", GUI_YES_NO ) == GUI_RET_YES ) {
CancelSetup = TRUE;
break;
}
} else if( *state == DLG_DONE ) {
CancelSetup = TRUE;
break;
}
if( got_disk_sizes ) {
if( !CheckDrive( FALSE ) ) {
break;
}
}
if( *state == DLG_SAME ) {
/* nothing */
} else if( *state == DLG_NEXT || *state == DLG_SKIP ) {
if( SkipDialogs ) {
++i;
} else {
for( ;; ) {
++i;
if( diag_list[i] == NULL ) break;
if( CheckDialog( diag_list[i] ) ) break;
}
}
} else if( *state == DLG_PREV ) {
for( ;; ) {
--i;
if( i < 0 ) break;
if( CheckDialog( diag_list[i] ) ) break;
}
} else if( *state == DLG_START ) {
i = 0;
}
} /* for */
return ret;
}
extern void GUImain( void )
/*************************/
{
int argc = 0;
char **argv = NULL;
char *dir;
char *drive;
char *inf_name;
char *tmp_path;
char *arc_name;
char *new_inf;
char current_dir[ _MAX_PATH ];
bool ret = FALSE;
dlg_state state;
GUIMemOpen();
GUIGetArgs( &argv, &argc );
#if defined( __NT__ )
if( CheckWin95Uninstall( argc, argv ) ) return;
#endif
#ifdef __WINDOWS__
if( CheckForSetup32( argc, argv ) ) return;
#endif
// initialize paths and env. vbls.
if( !GetDirParams( argc, argv, &inf_name, &tmp_path, &arc_name ) ) return;
if( !SetupInit() ) return;
GUIDrainEvents(); // push things along
FileInit( arc_name );
#ifdef PATCH
InitIO();
#endif
InitGlobalVarList();
strcpy( current_dir, tmp_path );
while( InitInfo( inf_name, tmp_path ) ) {
ret = DoMainLoop( &state );
if( state == DLG_DONE ) break;
// if( CancelSetup == TRUE || !ret ) break;
if( CancelSetup == TRUE ) break;
// if( !ret ) break;
// look for another SETUP.INF
if( GetVariableByName( "SetupPath" ) == NO_VAR ) {
if( DirParamStack( &inf_name, &tmp_path, Stack_IsEmpty ) == FALSE ) { // "IsEmpty"?
DirParamStack( &inf_name, &tmp_path, Stack_Pop ); // "Pop"
CloseDownMessage( ret );
CancelSetup = FALSE;
ret = TRUE;
} else {
CloseDownMessage( ret );
break;
}
} else {
if( GetVariableIntVal( "IsMultiInstall" ) ) {
// push current script on stack
DirParamStack( &inf_name, &tmp_path, Stack_Push ); // "Push"
}
new_inf = GUIMemAlloc( _MAX_PATH );
drive = GUIMemAlloc( _MAX_DRIVE );
dir = GUIMemAlloc( _MAX_PATH );
if( new_inf == NULL || drive == NULL || dir == NULL ) {
GUIMemFree( new_inf );
GUIMemFree( drive );
GUIMemFree( dir );
break;
}
// construct new path relative to previous
ReplaceVars( new_inf, GetVariableStrVal( "SetupPath" ) );
_splitpath( current_dir, drive, dir, NULL, NULL );
_makepath( inf_name, drive, dir, new_inf, NULL );
_splitpath( inf_name, drive, dir, NULL, NULL );
_makepath( tmp_path, drive, dir, NULL, NULL );
// strcpy( current_dir, tmp_path );
GUIMemFree( new_inf );
GUIMemFree( drive );
GUIMemFree( dir );
} /* if */
FreeGlobalVarList( FALSE );
FreeDefaultDialogs();
FreeAllStructs();
ConfigModified = FALSE;
} /* while */
#ifdef PATCH
FiniIO();
#endif
FileFini();
FreeGlobalVarList( TRUE );
FreeDefaultDialogs();
FreeAllStructs();
FreeDirParams( &inf_name, &tmp_path );
CloseDownProgram();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?