⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setver.c

📁 DOS 源代码 系列之 command 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
;/*
; *                      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 + -