📄 setver.c
字号:
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 + -