#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 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 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 .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 .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); }