NT4/private/ntos/fw/mips/jzcommon.c
2020-09-30 17:12:29 +02:00

877 lines
18 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
jzcommon.c
Abstract:
This program contains the common routines for the Jazz setup program.
Author:
David M. Robinson (davidro) 25-Oct-1991
Revision History:
--*/
#include "jzsetup.h"
//
// Static Data
//
CHAR VolatileEnvironment[LENGTH_OF_ENVIRONMENT];
BOOLEAN SetupIsRunning;
extern PCHAR Banner1, Banner2;
int
vsprintf (
char *string,
char *format,
va_list arglist);
VOID
JzPrint (
PCHAR Format,
...
)
{
va_list arglist;
UCHAR Buffer[256];
ULONG Count;
ULONG Length;
//
// Format the output into a buffer and then print it.
//
va_start(arglist, Format);
Length = vsprintf(Buffer, Format, arglist);
ArcWrite( ARC_CONSOLE_OUTPUT, Buffer, Length, &Count);
va_end(arglist);
return 0;
}
ULONG
JxDisplayMenu (
IN PCHAR Choices[],
IN ULONG NumberOfChoices,
IN LONG DefaultChoice,
IN ULONG CurrentLine
)
/*++
Routine Description:
Arguments:
Return Value:
Returns -1 if the escape key is pressed, otherwise returns the menu item
selected, where 0 is the first item.
--*/
{
ULONG Index;
UCHAR Character;
ULONG Count;
for (Index = 0; Index < NumberOfChoices ; Index++ ) {
JzSetPosition( Index + CurrentLine, 10);
if (Index == DefaultChoice) {
JzSetScreenAttributes( TRUE, FALSE, TRUE);
JzPrint(Choices[Index]);
JzSetScreenAttributes( TRUE, FALSE, FALSE);
} else {
JzPrint(Choices[Index]);
}
}
Character = 0;
do {
if (SetupIsRunning) {
JzShowTime(FALSE);
}
if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) {
ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count);
switch (Character) {
case ASCII_ESC:
//
// If there is another character available, look to see if
// this a control sequence. This is an attempt to make
// Escape sequences from a terminal work.
//
JzStallExecution(10000);
if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) {
ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count);
if (Character != '[') {
return(-1);
}
} else {
return(-1);
}
case ASCII_CSI:
ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count);
JzSetPosition( DefaultChoice + CurrentLine, 10);
JzPrint(Choices[DefaultChoice]);
switch (Character) {
case 'A':
case 'D':
DefaultChoice--;
if (DefaultChoice < 0) {
DefaultChoice = NumberOfChoices-1;
}
break;
case 'B':
case 'C':
DefaultChoice++;
if (DefaultChoice == NumberOfChoices) {
DefaultChoice = 0;
}
break;
case 'H':
DefaultChoice = 0;
break;
default:
break;
}
JzSetPosition( DefaultChoice + CurrentLine, 10);
JzSetScreenAttributes( TRUE, FALSE, TRUE);
JzPrint(Choices[DefaultChoice]);
JzSetScreenAttributes( TRUE, FALSE, FALSE);
continue;
default:
break;
}
}
} while ((Character != '\n') && (Character != ASCII_CR));
return DefaultChoice;
}
GETSTRING_ACTION
FwGetString(
OUT PCHAR String,
IN ULONG StringLength,
IN PCHAR InitialString OPTIONAL,
IN ULONG CurrentRow,
IN ULONG CurrentColumn
)
/*++
Routine Description:
This routine reads a string from standardin until a carriage return is
found, StringLength is reached, or ESC is pushed.
Arguments:
String - Supplies a pointer to a location where the string is to be stored.
StringLength - Supplies the Max Length to read.
InitialString - Supplies an optional initial string.
CurrentRow - Supplies the current screen row.
CurrentColumn - Supplies the current screen column.
Return Value:
If the string was successfully obtained GetStringSuccess is return,
otherwise one of the following codes is returned.
GetStringEscape - the escape key was pressed or StringLength was reached.
GetStringUpArrow - the up arrow key was pressed.
GetStringDownArrow - the down arrow key was pressed.
--*/
{
ARC_STATUS Status;
UCHAR c;
ULONG Count;
PCHAR Buffer;
PCHAR Cursor;
PCHAR CopyPointer;
GETSTRING_ACTION Action;
BOOLEAN CarriageReturn;
//
// If an initial string was supplied, update the output string.
//
if (ARGUMENT_PRESENT(InitialString)) {
strcpy(String, InitialString);
Buffer = strchr(String, 0);
} else {
*String = 0;
Buffer = String;
}
Cursor = Buffer;
while (TRUE) {
//
// Flag to print a carriage return/line feed when all is done.
//
CarriageReturn = FALSE;
//
// Print the string.
//
JzSetPosition(CurrentRow, CurrentColumn);
JzPrint(String);
JzPrint("\x9bK");
//
// Print the cursor.
//
JzSetScreenAttributes(TRUE,FALSE,TRUE);
JzSetPosition(CurrentRow, (Cursor - String) + CurrentColumn);
if (Cursor >= Buffer) {
JzPrint(" ");
} else {
ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count);
}
JzSetScreenAttributes(TRUE,FALSE,FALSE);
while (ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) {
if (SetupIsRunning) {
JzShowTime(FALSE);
}
}
Status = ArcRead(ARC_CONSOLE_INPUT,&c,1,&Count);
if (Status != ESUCCESS) {
Action = GetStringEscape;
goto EndGetString;
}
if (Buffer-String == StringLength) {
Action = GetStringEscape;
goto EndGetString;
}
switch (c) {
case ASCII_ESC:
//
// If there is another character available, look to see if
// this a control sequence, and fall through to ASCII_CSI.
// This is an attempt to make escape sequences from a terminal work.
//
JzStallExecution(10000);
if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) {
ArcRead(ARC_CONSOLE_INPUT, &c, 1, &Count);
if (c != '[') {
Action = GetStringEscape;
goto EndGetString;
}
} else {
Action = GetStringEscape;
goto EndGetString;
}
case ASCII_CSI:
ArcRead(ARC_CONSOLE_INPUT, &c, 1, &Count);
switch (c) {
case 'A':
Action = GetStringUpArrow;
goto EndGetString;
case 'D':
if (Cursor != String) {
Cursor--;
}
continue;
case 'B':
Action = GetStringDownArrow;
goto EndGetString;
case 'C':
if (Cursor != Buffer) {
Cursor++;
}
continue;
case 'H':
Cursor = String;
continue;
case 'K':
Cursor = Buffer;
continue;
case 'P':
CopyPointer = Cursor;
while (*CopyPointer) {
*CopyPointer = *(CopyPointer + 1);
CopyPointer++;
}
if (Buffer != String) {
Buffer--;
}
continue;
default:
break;
}
break;
case '\r':
case '\n':
CarriageReturn = TRUE;
Action = GetStringSuccess;
goto EndGetString;
case '\b':
if (Cursor != String) {
Cursor--;
}
CopyPointer = Cursor;
while (*CopyPointer) {
*CopyPointer = *(CopyPointer + 1);
CopyPointer++;
}
if (Buffer != String) {
Buffer--;
}
break;
default:
//
// Store the character.
//
CopyPointer = ++Buffer;
if (CopyPointer > Cursor) {
while (CopyPointer != Cursor) {
*CopyPointer = *(CopyPointer - 1);
CopyPointer--;
}
}
*Cursor++ = c;
break;
}
}
Action = GetStringEscape;
EndGetString:
//
// Clear the cursor.
//
JzSetPosition(CurrentRow, (Cursor - String) + CurrentColumn);
if (Cursor >= Buffer) {
JzPrint(" ");
} else {
ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count);
}
if (CarriageReturn) {
ArcWrite(ARC_CONSOLE_OUTPUT,JZ_CRLF_MSG,2,&Count);
}
//
// Make sure we return a null string if not successful.
//
if (Action != GetStringSuccess) {
*String = 0;
}
return(Action);
}
ARC_STATUS
FwEnvironmentCheckChecksum (
VOID
)
/*++
Routine Description:
This routine checks the environment area checksum.
Arguments:
None.
Return Value:
If the checksum is good, ESUCCESS is returned, otherwise EIO is returned.
--*/
{
PUCHAR NvChars;
PNV_CONFIGURATION NvConfiguration;
ULONG Index;
ULONG Checksum1, Checksum2;
NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
//
// Form checksum from NVRAM data.
//
Checksum1 = 0;
NvChars = (PUCHAR)&NvConfiguration->Environment[0];
for ( Index = 0 ;
Index < LENGTH_OF_ENVIRONMENT;
Index++ ) {
Checksum1 += READ_REGISTER_UCHAR( NvChars++ );
}
//
// Reconstitute checksum and return error if no compare.
//
Checksum2 = (ULONG)READ_REGISTER_UCHAR( &NvConfiguration->Checksum2[0] ) |
(ULONG)READ_REGISTER_UCHAR( &NvConfiguration->Checksum2[1] ) << 8 |
(ULONG)READ_REGISTER_UCHAR( &NvConfiguration->Checksum2[2] ) << 16 |
(ULONG)READ_REGISTER_UCHAR( &NvConfiguration->Checksum2[3] ) << 24 ;
if (Checksum1 != Checksum2) {
return EIO;
} else {
return ESUCCESS;
}
}
PCHAR
FwEnvironmentLoad (
VOID
)
/*++
Routine Description:
This routine loads the entire environment into a volatile environment
area.
Arguments:
None.
Return Value:
If the checksum is good, a pointer to the environment in returned,
otherwise NULL is returned.
--*/
{
ULONG Index;
PUCHAR NvChars;
PUCHAR VChars;
PNV_CONFIGURATION NvConfiguration;
if (FwEnvironmentCheckChecksum() == ESUCCESS) {
NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
//
// Copy the data into the volatile area.
//
NvChars = (PUCHAR)&NvConfiguration->Environment[0];
VChars = (PUCHAR)&VolatileEnvironment;
for ( Index = 0 ;
Index < LENGTH_OF_ENVIRONMENT;
Index++ ) {
*VChars++ = READ_REGISTER_UCHAR( NvChars++ );
}
return (PCHAR)&VolatileEnvironment;
} else {
return NULL;
}
}
BOOLEAN
FwGetPathMnemonicKey(
IN PCHAR OpenPath,
IN PCHAR Mnemonic,
IN PULONG Key
)
/*++
Routine Description:
This routine looks for the given Mnemonic in OpenPath.
If Mnemonic is a component of the path, then it converts the key
value to an integer wich is returned in Key.
Arguments:
OpenPath - Pointer to a string that contains an ARC pathname.
Mnemonic - Pointer to a string that contains a ARC Mnemonic
Key - Pointer to a ULONG where the Key value is stored.
Return Value:
FALSE if mnemonic is found in path and a valid key is converted.
TRUE otherwise.
--*/
{
PCHAR Tmp;
CHAR Digits[4];
ULONG i;
CHAR String[16];
//
// Construct a string of the form ")mnemonic("
//
String[0]=')';
for(i=1;*Mnemonic;i++) {
String[i] = * Mnemonic++;
}
String[i++]='(';
String[i]='\0';
if ((Tmp=strstr(OpenPath,&String[1])) == NULL) {
return TRUE;
}
if (Tmp != OpenPath) {
if ((Tmp=strstr(OpenPath,String)) == NULL) {
return TRUE;
}
} else {
i--;
}
//
// skip the mnemonic and convert the value in between parentesis to integer
//
Tmp+=i;
for (i=0;i<3;i++) {
if (*Tmp == ')') {
Digits[i] = '\0';
break;
}
Digits[i] = *Tmp++;
}
Digits[i]='\0';
*Key = atoi(Digits);
return FALSE;
}
VOID
FwWaitForKeypress(
VOID
)
/*++
Routine Description:
This routine waits for a keypress, then returns.
Arguments:
None.
Return Value:
None.
--*/
{
UCHAR Character;
ULONG Count;
JzPrint(JZ_PRESS_KEY_MSG);
while (ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) {
if (SetupIsRunning) {
JzShowTime(FALSE);
}
}
ArcRead(ARC_CONSOLE_INPUT, &Character, 1, &Count);
JzPrint("%c2J", ASCII_CSI);
}
BOOLEAN
FwGetVariableSegment (
IN ULONG SegmentNumber,
IN OUT PCHAR Segment
)
/*++
Routine Description:
This routine returns the specified segment of an environment variable.
Segments are separated by semicolons.
Arguments:
SegmentNumber - Supplies the number of the segment to return.
Segment - Supplies a pointer to the name of the environment variable.
The variable may be followed by an equal sign.
An '=' and the segment value are appended to this name and
returned.
Return Value:
If one or more segments exist after the specified segment, TRUE is returned,
otherwise FALSE is returned.
--*/
{
ULONG Index;
ULONG Count;
PCHAR VariableValue;
PCHAR TempPointer;
//
// Remove an equal sign if present.
//
if ((TempPointer = strchr(Segment, '=')) != NULL) {
*TempPointer = 0;
}
//
// Get variable, add equal sign, and advance Segment to where the value
// is to be added.
//
VariableValue = ArcGetEnvironmentVariable(Segment);
strcat(Segment, "=");
Segment = strchr(Segment, '=') + 1;
//
// If there was no variable, return.
//
if (VariableValue == NULL) {
return(FALSE);
}
Index = 0;
Count = 0;
//
// Search for the requested segment and copy it to the return value.
//
while ((TempPointer = strchr(VariableValue,';')) != NULL) {
Count = TempPointer - VariableValue;
if (Index == SegmentNumber) {
strncpy(Segment, VariableValue, Count);
Segment[Count] = 0;
return TRUE;
}
VariableValue += Count + 1;
Index++;
}
//
// If there is data left, copy it to the return value.
//
strcpy(Segment,VariableValue);
return(FALSE);
}
ARC_STATUS
FwSetVariableSegment (
IN ULONG SegmentNumber,
IN PCHAR VariableName,
IN PCHAR NewSegment
)
/*++
Routine Description:
This routine sets the specified segment of an environment variable.
Segments are separated by semicolons.
Arguments:
SegmentNumber - Supplies the number of the segment to add.
VariableName - Supplies a pointer to the name of the environment variable.
The variable may be followed by an equal sign.
NewSegment - Supplies a pointer to the new segment.
Return Value:
Returns ESUCCESS is the segment is set, otherwise an error code is
returned.
--*/
{
ARC_STATUS Status;
PCHAR Variable;
PCHAR NextVariable;
PCHAR EndOfVariable;
CHAR VariableValue[256];
ULONG Index;
ULONG Count;
Variable = ArcGetEnvironmentVariable(VariableName);
VariableValue[0] = 0;
if (Variable != NULL) {
EndOfVariable = strchr(Variable, 0);
for (Index = 0; Index < SegmentNumber ; Index++ ) {
NextVariable = strchr(Variable, ';');
if (NextVariable != NULL) {
Count = NextVariable - Variable + 1;
strncat(VariableValue, Variable, Count);
Variable = NextVariable + 1;
} else {
strcat(VariableValue, Variable);
Variable = EndOfVariable;
strcat(VariableValue, ";");
}
}
} else {
for (Index = 0; Index < SegmentNumber ; Index++ ) {
strcat(VariableValue, ";");
}
}
strcat(VariableValue, NewSegment);
if ((Variable != NULL) && (Variable != EndOfVariable)) {
strcat(VariableValue, ";");
strcat(VariableValue, Variable);
}
Status = ArcSetEnvironmentVariable(VariableName, VariableValue);
return(Status);
}
ULONG
JzGetSelection (
IN PCHAR Menu[],
IN ULONG NumberOfChoices,
IN ULONG DefaultChoice
)
/*++
Routine Description:
This routine gets a menu selection from the user.
Arguments:
Menu - Supplies an array of pointers to menu character strings.
Selections - Supplies the number of menu selections.
DefaultChoice - Supplies the current default choice.
Return Value:
Returns the value selected, -1 if the escape key was pressed.
--*/
{
ULONG CurrentLine;
ULONG Index;
//
// Clear screen and print banner.
//
JzSetScreenAttributes( TRUE, FALSE, FALSE);
JzPrint("%c2J", ASCII_CSI);
CurrentLine = 0;
JzSetPosition( CurrentLine++, 0);
JzPrint(Banner1);
JzSetPosition( CurrentLine++, 0);
JzPrint(Banner2);
JzShowTime(TRUE);
CurrentLine += NumberOfChoices + 3;
JzSetPosition(CurrentLine, 0);
//
// Display the menu and the wait for an action to be selected.
//
DefaultChoice = JxDisplayMenu(Menu,
NumberOfChoices,
DefaultChoice,
3);
//
// Clear the choices.
//
for (Index = 0; Index < NumberOfChoices ; Index++ ) {
JzSetPosition( Index + 3, 5);
JzPrint("%cK", ASCII_CSI);
}
return(DefaultChoice);
}