|
|
//----------------------------------------------------------------------------
//
// Copyright (c) 1999 Microsoft Corporation
// All rights reserved.
//
// File Name:
// makebt32.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.
//
// All characters and strings are wide (UNICODE). This file needs to be
// compiled with UNICODE and _UNICODE defined.
//
// Assumptions:
// This program will only run on NT 3.51 or later. This is a result of
// the CreateFile function call. It is not available on DOS, Windows 3.1
// or Windows 9x.
//
// The floppy disk images are in the current dir and named CDBOOT1.IMG,
// CDBOOT2.IMG, CDBOOT3.IMG and CDBOOT4.IMG.
//
// Please note that there are a lot of places where I call exit() without
// freeing memory for strings I have allocated. This version of the
// program only runs on NT so when the process exits it frees all its
// memory so it is not a concern that I may not call free() on some memory.
//
//----------------------------------------------------------------------------
#include <windows.h>
#include <setupapi.h>
#include <winioctl.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include "resource.h"
//
// Constants
//
#define MAKEBOOT_MAX_STRING_LEN 1024
#define BYTES_PER_SECTOR 512
#define SECTORS_PER_TRACK 18
#define TRACK_SIZE SECTORS_PER_TRACK * BYTES_PER_SECTOR
#define TRACKS_ON_DISK 80 * 2 // * 2 because it is double-sided
#define MAX_DISK_LABEL_LENGTH 256
#define MAX_INILINE_LENGTH 1023
#define ENTER_KEY 13
#define ESC_KEY 27
#define NT_IMAGE_1_NAME L"CDBOOT1.IMG"
#define NT_IMAGE_2_NAME L"CDBOOT2.IMG"
#define NT_IMAGE_3_NAME L"CDBOOT3.IMG"
#define NT_IMAGE_4_NAME L"CDBOOT4.IMG"
#define NT_IMAGE_5_NAME L"CDBOOT5.IMG"
#define NT_IMAGE_6_NAME L"CDBOOT6.IMG"
#define NT_IMAGE_7_NAME L"CDBOOT7.IMG"
#define NUMBER_OF_ASCII_WHEEL_SYMBOLS 4
const WCHAR rgAsciiWheel[NUMBER_OF_ASCII_WHEEL_SYMBOLS] = { '|', '/', '-', '\\' };
//
// Function prototypes
//
BOOL WriteImageToFloppy( WCHAR *szFileName, WCHAR *DrivePath ); VOID PrintErrorMessage( VOID ); VOID PrintErrorWrongDriveType( UINT iDriveType ); BOOL IsDriveLargeEnough( WCHAR *DrivePath ); VOID FreeStrings( VOID ); VOID LoadStrings( VOID ); INT DoImageFilesExist( VOID ) ; VOID CleanUp( HANDLE *hFloppyDrive, HANDLE *hFloppyImage ); BOOL DoesUserWantToTryCopyAgain( VOID ); LPWSTR MyLoadString( UINT StringId ); VOID print( WCHAR *szFirstString, ... ); BOOL DoesFileExist( LPWSTR lpFileName ); VOID PressAnyKeyToContinue( VOID ); void SetFarEastThread(); void ConsolePrint( WCHAR *szFirstString, ... ); //
// Global Strings
//
WCHAR *StrOutOfMemory = NULL; WCHAR *StrComplete = NULL; WCHAR *StrNtVersionName = NULL; WCHAR *StrCanNotFindFile = NULL; WCHAR *StrDiskLabel1 = NULL; WCHAR *StrDiskLabel2 = NULL; WCHAR *StrDiskLabel3 = NULL; WCHAR *StrDiskLabel4 = NULL; WCHAR *StrDiskLabel5 = NULL; WCHAR *StrDiskLabel6 = NULL; WCHAR *StrDiskLabel7 = NULL;
WCHAR *StrStars = NULL; WCHAR *StrExplanationLine1 = NULL; WCHAR *StrExplanationLine2 = NULL; WCHAR *StrExplanationLine3 = NULL; WCHAR *StrExplanationLine4 = NULL; WCHAR *StrInsertFirstDiskLine1 = NULL; WCHAR *StrInsertFirstDiskLine2 = NULL; WCHAR *StrInsertAnotherDiskLine1 = NULL; WCHAR *StrInsertAnotherDiskLine2 = NULL; WCHAR *StrPressAnyKeyWhenReady = NULL; WCHAR *StrCompletedSuccessfully = NULL;
//----------------------------------------------------------------------------
//
// Function: wmain
//
// 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 successful program completion
// - non-zero on unsuccessful program completion, program
// terminated because of an error
//
//----------------------------------------------------------------------------
INT __cdecl wmain( INT argc, WCHAR *argv[] ) {
WCHAR *szOsName; WCHAR DriveLetter; WCHAR Drive[10]; WCHAR DrivePath[10]; UINT iDriveType; BOOL bTryAgain;
szOsName = _wgetenv( L"OS" );
//
// Make sure we are on NT.
//
if( ( szOsName == NULL ) || ( _wcsicmp( szOsName, L"Windows_NT" ) != 0 ) ) {
// ******
// This string cannot be localized because if we are not on NT then
// we don't have wide chars.
//
printf( "This program only runs on Windows NT, Windows 2000 and Windows XP.\n" );
exit( 1 );
}
SetFarEastThread();
//
// Load all of the strings from the resource file
//
LoadStrings();
//
// Don't allow the system to do any pop-ups. We will handle all
// error messages
//
SetErrorMode( SEM_FAILCRITICALERRORS );
print( L"" );
print( StrStars );
print( StrExplanationLine1 );
print( StrExplanationLine2, StrNtVersionName );
print( StrExplanationLine3 ); print( StrExplanationLine4 );
print( L"" );
//
// If they didn't specified the floppy drive on the command line then
// prompt them for it.
//
if( argc == 1 ) {
WCHAR *StrSpecifyFloppyDrive = MyLoadString( IDS_SPECIFY_FLOPPY_DRIVE );
ConsolePrint( L"%s", StrSpecifyFloppyDrive );
DriveLetter = (WCHAR)_getche();
ConsolePrint( L"\n\n" );
free( StrSpecifyFloppyDrive );
} else {
DriveLetter = argv[1][0];
}
//
// Make sure the character they entered is a possible drive letter
//
if( ! isalpha( DriveLetter ) ) {
WCHAR *StrInvalidDriveLetter = MyLoadString( IDS_INVALID_DRIVE_LETTER );
ConsolePrint( L"%s\n", StrInvalidDriveLetter );
free( StrInvalidDriveLetter );
exit( 1 );
}
//
// Make sure all the image files are in the current directory.
//
if( ! DoImageFilesExist() ) {
exit( 1 );
}
//
// Make the char DriveLetter into a string
//
Drive[0] = DriveLetter; Drive[1] = L'\0';
//
// Build the drive path. For example the a: drive looks like \\.\a:
//
swprintf( DrivePath, L"\\\\.\\%c:", DriveLetter );
//
// Make sure the drive is a floppy drive
//
iDriveType = GetDriveType( wcscat( Drive, L":\\" ) );
if( iDriveType != DRIVE_REMOVABLE ) {
PrintErrorWrongDriveType( iDriveType );
exit( 1 );
}
//
// Make sure the drive can hold at least 1.44 MB
//
if( ! IsDriveLargeEnough( DrivePath ) ) {
WCHAR *Str144NotSupported = MyLoadString( IDS_144_NOT_SUPPORTED );
ConsolePrint( L"%s\n", Str144NotSupported );
free( Str144NotSupported );
exit( 1 );
}
print( StrInsertFirstDiskLine1, DriveLetter ); print( StrInsertFirstDiskLine2, StrDiskLabel1 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_1_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel2 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_2_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel3 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_3_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel4 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_4_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel5 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_5_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel6 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_6_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrInsertAnotherDiskLine1, DriveLetter ); print( StrInsertAnotherDiskLine2, StrDiskLabel7 );
PressAnyKeyToContinue();
while( ! WriteImageToFloppy( NT_IMAGE_7_NAME, DrivePath ) ) {
bTryAgain = DoesUserWantToTryCopyAgain();
if( ! bTryAgain ) { exit( 1 ); }
}
print( L"" );
print( StrCompletedSuccessfully );
print( StrStars );
FreeStrings();
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
// char *DrivePath - drive path of the floppy to write to, it is of
// the form \\.\x where x is the drive letter
//
// Returns: BOOL - TRUE if image written to floppy properly
// FALSE if there were errors
//
//----------------------------------------------------------------------------
BOOL WriteImageToFloppy( WCHAR *szFileName, WCHAR *DrivePath ) {
INT iCurrentTrack; INT cBytesRead = 0; INT cBytesWritten = 0; INT iPercentComplete = 0; INT iWheelPosition = 0; HANDLE hFloppyImage = NULL; HANDLE hFloppyDrive = NULL; char TrackBuffer[TRACK_SIZE];
hFloppyImage = CreateFile( szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if( hFloppyImage == INVALID_HANDLE_VALUE ) {
PrintErrorMessage();
return( FALSE );
}
hFloppyDrive = CreateFile( DrivePath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if( hFloppyDrive == INVALID_HANDLE_VALUE ) {
PrintErrorMessage();
CleanUp( &hFloppyDrive, &hFloppyImage );
return( FALSE );
}
for( iCurrentTrack = 0; iCurrentTrack < TRACKS_ON_DISK; iCurrentTrack++ ) { if( ! ReadFile( hFloppyImage, TrackBuffer, TRACK_SIZE, &cBytesRead, NULL ) ) {
PrintErrorMessage();
CleanUp( &hFloppyDrive, &hFloppyImage );
return( FALSE );
}
if( ! WriteFile( hFloppyDrive, TrackBuffer, TRACK_SIZE, &cBytesWritten, NULL ) ) {
PrintErrorMessage();
CleanUp( &hFloppyDrive, &hFloppyImage );
return( FALSE );
}
iPercentComplete = (int) ( ( (double) (iCurrentTrack) / (double) (TRACKS_ON_DISK) ) * 100.0 );
ConsolePrint( L"%c %3d%% %s.\r", rgAsciiWheel[iWheelPosition], iPercentComplete, StrComplete );
//
// 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.
//
ConsolePrint( L" 100%% %s. \n", StrComplete );
//
// Free allocated resources
//
CleanUp( &hFloppyDrive, &hFloppyImage );
return TRUE;
}
//----------------------------------------------------------------------------
//
// Function: PrintErrorMessage
//
// Purpose: To get the last system error, look up what it is and print it out
// to the user.
//
// Arguments: VOID
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID PrintErrorMessage( VOID ) {
LPVOID lpMsgBuf = NULL;
if(!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &lpMsgBuf, 0, NULL )) { // Great. Not enough memory to format an error message.
ConsolePrint( L"\nNot enough memory to format error message.\n" ); if( lpMsgBuf ) LocalFree( lpMsgBuf ); } else {
ConsolePrint( L"\n%s\n", (LPCWSTR)lpMsgBuf );
LocalFree( lpMsgBuf ); }
}
//----------------------------------------------------------------------------
//
// Function: PrintErrorWrongDriveType
//
// Purpose: To translate a drive type error code into a message and print it
//
// Arguments: UINT iDriveType - drive type error code to look-up
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID PrintErrorWrongDriveType( UINT iDriveType ) {
if( iDriveType == DRIVE_NO_ROOT_DIR ) { WCHAR *StrNoRootDir = MyLoadString( IDS_NO_ROOT_DIR );
ConsolePrint( L"\n%s\n", StrNoRootDir );
free( StrNoRootDir ); } else { WCHAR *StrDriveNotFloppy = MyLoadString( IDS_DRIVE_NOT_FL0PPY );
ConsolePrint( L"\n%s\n", StrDriveNotFloppy );
free( StrDriveNotFloppy ); }
}
//----------------------------------------------------------------------------
//
// Function: IsDriveLargeEnough
//
// Purpose: To determine if the floppy drive supports 1.44 MB or larger disks
//
// Arguments: char* DrivePath - drive path of the floppy to write to, it is of
// the form \\.\x where x is the drive letter
//
// Returns: BOOL - TRUE if the drive supports 1.44 MB or greater, FALSE if not
//
//----------------------------------------------------------------------------
BOOL IsDriveLargeEnough( WCHAR *DrivePath ) {
UINT i; HANDLE hFloppyDrive; DISK_GEOMETRY SupportedGeometry[20]; DWORD SupportedGeometryCount; DWORD ReturnedByteCount;
hFloppyDrive = CreateFile( DrivePath, 0, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL );
if( hFloppyDrive == INVALID_HANDLE_VALUE ) {
PrintErrorMessage();
exit( 1 );
}
if( DeviceIoControl( hFloppyDrive, IOCTL_DISK_GET_MEDIA_TYPES, NULL, 0, SupportedGeometry, sizeof( SupportedGeometry ), &ReturnedByteCount, NULL ) ) {
SupportedGeometryCount = ( ReturnedByteCount / sizeof( DISK_GEOMETRY ) );
} else { SupportedGeometryCount = 0; }
CloseHandle( hFloppyDrive );
for( i = 0; i < SupportedGeometryCount; i++ ) {
if( SupportedGeometry[i].MediaType == F3_1Pt44_512 ) {
//
// This drive supports 3.5, 1.44MB, 512 bytes/sector.
//
return( TRUE );
}
}
return( FALSE );
}
//----------------------------------------------------------------------------
//
// 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 ) {
BOOL bAllFilesExist = TRUE;
if( ! DoesFileExist( NT_IMAGE_1_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_1_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_2_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_2_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_3_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_3_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_4_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_4_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_5_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_5_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_6_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_6_NAME ); bAllFilesExist = FALSE; } if( ! DoesFileExist( NT_IMAGE_7_NAME ) ) { print( StrCanNotFindFile, NT_IMAGE_7_NAME ); bAllFilesExist = FALSE; }
if( bAllFilesExist ) { return( 1 ); } else { return( 0 ); }
}
//----------------------------------------------------------------------------
//
// Function: CleanUp
//
// Purpose: Closes open handles. This function should be called just before
// exiting the program.
//
// Arguments: HANDLE *hFloppyDrive - the floppy disk handle to be closed
// HANDLE *hFloppyImage - the floppy image file handle to be closed
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID CleanUp( HANDLE *hFloppyDrive, HANDLE *hFloppyImage ) {
if( *hFloppyDrive ) { CloseHandle( *hFloppyDrive ); *hFloppyDrive = NULL; }
if( *hFloppyImage ) { CloseHandle( *hFloppyImage ); *hFloppyImage = NULL; }
}
//----------------------------------------------------------------------------
//
// Function: FreeStrings
//
// Purpose: Deallocate the memory for all the strings.
//
// Arguments: VOID
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID FreeStrings( VOID ) {
free( StrNtVersionName ); free( StrDiskLabel1 ); free( StrDiskLabel2 ); free( StrDiskLabel3 ); free( StrDiskLabel4 ); free( StrDiskLabel5 ); free( StrDiskLabel6 ); free( StrDiskLabel7 );
free( StrStars ); free( StrExplanationLine1 ); free( StrExplanationLine2 ); free( StrExplanationLine3 ); free( StrExplanationLine4 ); free( StrInsertFirstDiskLine1 ); free( StrInsertFirstDiskLine2 ); free( StrInsertAnotherDiskLine1 ); free( StrInsertAnotherDiskLine2 ); free( StrPressAnyKeyWhenReady ); free( StrCompletedSuccessfully ); free( StrComplete );
free( StrCanNotFindFile );
free( StrOutOfMemory );
}
//----------------------------------------------------------------------------
//
// Function: LoadStrings
//
// Purpose: Load the string constants from the string table.
//
// Arguments: VOID
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID LoadStrings( VOID ) {
INT Length;
//
// Loading the Out of Memory string is a little tricky because of the
// error that can occur while loading it.
//
// For the other strings, just call the MyLoadString function to do
// the work
//
StrOutOfMemory = (WCHAR *) malloc( MAKEBOOT_MAX_STRING_LEN * sizeof(WCHAR) + 1 );
if( StrOutOfMemory == NULL ) { //
// Can't localize this string
//
ConsolePrint( L"\nOut of memory. Please free more memory and run this program again.\n" );
exit( 1 ); }
Length = LoadString( NULL, IDS_OUT_OF_MEMORY, StrOutOfMemory, MAKEBOOT_MAX_STRING_LEN );
if( ! Length ) { //
// Can't localize this string
//
ConsolePrint( L"Unable to load resources.\n" );
exit( 1 ) ; }
StrStars = MyLoadString( IDS_STARS ); StrExplanationLine1 = MyLoadString( IDS_PROGRAM_EXPLANATION_LINE_1 ); StrExplanationLine2 = MyLoadString( IDS_PROGRAM_EXPLANATION_LINE_2 ); StrExplanationLine3 = MyLoadString( IDS_PROGRAM_EXPLANATION_LINE_3 ); StrExplanationLine4 = MyLoadString( IDS_PROGRAM_EXPLANATION_LINE_4 );
StrInsertFirstDiskLine1 = MyLoadString( IDS_INSERT_FIRST_DISK_LINE_1 ); StrInsertFirstDiskLine2 = MyLoadString( IDS_INSERT_FIRST_DISK_LINE_2 );
StrInsertAnotherDiskLine1 = MyLoadString( IDS_INSERT_ANOTHER_DISK_LINE_1 ); StrInsertAnotherDiskLine2 = MyLoadString( IDS_INSERT_ANOTHER_DISK_LINE_2 );
StrPressAnyKeyWhenReady = MyLoadString( IDS_PRESS_ANY_KEY_WHEN_READY );
StrCompletedSuccessfully = MyLoadString( IDS_COMPLETED_SUCCESSFULLY ); StrComplete = MyLoadString( IDS_COMPLETE );
StrCanNotFindFile = MyLoadString( IDS_CANNOT_FIND_FILE );
StrNtVersionName = MyLoadString( IDS_NT_VERSION_NAME_DEFAULT ); StrDiskLabel1 = MyLoadString( IDS_DISK_LABEL_1_DEFAULT ); StrDiskLabel2 = MyLoadString( IDS_DISK_LABEL_2_DEFAULT ); StrDiskLabel3 = MyLoadString( IDS_DISK_LABEL_3_DEFAULT ); StrDiskLabel4 = MyLoadString( IDS_DISK_LABEL_4_DEFAULT ); StrDiskLabel5 = MyLoadString( IDS_DISK_LABEL_5_DEFAULT ); StrDiskLabel6 = MyLoadString( IDS_DISK_LABEL_6_DEFAULT ); StrDiskLabel7 = MyLoadString( IDS_DISK_LABEL_7_DEFAULT );
}
//----------------------------------------------------------------------------
//
// 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: BOOL - TRUE if user wants to attempt to copy again
// - FALSE if user does not want to attempt to copy again
//
//----------------------------------------------------------------------------
BOOL DoesUserWantToTryCopyAgain( VOID ) {
INT ch;
WCHAR *StrAttemptToCreateFloppyAgain = MyLoadString( IDS_ATTEMPT_TO_CREATE_FLOPPY_AGAIN ); WCHAR *StrPressEnterOrEsc = MyLoadString( IDS_PRESS_ENTER_OR_ESC );
//
// 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 { ConsolePrint( L"%s\n", StrAttemptToCreateFloppyAgain ); ConsolePrint( L"%s\n", StrPressEnterOrEsc );
ch = _getch();
} while( ch != ENTER_KEY && ch != ESC_KEY );
if( ch == ENTER_KEY ) { return( TRUE ); } else { return( FALSE ); }
free( StrAttemptToCreateFloppyAgain ); free( StrPressEnterOrEsc );
}
//----------------------------------------------------------------------------
//
// 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(); }
print( StrPressAnyKeyWhenReady );
//
// Spin until the keyboard is pressed
//
while( ! _kbhit() ) { ; }
}
//----------------------------------------------------------------------------
//
// Function: MyLoadString
//
// Purpose: Loads a string resource given it's IDS_* and returns
// a malloc'ed buffer with its contents.
//
// The malloc()'ed buffer must be freed with free()
//
// This function will either return the string or exit. It will
// never return NULL or a bad pointer.
//
// Arguments: UINT StringId - the string ID to load
//
// Returns:
// Pointer to buffer. An empty string is returned if the StringId
// does not exist. Null is returned if out of memory.
//
//----------------------------------------------------------------------------
LPWSTR MyLoadString( UINT StringId ) {
WCHAR Buffer[ MAKEBOOT_MAX_STRING_LEN ]; WCHAR *String = NULL; UINT Length;
Length = LoadString( NULL, StringId, Buffer, MAKEBOOT_MAX_STRING_LEN );
if( Length ) {
String = (WCHAR *) malloc( Length * sizeof(WCHAR) + 1 );
if( String == NULL ) {
ConsolePrint( L"%s\n", StrOutOfMemory );
exit( 1 );
} else {
wcscpy( String, Buffer ); String[Length] = L'\0';
return( String );
}
} else {
//
// Can't load the string so exit
// NOTE: this string will not be localized
//
ConsolePrint( L"Unable to load resources.\n" );
exit( 1 );
}
}
//----------------------------------------------------------------------------
//
// Function: print
//
// Purpose: To print out strings to the user. Useful when there is
// embedded formatting characters in a string that was loaded from
// a string table.
//
// Arguments: szFirstString - the string that contains the embedded formatting
// characters (such as %s, %c, etc.)
// ... - variable number of arguments that correspond to each
// formatting character
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID print( WCHAR *szFirstString, ... ) {
WCHAR OutputBuffer[MAKEBOOT_MAX_STRING_LEN]; va_list arglist;
va_start( arglist, szFirstString );
wvsprintf( OutputBuffer, szFirstString, arglist );
ConsolePrint( L"%s\n", OutputBuffer );
va_end( arglist );
}
//----------------------------------------------------------------------------
//
// Function: DoesFileExist
//
// Purpose: To determine whether a file exists or not
//
// Arguments: LPWSTR lpFileName - filename to see if it exists or not
//
// Returns: BOOL - TRUE if the file exists
// - FALSE if the file does not exist
//
//----------------------------------------------------------------------------
BOOL DoesFileExist( LPWSTR lpFileName ) { DWORD dwAttribs = GetFileAttributes( lpFileName );
if( dwAttribs == (DWORD) -1 ) { return( FALSE ); }
if( dwAttribs & FILE_ATTRIBUTE_DIRECTORY ) { return( FALSE ); }
return( TRUE ); }
//----------------------------------------------------------------------------
//
// Function: IsDBCSConsole
//
// Purpose: To determine whether a DBC console or not
//
// Arguments: None
//
// Returns: BOOL - TRUE if FE console codepage
// - FALSE if not FE console codepage
//
//----------------------------------------------------------------------------
BOOL IsDBCSCodePage(UINT CodePage) { switch(CodePage) { case 932: case 936: case 949: case 950: return TRUE; } return FALSE; }
//----------------------------------------------------------------------------
//
// Function: SetFarEastThread
//
// Purpose: FarEast version wants to display bi-lingual string according console OCP
//
// Arguments: None
//
// Returns: None
//----------------------------------------------------------------------------
void SetFarEastThread() { LANGID LangId = 0;
switch(GetConsoleOutputCP()) { case 932: LangId = MAKELANGID( LANG_JAPANESE, SUBLANG_DEFAULT ); break; case 949: LangId = MAKELANGID( LANG_KOREAN, SUBLANG_KOREAN ); break; case 936: LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED ); break; case 950: LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ); break; default: { LANGID TmpLangId = PRIMARYLANGID(LANGIDFROMLCID( GetUserDefaultLCID() ));
if (TmpLangId == LANG_JAPANESE || TmpLangId == LANG_KOREAN || TmpLangId == LANG_CHINESE ) { LangId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); } } break; }
if (LangId) { SetThreadLocale( MAKELCID(LangId, SORT_DEFAULT) ); } }
//----------------------------------------------------------------------------
//
// Function: ConsolePrint
//
// Purpose: There is a bug in CRT library that unicode FE characters can't
// convert correctly, so we output characters directly.
//
// Arguments: None
//
// Returns: None
//----------------------------------------------------------------------------
void ConsolePrint( WCHAR *szFirstString, ... ) { HANDLE StdOut; DWORD WrittenCount; WCHAR OutputBuffer[MAKEBOOT_MAX_STRING_LEN]; va_list arglist;
if((StdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) { return; }
va_start( arglist, szFirstString );
wvsprintf( OutputBuffer, szFirstString, arglist );
WriteConsoleW( StdOut, OutputBuffer, lstrlenW(OutputBuffer), &WrittenCount, NULL );
va_end( arglist ); }
|