|
|
#include "enduser.h"
/*
In message files:
[10000]-[10019] are reserved for language names
[11000]-[11019] are reserved for OS selection names, which override the names specified in the images' partition image header structures.
*/
//
// Global data
//
FPVOID IoBuffer,_IoBuffer; MASTER_DISK MasterDiskInfo; CMD_LINE_ARGS CmdLineArgs;
VOID GetUserLanguageChoice( IN HDISK DiskHandle );
VOID SwitchMessageFiles( IN UINT LanguageOrdinal );
VOID SwitchBitmapAndFont( IN UINT LanguageOrdinal );
VOID main( IN int argc, IN char *argv[] ) { HDISK DiskHandle; UINT MasterDiskId;
ParseArgs(argc,argv,FALSE,"DLMTXY",&CmdLineArgs); _LogSetFlags(LOGFLAG_CLOSE_REOPEN);
//
// Load the initial message file. If this fails something is *really* hosed.
// Bail out. Note that the bail-out message is in English but there's nothing
// we can do about it since we haven't been able to load the message file!
//
if(!PatchMessagesFromFile("enduser.msg",TextMessages,GetTextCount())) { fprintf(stderr,"Setup could not load its message file.\n"); fprintf(stderr,"Contact your computer's manufacturer.\n"); return; }
//
// Load the initial font. If this failes something is *really* hosed.
// We won't even be able to go into graphics mode, but we will be able
// to at least tell the user something's wrong using the text from
// the message file.
//
if(!FontLoadAndInit("enduser.fon")) { fprintf(stderr,"%s\n\n%s\n\n",textFatalError1,textFatalError2); fprintf(stderr,textCantLoadFont,"enduser.fon"); fprintf(stderr,"\n"); return; }
//
// Allocate a maximally-sized track buffer now.
//
if(!AllocTrackBuffer(63,&IoBuffer,&_IoBuffer)) { _Log("Can't allocate 63-sector I/O buffer\n"); FatalError(textOOM); }
//
// Initialize the display package. This clears the screen and
// tosses up the background and banner bitmaps.
//
DispInitialize();
//
// Locate and open the master HD. Read the master disk info structure
// off the disk.
//
MasterDiskId = LocateMasterDisk(CmdLineArgs.MasterDiskInt13Unit); DiskHandle = OpenDisk(MasterDiskId); if(!DiskHandle) { FatalError(textCantOpenMasterDisk); } if(!ReadDisk(DiskHandle,1,1,IoBuffer)) { FatalError(textReadFailedAtSector,1,1L); } memcpy(&MasterDiskInfo,IoBuffer,sizeof(MASTER_DISK));
_Log("\nInitial master disk info (read from disk sector 1):\n"); _Log(" Signature = 0x%lx\n",MasterDiskInfo.Signature); _Log(" Size = %u\n",MasterDiskInfo.Size); _Log(" State = %u\n",MasterDiskInfo.State); _Log(" StartupPartitionStartSector = 0x%lx\n",MasterDiskInfo.StartupPartitionStartSector); _Log(" ImageCount = %u\n",MasterDiskInfo.ImageCount); _Log(" SelectedLanguage = %u\n",MasterDiskInfo.SelectedLanguage); _Log(" SelectionOrdinal = %u\n",MasterDiskInfo.SelectionOrdinal); _Log(" ClusterBitmapStart = 0x%lx\n",MasterDiskInfo.ClusterBitmapStart); _Log(" NonClusterSectorsDone = 0x%lx\n",MasterDiskInfo.NonClusterSectorsDone); _Log(" ForwardXferSectorCount = 0x%lx\n",MasterDiskInfo.ForwardXferSectorCount); _Log(" ReverseXferSectorCount = 0x%lx\n",MasterDiskInfo.ReverseXferSectorCount); _Log(" OriginalSectorsPerTrack = 0x%u\n",MasterDiskInfo.OriginalSectorsPerTrack); _Log(" OriginalHeads = 0x%u\n",MasterDiskInfo.OriginalHeads); _Log("\n");
//
// Get user's choice of language and change message files and font
// and banner bitmap.
//
GetUserLanguageChoice(DiskHandle); SwitchMessageFiles(MasterDiskInfo.SelectedLanguage); SwitchBitmapAndFont(MasterDiskInfo.SelectedLanguage);
//
// Get user's choice of OSes.
//
GetUserOsChoice(DiskHandle);
//
// Restore the selected OS.
//
RestoreUsersDisk(DiskHandle);
//
// Done, reboot.
//
DispClearClientArea(NULL); DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE+2); DispWriteString(textRebootPrompt1); DispWriteString("\n\n"); DispWriteString(textRebootPrompt2);
_Log("Done.\n");
while(GetKey() != ASCI_CR) ;
if(CmdLineArgs.Test) { _asm { mov ax,3 // standard vga mode
int 10h } } else { RebootSystem(); } }
VOID GetUserLanguageChoice( IN HDISK DiskHandle ) { UINT Selection = 0; int Previous; UINT OriginalLangCount; UINT Count,i; UINT BaseMsg; BYTE x,y; USHORT c; char string[250];
//
// See if we already got the user's selection. If so, don't get it again.
// If not, get it.
//
if(!CmdLineArgs.Test && (MasterDiskInfo.State >= MDS_GOT_LANGUAGE)) { _Log("Already have language (%u), returning\n",MasterDiskInfo.SelectedLanguage); return; }
OriginalLangCount = CmdLineArgs.LanguageCount; if(CmdLineArgs.LanguageCount > 1) {
_Log("Don't already have language, allow user to select 1 of %u languages\n",CmdLineArgs.LanguageCount);
//
// Verify that we actually have names for these languages.
// Otherwise we could end up following null pointers.
//
CmdLineArgs.LanguageCount = 0; Count = GetTextCount(); for(i=0; i<Count; i++) { if(TextMessages[i].Id == TEXT_LANGUAGE_NAME_BASE) { BaseMsg = i; while((TextMessages[i].Id <= TEXT_LANGUAGE_NAME_END) && TextMessages[i].String && *TextMessages[i].String) {
CmdLineArgs.LanguageCount++; i++; } break; } }
if(CmdLineArgs.LanguageCount > OriginalLangCount) { CmdLineArgs.LanguageCount = OriginalLangCount; } }
if(CmdLineArgs.LanguageCount > 1) {
_Log("Language count validated, user will select 1 of %u languages\n",CmdLineArgs.LanguageCount);
reselect:
DrainKeyboard(); DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE); DispWriteString(textSelectLanguage); DispWriteString("\n\n");
DispGetCursorPosition(&x,&y); y++; // y is coord of top language line
#define LANG_LEFT 15
DispSetLeftMargin(LANG_LEFT);
x = 0; for(i=0; i<CmdLineArgs.LanguageCount; i++) { DispWriteString("\n "); DispWriteString(*TextMessages[BaseMsg+i].String); if((Count = strlen(*TextMessages[BaseMsg+i].String)) > x) { x = (BYTE)Count; } }
goto highlight;
while((c = GetKey()) != ASCI_CR) {
Previous = -1;
if(c == DN_KEY_UP) { if(Selection) { Previous = Selection; Selection--; } } else { if(c == DN_KEY_DOWN) { if(Selection < (CmdLineArgs.LanguageCount-1)) { Previous = Selection; Selection++; } } }
if(Previous != -1) {
memset(string,' ',x+2); string[x+2] = 0;
memcpy( string+1, *TextMessages[BaseMsg+Previous].String, strlen(*TextMessages[BaseMsg+Previous].String) );
DispPositionCursor(LANG_LEFT,(BYTE)(y+Previous)); DispWriteString(string);
highlight:
memset(string,' ',x+2); string[x+2] = 0;
memcpy( string+1, *TextMessages[BaseMsg+Selection].String, strlen(*TextMessages[BaseMsg+Selection].String) );
DispPositionCursor(LANG_LEFT,(BYTE)(y+Selection)); DispSetCurrentPixelValue(HIGHLIGHT_TEXT_PIXEL_VALUE); DispWriteString(string); DispSetCurrentPixelValue(DEFAULT_TEXT_PIXEL_VALUE); } }
DispSetLeftMargin(TEXT_LEFT_MARGIN);
//
// Now confirm.
//
DispClearClientArea(NULL); DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE); sprintf(string,textConfirmLanguage1,*TextMessages[BaseMsg+Selection].String); DispWriteString(string); DispWriteString("\n\n"); DispWriteString(textConfirmLanguage2); DrainKeyboard(); if(GetKey() != ASCI_CR) { DispClearClientArea(NULL); goto reselect; } } else { _Log("Language selection option not invoked\n"); Selection = 0; }
MasterDiskInfo.SelectedLanguage = Selection;
if(!CmdLineArgs.Test) { _Log("Updating master disk state for language selection (%u)...\n",Selection); UpdateMasterDiskState(DiskHandle,MDS_GOT_LANGUAGE); _Log("Master disk state for language selection has been updated\n"); } }
VOID SwitchMessageFiles( IN UINT LanguageOrdinal )
/*++
Routine Description:
This routine loads a new text message file based on the language selected by the user.
The filename will be <language_ordinal>.msg.
Arguments:
LanguageOrdinal - supplies the ordinal of the language selected by the user, 0-n.
Return Value:
None.
--*/
{ char Filename[20];
sprintf(Filename,"%u.msg",LanguageOrdinal);
//
// If this fails, oh, well.
//
PatchMessagesFromFile(Filename,TextMessages,GetTextCount()); }
VOID SwitchBitmapAndFont( IN UINT LanguageOrdinal )
/*++
Routine Description:
This routine loads a new font and banner bitmap based on the language selected by the user.
The filenames will be <language_ordinal>.fon and .bmp.
Arguments:
LanguageOrdinal - supplies the ordinal of the language selected by the user, 0-n.
Return Value:
None.
--*/
{ char Filename[20];
//
// If this fails assume the file doesn't exist and
// don't worry about it.
//
sprintf(Filename,"%u.fon",LanguageOrdinal); FontLoadAndInit(Filename);
//
// Reinitialize the display to recalc font stuff
//
DispReinitialize();
//
// Pass a new banner bitmap filename and reinitialize
// the display area.
//
sprintf(Filename,"%u.bmp",LanguageOrdinal); DispClearClientArea(Filename); }
|