dosdata.c
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:15k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /* DOSDATA.C -
  2. Copyright (c) 1991 - Microsoft Corp.
  3. All rights reserved.
  4. Microsoft Confidential
  5. Program to maintain the data file for the retail upgrade install
  6. utility.  Usage is as follows:
  7. DOSDATA filename
  8. Incorporates the information from the specified text information
  9. file into the master data file.
  10. DOSDATA /D oemname version
  11. Deletes all information for the specified version of DOS
  12. from the master data file.
  13. An typical text information file might contain:
  14. Compaq 3.31
  15. lie:
  16. mode.com
  17. fdisk.exe
  18. rename:
  19. mode.com mode40.com
  20. fdisk.exe fdisk40.exe
  21. delete:
  22. print.exe
  23. The master data file has the format:
  24. Dos_record_1
  25. Dos_record_2
  26. ...
  27. Dos_record_n
  28. Null_dos_record
  29. Name_record_1
  30. Name_record_2
  31. ...
  32. Name_record_n
  33. Null_name_record
  34. Name_entry_1
  35. Name_entry_2
  36. ...
  37. A Dos_record is:
  38. [oem-name][dos-version][data-addr]
  39.     18          2           4       = 24 bytes
  40. (The data-addr field is a pointer to the beginning of the
  41. various data tables for that DOS.)
  42. A Name_record is a variable length record containing a
  43. zero-terminated string with a file name or action name.
  44. A Name_entry is a 1 byte record containing an integer index into
  45. the name record table.
  46. */
  47. #include <stdio.h>
  48. #include <fcntl.h>
  49. #include <io.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <dos.h>
  53. #include <errno.h>
  54. #include <systypes.h>
  55. #include <sysstat.h>
  56. #include <memory.h>
  57. #include "messages.h"
  58. #define FALSE 0
  59. #define TRUE 1
  60. #define OK  0
  61. #define EOL ''
  62. #define USIZE sizeof( unsigned )
  63. #define OEM_SIZE 20
  64. #define COMMENT_CHAR  ';'
  65. #define OPEN_MODE  ( O_CREAT | O_RDWR | O_BINARY )
  66. typedef char FLAG;
  67. char *szEOD = "###";
  68. char *szDosDataFile = "dosdata.dat";
  69. char *szOldDataFile = "dosdata.bak";
  70. /***************************************************************************/
  71. #define MAX_OEMS  256
  72. #define MAX_STRINGS 1000
  73. #define MAX_DATA  4000
  74. #define MAX_TEXT  20000U
  75. struct NEW_DDR
  76. {
  77. char szOemName[ OEM_SIZE ]; /* OEM name  */
  78. char MajorVer; /* Major DOS version number */
  79. char MinorVer; /* Minor DOS verison number */
  80. unsigned  uDataOffset; /* Offset of start of data  */
  81. }nDDR;
  82. struct NEW_DDR *ddrOemList; /* Array of DDR structures  */
  83. struct NEW_DDR *pNextOem;
  84. char *pchStringBuf; /* Flat buffer to hold the data text */
  85. char *pchNextStr; /* Ptr to next free data text addr */
  86. unsigned *uDataBuf; /* Array to hold offset of data text */
  87. unsigned uDataNext; /* Next free entry in the data array */
  88. char **apszPtr; /* Araray of ptrs to the data text */
  89. unsigned uNextPtr; /* Index to next free text list entry */
  90. void *Buf[3]; /* Ptrs to 3 allocated buffers */
  91. /***************************************************************************/
  92. void main ( int cszArg,char * *rgszArg );
  93. void TrimSz ( char *sz );
  94. void ExitMsg ( char *szMsg );
  95. void ExitMsg1 ( char *szMsg,void *pParam );
  96. void GetFileName ( char *szFileName,int cszArg,char * *rgszArg );
  97. char DoesItExist ( void );
  98. void InitializeBuffers ( void );
  99. void ReadOldFile  ( void );
  100. void GetDosId  ( FILE *pFile, char *szSourceFile );
  101. void WriteNewFile ( void );
  102. void ReadSourceData  ( char *szSourceFile );
  103. unsigned GetTextOffset ( char *szText );
  104. void *GetMemory ( unsigned int Bytes );
  105. /***************************************************************************/
  106. void main( int cszArg, char **rgszArg )
  107. {
  108.         char                                    szSourceFile[ 200 ];
  109. struct find_t File;
  110. InitializeBuffers();
  111. GetFileName( szSourceFile, cszArg, rgszArg );
  112. if ( !(_dos_findfirst( szDosDataFile, _A_NORMAL, &File )) )
  113. ReadOldFile();
  114. ReadSourceData( szSourceFile );
  115. WriteNewFile();
  116. }
  117. /***************************************************************************/
  118. /* Allocate all needed buffers. */
  119. /*  */
  120. /* void InitializeBuffers( void ) */
  121. /*  */
  122. /* ARGUMENTS: NONE */
  123. /*  */
  124. /* RETURNS:  void */
  125. /*  */
  126. /* johnhe 11-10-89 */
  127. /***************************************************************************/
  128. void InitializeBuffers( void )
  129. {
  130. ddrOemList = GetMemory( sizeof( struct NEW_DDR ) * MAX_OEMS );
  131. pchStringBuf = GetMemory( sizeof( unsigned ) * MAX_TEXT );
  132. uDataBuf = GetMemory( sizeof( unsigned ) * MAX_DATA );
  133. apszPtr = GetMemory( sizeof( char * ) * MAX_STRINGS );
  134. memset( ddrOemList, 0, sizeof( struct NEW_DDR ) * MAX_OEMS );
  135. /* Initialize all ptrs and indexes in */
  136. /* case starting new file */
  137. pNextOem = ddrOemList;
  138. pchNextStr = pchStringBuf;
  139. uDataNext = 0;
  140. uNextPtr = 0;
  141. Buf[0] = ddrOemList;  /* Initialize array of ptrs to buffers */
  142. Buf[1] = pchStringBuf;
  143. Buf[2] = uDataBuf;
  144. }
  145. /***************************************************************************/
  146. /* Read in all the data from the existing data file and initialize the */
  147. /* array of indexes to the strings in the text buffer. On return the all */
  148. /* of the indices and ptrs to the next free positions will be set to the */
  149. /* correct value and ready for adding new data to each of the data areas. */
  150. /*  */
  151. /* void ReadOldFile( void ) */
  152. /*  */
  153. /* ARGUMENTS: NONE */
  154. /*  */
  155. /* RETURNS:  void */
  156. /*  */
  157. /* johnhe 11-10-89 */
  158. /***************************************************************************/
  159. void ReadOldFile( void )
  160. {
  161. char *EndStrBuf;
  162. int iFile;
  163. int i;
  164. unsigned  uSize[3];
  165. /* Read in the 3 parts of the file */
  166. if ( (iFile = open( szDosDataFile, O_RDONLY | O_BINARY )) != -1 )
  167. {
  168. for ( i = 0; i < 3; i++ )
  169. if ( read( iFile, (char *) &uSize[i], USIZE ) != USIZE ||
  170.   read( iFile, (char *)Buf[i], uSize[i] ) != (int)uSize[i] )
  171. ExitMsg1( szMsgErrReading, szOldDataFile );
  172. close ( iFile );
  173. }
  174. /* Initialize the array of ptrs to text */
  175. EndStrBuf = pchStringBuf + uSize[1];
  176. pchNextStr = pchStringBuf;
  177. for ( uNextPtr = 0;
  178. pchNextStr < EndStrBuf;
  179. uNextPtr++ )
  180. {
  181. apszPtr[ uNextPtr ] = pchNextStr;
  182. pchNextStr = strchr( pchNextStr, EOL ) + 1;
  183. }
  184. pNextOem = ddrOemList + (uSize[0] / sizeof( struct NEW_DDR ));
  185. uDataNext = uSize[2] / sizeof( unsigned );
  186. }
  187. /***************************************************************************/
  188. /* Opens the file specified on the command line and processes the text in */
  189. /* in the file and then updates the 4 data areas in memory with the new  */
  190. /* information. */
  191. /*  */
  192. /* void ReadSourceData( char *szSourceFile )  */
  193. /*  */
  194. /* ARGUMENTS: szSource  - Path and name string for the file to process */
  195. /*  */
  196. /* RETURNS:  void */
  197. /*  */
  198. /* johnhe 11-10-89 */
  199. /***************************************************************************/
  200. void ReadSourceData( char *szSourceFile )
  201. {
  202. FILE *pFile;
  203. char szBuf[ 80 ];
  204. char *szString;
  205. if ( (pFile = fopen( szSourceFile, "rt" )) == NULL )
  206. ExitMsg1( szMsgErrOpening, szSourceFile );
  207. while ( ! feof( pFile ) )
  208. {
  209. /* Create an OEM struct for this vender */
  210. GetDosId( pFile, szSourceFile );
  211. while ( !feof( pFile ) )
  212. {
  213. if ( !fgets( szBuf, 80, pFile ) ) /* Get next line from file */
  214. {
  215. if ( ferror( pFile ) )
  216. ExitMsg1( szMsgErrReading, szSourceFile );
  217. }
  218. else
  219. { /* Check for buffer overflow */
  220. if ( uDataNext >= MAX_DATA - 1 ||
  221.   uNextPtr >= (MAX_STRINGS - 1) ||
  222.   (pchNextStr - pchStringBuf) > (int)(MAX_TEXT - 100) )
  223. ExitMsg1( szMsgTooMuch, szSourceFile );
  224. szString = strchr( szBuf, COMMENT_CHAR );
  225. if ( szString )
  226. *szString = 0 ; /* truncate comments */
  227. TrimSz( szBuf );
  228. if ( strcmp( szBuf, szEOD ) == 0 )
  229. break; /* End of this OEM's data */
  230. if ( *szBuf )
  231. uDataBuf[ uDataNext++ ] = GetTextOffset( szBuf );
  232. }
  233. }
  234. uDataBuf[ uDataNext++ ] = 0xffffU; /* Mark end of OEM data  */
  235. }
  236. fclose( pFile );
  237. }
  238. /***************************************************************************/
  239. /* Reads in an OEM string and initializes the next free OEM ddr structure */
  240. /* with the OEM name, version number and then increments the next free OEM */
  241. /* structure pointer. */
  242. /*  */
  243. /* void GetDosId( FILE *pFile, char *szSourceFile ) */
  244. /*  */
  245. /* ARGUMENTS: pFile  - Open file structure */
  246. /*  szSourceFile - The name of the source file (for error msgs) */
  247. /*  */
  248. /* RETURNS:  void */
  249. /*  */
  250. /* johnhe 11-10-89 */
  251. /***************************************************************************/
  252. void GetDosId( FILE *pFile, char *szSourceFile )
  253. {
  254. char *szString;
  255. char szBuf[ 80 ];
  256. char szOemName[ OEM_SIZE ];
  257. register  i;
  258. int MajorVer;
  259. int MinorVer;
  260. do
  261. {
  262. if ( feof( pFile ) )
  263. return;
  264. if ( ! fgets( szBuf, 80, pFile ) )
  265. ExitMsg1( szMsgErrReading, szSourceFile );
  266. szString = strchr( szBuf, COMMENT_CHAR );
  267. if ( szString )
  268. *szString = 0; /* truncate comments */
  269. TrimSz( szBuf );
  270. while ( *szBuf == 0 );
  271. for ( i = 0;
  272. szBuf[i] != '*' &&
  273. szBuf[i] != EOL &&
  274. i < (OEM_SIZE - 1);
  275. i++ )
  276. szOemName[i] = szBuf[i];
  277. szOemName[i++] = EOL;
  278. if ( sscanf( szBuf+i, "%d.%d", &MajorVer, &MinorVer ) != 2 )
  279. ExitMsg1( szMsgBadFormat, szSourceFile );
  280. strncpy( pNextOem->szOemName, szOemName, sizeof( pNextOem->szOemName ) - 1 );
  281. pNextOem->MajorVer = (char)MajorVer;
  282. pNextOem->MinorVer = (char)MinorVer;
  283. pNextOem->uDataOffset = uDataNext * USIZE;
  284. pNextOem++;  /* Increment ptr to next OEM */
  285. printf( "OEM: %-24s Version: %2d.%2.2dn", szOemName, MajorVer, MinorVer );
  286. }
  287. /* johnhe 11-10-89 */
  288. /***************************************************************************/
  289. void WriteNewFile( void )
  290. {
  291. int iFile;
  292. int i;
  293. unsigned  uSize[3];
  294. uSize[0] = (unsigned)((pNextOem - ddrOemList) * sizeof( struct NEW_DDR ));
  295. uSize[1] = (unsigned)(pchNextStr - pchStringBuf);
  296. uSize[2] = uDataNext * USIZE;
  297. unlink( szOldDataFile ); /* Delete existing .bak file */
  298. rename( szOldDataFile, szOldDataFile );
  299. if ( (iFile = open( szDosDataFile, OPEN_MODE, S_IWRITE )) != -1 )
  300. {
  301. for ( i = 0; i < 3; i++ )
  302. if ( write( iFile, (char *) &uSize[i], USIZE ) != USIZE ||
  303.   write( iFile, (char *)Buf[i], uSize[i] ) != (int)uSize[i] )
  304. ExitMsg1( szMsgErrWriting, szOldDataFile );
  305. close ( iFile );
  306. }
  307. else
  308. ExitMsg1( szMsgErrWriting, szOldDataFile );
  309. }
  310. /***************************************************************************/
  311. /* Remove trailing spaces, tabs, and new-lines from string */
  312. void TrimSz( char *szString )
  313. {
  314. char *szPtr;
  315. /* szPtr -> end of string marker */
  316. szPtr = strchr( szString, EOL );
  317. /* go back to first non-space, non-tab */
  318. while ( (--szPtr >= szString ) &&
  319.   (*szPtr == ' ' || *szPtr == 't' || *szPtr == 'n') )
  320. ;
  321. *(++szPtr) = EOL;  /* terminate the string after that */
  322. }
  323. /***************************************************************************/
  324. void ExitMsg( char *szMsg )
  325. {
  326. printf( szMsg );
  327. exit( 1 );
  328. }
  329. /***************************************************************************/
  330. void ExitMsg1( char *szMsg, void *pParam )
  331. {
  332. char szBuf[ 80 ];
  333. sprintf( szBuf, szMsg, pParam );
  334. ExitMsg( szBuf );
  335. }
  336. /***************************************************************************/
  337. /* Returns an index to the array of pointers which has a pointer to the  */
  338. /* specified string. If the string does not exist a buffer is allocated  */
  339. /* for it and a pointer to this buffer is added in the next available */
  340. /* element in the array of pointers an the index to this element is */
  341. /* returned. */
  342. /*  */
  343. /* unsigned GetTextOffset( char *szText )  */
  344. /*  */
  345. /* ARGUMENTS: szText - Point to a string to find in or add to buffer */
  346. /*  */
  347. /* RETURNS:  unsigned  - Offset in text buffer where string is located */
  348. /*  */
  349. /* johnhe 11-10-89 */
  350. /***************************************************************************/
  351. unsigned GetTextOffset( char *szText )
  352. {
  353. int i;
  354. unsigned  uOffset;
  355. /* See if the string is a duplicate */
  356. for ( i = 0; i < (int)uNextPtr; i++ )
  357. {
  358. if ( strcmp( apszPtr[ i ], szText ) == OK )
  359. {
  360. uOffset = (unsigned)(apszPtr[i] - pchStringBuf);
  361. break;
  362. }
  363. }
  364. /* If didn't find a match need to add  */
  365. /* this string to the text buffer */
  366. if ( i >= (int) uNextPtr )
  367. {
  368. uOffset = (unsigned)(pchNextStr - pchStringBuf);
  369. strcpy( pchNextStr, szText );
  370. apszPtr[ uNextPtr++ ] = pchNextStr;
  371. pchNextStr = strchr( pchNextStr, EOL ) + 1;
  372. }
  373. return( uOffset );
  374. }
  375. /***************************************************************************/
  376. void GetFileName( char *szFileName, int cszArg, char *rgszArg[] )
  377. {
  378. if ( cszArg < 2 )
  379. ExitMsg( szMsgInfParam );
  380.         if ( strlen( rgszArg [1] ) > 128 )
  381. ExitMsg( szMsgIllegalParam );
  382. strcpy( szFileName, rgszArg[ 1 ] );
  383. }
  384. /***************************************************************************/
  385. /* Allocates the specified size buffer and returns a pointer to it. Checks */
  386. /* for error and aborts program if memory is not available.  */
  387. /*  */
  388. /* void *GetMemory( unsigned int Bytes ) */
  389. /*  */
  390. /* ARGUMENTS: Bytes  - Size of buffer to allocate in bytes */
  391. /*  */
  392. /* RETURNS:  void * - Ptr to allocated buffer */
  393. /*  */
  394. /* johnhe 11-10-89 */
  395. /***************************************************************************/
  396. void *GetMemory( unsigned int Bytes )
  397. {
  398. void *Ptr;
  399. if ( (Ptr = malloc( Bytes )) == NULL )
  400. ExitMsg( szMsgMemFailed );
  401. return( Ptr );
  402. }