📄 setver.c
字号:
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
/***************************************************************************/
/* SETVER.C */
/* */
/* This module contains the functions which read in the version table */
/* from MSDOS.SYS and then updates the table with new entries and */
/* writes it back to the file. */
/* */
/* The fake version table is located in the DOS system file and it's */
/* location and length are specified with 2 words at offset 7 in the */
/* file. The first word is the table offset and second word is length. */
/* */
/* Table layout: */
/* */
/* ENTRY FILENAME LEN: Length of filename in bytes 1 byte */
/* ENTRY FILENAME: Variable length to 12 bytes ? bytes */
/* ENTRY VERSION MAJOR: Dos major version to return 1 byte */
/* ENTRY VERSION MINOR: Dos minor version to return 1 byte */
/* */
/* */
/* USEAGE: */
/* List table: SETVER [D:] */
/* Add entry: SETVER [D:] name.ext X.XX */
/* Delete entry: SETVER [D:] name.ext /DELETE */
/* Delete entry quietly: SETVER [D:] name.ext /DELETE /QUIET */
/* Display help SETVER /? */
/* */
/* WHERE: */
/* D: is the drive containing MSDOS.SYS */
/* name.ext is the executable file name */
/* X.XX is the major and minor version numbers */
/* */
/* RETURN CODES: */
/* 0 Successful completion */
/* 1 Invalid switch */
/* 2 Invalid file name */
/* 3 Insuffient memory */
/* 4 Invalid version number format */
/* 5 Entry not found in the table */
/* 6 MSDOS.SYS file not found */
/* 7 Invalid MSDOS.SYS or IBMDOS.SYS file */
/* 8 Invalid drive specifier */
/* 9 Too many command line parameters */
/* 10 DOS version was not specified */
/* 11 Missing parameter */
/* 12 Error reading MS-DOS system file */
/* 13 Version table is corrupt */
/* 14 Specifed file does not support a version table */
/* 15 Insuffient space in version table for new entry */
/* 16 Error writing MS-DOS system file */
/* */
/* johnhe 05-01-90 */
/***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <setver.h>
#include <message.h>
/***************************************************************************/
static char *ReadBuffer;
static char *LieBuffer; /* Buffer to read lietable into */
static char *EndBuf; /* Ptr to end of the buffer */
struct ExeHeader ExeHdr;
struct DevHeader DevHdr;
struct TableEntry Entry;
static char *szSetVer = "SETVERXX";
long FileOffset;
/* static UINT TableLen; */
/***************************************************************************/
/* Program entry point. Parses the command line and if it's valid executes */
/* the requested function and then returns the proper error code. Any */
/* error codes returned by ParseCommand are negative so they must be */
/* converted with a negate before being returned as valid error codes. */
/* */
/* int main( int argc, char *argv[] ) */
/* */
/* ARGUMENTS: argc - Count of command line arguments */
/* argv - Array of ptrs to argument strings */
/* RETURNS: int - Valid return code for batch processing */
/* */
/***************************************************************************/
int main( int argc, char *argv[] )
{
register iFunc;
char szError[ 80 ];
iFunc = ParseCmd( argc, argv, &Entry );
if ( iFunc >= 0 )
iFunc = DoFunction( iFunc );
if ( iFunc != S_OK )
{
iFunc = -(iFunc);
strcpy( szError, ErrorMsg[ 0 ] );
strcat( szError, ErrorMsg[ iFunc ] );
PutStr( szError );
PutStr( szMiniHelp );
}
return( iFunc );
}
/***************************************************************************/
/* Calls the appropriate function to do whatever was specified by the */
/* user. The lie table if first read in except in the case only the help */
/* function was requested. To be sure duplicate table entries are not */
/* created a call to DeleteEntry with the new program name will be done */
/* before the new entry is created. */
/* */
/* int DoFunction( int iFunc ) */
/* */
/* ARGUMENTS: iFunct - The function to be performed */
/* RETURNS: int - S_OK if no errors else an error code */
/* */
/***************************************************************************/
int DoFunction( int iFunc )
{
register iStatus;
if ( iFunc == DO_HELP )
{
DisplayMsg( Help );
return( S_OK );
}
if ( iFunc == DO_ADD_FILE )
DisplayMsg( Warn ); /* Read in the lie table and */
/* then decide what to do */
if ( (iStatus = ReadVersionTable()) == S_OK )
{
if ( iFunc == DO_LIST )
iStatus = DisplayTable();
else
{
if ( (iFunc == DO_DELETE || iFunc == DO_QUIET) &&
(iStatus = MatchFile( LieBuffer, Entry.szFileName )) < S_OK )
return( iStatus );
/* Always a delete before add */
if ( (iStatus = DeleteEntry()) == S_OK && iFunc == DO_ADD_FILE )
iStatus = AddEntry();
if ( iStatus == S_OK &&
(iStatus = WriteVersionTable()) == S_OK &&
!(iFunc == DO_QUIET) )
{
PutStr( SuccessMsg );
if ( SetVerCheck() == TRUE ) /* M001 */
PutStr( SuccessMsg2 );
}
}
}
/* M001 Install check to see if currently in device chain */
if ( iStatus == S_OK && iFunc != DO_QUIET && SetVerCheck() == FALSE )
DisplayMsg( szNoLoadMsg );
return( iStatus );
}
/***************************************************************************/
/* Displays the help text for "/?" option, or the warning text. */
/* */
/* void DisplayHelp( tbl ) */
/* */
/* ARGUMENTS: char *tbl[] */
/* RETURNS: void */
/* */
/***************************************************************************/
void DisplayMsg( char *tbl[] )
{
register i;
for ( i = 0; tbl[i] != NULL; i++ )
PutStr( tbl[ i ] );
}
/***************************************************************************/
/* Displays all entries in the version table which must have already been */
/* read into the work buffer. The name and version number are created as */
/* as ascii string in a tempory buffer and then printed as a single string */
/* in the format: */
/* */
/* 1234567890123456789 */
/* FILENAME.EXT X.XX */
/* */
/* int DisplayTable( void ) */
/* */
/* ARGUMENTS: void */
/* RETURNS: int - S_CORRUPT_TABLE if table corrupt else S_OK */
/* */
/***************************************************************************/
int DisplayTable( void )
{
char *BufPtr;
char *szTmp;
char *szVersion;
char szEntry[ 50 ];
BufPtr = LieBuffer;
szVersion = szEntry + VERSION_COLUMN;
PutStr( "" );
while ( *BufPtr != 0 && BufPtr < EndBuf )
{
/* Chk for table corruption */
if ( !IsValidEntry( BufPtr ) )
return( S_CORRUPT_TABLE );
/* Copy file name and pad with spaces */
strncpy( szEntry, BufPtr+1, (unsigned)((int)*BufPtr) );
for ( szTmp = szEntry + *BufPtr; szTmp < szVersion; szTmp++ )
*szTmp = ' ';
/* Point to version number */
BufPtr += *BufPtr;
BufPtr++;
/* Now create ascii version */
itoa( (int)*(BufPtr++), szVersion, DECIMAL );
strcat( szVersion, (int)*BufPtr < 10 ? ".0" : "." );
itoa( (int)*(BufPtr++), strchr( szVersion, EOL ), DECIMAL );
PutStr( szEntry );
}
if ( BufPtr == LieBuffer )
PutStr( szTableEmpty );
return( S_OK );
}
/***************************************************************************/
/* Deletes all matching entries in the version table by moving all of the */
/* entries following the matched entry down in the buffer to replace the */
/* entry being deleted. After the entries are moved down the residuals */
/* at the end of the table must be zeroed out. Before returning the entire */
/* end of the table buffer after the valid entries is zeroed out to remove */
/* any possible corruption. */
/* */
/* int DeleteEntry( void ) */
/* */
/* ARGUMENTS: NONE */
/* RETURNS: int - S_CORRUPT_TABLE if errors found else S_OK */
/* */
/***************************************************************************/
int DeleteEntry( void )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -