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

📄 setver.c

📁 DOS 源代码 系列之 command 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	char		*pchPtr;
	char		*pchTmp;
	int		iOffset;
	UINT		uEntryLen;
	UINT		uBlockLen;

	pchPtr = LieBuffer;

	while ( (iOffset = MatchFile( pchPtr, Entry.szFileName )) >= 0 )
	{
		pchPtr = LieBuffer + iOffset;						/* Move block down		*/
		uEntryLen = (UINT)((int)*pchPtr) + 3;
		uBlockLen = (UINT)(EndBuf - pchPtr) + uEntryLen;
		memmove( pchPtr, pchPtr + uEntryLen, uBlockLen );

		pchTmp = pchPtr + uBlockLen;			 			/* Clean end of blk		*/
		memset( pchTmp, 0, uEntryLen );
	}

	if ( iOffset == S_ENTRY_NOT_FOUND )		 			/* Clean end of table	*/
	{
		if ( (pchTmp = GetNextFree()) != NULL )
			memset( pchTmp, 0, DevHdr.TblLen - (unsigned)(pchTmp - LieBuffer) );
		return( S_OK );
	}
	else
		return( S_CORRUPT_TABLE );
}


/***************************************************************************/
/* Adds a new entry to the end of any existing entries in the version		*/
/* table. There must be suffient room in the table for the entry or the	 	*/
/* call will fail with a S_NO_ROOM error returned.									*/
/*																									*/
/*	int AddEntry( void )																		*/
/*																									*/
/*	ARGUMENTS:	NONE																			*/
/*	RETURNS:		int	- S_OK if room for entry else S_NO_ROOM		 			*/
/*																									*/
/***************************************************************************/

int AddEntry( void )
{
	register		iLen;
	char			*pchNext;

	iLen = (int)strlen( Entry.szFileName ) + 3;

	if ( (pchNext = GetNextFree()) != NULL && iLen <= EndBuf - pchNext )
	{
		*pchNext = (char)(iLen - 3);
		strcpy( pchNext + 1, Entry.szFileName );
		pchNext += (int)(*pchNext) + 1;
		*(pchNext++) = (char)Entry.MajorVer;
		*pchNext = (char)Entry.MinorVer;
		return( S_OK );
	}
	else
		return( S_NO_ROOM );
}


/***************************************************************************/
/* Returns the offset of a specified name in the version table. The start	*/
/* of the search is specified by the caller so that searches for duplicate */
/* entries can be made without redundency. NOTE: file name entries in the	*/
/* version table are not zero terminated strings so the comparision must	*/
/* be conditioned by length and the search strings length must be checked	*/
/* to avoid an error caused by a match of a shorter table entry name.		*/
/*																								 	*/
/*	int MatchFile( char *pchStart, char *szFile )							 		*/
/*																								 	*/
/*	ARGUMENTS:	pchStart - Ptr specifying search starting point	 				*/
/*					szFile	- Ptr to file name to match								*/		
/*	RETURNS:		int		- Offset of entry from start of version				*/
/*								  buffer or -1 if not match or							*/
/*								  S_CORRUPT_TABLE if error					 				*/
/*																								 	*/
/***************************************************************************/

int MatchFile( char *pchPtr, char *szFile )
{
	for ( ; pchPtr < EndBuf && *pchPtr != 0; pchPtr += *pchPtr + 3 )
	{
		if ( !IsValidEntry( pchPtr ) )						/* Corruption check	*/
			return( S_CORRUPT_TABLE );
		else if ( strncmp( szFile, pchPtr + 1, (UINT)((int)*pchPtr) ) == S_OK &&
					 *(szFile + *pchPtr) == EOL )
			return( pchPtr - LieBuffer );						/* Return ptr offset */
	}
	return( S_ENTRY_NOT_FOUND );								/* Return no match	*/
}

/***************************************************************************/
/* Checks a version table entry to see if it a valid entry. The definition */
/* of a valid entry is one which has a file length less than MAX_NAME_LEN	*/
/* and the entire entry lies within the version table.							*/
/*																								 	*/
/*	int IsValidEntry( char *pchPtr )														*/
/*																								 	*/
/*	ARGUMENTS:	pchPtr - Ptr to version tbl entry in table buffer				*/
/*	RETURNS:		int	 - TRUE if entry is valid else FALSE						*/
/*																								 	*/
/***************************************************************************/

int IsValidEntry( char *pchPtr )
{
	if ( (int)*pchPtr < MAX_NAME_LEN && (pchPtr + (int)*pchPtr + 3) < EndBuf )
		return( TRUE );
	else
		return( FALSE );
}


/***************************************************************************/
/* Returns a pointer to the next free entry in the version table. If there */
/* are no free entries left in the buffer a NULL ptr will be returned.		*/
/* Since DeleteEntry is always called before AddEntry there is no check	 	*/
/* for table corruption since it will have already been done by the			*/
/* DeleteEntry call.																		 	*/
/*																								 	*/
/*	char *GetNextFree( void )																*/
/*																								 	*/
/*	ARGUMENTS:	NONE																			*/
/*	RETURNS:		char*	- Ptr to next free entry or NULL if tbl full 			*/
/*																								 	*/
/* NOTE: This caller of this function must check to be sure any entry any	*/
/*			entry to be added at the ptr returned will fit in the remaining	*/
/*			buffer area because the remaining buffer size may be less than	 	*/
/*			MAX_ENTRY_SIZE.																	*/
/*																								 	*/
/***************************************************************************/

char *GetNextFree( void )
{
	char		*pchPtr;

	for ( pchPtr = LieBuffer; *pchPtr != 0 && pchPtr < EndBuf;
			pchPtr += *pchPtr + 3 )
		;

	return( pchPtr < EndBuf ? pchPtr : NULL );
}

/***************************************************************************/
/* Opens the DOS system file and reads in the table offset and length		*/
/* structure. Then allocates a buffer and reads in the table.					*/
/*																									*/
/*	int ReadVersionTable( void )															*/
/*																									*/
/*	ARGUMENTS:	NONE																			*/
/*	RETURNS:		int	- OK if successful else error code							*/
/*																									*/
/***************************************************************************/

int ReadVersionTable( void )
{
	register		iStatus;						/* Function's return value				*/
	int			iFile;						/* DOS file handle 						*/
	unsigned		uRead;						/* Number of bytes read from file	*/


			/* Open the file and read in the max buffer len from stack seg		*/

	if ( _dos_open( Entry.Path, O_RDONLY, &iFile ) != S_OK )
		return( S_FILE_NOT_FOUND );

	if ( _dos_read( iFile, &ExeHdr, sizeof( ExeHdr ), &uRead ) == S_OK &&
		  uRead == sizeof( ExeHdr ) )
	{
		FileOffset += (long)(ExeHdr.HeaderParas * 16);
		if ( SeekRead( iFile, &DevHdr, FileOffset, sizeof( DevHdr ) ) == S_OK )
		{
			if ( strncmp( DevHdr.Name, szSetVer, 8 ) == S_OK &&
				  DevHdr.VersMajor == 1 )
			{
				FileOffset += DevHdr.TblOffset;
				if ( (LieBuffer = malloc( DevHdr.TblLen )) == NULL )
					iStatus = S_MEMORY_ERROR;

				else if ( SeekRead( iFile, LieBuffer, FileOffset,
							 DevHdr.TblLen ) == S_OK )
				{
					iStatus = S_OK;
					EndBuf = LieBuffer + DevHdr.TblLen;
				}
			}
			else
				iStatus = S_INVALID_SIG;
		}
		else
			iStatus = S_FILE_READ_ERROR;
	 }
	 else
		iStatus = S_FILE_READ_ERROR;
	_dos_close( iFile );

	return( iStatus );
}

/***************************************************************************/
/* Opens the DOS system file and writes the versin table back to the file. */
/*																									*/
/*	int WriteVersionTable( void )															*/
/*																									*/
/*	ARGUMENTS:	NONE																			*/
/*	RETURNS:		int	- OK if successful else error code							*/
/*																									*/
/***************************************************************************/

int WriteVersionTable( void )
{
	register			iStatus;					/* Function's return value				*/
	int				iFile;					/* DOS file handle						*/
	unsigned			uWritten;				/* Number of bytes written to file	*/
	struct find_t	Info;

	if ( _dos_findfirst( Entry.Path, _A_HIDDEN|_A_SYSTEM, &Info ) == S_OK &&
		  _dos_setfileattr( Entry.Path, _A_NORMAL ) == S_OK &&
		  _dos_open( Entry.Path, O_RDWR, &iFile ) == S_OK )
	{
		if ( _dos_seek( iFile, FileOffset, SEEK_SET ) == FileOffset &&
			  _dos_write(iFile, LieBuffer, DevHdr.TblLen, &uWritten ) == S_OK &&
			  uWritten == DevHdr.TblLen )
			iStatus = S_OK;
		else
			iStatus = S_FILE_WRITE_ERROR;

		_dos_setftime( iFile, Info.wr_date, Info.wr_time );
		_dos_close( iFile );
		_dos_setfileattr( Entry.Path, (UINT)((int)(Info.attrib)) );
	}
	else
		iStatus = S_FILE_NOT_FOUND;

	return( iStatus );
}

/***************************************************************************/
/* Seeks to the specified offset in a file and reads in the specified		*/
/* number of bytes into the caller's buffer.											*/
/*																									*/
/*	unsigned SeekRead( int iFile, char *Buf, long lOffset, unsigned uBytes )*/
/*																									*/
/*	ARGUMENTS:	iFile		- Open DOS file handle										*/
/*					Buf		- Ptr to read buffer											*/
/*					lOffset	- Offset in file to start reading at					*/
/*					uBytes	- Number of bytes to read									*/
/*	RETURNS:		unsigned	- S_OK if successfull else S_FILE_READ_ERROR			*/
/*																									*/
/***************************************************************************/

int SeekRead( int iFile, void *Buf, long lOffset, unsigned uBytes )
{
	unsigned		uRead;

	if ( _dos_seek( iFile, lOffset, SEEK_SET ) == lOffset &&
		  _dos_read( iFile, Buf, uBytes, &uRead ) == S_OK &&
		  uRead == uBytes )
		return( S_OK );
	else
		return( S_FILE_READ_ERROR );
}

⌨️ 快捷键说明

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