Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

935 lines
24 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation
  4. // All rights reserved.
  5. //
  6. // File Name:
  7. // makeboot.c
  8. //
  9. // Description:
  10. // This program copies the images of the 4 Windows NT setup disks to
  11. // floppy disk so the user can boot their system with them.
  12. //
  13. // Assumptions:
  14. // The sector size is 512 and the sectors per track is 18
  15. //
  16. // The floppy disk images are in the current dir and named CDBOOT1.IMG,
  17. // CDBOOT2.IMG, CDBOOT3.IMG and CDBOOT4.IMG.
  18. //
  19. // The txtsetup.sif resides in ..\i386 or ..\alpha from where the
  20. // program is being run.
  21. //
  22. //----------------------------------------------------------------------------
  23. #include <bios.h>
  24. #include <string.h>
  25. #include <malloc.h>
  26. #include <io.h>
  27. #include <fcntl.h>
  28. #include <process.h>
  29. #include <errno.h>
  30. #include <conio.h>
  31. #include <ctype.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdarg.h>
  35. #include "makeboot.h"
  36. //
  37. // Constants
  38. //
  39. //
  40. // To support disks other than 1.44 MB High-Density floppies, then these
  41. // numbers will have to be changed or determined at run-time.
  42. //
  43. #define SECTORS_PER_TRACK 18
  44. #define SECTOR_SIZE 512
  45. #define TRACK_SIZE SECTORS_PER_TRACK * SECTOR_SIZE
  46. #define NUMBER_OF_TRACKS 80
  47. #define SECTORS_TO_COPY_AT_A_TIME 18
  48. // we multiply by 2 because the disk is double-sided
  49. #define NUMBER_OF_SECTORS_ON_DISK NUMBER_OF_TRACKS * SECTORS_PER_TRACK * 2
  50. #define NT_NAME_OF_MAKEBOOT "makebt32.exe"
  51. #define NT_IMAGE_1_NAME "CDBOOT1.IMG"
  52. #define NT_IMAGE_2_NAME "CDBOOT2.IMG"
  53. #define NT_IMAGE_3_NAME "CDBOOT3.IMG"
  54. #define NT_IMAGE_4_NAME "CDBOOT4.IMG"
  55. #define NT_IMAGE_5_NAME "CDBOOT5.IMG"
  56. #define NT_IMAGE_6_NAME "CDBOOT6.IMG"
  57. #define NT_IMAGE_7_NAME "CDBOOT7.IMG"
  58. #define MAX_INILINE_LENGTH 1023
  59. #define ENTER_KEY 13
  60. #define ESC_KEY 27
  61. #define NUMBER_OF_ASCII_WHEEL_SYMBOLS 4
  62. const char rgAsciiWheel[NUMBER_OF_ASCII_WHEEL_SYMBOLS] = { '|', '/', '-', '\\' };
  63. //
  64. // Function prototypes
  65. //
  66. int WriteImageToFloppy( char *szFileName, int drive );
  67. int DoesUserWantToTryCopyAgain( void );
  68. void ReportBiosError( unsigned int iBiosErrorCode );
  69. int DoImageFilesExist( void );
  70. unsigned int IsFloppyDrive( int DriveLetter );
  71. void PressAnyKeyToContinue( void );
  72. unsigned int AbsoluteDiskWrite( unsigned int *iErrorCode,
  73. unsigned int iDrive,
  74. unsigned int iStartingSector,
  75. unsigned int iNumberOfSectorsToWrite,
  76. void far *Buffer_to_be_written );
  77. unsigned DnGetCodepage(void);
  78. //
  79. // Variables that are allocated in strings.c that are used to determine what
  80. // string table to use.
  81. //
  82. extern unsigned int CODEPAGE;
  83. extern const char *EngStrings[];
  84. extern const char *LocStrings[];
  85. //
  86. // This var holds a pointer to the array of strings to be used
  87. //
  88. const char **StringTable;
  89. //----------------------------------------------------------------------------
  90. //
  91. // Function: main
  92. //
  93. // Purpose: Instructs user to insert floppy disks to be copied and performs
  94. // the copy.
  95. //
  96. // Arguments: int argc - standard program argument, count of the command line args
  97. // char *argv[] - standard program argument, the 2nd argument is the
  98. // floppy drive to copy the images to.
  99. // Returns: int - zero on success, non-zero on error
  100. //
  101. //----------------------------------------------------------------------------
  102. int
  103. main( int argc, char *argv[] )
  104. {
  105. char *szOsName;
  106. char Drive;
  107. char DriveLetter;
  108. int bTryAgain;
  109. //
  110. // Set the string table to the appropriate language depending on
  111. // the code page.
  112. //
  113. if( *LocStrings[0] == '\0' )
  114. {
  115. StringTable = EngStrings;
  116. }
  117. else {
  118. if( DnGetCodepage() != CODEPAGE )
  119. {
  120. StringTable = EngStrings;
  121. }
  122. else
  123. {
  124. StringTable = LocStrings;
  125. }
  126. }
  127. szOsName = getenv( "OS" );
  128. //
  129. // See if we are on NT. If we are, call the NT version and exit.
  130. // If we aren't then just continue executing this program.
  131. //
  132. if( szOsName && ( stricmp( szOsName, "Windows_NT" ) == 0 ) )
  133. {
  134. int iRetVal;
  135. iRetVal = spawnl( P_WAIT, NT_NAME_OF_MAKEBOOT, NT_NAME_OF_MAKEBOOT, argv[1], NULL );
  136. if( iRetVal == -1 )
  137. {
  138. if( errno == ENOENT )
  139. {
  140. printf( StringTable[ CANNOT_FIND_FILE ], NT_NAME_OF_MAKEBOOT );
  141. exit( 1 );
  142. }
  143. else if( errno == ENOMEM )
  144. {
  145. printf( StringTable[ NOT_ENOUGH_MEMORY ] );
  146. exit( 1 );
  147. }
  148. else if( errno == ENOEXEC )
  149. {
  150. printf( StringTable[ NOT_EXEC_FORMAT ], NT_NAME_OF_MAKEBOOT );
  151. exit( 1 );
  152. }
  153. else
  154. {
  155. printf( StringTable[ UNKNOWN_SPAWN_ERROR ], NT_NAME_OF_MAKEBOOT );
  156. exit( 1 );
  157. }
  158. }
  159. // successful completion
  160. exit( 0 );
  161. }
  162. printf( "\n%s\n", StringTable[ STARS ] );
  163. printf( "%s\n", StringTable[ EXPLANATION_LINE_1 ] );
  164. printf( StringTable[ EXPLANATION_LINE_2 ], StringTable[ NT_VERSION_NAME ] );
  165. printf( "\n\n" );
  166. printf( "%s\n", StringTable[ EXPLANATION_LINE_3 ] );
  167. printf( "%s\n\n", StringTable[ EXPLANATION_LINE_4 ] );
  168. //
  169. // If they didn't specified the floppy drive on the command line then
  170. // prompt them for it.
  171. //
  172. if( argc == 1 )
  173. {
  174. printf( StringTable[ SPECIFY_DRIVE ] );
  175. DriveLetter = (char) getche();
  176. printf( "\n\n" );
  177. }
  178. else
  179. {
  180. DriveLetter = argv[1][0];
  181. }
  182. //
  183. // Make sure the character they entered is a possible drive letter
  184. //
  185. if( ! isalpha( DriveLetter ) )
  186. {
  187. printf( StringTable[ INVALID_DRIVE_LETTER ] );
  188. exit( 1 );
  189. }
  190. //
  191. // Make sure the drive specified is actually a floppy drive
  192. //
  193. if( ! IsFloppyDrive( DriveLetter ) )
  194. {
  195. printf( StringTable[ NOT_A_FLOPPY ], DriveLetter );
  196. exit( 1 );
  197. }
  198. //
  199. // map the drive letter a or A to 0, b or B to 1, etc.
  200. //
  201. Drive = (char) ( toupper( DriveLetter ) - (int)'A' );
  202. //
  203. // Make sure all the images files exist in the current directory
  204. //
  205. if( ! DoImageFilesExist() )
  206. {
  207. exit( 1 );
  208. }
  209. printf( StringTable[ INSERT_FIRST_DISK_LINE_1 ], DriveLetter );
  210. printf( "\n" );
  211. printf( StringTable[ INSERT_FIRST_DISK_LINE_2 ], StringTable[ DISK_LABEL_1 ] );
  212. printf( "\n\n" );
  213. PressAnyKeyToContinue();
  214. while( ! WriteImageToFloppy( NT_IMAGE_1_NAME, Drive ) )
  215. {
  216. bTryAgain = DoesUserWantToTryCopyAgain();
  217. if( ! bTryAgain )
  218. {
  219. exit( 1 );
  220. }
  221. }
  222. printf( "\n" );
  223. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  224. printf( "\n" );
  225. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_2 ] );
  226. printf( "\n\n" );
  227. PressAnyKeyToContinue();
  228. while( ! WriteImageToFloppy( NT_IMAGE_2_NAME, Drive ) )
  229. {
  230. bTryAgain = DoesUserWantToTryCopyAgain();
  231. if( ! bTryAgain )
  232. {
  233. exit( 1 );
  234. }
  235. }
  236. printf( "\n" );
  237. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  238. printf( "\n" );
  239. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_3 ] );
  240. printf( "\n\n" );
  241. PressAnyKeyToContinue();
  242. while( ! WriteImageToFloppy( NT_IMAGE_3_NAME, Drive ) )
  243. {
  244. bTryAgain = DoesUserWantToTryCopyAgain();
  245. if( ! bTryAgain )
  246. {
  247. exit( 1 );
  248. }
  249. }
  250. printf( "\n" );
  251. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  252. printf( "\n" );
  253. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_4 ] );
  254. printf( "\n\n" );
  255. PressAnyKeyToContinue();
  256. while( ! WriteImageToFloppy( NT_IMAGE_4_NAME, Drive ) )
  257. {
  258. bTryAgain = DoesUserWantToTryCopyAgain();
  259. if( ! bTryAgain )
  260. {
  261. exit( 1 );
  262. }
  263. }
  264. printf( "\n" );
  265. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  266. printf( "\n" );
  267. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_5 ] );
  268. printf( "\n\n" );
  269. PressAnyKeyToContinue();
  270. while( ! WriteImageToFloppy( NT_IMAGE_5_NAME, Drive ) )
  271. {
  272. bTryAgain = DoesUserWantToTryCopyAgain();
  273. if( ! bTryAgain )
  274. {
  275. exit( 1 );
  276. }
  277. }
  278. printf( "\n" );
  279. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  280. printf( "\n" );
  281. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_6 ] );
  282. printf( "\n\n" );
  283. PressAnyKeyToContinue();
  284. while( ! WriteImageToFloppy( NT_IMAGE_6_NAME, Drive ) )
  285. {
  286. bTryAgain = DoesUserWantToTryCopyAgain();
  287. if( ! bTryAgain )
  288. {
  289. exit( 1 );
  290. }
  291. }
  292. printf( "\n" );
  293. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
  294. printf( "\n" );
  295. printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_7 ] );
  296. printf( "\n\n" );
  297. PressAnyKeyToContinue();
  298. while( ! WriteImageToFloppy( NT_IMAGE_7_NAME, Drive ) )
  299. {
  300. bTryAgain = DoesUserWantToTryCopyAgain();
  301. if( ! bTryAgain )
  302. {
  303. exit( 1 );
  304. }
  305. }
  306. printf( "\n\n%s\n\n", StringTable[ COMPLETED_SUCCESSFULLY ] );
  307. printf( "%s\n", StringTable[ STARS ] );
  308. return( 0 );
  309. }
  310. //----------------------------------------------------------------------------
  311. //
  312. // Function: WriteImageToFloppy
  313. //
  314. // Purpose: Writes an image file to a floppy disk. Handles all error
  315. // reporting to the user.
  316. //
  317. // Arguments: char *szFileName - filename to write to the floppy
  318. // int drive - drive letter of the floppy to write to
  319. //
  320. // Returns: int - non-zero on success
  321. // - zero on error
  322. //
  323. //----------------------------------------------------------------------------
  324. int
  325. WriteImageToFloppy( char *szFileName, int drive )
  326. {
  327. char *pTrack;
  328. int hImageFile;
  329. unsigned int iSuccess;
  330. unsigned int iErrorCode;
  331. unsigned int iBytesRead;
  332. unsigned int iTotalSectorsWritten;
  333. unsigned int iPercentComplete;
  334. unsigned int iWheelPosition;
  335. char TrackBuffer[ TRACK_SIZE ];
  336. _fmode = O_BINARY;
  337. //
  338. // Open the image file
  339. //
  340. hImageFile = open( szFileName, O_RDONLY );
  341. if( hImageFile == -1 )
  342. {
  343. perror( szFileName );
  344. return( 0 );
  345. }
  346. iWheelPosition = 0;
  347. iTotalSectorsWritten = 0;
  348. //
  349. // Loop reading a track and then writing SECTORS_TO_COPY_AT_A_TIME sectors
  350. // out at a time until we reach the end of the file
  351. //
  352. while( ( iBytesRead = read( hImageFile, TrackBuffer, TRACK_SIZE ) ) > 0 )
  353. {
  354. pTrack = TrackBuffer;
  355. for( ;
  356. iBytesRead > 0;
  357. iTotalSectorsWritten += SECTORS_TO_COPY_AT_A_TIME )
  358. {
  359. iSuccess = AbsoluteDiskWrite( &iErrorCode,
  360. drive,
  361. iTotalSectorsWritten,
  362. SECTORS_TO_COPY_AT_A_TIME,
  363. (void far *) pTrack );
  364. if( ! iSuccess )
  365. {
  366. ReportBiosError( iErrorCode );
  367. close( hImageFile );
  368. return( 0 );
  369. }
  370. iBytesRead = iBytesRead - ( SECTOR_SIZE * SECTORS_TO_COPY_AT_A_TIME );
  371. pTrack = pTrack + ( SECTOR_SIZE * SECTORS_TO_COPY_AT_A_TIME );
  372. }
  373. iPercentComplete = (int) ( ( (double) (iTotalSectorsWritten) / (double) (NUMBER_OF_SECTORS_ON_DISK) ) * 100.0 );
  374. printf( "%c %3d%% %s\r",
  375. rgAsciiWheel[iWheelPosition],
  376. iPercentComplete,
  377. StringTable[ COMPLETE ] );
  378. //
  379. // Advance the ASCII wheel
  380. //
  381. iWheelPosition++;
  382. if( iWheelPosition >= NUMBER_OF_ASCII_WHEEL_SYMBOLS )
  383. {
  384. iWheelPosition = 0;
  385. }
  386. }
  387. //
  388. // We are done copying the disk so force it to read 100% and get rid of
  389. // the ascii wheel symbol.
  390. //
  391. printf( " 100%% %s \n", StringTable[ COMPLETE ] );
  392. close( hImageFile );
  393. return( 1 );
  394. }
  395. //----------------------------------------------------------------------------
  396. //
  397. // Function: DoesUserWantToTryCopyAgain
  398. //
  399. // Purpose: Ask the user if they want to retry to copy the image to floppy.
  400. // Get the user input and return whether to copy again or not.
  401. //
  402. // Arguments: void
  403. //
  404. // Returns: int - non-zero if user wants to attempt to copy again
  405. // - zero if user does not want to attempt to copy again
  406. //
  407. //----------------------------------------------------------------------------
  408. int
  409. DoesUserWantToTryCopyAgain( void )
  410. {
  411. int ch;
  412. //
  413. // Clear the input stream by eating all the chars until there are none
  414. // left. Print the message and then wait for a key press.
  415. //
  416. while( kbhit() )
  417. {
  418. getch();
  419. }
  420. do
  421. {
  422. printf( "%s\n", StringTable[ ATTEMPT_TO_CREATE_FLOPPY_AGAIN ] );
  423. printf( "%s\n", StringTable[ PRESS_ENTER_OR_ESC ] );
  424. ch = getch();
  425. } while( ch != ENTER_KEY && ch != ESC_KEY );
  426. if( ch == ENTER_KEY )
  427. {
  428. return( 1 );
  429. }
  430. else
  431. {
  432. return( 0 );
  433. }
  434. }
  435. //----------------------------------------------------------------------------
  436. //
  437. // Function: PressAnyKeyToContinue
  438. //
  439. // Purpose: Print the "Press any key when ready" message and wait until the
  440. // user presses a key.
  441. //
  442. // Arguments: void
  443. //
  444. // Returns: void
  445. //
  446. //----------------------------------------------------------------------------
  447. void
  448. PressAnyKeyToContinue( void )
  449. {
  450. //
  451. // Clear the input stream by eating all the chars until there are none
  452. // left. Print the message and then wait for a key press.
  453. //
  454. while( kbhit() )
  455. {
  456. getch();
  457. }
  458. printf( "%s\n", StringTable[ PRESS_ANY_KEY_TO_CONTINUE ] );
  459. //
  460. // Spin until the keyboard is pressed
  461. //
  462. while( ! kbhit() )
  463. {
  464. ;
  465. }
  466. }
  467. //----------------------------------------------------------------------------
  468. //
  469. // Function: DoImageFilesExist
  470. //
  471. // Purpose: Determines if all the image files are in the current directory or
  472. // not. If an image file is missing, an error message is printed
  473. // to the user.
  474. //
  475. // Note: it detemines if a file exists by seeing if it can open it
  476. // for reading.
  477. //
  478. // Arguments: void
  479. //
  480. // Returns: int -- non-zero on success, all images files exist in current dir
  481. // zero on failure, 1 or more image files do not exist
  482. //
  483. //----------------------------------------------------------------------------
  484. int
  485. DoImageFilesExist( void )
  486. {
  487. FILE *FileStream;
  488. int iSuccess = 1; // assume success
  489. if( ( FileStream = fopen( NT_IMAGE_1_NAME, "r" ) ) == NULL )
  490. {
  491. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_1_NAME );
  492. printf( "\n" );
  493. iSuccess = 0;
  494. }
  495. else
  496. {
  497. fclose( FileStream );
  498. }
  499. if( ( FileStream = fopen( NT_IMAGE_2_NAME, "r" ) ) == NULL )
  500. {
  501. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_2_NAME );
  502. printf( "\n" );
  503. iSuccess = 0;
  504. }
  505. else
  506. {
  507. fclose( FileStream );
  508. }
  509. if( ( FileStream = fopen( NT_IMAGE_3_NAME, "r" ) ) == NULL )
  510. {
  511. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_3_NAME );
  512. printf( "\n" );
  513. iSuccess = 0;
  514. }
  515. else
  516. {
  517. fclose( FileStream );
  518. }
  519. if( ( FileStream = fopen( NT_IMAGE_4_NAME, "r" ) ) == NULL )
  520. {
  521. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_4_NAME );
  522. printf( "\n" );
  523. iSuccess = 0;
  524. }
  525. else
  526. {
  527. fclose( FileStream );
  528. }
  529. if( ( FileStream = fopen( NT_IMAGE_5_NAME, "r" ) ) == NULL )
  530. {
  531. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_5_NAME );
  532. printf( "\n" );
  533. iSuccess = 0;
  534. }
  535. else
  536. {
  537. fclose( FileStream );
  538. }
  539. if( ( FileStream = fopen( NT_IMAGE_6_NAME, "r" ) ) == NULL )
  540. {
  541. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_6_NAME );
  542. printf( "\n" );
  543. iSuccess = 0;
  544. }
  545. else
  546. {
  547. fclose( FileStream );
  548. }
  549. if( ( FileStream = fopen( NT_IMAGE_7_NAME, "r" ) ) == NULL )
  550. {
  551. printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_7_NAME );
  552. printf( "\n" );
  553. iSuccess = 0;
  554. }
  555. else
  556. {
  557. fclose( FileStream );
  558. }
  559. return( iSuccess );
  560. }
  561. //----------------------------------------------------------------------------
  562. //
  563. // Function: IsFloppyDrive
  564. //
  565. // Purpose: To determine if a particular drive is a floppy drive.
  566. //
  567. // Arguments: int DriveLetter - the drive letter to test whether it is a
  568. // floppy or not
  569. //
  570. // Returns: unsigned int -- non-zero if the specified drive is a floppy drive
  571. // zero if the specified drive is not a floppy drive
  572. //
  573. //----------------------------------------------------------------------------
  574. unsigned int
  575. IsFloppyDrive( int DriveLetter )
  576. {
  577. unsigned int drive;
  578. unsigned int iIsFloppy;
  579. //
  580. // Convert the drive letter to a number. 1 = A, 2 = B, 3 = C, ...
  581. //
  582. drive = ( toupper( DriveLetter ) - (int)'A' ) + 1;
  583. //
  584. // Assume it is not a floppy
  585. //
  586. iIsFloppy = 0;
  587. _asm {
  588. push ds
  589. push es
  590. push bp
  591. mov ah, 1Ch // going to call function 1Ch
  592. mov dl, BYTE PTR [drive]
  593. int 21h // call Int 21h function 1Ch
  594. cmp BYTE PTR ds:[bx], 0F8h // test for fixed drive
  595. je done
  596. mov iIsFloppy, 1 // it is a floppy
  597. done:
  598. pop bp
  599. pop es
  600. pop ds
  601. }
  602. return( iIsFloppy );
  603. }
  604. //----------------------------------------------------------------------------
  605. //
  606. // Function: ReportBiosError
  607. //
  608. // Purpose: To convert a BIOS error code to a error message and print it out
  609. // for the user to see.
  610. //
  611. // Arguments: unsigned int iBiosErrorCode - the BIOS error code to be looked up
  612. //
  613. // Returns: void
  614. //
  615. //----------------------------------------------------------------------------
  616. void
  617. ReportBiosError( unsigned int iBiosErrorCode )
  618. {
  619. //
  620. // Print out the error code for the lower byte
  621. //
  622. switch( iBiosErrorCode & 0x00FF )
  623. {
  624. case 0x0000: printf( StringTable[ ERROR_DISK_WRITE_PROTECTED ] ); break;
  625. case 0x0001: printf( StringTable[ ERROR_UNKNOWN_DISK_UNIT ] ); break;
  626. case 0x0002: printf( StringTable[ ERROR_DRIVE_NOT_READY ] ); break;
  627. case 0x0003: printf( StringTable[ ERROR_UNKNOWN_COMMAND ] ); break;
  628. case 0x0004: printf( StringTable[ ERROR_DATA_ERROR ] ); break;
  629. case 0x0005: printf( StringTable[ ERROR_BAD_REQUEST ] ); break;
  630. case 0x0006: printf( StringTable[ ERROR_SEEK_ERROR ] ); break;
  631. case 0x0007: printf( StringTable[ ERROR_MEDIA_TYPE_NOT_FOUND ] ); break;
  632. case 0x0008: printf( StringTable[ ERROR_SECTOR_NOT_FOUND ] ); break;
  633. case 0x000A: printf( StringTable[ ERROR_WRITE_FAULT ] ); break;
  634. case 0x000C: printf( StringTable[ ERROR_GENERAL_FAILURE ] ); break;
  635. }
  636. //
  637. // Print out the error code for the upper byte
  638. //
  639. switch( iBiosErrorCode & 0xFF00 )
  640. {
  641. case 0x0100: printf( StringTable[ ERROR_INVALID_REQUEST ] ); break;
  642. case 0x0200: printf( StringTable[ ERROR_ADDRESS_MARK_NOT_FOUND ] ); break;
  643. case 0x0300: printf( StringTable[ ERROR_DISK_WRITE_FAULT ] ); break;
  644. case 0x0400: printf( StringTable[ ERROR_SECTOR_NOT_FOUND ] ); break;
  645. case 0x0800: printf( StringTable[ ERROR_DMA_OVERRUN ] ); break;
  646. case 0x1000: printf( StringTable[ ERROR_CRC_ERROR ] ); break;
  647. case 0x2000: printf( StringTable[ ERROR_CONTROLLER_FAILURE ] ); break;
  648. case 0x4000: printf( StringTable[ ERROR_SEEK_ERROR ] ); break;
  649. case 0x8000: printf( StringTable[ ERROR_DISK_TIMED_OUT ] ); break;
  650. }
  651. }
  652. //----------------------------------------------------------------------------
  653. //
  654. // Function: AbsoluteDiskWrite
  655. //
  656. // Purpose: To write a buffer in memory to a specific portion of a disk.
  657. //
  658. // Arguments: unsigned int *iErrorCode - if an error occurs, the error code
  659. // is returned in this OUT variable
  660. // unsigned int iDrive - drive to write the buffer to
  661. // unsigned int iStartingSector - sector where the write is to begin
  662. // unsigned int iNumberOfSectorsToWrite - the number of sectors
  663. // to write
  664. //
  665. // Returns: returns 1 on success, 0 on failure
  666. // If it fails, then the error code is returned in the argument
  667. // iErrorCode.
  668. // If it succeeds, iErrorCode is undefined.
  669. //
  670. //----------------------------------------------------------------------------
  671. unsigned int
  672. AbsoluteDiskWrite( unsigned int *iErrorCode,
  673. unsigned int iDrive,
  674. unsigned int iStartingSector,
  675. unsigned int iNumberOfSectorsToWrite,
  676. void far *Buffer_to_be_written )
  677. {
  678. //
  679. // used to temporarily store the error code
  680. //
  681. unsigned int iTempErrorCode;
  682. unsigned int iRetVal;
  683. _asm
  684. {
  685. push ds
  686. push es
  687. push bp
  688. mov ax, WORD PTR [Buffer_to_be_written + 2]
  689. mov ds, ax
  690. mov bx, WORD PTR [Buffer_to_be_written]
  691. mov dx, iStartingSector
  692. mov cx, iNumberOfSectorsToWrite
  693. mov al, BYTE PTR [iDrive]
  694. int 26h // do the absolute disk write
  695. lahf
  696. popf
  697. sahf
  698. pop bp
  699. pop es
  700. pop ds
  701. mov iRetVal, 1 // assume success
  702. jnc done // see if an error occured
  703. mov iRetVal, 0
  704. mov iTempErrorCode, ax
  705. done:
  706. }
  707. *iErrorCode = iTempErrorCode;
  708. return( iRetVal );
  709. }
  710. unsigned
  711. DnGetCodepage(void)
  712. /*++
  713. Routine Description:
  714. Determine the currently active codepage.
  715. Arguments:
  716. None.
  717. Return Value:
  718. Currently active codepage. 0 if we can't determine it.
  719. --*/
  720. {
  721. unsigned int iRetVal;
  722. _asm {
  723. mov ax,06601h
  724. int 21h
  725. jnc ok
  726. xor bx,bx
  727. ok: mov iRetVal,bx
  728. }
  729. return( iRetVal );
  730. }