windows-nt/Source/XPSP1/NT/base/ntsetup/mpk/enduser/oschoice.c

261 lines
6.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "enduser.h"
UINT
PresentOsMenu(
IN FPCHAR ImageNames[MAX_PARTITION_IMAGES],
IN FPCHAR ImageDesc[MAX_PARTITION_IMAGES],
IN UINT ImageCount
);
BOOL
ValidateOsSelection(
IN FPCHAR Name
);
VOID
GetUserOsChoice(
IN HDISK DiskHandle
)
{
UINT Selection;
FPCHAR ImageNames[MAX_PARTITION_IMAGES];
FPCHAR ImageDesc[MAX_PARTITION_IMAGES];
UINT Count;
UINT u;
int BaseMsg,DescBase;
FPPARTITION_IMAGE Image;
//
// See if we already got the user's selection. If so, don't get it again.
// If not, get it.
//
if(MasterDiskInfo.State >= MDS_GOT_OS_CHOICE) {
_Log("Already have OS choice (%u), returning\n",MasterDiskInfo.SelectionOrdinal);
return;
}
//
// Validate image count.
//
if(!MasterDiskInfo.ImageCount) {
FatalError(textNoOsImages);
}
//
// Locate the first message for the OS name overrides in the
// message file. We assume the messages are contiguous in the table.
//
Count = GetTextCount();
BaseMsg = -1;
for(u=0; u<Count; u++) {
if(TextMessages[u].Id == TEXT_OS_NAME_BASE) {
BaseMsg = u;
}
if(TextMessages[u].Id == TEXT_OS_DESC_BASE) {
DescBase = u;
}
}
//
// Build the array of names.
//
_Log("Reading partition image headers to build os choice menu...\n\n");
Image = IoBuffer;
for(u=0; u<MasterDiskInfo.ImageCount; u++) {
//
// Read the image's header from the disk.
//
if(!ReadDisk(DiskHandle,MasterDiskInfo.ImageStartSector[u],1,IoBuffer)) {
FatalError(textReadFailedAtSector,1,MasterDiskInfo.ImageStartSector[u]);
}
_Log("Image %u --\n",u);
_Log(" Signature: 0x%lx\n",Image->Signature);
_Log(" Size: %u\n",Image->Size);
_Log(" NonClusterSectors: 0x%lx\n",Image->NonClusterSectors);
_Log(" ClusterCount: 0x%lx\n",Image->ClusterCount);
_Log(" TotalSectorCount: 0x%lx\n",Image->TotalSectorCount);
_Log(" LastUsedCluster: 0x%lx\n",Image->LastUsedCluster);
_Log(" UsedClusterCount: 0x%lx\n",Image->UsedClusterCount);
_Log(" BitmapRelocStart: 0x%lx\n",Image->BitmapRelocationStart);
_Log(" BootRelocStart: 0x%lx\n",Image->BootRelocationStart);
_Log(" SectorsPerCluster: %u\n",Image->SectorsPerCluster);
_Log(" SystemId: %u\n",Image->SystemId);
_Log(" Flags: 0x%x\n",Image->Flags);
_Log("\n");
ImageNames[u] = strdup(*TextMessages[BaseMsg+u].String);
if(!ImageNames[u]) {
FatalError(textOOM);
}
ImageDesc[u] = strdup(*TextMessages[DescBase+u].String);
if(!ImageDesc[u]) {
FatalError(textOOM);
}
}
do {
Selection = PresentOsMenu(ImageNames,ImageDesc,MasterDiskInfo.ImageCount);
} while(!ValidateOsSelection(ImageNames[Selection]));
for(u=0; u<MasterDiskInfo.ImageCount; u++) {
free(ImageNames[u]);
free(ImageDesc[u]);
}
MasterDiskInfo.SelectionOrdinal = Selection;
if(!CmdLineArgs.Test) {
_Log("Updating master disk state for os selection (%u)...\n",Selection);
UpdateMasterDiskState(DiskHandle,MDS_GOT_OS_CHOICE);
_Log("Master disk state for os selection has been updated\n");
}
}
UINT
PresentOsMenu(
IN FPCHAR ImageNames[MAX_PARTITION_IMAGES],
IN FPCHAR ImageDesc[MAX_PARTITION_IMAGES],
IN UINT ImageCount
)
{
UINT u;
BYTE x,top;
UINT LongestName,Length;
char str[80];
USHORT key;
UINT Selection;
int Previous;
FPVOID SaveArea;
unsigned SaveBytesPerRow,SaveTop,SaveHeight,DescriptionTop;
DispClearClientArea(NULL);
DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
DispWriteString(textSelectOsPrompt);
DispWriteString("\n\n");
DispGetCursorPosition(&x,&top);
top++; // top is now first line of menu
#define OS_LEFT 10
DispSetLeftMargin(OS_LEFT);
SaveArea = DispSaveDescriptionArea(&SaveTop,&SaveHeight,&SaveBytesPerRow,&DescriptionTop);
DrainKeyboard();
LongestName = 0;
for(u=0; u<ImageCount; u++) {
Length = strlen(ImageNames[u]);
if(Length > LongestName) {
LongestName = Length;
}
DispWriteString("\n ");
DispWriteString(ImageNames[u]);
}
Selection = 0;
goto highlight;
while((key = GetKey()) != ASCI_CR) {
Previous = -1;
if(key == DN_KEY_UP) {
if(Selection) {
Previous = Selection;
Selection--;
}
} else {
if(key == DN_KEY_DOWN) {
if(Selection < (ImageCount-1)) {
Previous = Selection;
Selection++;
}
}
}
if(Previous != -1) {
//
// Unhighlight the previous one and erase its description
//
memset(str,' ',LongestName+2);
str[LongestName+2] = 0;
memcpy(str+1,ImageNames[Previous],strlen(ImageNames[Previous]));
DispPositionCursor(OS_LEFT,(BYTE)(top+Previous));
DispWriteString(str);
//
// Restore description area
//
if(SaveArea) {
VgaBitBlt(0,SaveTop,640,SaveHeight,SaveBytesPerRow,TRUE,NULL,SaveArea);
} else {
VgaClearRegion(0,SaveTop,640,SaveHeight,VGAPIX_BLUE);
}
//
// Highlight the newly selected one
//
highlight:
memset(str,' ',LongestName+2);
str[LongestName+2] = 0;
memcpy(str+1,ImageNames[Selection],strlen(ImageNames[Selection]));
DispPositionCursor(OS_LEFT,(BYTE)(top+Selection));
DispSetCurrentPixelValue(HIGHLIGHT_TEXT_PIXEL_VALUE);
DispWriteString(str);
//
// Write description
//
DispPositionCursor(1,(BYTE)DescriptionTop);
DispSetLeftMargin(1);
DispSetCurrentPixelValue(VGAPIX_LIGHT_CYAN);
DispWriteString(ImageDesc[Selection]);
//
// Restore defaults for future text display
//
DispSetLeftMargin(OS_LEFT);
DispSetCurrentPixelValue(DEFAULT_TEXT_PIXEL_VALUE);
}
}
if(SaveArea) {
free(SaveArea);
}
DispSetLeftMargin(TEXT_LEFT_MARGIN);
return(Selection);
}
BOOL
ValidateOsSelection(
IN FPCHAR Name
)
{
DispClearClientArea(NULL);
DispPositionCursor(TEXT_LEFT_MARGIN,TEXT_TOP_LINE);
DispWriteString(textConfirmOs1);
DispWriteString("\n\n\n");
DispWriteString(Name);
DispWriteString("\n\n\n");
DispWriteString(textConfirmOs2);
DrainKeyboard();
return(GetKey() == DN_KEY_F8);
}