/*++ Copyright (c) 1993 Microsoft Corporation Module Name: jzgetpar.c Abstract: This module contains the code to manage the boot selections. Author: David M. Robinson (davidro) 25-Oct-1991 Revision History: --*/ #include "jzsetup.h" #ifdef DUO ULONG JzGetScsiBus ( IN PULONG CurrentLine, IN ULONG InitialValue ) /*++ Routine Description: Arguments: None. Return Value: None. --*/ { ULONG Line; ULONG ReturnValue; CHAR TempString[5]; GETSTRING_ACTION Action; Line = *CurrentLine; *CurrentLine += 1; while (TRUE) { JzSetPosition( Line, 0); JzPrint(JZ_ENTER_SCSI_BUS_MSG); JzPrint("\x9bK"); sprintf(TempString, "%1d", InitialValue); do { Action = FwGetString( TempString, sizeof(TempString), TempString, Line, strlen(JZ_ENTER_SCSI_BUS_MSG)); if (Action == GetStringEscape) { return(-1); } } while ( Action != GetStringSuccess ); ReturnValue = atoi(TempString); if ((ReturnValue >= 0) && (ReturnValue <= 1)) { break; } } JzSetPosition( *CurrentLine, 0); return ReturnValue; } #endif // DUO ULONG JzGetDevice ( IN PULONG CurrentLine ) /*++ Routine Description: Arguments: None. Return Value: None. --*/ { ULONG Line; ULONG ReturnValue; Line = *CurrentLine; *CurrentLine += NUMBER_OF_MEDIA + 2; JzPrint(JZ_SELECT_MEDIA_MSG); ReturnValue = JxDisplayMenu( MediaChoices, NUMBER_OF_MEDIA, 0, Line + 1); JzSetPosition( *CurrentLine, 0); return ReturnValue; } ULONG JzGetScsiId ( IN PULONG CurrentLine, IN PCHAR Prompt, IN ULONG InitialValue ) /*++ Routine Description: Arguments: None. Return Value: None. --*/ { ULONG Line; ULONG ReturnValue; CHAR TempString[5]; GETSTRING_ACTION Action; Line = *CurrentLine; *CurrentLine += 1; while (TRUE) { JzSetPosition( Line, 0); JzPrint(Prompt); JzPrint("\x9bK"); sprintf(TempString, "%1d", InitialValue); do { Action = FwGetString( TempString, sizeof(TempString), TempString, Line, strlen(Prompt) + 1); if (Action == GetStringEscape) { return(-1); } } while ( Action != GetStringSuccess ); ReturnValue = atoi(TempString); if ((ReturnValue >= 0) && (ReturnValue <= 7)) { break; } } JzSetPosition( *CurrentLine, 0); return ReturnValue; } ULONG JzGetPartition ( IN PULONG CurrentLine, IN BOOLEAN MustBeFat ) /*++ Routine Description: Arguments: None. Return Value: None. --*/ { ULONG Line; ULONG ReturnValue; CHAR TempString[5]; GETSTRING_ACTION Action; Line = *CurrentLine; *CurrentLine += 1; while (TRUE) { JzSetPosition( Line, 0); if (MustBeFat) { JzPrint(JZ_ENTER_FAT_PART_MSG); JzPrint("\x9bK"); do { Action = FwGetString( TempString, sizeof(TempString), "1", Line, strlen(JZ_ENTER_FAT_PART_MSG)); if (Action == GetStringEscape) { return(-1); } } while ( Action != GetStringSuccess ); } else { JzPrint(JZ_ENTER_PART_MSG); JzPrint("\x9bK"); do { Action = FwGetString( TempString, sizeof(TempString), "1", Line, strlen(JZ_ENTER_PART_MSG)); if (Action == GetStringEscape) { return(-1); } } while ( Action != GetStringSuccess ); } ReturnValue = atoi(TempString); if ((ReturnValue >= 0) && (ReturnValue <= 9)) { break; } } JzSetPosition( *CurrentLine, 0); return ReturnValue; } ARC_STATUS JzPickSystemPartition ( OUT PCHAR SystemPartition, IN OUT PULONG CurrentLine ) /*++ Routine Description: This routine picks a system partition from the FWSEARCHPATH or SYSTEMPARTITION environment variables, or builds a new one. Arguments: SystemPartition - Supplies a pointer to a character array to receive the system partition. CurrentLine - The current display line. Return Value: If a system partition is picked, ESUCCESS is returned, otherwise an error code is returned. --*/ { CHAR Variable[128]; PCHAR Segment; ULONG NumberOfChoices; ULONG Index, i; BOOLEAN More; BOOLEAN FoundOne; ULONG SecondPass; ULONG BusNumber[10]; ULONG Device[10]; // 0 = scsi disk, 1 = scsi floppy, 2 = cdrom ULONG DeviceId[10]; ULONG DevicePartition[10]; ULONG Key; CHAR MenuItem[11][40]; PCHAR Menu[10]; // // Loop through the FWSEARCHPATH and SYSTEMPARTITION variables // for potential system partitions. // NumberOfChoices = 0; SecondPass = 0; do { Index = 0; if (!SecondPass) { strcpy(Variable, "FWSEARCHPATH"); } else { strcpy(Variable, BootString[SystemPartitionVariable]); } do { FoundOne = FALSE; More = FwGetVariableSegment(Index++, Variable); // // Advance to the segment. // Segment = strchr(Variable, '=') + 1; if (Segment == NULL) { continue; } // // Convert Segment to lower case. // for (i = 0 ; Segment[i] ; i++ ) { Segment[i] = tolower(Segment[i]); } // // Look for segments of the type "scsi(w)disk(x)rdisk()partition(z)" // or "scsi(w)disk(x)fdisk()" or "scsi(w)cdrom(x)fdisk()" // if (!FwGetPathMnemonicKey( Segment, "scsi", &Key )) { BusNumber[NumberOfChoices] = Key; if (!FwGetPathMnemonicKey( Segment, "disk", &Key )) { DeviceId[NumberOfChoices] = Key; if (!FwGetPathMnemonicKey( Segment, "rdisk", &Key )) { if (!FwGetPathMnemonicKey( Segment, "partition", &Key )) { Device[NumberOfChoices] = 0; DevicePartition[NumberOfChoices] = Key; FoundOne = TRUE; } } else if (!FwGetPathMnemonicKey( Segment, "fdisk", &Key )) { Device[NumberOfChoices] = 1; DevicePartition[NumberOfChoices] = 0; FoundOne = TRUE; } } else if (!FwGetPathMnemonicKey( Segment, "cdrom", &Key )) { if (!FwGetPathMnemonicKey( Segment, "fdisk", &Key )) { Device[NumberOfChoices] = 2; DeviceId[NumberOfChoices] = Key; DevicePartition[NumberOfChoices] = 0; FoundOne = TRUE; } } } // // Increment number of choices if this is not a duplicate entry. // if (FoundOne) { for ( i = 0 ; i < NumberOfChoices ; i++ ) { if ((Device[NumberOfChoices] == Device[i]) && #ifdef DUO (BusNumber[NumberOfChoices] == BusNumber[i]) && #endif DUO (DeviceId[NumberOfChoices] == DeviceId[i]) && (DevicePartition[NumberOfChoices] == DevicePartition[i])) { break; } } if (i == NumberOfChoices) { NumberOfChoices++; if (NumberOfChoices == 10) { break; } } } } while ( More ); } while ( !(SecondPass++) && (NumberOfChoices < 10)); if (NumberOfChoices != 0) { // // Display the choices. // JzPrint(JZ_SELECT_SYS_PART_MSG); *CurrentLine += 1; JzSetPosition( *CurrentLine, 0); for ( Index = 0 ; Index < NumberOfChoices ; Index++ ) { switch (Device[Index]) { #ifdef DUO case 0: sprintf( MenuItem[Index], JZ_SCSI_HD_MSG, BusNumber[Index], DeviceId[Index], DevicePartition[Index]); break; case 1: sprintf( MenuItem[Index], JZ_SCSI_FL_MSG, BusNumber[Index], DeviceId[Index]); break; default: sprintf( MenuItem[Index], JZ_SCSI_CD_MSG, BusNumber[Index], DeviceId[Index]); break; #else case 0: sprintf( MenuItem[Index], JZ_SCSI_HD_MSG, DeviceId[Index], DevicePartition[Index]); break; case 1: sprintf( MenuItem[Index], JZ_SCSI_FL_MSG, DeviceId[Index]); break; default: sprintf( MenuItem[Index], JZ_SCSI_CD_MSG, DeviceId[Index]); break; #endif // DUO } Menu[Index] = MenuItem[Index]; } strcpy(MenuItem[Index], JZ_NEW_SYS_PART_MSG); Menu[Index] = MenuItem[Index]; Index = JxDisplayMenu(Menu, NumberOfChoices + 1, 0, *CurrentLine); *CurrentLine += NumberOfChoices + 2; if (Index == -1) { return(EINVAL); } // // If the user selects new system partition, indicate this by setting // NumberOfChoices to zero. // if (Index == NumberOfChoices) { NumberOfChoices = 0; } } // // If NumberOfChoices is zero, select a new partition. // if (NumberOfChoices == 0) { Index = 0; // // Determine system partition. // JzSetPosition( *CurrentLine, 0); JzPrint(JZ_LOCATE_SYS_PART_MSG); *CurrentLine += 1; JzSetPosition( *CurrentLine, 0); #ifdef DUO BusNumber[0] = JzGetScsiBus(CurrentLine, 0); if (BusNumber[0] == -1) { return(EINVAL); } #endif // DUO Device[0] = JzGetDevice(CurrentLine); if (Device[0] == -1) { return(EINVAL); } DeviceId[0] = JzGetScsiId(CurrentLine, JZ_ENTER_SCSI_ID_MSG, 0); if (DeviceId[0] == -1) { return(EINVAL); } // // If the media is scsi disk, get the partition. // if (Device[0] == 0) { DevicePartition[0] = JzGetPartition(CurrentLine, TRUE); if (DevicePartition[0] == -1) { return(EINVAL); } } } // // Create a name string from the Device, DeviceId, // DevicePartition. // switch (Device[Index]) { #ifdef DUO case 0: sprintf( SystemPartition, "scsi(%1d)disk(%1d)rdisk()partition(%1d)", BusNumber[Index], DeviceId[Index], DevicePartition[Index]); break; case 1: sprintf( SystemPartition, "scsi(%1d)disk(%1d)fdisk()", BusNumber[Index], DeviceId[Index]); break; default: sprintf( SystemPartition, "scsi(%1d)cdrom(%1d)fdisk()", BusNumber[Index], DeviceId[Index]); break; #else case 0: sprintf( SystemPartition, "scsi()disk(%1d)rdisk()partition(%1d)", DeviceId[Index], DevicePartition[Index]); break; case 1: sprintf( SystemPartition, "scsi()disk(%1d)fdisk()", DeviceId[Index]); break; default: sprintf( SystemPartition, "scsi()cdrom(%1d)fdisk()", DeviceId[Index]); break; #endif // DUO } JzSetPosition(*CurrentLine, 0); return(ESUCCESS); } ARC_STATUS JzPickOsPartition ( OUT PCHAR OsPartition, IN OUT PULONG CurrentLine ) /*++ Routine Description: This routine picks an OsPartition. Arguments: OsSystemPartition - Supplies a pointer to a character array to receive the operationg system partition. CurrentLine - The current display line. Return Value: If a system partition is picked, ESUCCESS is returned, otherwise an error code is returned. --*/ { LONG BusNumber; LONG Device; LONG DeviceId; LONG DevicePartition; // // Determine os partition. // JzPrint(JZ_LOCATE_OS_PART_MSG); *CurrentLine += 1; JzSetPosition( *CurrentLine, 0); #ifdef DUO BusNumber = JzGetScsiBus(CurrentLine, 0); if (BusNumber == -1) { return(EINVAL); } #endif // DUO Device = JzGetDevice(CurrentLine); if (Device == -1) { return(EINVAL); } DeviceId = JzGetScsiId(CurrentLine, JZ_ENTER_SCSI_ID_MSG, 0); if (DeviceId == -1) { return(EINVAL); } // // If the media is scsi disk, get the partition. // if (Device == 0) { DevicePartition = JzGetPartition(CurrentLine, FALSE); if (DevicePartition == -1) { return(EINVAL); } } // // Create a name string from the Device, DeviceId, // DevicePartition. // switch (Device) { #ifdef DUO case 0: sprintf( OsPartition, "scsi(%1d)disk(%1d)rdisk()partition(%1d)", BusNumber, DeviceId, DevicePartition); break; case 1: sprintf( OsPartition, "scsi(%1d)disk(%1d)fdisk()", BusNumber, DeviceId); break; default: sprintf( OsPartition, "scsi(%1d)cdrom(%1d)fdisk()", BusNumber, DeviceId); break; #else case 0: sprintf( OsPartition, "scsi()disk(%1d)rdisk()partition(%1d)", DeviceId, DevicePartition); break; case 1: sprintf( OsPartition, "scsi()disk(%1d)fdisk()", DeviceId); break; default: sprintf( OsPartition, "scsi()cdrom(%1d)fdisk()", DeviceId); break; #endif // DUO } return(ESUCCESS); }