📄 dosdata.c
字号:
/* DOSDATA.C -
Copyright (c) 1991 - Microsoft Corp.
All rights reserved.
Microsoft Confidential
Program to maintain the data file for the retail upgrade install
utility. Usage is as follows:
DOSDATA filename
Incorporates the information from the specified text information
file into the master data file.
DOSDATA /D oemname version
Deletes all information for the specified version of DOS
from the master data file.
An typical text information file might contain:
Compaq 3.31
lie:
mode.com
fdisk.exe
rename:
mode.com mode40.com
fdisk.exe fdisk40.exe
delete:
print.exe
The master data file has the format:
Dos_record_1
Dos_record_2
...
Dos_record_n
Null_dos_record
Name_record_1
Name_record_2
...
Name_record_n
Null_name_record
Name_entry_1
Name_entry_2
...
A Dos_record is:
[oem-name][dos-version][data-addr]
18 2 4 = 24 bytes
(The data-addr field is a pointer to the beginning of the
various data tables for that DOS.)
A Name_record is a variable length record containing a
zero-terminated string with a file name or action name.
A Name_entry is a 1 byte record containing an integer index into
the name record table.
*/
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <errno.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <memory.h>
#include "messages.h"
#define FALSE 0
#define TRUE 1
#define OK 0
#define EOL '\0'
#define USIZE sizeof( unsigned )
#define OEM_SIZE 20
#define COMMENT_CHAR ';'
#define OPEN_MODE ( O_CREAT | O_RDWR | O_BINARY )
typedef char FLAG;
char *szEOD = "###";
char *szDosDataFile = "dosdata.dat";
char *szOldDataFile = "dosdata.bak";
/***************************************************************************/
#define MAX_OEMS 256
#define MAX_STRINGS 1000
#define MAX_DATA 4000
#define MAX_TEXT 20000U
struct NEW_DDR
{
char szOemName[ OEM_SIZE ]; /* OEM name */
char MajorVer; /* Major DOS version number */
char MinorVer; /* Minor DOS verison number */
unsigned uDataOffset; /* Offset of start of data */
}nDDR;
struct NEW_DDR *ddrOemList; /* Array of DDR structures */
struct NEW_DDR *pNextOem;
char *pchStringBuf; /* Flat buffer to hold the data text */
char *pchNextStr; /* Ptr to next free data text addr */
unsigned *uDataBuf; /* Array to hold offset of data text */
unsigned uDataNext; /* Next free entry in the data array */
char **apszPtr; /* Araray of ptrs to the data text */
unsigned uNextPtr; /* Index to next free text list entry */
void *Buf[3]; /* Ptrs to 3 allocated buffers */
/***************************************************************************/
void main ( int cszArg,char * *rgszArg );
void TrimSz ( char *sz );
void ExitMsg ( char *szMsg );
void ExitMsg1 ( char *szMsg,void *pParam );
void GetFileName ( char *szFileName,int cszArg,char * *rgszArg );
char DoesItExist ( void );
void InitializeBuffers ( void );
void ReadOldFile ( void );
void GetDosId ( FILE *pFile, char *szSourceFile );
void WriteNewFile ( void );
void ReadSourceData ( char *szSourceFile );
unsigned GetTextOffset ( char *szText );
void *GetMemory ( unsigned int Bytes );
/***************************************************************************/
void main( int cszArg, char **rgszArg )
{
char szSourceFile[ 200 ];
struct find_t File;
InitializeBuffers();
GetFileName( szSourceFile, cszArg, rgszArg );
if ( !(_dos_findfirst( szDosDataFile, _A_NORMAL, &File )) )
ReadOldFile();
ReadSourceData( szSourceFile );
WriteNewFile();
}
/***************************************************************************/
/* Allocate all needed buffers. */
/* */
/* void InitializeBuffers( void ) */
/* */
/* ARGUMENTS: NONE */
/* */
/* RETURNS: void */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
void InitializeBuffers( void )
{
ddrOemList = GetMemory( sizeof( struct NEW_DDR ) * MAX_OEMS );
pchStringBuf = GetMemory( sizeof( unsigned ) * MAX_TEXT );
uDataBuf = GetMemory( sizeof( unsigned ) * MAX_DATA );
apszPtr = GetMemory( sizeof( char * ) * MAX_STRINGS );
memset( ddrOemList, 0, sizeof( struct NEW_DDR ) * MAX_OEMS );
/* Initialize all ptrs and indexes in */
/* case starting new file */
pNextOem = ddrOemList;
pchNextStr = pchStringBuf;
uDataNext = 0;
uNextPtr = 0;
Buf[0] = ddrOemList; /* Initialize array of ptrs to buffers */
Buf[1] = pchStringBuf;
Buf[2] = uDataBuf;
}
/***************************************************************************/
/* Read in all the data from the existing data file and initialize the */
/* array of indexes to the strings in the text buffer. On return the all */
/* of the indices and ptrs to the next free positions will be set to the */
/* correct value and ready for adding new data to each of the data areas. */
/* */
/* void ReadOldFile( void ) */
/* */
/* ARGUMENTS: NONE */
/* */
/* RETURNS: void */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
void ReadOldFile( void )
{
char *EndStrBuf;
int iFile;
int i;
unsigned uSize[3];
/* Read in the 3 parts of the file */
if ( (iFile = open( szDosDataFile, O_RDONLY | O_BINARY )) != -1 )
{
for ( i = 0; i < 3; i++ )
if ( read( iFile, (char *) &uSize[i], USIZE ) != USIZE ||
read( iFile, (char *)Buf[i], uSize[i] ) != (int)uSize[i] )
ExitMsg1( szMsgErrReading, szOldDataFile );
close ( iFile );
}
/* Initialize the array of ptrs to text */
EndStrBuf = pchStringBuf + uSize[1];
pchNextStr = pchStringBuf;
for ( uNextPtr = 0;
pchNextStr < EndStrBuf;
uNextPtr++ )
{
apszPtr[ uNextPtr ] = pchNextStr;
pchNextStr = strchr( pchNextStr, EOL ) + 1;
}
pNextOem = ddrOemList + (uSize[0] / sizeof( struct NEW_DDR ));
uDataNext = uSize[2] / sizeof( unsigned );
}
/***************************************************************************/
/* Opens the file specified on the command line and processes the text in */
/* in the file and then updates the 4 data areas in memory with the new */
/* information. */
/* */
/* void ReadSourceData( char *szSourceFile ) */
/* */
/* ARGUMENTS: szSource - Path and name string for the file to process */
/* */
/* RETURNS: void */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
void ReadSourceData( char *szSourceFile )
{
FILE *pFile;
char szBuf[ 80 ];
char *szString;
if ( (pFile = fopen( szSourceFile, "rt" )) == NULL )
ExitMsg1( szMsgErrOpening, szSourceFile );
while ( ! feof( pFile ) )
{
/* Create an OEM struct for this vender */
GetDosId( pFile, szSourceFile );
while ( !feof( pFile ) )
{
if ( !fgets( szBuf, 80, pFile ) ) /* Get next line from file */
{
if ( ferror( pFile ) )
ExitMsg1( szMsgErrReading, szSourceFile );
}
else
{ /* Check for buffer overflow */
if ( uDataNext >= MAX_DATA - 1 ||
uNextPtr >= (MAX_STRINGS - 1) ||
(pchNextStr - pchStringBuf) > (int)(MAX_TEXT - 100) )
ExitMsg1( szMsgTooMuch, szSourceFile );
szString = strchr( szBuf, COMMENT_CHAR );
if ( szString )
*szString = 0 ; /* truncate comments */
TrimSz( szBuf );
if ( strcmp( szBuf, szEOD ) == 0 )
break; /* End of this OEM's data */
if ( *szBuf )
uDataBuf[ uDataNext++ ] = GetTextOffset( szBuf );
}
}
uDataBuf[ uDataNext++ ] = 0xffffU; /* Mark end of OEM data */
}
fclose( pFile );
}
/***************************************************************************/
/* Reads in an OEM string and initializes the next free OEM ddr structure */
/* with the OEM name, version number and then increments the next free OEM */
/* structure pointer. */
/* */
/* void GetDosId( FILE *pFile, char *szSourceFile ) */
/* */
/* ARGUMENTS: pFile - Open file structure */
/* szSourceFile - The name of the source file (for error msgs) */
/* */
/* RETURNS: void */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
void GetDosId( FILE *pFile, char *szSourceFile )
{
char *szString;
char szBuf[ 80 ];
char szOemName[ OEM_SIZE ];
register i;
int MajorVer;
int MinorVer;
do
{
if ( feof( pFile ) )
return;
if ( ! fgets( szBuf, 80, pFile ) )
ExitMsg1( szMsgErrReading, szSourceFile );
szString = strchr( szBuf, COMMENT_CHAR );
if ( szString )
*szString = 0; /* truncate comments */
TrimSz( szBuf );
}
while ( *szBuf == 0 );
for ( i = 0;
szBuf[i] != '*' &&
szBuf[i] != EOL &&
i < (OEM_SIZE - 1);
i++ )
szOemName[i] = szBuf[i];
szOemName[i++] = EOL;
if ( sscanf( szBuf+i, "%d.%d", &MajorVer, &MinorVer ) != 2 )
ExitMsg1( szMsgBadFormat, szSourceFile );
strncpy( pNextOem->szOemName, szOemName, sizeof( pNextOem->szOemName ) - 1 );
pNextOem->MajorVer = (char)MajorVer;
pNextOem->MinorVer = (char)MinorVer;
pNextOem->uDataOffset = uDataNext * USIZE;
pNextOem++; /* Increment ptr to next OEM */
printf( "OEM: %-24s Version: %2d.%2.2d\n", szOemName, MajorVer, MinorVer );
}
/* johnhe 11-10-89 */
/***************************************************************************/
void WriteNewFile( void )
{
int iFile;
int i;
unsigned uSize[3];
uSize[0] = (unsigned)((pNextOem - ddrOemList) * sizeof( struct NEW_DDR ));
uSize[1] = (unsigned)(pchNextStr - pchStringBuf);
uSize[2] = uDataNext * USIZE;
unlink( szOldDataFile ); /* Delete existing .bak file */
rename( szOldDataFile, szOldDataFile );
if ( (iFile = open( szDosDataFile, OPEN_MODE, S_IWRITE )) != -1 )
{
for ( i = 0; i < 3; i++ )
if ( write( iFile, (char *) &uSize[i], USIZE ) != USIZE ||
write( iFile, (char *)Buf[i], uSize[i] ) != (int)uSize[i] )
ExitMsg1( szMsgErrWriting, szOldDataFile );
close ( iFile );
}
else
ExitMsg1( szMsgErrWriting, szOldDataFile );
}
/***************************************************************************/
/* Remove trailing spaces, tabs, and new-lines from string */
void TrimSz( char *szString )
{
char *szPtr;
/* szPtr -> end of string marker */
szPtr = strchr( szString, EOL );
/* go back to first non-space, non-tab */
while ( (--szPtr >= szString ) &&
(*szPtr == ' ' || *szPtr == '\t' || *szPtr == '\n') )
;
*(++szPtr) = EOL; /* terminate the string after that */
}
/***************************************************************************/
void ExitMsg( char *szMsg )
{
printf( szMsg );
exit( 1 );
}
/***************************************************************************/
void ExitMsg1( char *szMsg, void *pParam )
{
char szBuf[ 80 ];
sprintf( szBuf, szMsg, pParam );
ExitMsg( szBuf );
}
/***************************************************************************/
/* Returns an index to the array of pointers which has a pointer to the */
/* specified string. If the string does not exist a buffer is allocated */
/* for it and a pointer to this buffer is added in the next available */
/* element in the array of pointers an the index to this element is */
/* returned. */
/* */
/* unsigned GetTextOffset( char *szText ) */
/* */
/* ARGUMENTS: szText - Point to a string to find in or add to buffer */
/* */
/* RETURNS: unsigned - Offset in text buffer where string is located */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
unsigned GetTextOffset( char *szText )
{
int i;
unsigned uOffset;
/* See if the string is a duplicate */
for ( i = 0; i < (int)uNextPtr; i++ )
{
if ( strcmp( apszPtr[ i ], szText ) == OK )
{
uOffset = (unsigned)(apszPtr[i] - pchStringBuf);
break;
}
}
/* If didn't find a match need to add */
/* this string to the text buffer */
if ( i >= (int) uNextPtr )
{
uOffset = (unsigned)(pchNextStr - pchStringBuf);
strcpy( pchNextStr, szText );
apszPtr[ uNextPtr++ ] = pchNextStr;
pchNextStr = strchr( pchNextStr, EOL ) + 1;
}
return( uOffset );
}
/***************************************************************************/
void GetFileName( char *szFileName, int cszArg, char *rgszArg[] )
{
if ( cszArg < 2 )
ExitMsg( szMsgInfParam );
if ( strlen( rgszArg [1] ) > 128 )
ExitMsg( szMsgIllegalParam );
strcpy( szFileName, rgszArg[ 1 ] );
}
/***************************************************************************/
/* Allocates the specified size buffer and returns a pointer to it. Checks */
/* for error and aborts program if memory is not available. */
/* */
/* void *GetMemory( unsigned int Bytes ) */
/* */
/* ARGUMENTS: Bytes - Size of buffer to allocate in bytes */
/* */
/* RETURNS: void * - Ptr to allocated buffer */
/* */
/* johnhe 11-10-89 */
/***************************************************************************/
void *GetMemory( unsigned int Bytes )
{
void *Ptr;
if ( (Ptr = malloc( Bytes )) == NULL )
ExitMsg( szMsgMemFailed );
return( Ptr );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -