dopatch.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 529 行 · 第 1/2 页
C
529 行
ClosePatch();
return( PATCH_CANT_OPEN_FILE );
}
}
#ifdef BDIFF
PATCH_RET_CODE Execute( byte *dest )
{
char *tmp;
#else
PATCH_RET_CODE Execute( void )
{
char tmp[4];
#if defined(__386__)
#if defined(_WPATCH)
extern MY_FILE NewFile;
#define InNew( offset ) ( Input( &NewFile, tmp, offset, \
sizeof(hole)), \
*(hole*)tmp )
#define OutNew( off, x, type ) *(type*)tmp = (x); \
Output( &NewFile, tmp, \
off, sizeof( type ) );
#else
extern byte *NewFile;
#define OutNew( off, x, type ) *(type*)(NewFile+off) = (x);
#define InNew( off ) *(hole*)(NewFile+off)
#endif
#elif defined(BDUMP)
#define InNew( offset ) 1
#define OutNew( off, x, type ) ( x )
#undef Dump
#define Dump( x ) printf x
#undef DOPROMPT
#undef DOBACKUP
#define DOPROMPT 0
#define DOBACKUP 0
#else
extern MY_FILE NewFile;
extern void Input( MY_FILE *file, void *tmp, foff off, size_t len );
#define InNew( offset ) ( Input( &NewFile, tmp, offset, \
sizeof(hole)), \
*(hole*)tmp )
extern void Output( MY_FILE *file, void *tmp, foff off, size_t len );
#define OutNew( off, x, type ) *(type*)tmp = (x); \
Output( &NewFile, tmp, \
off, sizeof( type ) );
#endif
#endif
patch_cmd cmd;
byte next;
hole diff;
foff size;
foff incr;
foff iters;
foff old_size;
foff new_size;
foff checksum;
foff new_offset;
foff old_offset;
char ch;
int havenew;
PATCH_RET_CODE ret;
PATCH_RET_CODE ret2;
#ifdef BDIFF
char *dummy = NULL;
#endif
havenew = 1;
#ifdef BDIFF
InitPatch( &dummy );
#endif
old_size = InPatch( foff );
new_size = InPatch( foff );
checksum = InPatch( foff );
ret = OpenOld( old_size, DOPROMPT, new_size, checksum );
if( ret != PATCH_RET_OKAY ) goto error1;
ret = OpenNew( new_size );
if( ret != PATCH_RET_OKAY ) goto error2;
InitHoles();
for( ;; ) {
#if defined( INSTALL_PROGRAM )
#if defined( WINNT ) || defined( WIN ) || defined( OS2 )
if( StatusCancelled() ) {
ret = PATCH_RET_CANCEL;
goto error3;
}
#endif
#endif
cmd = InPatch( patch_cmd );
if( cmd == CMD_DONE ) break;
switch( cmd ) {
case CMD_DIFFS:
new_offset = InPatch( foff );
size = InPatch( foff );
Dump(( "Different new-%8.8lx size-%8.8lx\n", new_offset, size ));
while( size != 0 ) {
OutNew( new_offset, InPatch( byte ), byte );
++new_offset;
--size;
}
break;
case CMD_SAMES:
new_offset = InPatch( foff );
old_offset = InPatch( foff );
size = InPatch( foff );
Dump(( "Similar new-%8.8lx old-%8.8lx size-%8.8lx\n",
new_offset, old_offset, size));
while( size != 0 ) {
OutNew( new_offset, InOld( old_offset ), byte );
++new_offset;
++old_offset;
--size;
}
break;
case CMD_ITER_HOLES:
new_offset = InPatch( foff );
diff = InPatch( hole );
iters = InPatch( foff );
incr = InPatch( foff );
ch = InPatch( byte );
Dump(( "IterHole new-%8.8lx diff-%8.8lx iter-%8.8lx inc-%8.8lx\n",
new_offset, diff, iters, incr ));
while( iters != 0 ) {
AddHole( new_offset, diff );
new_offset += incr;
--iters;
}
break;
case CMD_HOLES:
new_offset = InPatch( foff );
diff = InPatch( hole );
for( ;; ) {
Dump(( "Hole new-%8.8lx diff-%8.8lx\n",new_offset,diff));
AddHole( new_offset, diff );
next = InPatch( byte );
if( next == 0 ) break;
if( ( next & 0x80 ) == 0 ) {
new_offset += (foff)next & 0x7f;
} else if( ( next & 0x40 ) == 0 ) {
new_offset += ( (foff)next & 0x3f ) << 8;
new_offset += (foff)InPatch( byte );
} else {
new_offset += ( (foff)next & 0x3f ) << 16;
new_offset += (foff)InPatch(byte) << 8;
new_offset += (foff)InPatch(byte);
}
}
break;
default:
PatchError( ERR_BAD_PATCHFILE, PatchName );
ret = PATCH_BAD_PATCH_FILE;
goto error3;
}
}
ret = PATCH_RET_OKAY;
FlushHoles();
error3:
FreeHoleArray();
ret2 = CloseNew( new_size, checksum, &havenew );
if( ret == PATCH_RET_OKAY ) {
ret = ret2;
}
error2:
CloseOld( havenew && DOPROMPT, DOBACKUP );
error1:
ClosePatch();
return( ret );
}
#if !defined( BDIFF )
extern PATCH_RET_CODE DoPatch( char *patchname,
int doprompt,
int dobackup,
int printlevel,
char *outfilename )
{
char buffer[ sizeof( LEVEL ) ];
#ifndef _WPATCH
char *target = NULL;
#endif
PATCH_RET_CODE ret;
outfilename=outfilename;
PatchName = patchname;
DoPrompt = doprompt;
DoBackup = dobackup;
PrintLevel = printlevel;
NewName = tmpnam( NULL );
#ifndef _WPATCH
if( access( PatchName, R_OK ) != 0 ) {
PatchError( ERR_CANT_FIND, PatchName );
return( PATCH_CANT_FIND_PATCH );
}
#endif
#if !defined( INSTALL_PROGRAM )
if( PrintLevel ) {
GetLevel( PatchName );
if( CurrLevel[ 0 ] == '\0' ) {
Message( MSG_NOT_PATCHED, PatchName );
} else {
Message( MSG_PATCHED_TO_LEVEL, PatchName, CurrLevel );
}
return( PATCH_RET_OKAY );
}
#endif
_splitpath( PatchName, NULL, NULL, NULL, buffer );
#ifndef _WPATCH
ret = InitPatch( &target );
#else
ret = InitPatch( &outfilename );
#endif
#if defined( INSTALL_PROGRAM )
if( ret != PATCH_RET_OKAY ) {
return( ret );
}
if( outfilename != NULL ) {
strcpy( outfilename, target );
PatchingFile( PatchName, outfilename );
}
#endif
#ifndef _WPATCH
GetLevel( target );
if( stricmp( buffer, CurrLevel ) <= 0 ) {
ClosePatch();
#if !defined( INSTALL_PROGRAM )
Message( MSG_ALREADY_PATCHED, target, CurrLevel );
#endif
return( PATCH_ALREADY_PATCHED );
} else {
#endif
ret = Execute();
if( ret != PATCH_RET_OKAY ) {
return( ret );
}
#ifndef _WPATCH
}
#endif
#if !defined( INSTALL_PROGRAM ) && !defined( _WPATCH )
Message( MSG_SUCCESSFULLY_PATCHED, target, buffer );
#endif
return( PATCH_RET_OKAY );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?