903 lines
22 KiB
C
903 lines
22 KiB
C
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) 1999 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// File Name:
|
|
// makeboot.c
|
|
//
|
|
// Description:
|
|
// This program copies the images of the 4 Windows NT setup disks to
|
|
// floppy disk so the user can boot their system with them.
|
|
//
|
|
// Assumptions:
|
|
// The sector size is 512 and the sectors per track is 18
|
|
//
|
|
// The floppy disk images are in the current dir and named CDBOOT1.IMG,
|
|
// CDBOOT2.IMG, CDBOOT3.IMG and CDBOOT4.IMG.
|
|
//
|
|
// The txtsetup.sif resides in ..\i386 or ..\alpha from where the
|
|
// program is being run.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <bios.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <process.h>
|
|
#include <errno.h>
|
|
#include <conio.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include "makeboot.h"
|
|
|
|
//
|
|
// Constants
|
|
//
|
|
|
|
//
|
|
// To support disks other than 1.44 MB High-Density floppies, then these
|
|
// numbers will have to be changed or determined at run-time.
|
|
//
|
|
#define SECTORS_PER_TRACK 18
|
|
#define SECTOR_SIZE 512
|
|
#define TRACK_SIZE SECTORS_PER_TRACK * SECTOR_SIZE
|
|
#define NUMBER_OF_TRACKS 80
|
|
#define SECTORS_TO_COPY_AT_A_TIME 18
|
|
|
|
// we multiply by 2 because the disk is double-sided
|
|
#define NUMBER_OF_SECTORS_ON_DISK NUMBER_OF_TRACKS * SECTORS_PER_TRACK * 2
|
|
|
|
#define NT_NAME_OF_MAKEBOOT "makebt32.exe"
|
|
|
|
#define NT_IMAGE_1_NAME "CDBOOT1.IMG"
|
|
#define NT_IMAGE_2_NAME "CDBOOT2.IMG"
|
|
#define NT_IMAGE_3_NAME "CDBOOT3.IMG"
|
|
#define NT_IMAGE_4_NAME "CDBOOT4.IMG"
|
|
#define NT_IMAGE_5_NAME "CDBOOT5.IMG"
|
|
#define NT_IMAGE_6_NAME "CDBOOT6.IMG"
|
|
|
|
#define MAX_INILINE_LENGTH 1023
|
|
|
|
#define ENTER_KEY 13
|
|
#define ESC_KEY 27
|
|
|
|
#define NUMBER_OF_ASCII_WHEEL_SYMBOLS 4
|
|
|
|
const char rgAsciiWheel[NUMBER_OF_ASCII_WHEEL_SYMBOLS] = { '|', '/', '-', '\\' };
|
|
|
|
//
|
|
// Function prototypes
|
|
//
|
|
int WriteImageToFloppy( char *szFileName, int drive );
|
|
int DoesUserWantToTryCopyAgain( void );
|
|
void ReportBiosError( unsigned int iBiosErrorCode );
|
|
int DoImageFilesExist( void );
|
|
unsigned int IsFloppyDrive( int DriveLetter );
|
|
void PressAnyKeyToContinue( void );
|
|
unsigned int AbsoluteDiskWrite( unsigned int *iErrorCode,
|
|
unsigned int iDrive,
|
|
unsigned int iStartingSector,
|
|
unsigned int iNumberOfSectorsToWrite,
|
|
void far *Buffer_to_be_written );
|
|
|
|
unsigned DnGetCodepage(void);
|
|
|
|
//
|
|
// Variables that are allocated in strings.c that are used to determine what
|
|
// string table to use.
|
|
//
|
|
|
|
extern unsigned int CODEPAGE;
|
|
|
|
extern const char *EngStrings[];
|
|
|
|
extern const char *LocStrings[];
|
|
|
|
//
|
|
// This var holds a pointer to the array of strings to be used
|
|
//
|
|
const char **StringTable;
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: main
|
|
//
|
|
// Purpose: Instructs user to insert floppy disks to be copied and performs
|
|
// the copy.
|
|
//
|
|
// Arguments: int argc - standard program argument, count of the command line args
|
|
// char *argv[] - standard program argument, the 2nd argument is the
|
|
// floppy drive to copy the images to.
|
|
// Returns: int - zero on success, non-zero on error
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
main( int argc, char *argv[] )
|
|
{
|
|
|
|
char *szOsName;
|
|
char Drive;
|
|
char DriveLetter;
|
|
int bTryAgain;
|
|
|
|
//
|
|
// Set the string table to the appropriate language depending on
|
|
// the code page.
|
|
//
|
|
if( *LocStrings[0] == '\0' )
|
|
{
|
|
StringTable = EngStrings;
|
|
}
|
|
else {
|
|
|
|
if( DnGetCodepage() != CODEPAGE )
|
|
{
|
|
StringTable = EngStrings;
|
|
}
|
|
else
|
|
{
|
|
StringTable = LocStrings;
|
|
}
|
|
|
|
}
|
|
|
|
szOsName = getenv( "OS" );
|
|
|
|
//
|
|
// See if we are on NT. If we are, call the NT version and exit.
|
|
// If we aren't then just continue executing this program.
|
|
//
|
|
if( szOsName && ( stricmp( szOsName, "Windows_NT" ) == 0 ) )
|
|
{
|
|
|
|
int iRetVal;
|
|
|
|
iRetVal = spawnl( P_WAIT, NT_NAME_OF_MAKEBOOT, NT_NAME_OF_MAKEBOOT, argv[1], NULL );
|
|
|
|
if( iRetVal == -1 )
|
|
{
|
|
if( errno == ENOENT )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_NAME_OF_MAKEBOOT );
|
|
|
|
exit( 1 );
|
|
}
|
|
else if( errno == ENOMEM )
|
|
{
|
|
printf( StringTable[ NOT_ENOUGH_MEMORY ] );
|
|
|
|
exit( 1 );
|
|
}
|
|
else if( errno == ENOEXEC )
|
|
{
|
|
printf( StringTable[ NOT_EXEC_FORMAT ], NT_NAME_OF_MAKEBOOT );
|
|
|
|
exit( 1 );
|
|
}
|
|
else
|
|
{
|
|
printf( StringTable[ UNKNOWN_SPAWN_ERROR ], NT_NAME_OF_MAKEBOOT );
|
|
|
|
exit( 1 );
|
|
}
|
|
}
|
|
|
|
// successful completion
|
|
exit( 0 );
|
|
|
|
}
|
|
|
|
printf( "\n%s\n", StringTable[ STARS ] );
|
|
printf( "%s\n", StringTable[ EXPLANATION_LINE_1 ] );
|
|
printf( StringTable[ EXPLANATION_LINE_2 ], StringTable[ NT_VERSION_NAME ] );
|
|
printf( "\n\n" );
|
|
|
|
printf( "%s\n", StringTable[ EXPLANATION_LINE_3 ] );
|
|
printf( "%s\n\n", StringTable[ EXPLANATION_LINE_4 ] );
|
|
|
|
//
|
|
// If they didn't specified the floppy drive on the command line then
|
|
// prompt them for it.
|
|
//
|
|
if( argc == 1 )
|
|
{
|
|
|
|
printf( StringTable[ SPECIFY_DRIVE ] );
|
|
|
|
DriveLetter = (char) getche();
|
|
|
|
printf( "\n\n" );
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
DriveLetter = argv[1][0];
|
|
|
|
}
|
|
|
|
//
|
|
// Make sure the character they entered is a possible drive letter
|
|
//
|
|
if( ! isalpha( DriveLetter ) )
|
|
{
|
|
|
|
printf( StringTable[ INVALID_DRIVE_LETTER ] );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
//
|
|
// Make sure the drive specified is actually a floppy drive
|
|
//
|
|
|
|
if( ! IsFloppyDrive( DriveLetter ) )
|
|
{
|
|
|
|
printf( StringTable[ NOT_A_FLOPPY ], DriveLetter );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
//
|
|
// map the drive letter a or A to 0, b or B to 1, etc.
|
|
//
|
|
Drive = (char) ( toupper( DriveLetter ) - (int)'A' );
|
|
|
|
//
|
|
// Make sure all the images files exist in the current directory
|
|
//
|
|
if( ! DoImageFilesExist() )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
printf( StringTable[ INSERT_FIRST_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
|
|
printf( StringTable[ INSERT_FIRST_DISK_LINE_2 ], StringTable[ DISK_LABEL_1 ] );
|
|
printf( "\n\n" );
|
|
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_1_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_2 ] );
|
|
printf( "\n\n" );
|
|
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_2_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_3 ] );
|
|
printf( "\n\n" );
|
|
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_3_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_4 ] );
|
|
printf( "\n\n" );
|
|
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_4_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_5 ] );
|
|
printf( "\n\n" );
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_5_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_1 ], DriveLetter );
|
|
printf( "\n" );
|
|
printf( StringTable[ INSERT_ANOTHER_DISK_LINE_2 ], StringTable[ DISK_LABEL_6 ] );
|
|
printf( "\n\n" );
|
|
PressAnyKeyToContinue();
|
|
|
|
while( ! WriteImageToFloppy( NT_IMAGE_6_NAME, Drive ) )
|
|
{
|
|
|
|
bTryAgain = DoesUserWantToTryCopyAgain();
|
|
|
|
if( ! bTryAgain )
|
|
{
|
|
exit( 1 );
|
|
}
|
|
|
|
}
|
|
|
|
printf( "\n\n%s\n\n", StringTable[ COMPLETED_SUCCESSFULLY ] );
|
|
|
|
printf( "%s\n", StringTable[ STARS ] );
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: WriteImageToFloppy
|
|
//
|
|
// Purpose: Writes an image file to a floppy disk. Handles all error
|
|
// reporting to the user.
|
|
//
|
|
// Arguments: char *szFileName - filename to write to the floppy
|
|
// int drive - drive letter of the floppy to write to
|
|
//
|
|
// Returns: int - non-zero on success
|
|
// - zero on error
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
WriteImageToFloppy( char *szFileName, int drive )
|
|
{
|
|
|
|
char *pTrack;
|
|
int hImageFile;
|
|
unsigned int iSuccess;
|
|
unsigned int iErrorCode;
|
|
unsigned int iBytesRead;
|
|
unsigned int iTotalSectorsWritten;
|
|
unsigned int iPercentComplete;
|
|
unsigned int iWheelPosition;
|
|
char TrackBuffer[ TRACK_SIZE ];
|
|
|
|
_fmode = O_BINARY;
|
|
|
|
//
|
|
// Open the image file
|
|
//
|
|
hImageFile = open( szFileName, O_RDONLY );
|
|
|
|
if( hImageFile == -1 )
|
|
{
|
|
perror( szFileName );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
iWheelPosition = 0;
|
|
iTotalSectorsWritten = 0;
|
|
|
|
//
|
|
// Loop reading a track and then writing SECTORS_TO_COPY_AT_A_TIME sectors
|
|
// out at a time until we reach the end of the file
|
|
//
|
|
while( ( iBytesRead = read( hImageFile, TrackBuffer, TRACK_SIZE ) ) > 0 )
|
|
{
|
|
|
|
pTrack = TrackBuffer;
|
|
|
|
for( ;
|
|
iBytesRead > 0;
|
|
iTotalSectorsWritten += SECTORS_TO_COPY_AT_A_TIME )
|
|
{
|
|
|
|
iSuccess = AbsoluteDiskWrite( &iErrorCode,
|
|
drive,
|
|
iTotalSectorsWritten,
|
|
SECTORS_TO_COPY_AT_A_TIME,
|
|
(void far *) pTrack );
|
|
|
|
if( ! iSuccess )
|
|
{
|
|
ReportBiosError( iErrorCode );
|
|
|
|
close( hImageFile );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
iBytesRead = iBytesRead - ( SECTOR_SIZE * SECTORS_TO_COPY_AT_A_TIME );
|
|
|
|
pTrack = pTrack + ( SECTOR_SIZE * SECTORS_TO_COPY_AT_A_TIME );
|
|
|
|
}
|
|
|
|
iPercentComplete = (int) ( ( (double) (iTotalSectorsWritten) / (double) (NUMBER_OF_SECTORS_ON_DISK) ) * 100.0 );
|
|
|
|
printf( "%c %3d%% %s\r",
|
|
rgAsciiWheel[iWheelPosition],
|
|
iPercentComplete,
|
|
StringTable[ COMPLETE ] );
|
|
|
|
//
|
|
// Advance the ASCII wheel
|
|
//
|
|
|
|
iWheelPosition++;
|
|
|
|
if( iWheelPosition >= NUMBER_OF_ASCII_WHEEL_SYMBOLS )
|
|
{
|
|
iWheelPosition = 0;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// We are done copying the disk so force it to read 100% and get rid of
|
|
// the ascii wheel symbol.
|
|
//
|
|
printf( " 100%% %s \n", StringTable[ COMPLETE ] );
|
|
|
|
close( hImageFile );
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: DoesUserWantToTryCopyAgain
|
|
//
|
|
// Purpose: Ask the user if they want to retry to copy the image to floppy.
|
|
// Get the user input and return whether to copy again or not.
|
|
//
|
|
// Arguments: void
|
|
//
|
|
// Returns: int - non-zero if user wants to attempt to copy again
|
|
// - zero if user does not want to attempt to copy again
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
DoesUserWantToTryCopyAgain( void )
|
|
{
|
|
|
|
int ch;
|
|
|
|
//
|
|
// Clear the input stream by eating all the chars until there are none
|
|
// left. Print the message and then wait for a key press.
|
|
//
|
|
while( kbhit() )
|
|
{
|
|
getch();
|
|
}
|
|
|
|
do
|
|
{
|
|
printf( "%s\n", StringTable[ ATTEMPT_TO_CREATE_FLOPPY_AGAIN ] );
|
|
printf( "%s\n", StringTable[ PRESS_ENTER_OR_ESC ] );
|
|
|
|
ch = getch();
|
|
|
|
} while( ch != ENTER_KEY && ch != ESC_KEY );
|
|
|
|
if( ch == ENTER_KEY )
|
|
{
|
|
return( 1 );
|
|
}
|
|
else
|
|
{
|
|
return( 0 );
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: PressAnyKeyToContinue
|
|
//
|
|
// Purpose: Print the "Press any key when ready" message and wait until the
|
|
// user presses a key.
|
|
//
|
|
// Arguments: void
|
|
//
|
|
// Returns: void
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
PressAnyKeyToContinue( void )
|
|
{
|
|
|
|
//
|
|
// Clear the input stream by eating all the chars until there are none
|
|
// left. Print the message and then wait for a key press.
|
|
//
|
|
while( kbhit() )
|
|
{
|
|
getch();
|
|
}
|
|
|
|
printf( "%s\n", StringTable[ PRESS_ANY_KEY_TO_CONTINUE ] );
|
|
|
|
//
|
|
// Spin until the keyboard is pressed
|
|
//
|
|
while( ! kbhit() )
|
|
{
|
|
;
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: DoImageFilesExist
|
|
//
|
|
// Purpose: Determines if all the image files are in the current directory or
|
|
// not. If an image file is missing, an error message is printed
|
|
// to the user.
|
|
//
|
|
// Note: it detemines if a file exists by seeing if it can open it
|
|
// for reading.
|
|
//
|
|
// Arguments: void
|
|
//
|
|
// Returns: int -- non-zero on success, all images files exist in current dir
|
|
// zero on failure, 1 or more image files do not exist
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
DoImageFilesExist( void )
|
|
{
|
|
|
|
FILE *FileStream;
|
|
int iSuccess = 1; // assume success
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_1_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_1_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_2_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_2_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_3_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_3_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_4_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_4_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_5_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_5_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
if( ( FileStream = fopen( NT_IMAGE_6_NAME, "r" ) ) == NULL )
|
|
{
|
|
printf( StringTable[ CANNOT_FIND_FILE ], NT_IMAGE_6_NAME );
|
|
|
|
printf( "\n" );
|
|
|
|
iSuccess = 0;
|
|
}
|
|
else
|
|
{
|
|
fclose( FileStream );
|
|
}
|
|
|
|
return( iSuccess );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: IsFloppyDrive
|
|
//
|
|
// Purpose: To determine if a particular drive is a floppy drive.
|
|
//
|
|
// Arguments: int DriveLetter - the drive letter to test whether it is a
|
|
// floppy or not
|
|
//
|
|
// Returns: unsigned int -- non-zero if the specified drive is a floppy drive
|
|
// zero if the specified drive is not a floppy drive
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
unsigned int
|
|
IsFloppyDrive( int DriveLetter )
|
|
{
|
|
|
|
unsigned int drive;
|
|
unsigned int iIsFloppy;
|
|
|
|
//
|
|
// Convert the drive letter to a number. 1 = A, 2 = B, 3 = C, ...
|
|
//
|
|
drive = ( toupper( DriveLetter ) - (int)'A' ) + 1;
|
|
|
|
//
|
|
// Assume it is not a floppy
|
|
//
|
|
iIsFloppy = 0;
|
|
|
|
_asm {
|
|
push ds
|
|
push es
|
|
push bp
|
|
|
|
mov ah, 1Ch // going to call function 1Ch
|
|
mov dl, BYTE PTR [drive]
|
|
|
|
int 21h // call Int 21h function 1Ch
|
|
|
|
cmp BYTE PTR ds:[bx], 0F8h // test for fixed drive
|
|
|
|
je done
|
|
|
|
mov iIsFloppy, 1 // it is a floppy
|
|
|
|
done:
|
|
|
|
pop bp
|
|
pop es
|
|
pop ds
|
|
}
|
|
|
|
return( iIsFloppy );
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: ReportBiosError
|
|
//
|
|
// Purpose: To convert a BIOS error code to a error message and print it out
|
|
// for the user to see.
|
|
//
|
|
// Arguments: unsigned int iBiosErrorCode - the BIOS error code to be looked up
|
|
//
|
|
// Returns: void
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
ReportBiosError( unsigned int iBiosErrorCode )
|
|
{
|
|
//
|
|
// Print out the error code for the lower byte
|
|
//
|
|
switch( iBiosErrorCode & 0x00FF )
|
|
{
|
|
|
|
case 0x0000: printf( StringTable[ ERROR_DISK_WRITE_PROTECTED ] ); break;
|
|
case 0x0001: printf( StringTable[ ERROR_UNKNOWN_DISK_UNIT ] ); break;
|
|
case 0x0002: printf( StringTable[ ERROR_DRIVE_NOT_READY ] ); break;
|
|
case 0x0003: printf( StringTable[ ERROR_UNKNOWN_COMMAND ] ); break;
|
|
case 0x0004: printf( StringTable[ ERROR_DATA_ERROR ] ); break;
|
|
case 0x0005: printf( StringTable[ ERROR_BAD_REQUEST ] ); break;
|
|
case 0x0006: printf( StringTable[ ERROR_SEEK_ERROR ] ); break;
|
|
case 0x0007: printf( StringTable[ ERROR_MEDIA_TYPE_NOT_FOUND ] ); break;
|
|
case 0x0008: printf( StringTable[ ERROR_SECTOR_NOT_FOUND ] ); break;
|
|
case 0x000A: printf( StringTable[ ERROR_WRITE_FAULT ] ); break;
|
|
case 0x000C: printf( StringTable[ ERROR_GENERAL_FAILURE ] ); break;
|
|
}
|
|
|
|
//
|
|
// Print out the error code for the upper byte
|
|
//
|
|
switch( iBiosErrorCode & 0xFF00 )
|
|
{
|
|
case 0x0100: printf( StringTable[ ERROR_INVALID_REQUEST ] ); break;
|
|
case 0x0200: printf( StringTable[ ERROR_ADDRESS_MARK_NOT_FOUND ] ); break;
|
|
case 0x0300: printf( StringTable[ ERROR_DISK_WRITE_FAULT ] ); break;
|
|
case 0x0400: printf( StringTable[ ERROR_SECTOR_NOT_FOUND ] ); break;
|
|
case 0x0800: printf( StringTable[ ERROR_DMA_OVERRUN ] ); break;
|
|
case 0x1000: printf( StringTable[ ERROR_CRC_ERROR ] ); break;
|
|
case 0x2000: printf( StringTable[ ERROR_CONTROLLER_FAILURE ] ); break;
|
|
case 0x4000: printf( StringTable[ ERROR_SEEK_ERROR ] ); break;
|
|
case 0x8000: printf( StringTable[ ERROR_DISK_TIMED_OUT ] ); break;
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: AbsoluteDiskWrite
|
|
//
|
|
// Purpose: To write a buffer in memory to a specific portion of a disk.
|
|
//
|
|
// Arguments: unsigned int *iErrorCode - if an error occurs, the error code
|
|
// is returned in this OUT variable
|
|
// unsigned int iDrive - drive to write the buffer to
|
|
// unsigned int iStartingSector - sector where the write is to begin
|
|
// unsigned int iNumberOfSectorsToWrite - the number of sectors
|
|
// to write
|
|
//
|
|
// Returns: returns 1 on success, 0 on failure
|
|
// If it fails, then the error code is returned in the argument
|
|
// iErrorCode.
|
|
// If it succeeds, iErrorCode is undefined.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
unsigned int
|
|
AbsoluteDiskWrite( unsigned int *iErrorCode,
|
|
unsigned int iDrive,
|
|
unsigned int iStartingSector,
|
|
unsigned int iNumberOfSectorsToWrite,
|
|
void far *Buffer_to_be_written )
|
|
{
|
|
//
|
|
// used to temporarily store the error code
|
|
//
|
|
unsigned int iTempErrorCode;
|
|
|
|
unsigned int iRetVal;
|
|
|
|
_asm
|
|
{
|
|
push ds
|
|
push es
|
|
push bp
|
|
|
|
mov ax, WORD PTR [Buffer_to_be_written + 2]
|
|
mov ds, ax
|
|
mov bx, WORD PTR [Buffer_to_be_written]
|
|
mov dx, iStartingSector
|
|
mov cx, iNumberOfSectorsToWrite
|
|
mov al, BYTE PTR [iDrive]
|
|
|
|
int 26h // do the absolute disk write
|
|
|
|
lahf
|
|
popf
|
|
sahf
|
|
|
|
pop bp
|
|
pop es
|
|
pop ds
|
|
|
|
mov iRetVal, 1 // assume success
|
|
jnc done // see if an error occured
|
|
mov iRetVal, 0
|
|
mov iTempErrorCode, ax
|
|
done:
|
|
}
|
|
|
|
*iErrorCode = iTempErrorCode;
|
|
|
|
return( iRetVal );
|
|
|
|
}
|
|
|
|
unsigned
|
|
DnGetCodepage(void)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine the currently active codepage.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Currently active codepage. 0 if we can't determine it.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
unsigned int iRetVal;
|
|
|
|
_asm {
|
|
mov ax,06601h
|
|
int 21h
|
|
jnc ok
|
|
xor bx,bx
|
|
ok: mov iRetVal,bx
|
|
}
|
|
|
|
return( iRetVal );
|
|
|
|
}
|