VOID SlWriteStatusText( IN PCHAR Text ) /*++ Routine Description: Updates the status area on the screen with a given string Arguments: Text - Supplies the new text for the status area. Return Value: None. --*/ { UCHAR AttributeSave = CurAttribute; CHAR *p; ULONG Count; ULONG MaxWidth = ScreenWidth - 2; if (MaxWidth > MAX_STATUS) { MaxWidth = MAX_STATUS; } RtlFillMemory(StatusText,sizeof(StatusText),' '); // // Strip cr/lf as we copy the status text into the status text buffer. // p = StatusText; Count = 0; while((Count < MaxWidth) && *Text) { if((*Text != '\r') && (*Text != '\n')) { *p++ = *Text; Count++; } Text++; } SlSetCurrentAttribute(StatusAttribute); SlPositionCursor(0,ScreenHeight-1); ArcWrite(ARC_CONSOLE_OUTPUT," ",2,&Count); SlPositionCursor(2,ScreenHeight-1); ArcWrite(ARC_CONSOLE_OUTPUT,StatusText,MaxWidth*sizeof(CHAR),&Count); SlSetCurrentAttribute(AttributeSave); SlPositionCursor(0,5); }
void prom_putchar(char c) { ULONG cnt; CHAR it = c; ArcWrite(1, &it, 1, &cnt); }
// // output long integer // VOID puti(__in LONG i) { UCHAR Value; ULONG Count; if(i < 0) { i = -i; Value = '-'; ArcWrite(BlConsoleOutDeviceId,&Value,sizeof(Value),&Count); } if(i / 10) puti(i / 10); Value = static_cast<UCHAR>(i % 10) + '0'; ArcWrite(BlConsoleOutDeviceId,&Value,sizeof(Value),&Count); }
void prom_putchar(char c) { ULONG cnt; CHAR it = c; bc_disable(); ArcWrite(1, &it, 1, &cnt); bc_enable(); }
// // output an unsigned long // VOID putu(__in ULONG u) { if(u / 10) putu(u / 10); UCHAR Value = static_cast<UCHAR>(u % 10) + '0'; ULONG Count; ArcWrite(BlConsoleOutDeviceId,&Value,sizeof(Value),&Count); }
// // output unicode string // VOID putwS(__in PUNICODE_STRING String) { for(USHORT i = 0; i < String->Length / sizeof(WCHAR); i ++) { UCHAR Value = static_cast<UCHAR>(String->Buffer[i]); ULONG Count; ArcWrite(BlConsoleOutDeviceId,&Value,sizeof(Value),&Count); } }
// // output hex long // VOID putx(__in ULONG x) { if(x >> 4) putx(x >> 4); UCHAR j = static_cast<UCHAR>(x & 0xf); if(j > 9) j += ('A' - 10); else j += '0'; ArcWrite(BlConsoleOutDeviceId,&j,sizeof(j),&x); }
ARC_STATUS SlWriteString( IN PUCHAR s ) { PUCHAR p = s,q; BOOLEAN done = FALSE; ULONG len,count; do { q = p; while((*q != '\0') && (*q != '\n')) { q++; } if(*q == '\0') { done = TRUE; } else { *q = '\0'; } len = q - p; ArcWrite(ARC_CONSOLE_OUTPUT,p,len,&count); ScreenX += len; if(!done) { ArcWrite(ARC_CONSOLE_OUTPUT,"\r\n",2,&count); ScreenX = 0; ScreenY++; if(ScreenY == ScreenHeight) { ScreenY = ScreenHeight-1; } *q = '\n'; } p = q + 1; } while(!done); return(ESUCCESS); }
VOID SlPrint( IN PCHAR FormatString, ... ) { va_list arglist; CHAR text[MAX_STATUS+1]; ULONG Count,Length; ULONG MaxWidth = ScreenWidth - 2; if (MaxWidth > MAX_STATUS) { MaxWidth = MAX_STATUS; } va_start(arglist,FormatString); Length = _vsnprintf(text,MaxWidth*sizeof(CHAR),FormatString,arglist); text[MaxWidth] = 0; ArcWrite(ARC_CONSOLE_OUTPUT,text,Length,&Count); va_end(arglist); }
ARC_STATUS LowWriteSectors( IN ULONG VolumeId, IN ULONG SectorSize, IN ULONG StartingSector, IN ULONG NumberOfSectors, IN PVOID Buffer ) /*++ Routine Description: This routine write 'NumberOfSectors' sectors starting at sector 'StartingSector' on the volume with ID 'VolumeId'. Arguments: VolumeId - Supplies the ID for the volume. SectorSize - Supplies the number of bytes per sector. StartingSector - Supplies the starting sector for the write. NumberOfSectors - Supplies the number of sectors to write. Buffer - Supplies the sectors to write. Return Value: ArcSeek, ArcWrite, EIO, ESUCCESS --*/ { ARC_STATUS r; ULONG c; LARGE_INTEGER l; ULONG i; ULONG transfer; PCHAR buf; ULONG total; l.QuadPart = UInt32x32To64(StartingSector,SectorSize); buf = (PCHAR) Buffer; r = ArcSeek(VolumeId, &l, SeekAbsolute); if (r != ESUCCESS) { return r; } total = SectorSize*NumberOfSectors; for (i = 0; i < total; i += MAX_TRANSFER) { transfer = min(MAX_TRANSFER, total - i); r = ArcWrite(VolumeId, &buf[i], transfer, &c); if (r != ESUCCESS) { return r; } if (c != transfer) { return EIO; } } return ESUCCESS; }
GETSTRING_ACTION JzGetString( OUT PCHAR String, IN ULONG StringLength, IN PCHAR InitialString OPTIONAL, IN ULONG CurrentRow, IN ULONG CurrentColumn, IN BOOLEAN ShowTheTime ) /*++ Routine Description: This routine reads a string from standardin until a carriage return is found, StringLength is reached, or ESC is pushed. Semicolons are discarded. Reason: semicolons are key characters in the parsing of multi-segment environment variables. They aren not needed for any valid input to the firmware, so the easiest solution is to filter them here. 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. ShowTheTime If true, the time is displayed in the upper right-hand corner of the screen. 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; // // 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) { // // Print the string. // VenSetPosition(CurrentRow, CurrentColumn); VenPrint(String); VenPrint("\x9bK"); // // Print the cursor. // VenSetScreenAttributes(TRUE,FALSE,TRUE); VenSetPosition(CurrentRow, (Cursor - String) + CurrentColumn); if (Cursor >= Buffer) { VenPrint(" "); } else { ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count); } VenSetScreenAttributes(TRUE,FALSE,FALSE); #ifndef JNUPDATE while (ShowTheTime && ArcGetReadStatus(ARC_CONSOLE_INPUT) != ESUCCESS) { JzShowTime(FALSE); } #endif 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. // VenStallExecution(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': Action = GetStringSuccess; goto EndGetString; // // Do not bother handling the tab character properly. // case '\t' : Action = GetStringEscape; goto EndGetString; case '\b': if (Cursor != String) { Cursor--; } CopyPointer = Cursor; while (*CopyPointer) { *CopyPointer = *(CopyPointer + 1); CopyPointer++; } if (Buffer != String) { Buffer--; } break; // // Discard any semicolons because they will corrupt multi- // segment environment variables. // case ';': break; default: // // Store the character. // CopyPointer = ++Buffer; if (CopyPointer > Cursor) { while (CopyPointer != Cursor) { *CopyPointer = *(CopyPointer - 1); CopyPointer--; } } *Cursor++ = c; break; } } Action = GetStringEscape; EndGetString: VenSetPosition(CurrentRow, (Cursor - String) + CurrentColumn); if (Cursor >= Buffer) { VenPrint(" "); } else { ArcWrite(ARC_CONSOLE_OUTPUT,Cursor,1,&Count); } // // Make sure we return a null string if not successful. // if (Action != GetStringSuccess) { *String = 0; } return(Action); }
// // standard printf function with a subset of formating features supported. // // supported // %d, %ld - signed short, signed long // %u, %lu - unsigned short, unsigned long // %c, %s - character, string // %x, %lx - unsigned print in hex, unsigned long print in hex // %wS,%wZ - unicode string // // does not do: // // - field width specification // - floating point. // VOID BlPrint(__in PCHAR cp,...) { PVOID ap = Add2Ptr(&cp,sizeof(PCHAR),PVOID); USHORT b = 0; ULONG Count = 0; ULONG DeviceId = BlConsoleOutDeviceId ? BlConsoleOutDeviceId : 1; while(b = *cp ++) { if(b == '%') { USHORT c = *cp ++; switch(c) { case 'c': ArcWrite(DeviceId,ap,sizeof(UCHAR),&Count); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'd': puti(*static_cast<PLONG>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'l': { USHORT d = *cp ++; switch(d) { case 'd': puti(*static_cast<PLONG>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'u': putu(*static_cast<PUSHORT>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'x': { ULONG x = *static_cast<PULONG>(ap); ULONG ZeroLength = (x < 0x10) + (x < 0x100) + (x < 0x1000) + (x < 0x10000) + (x < 0x100000) + (x < 0x1000000) + (x < 0x10000000); while(ZeroLength --) ArcWrite(DeviceId,"0",sizeof(UCHAR),&Count); putx(x); ap = Add2Ptr(ap,sizeof(LONG),PVOID); } break; } } break; case 's': { PCHAR String = *static_cast<PCHAR*>(ap); ArcWrite(DeviceId,String,strlen(String),&Count); ap = Add2Ptr(ap,sizeof(PCHAR),PVOID); } break; case 'u': putu(*static_cast<PUSHORT>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'w': { USHORT d = *cp ++; switch(d) { case 'S': case 'W': putwS(*static_cast<PUNICODE_STRING*>(ap)); ap = Add2Ptr(ap,sizeof(PUNICODE_STRING),PVOID); break; } } break; case 'x': { USHORT x = *static_cast<PUSHORT>(ap); ULONG ZeroLength = (x < 0x10) + (x < 0x100) + (x < 0x1000); while(ZeroLength --) ArcWrite(DeviceId,"0",sizeof(UCHAR),&Count); putx(x); ap = Add2Ptr(ap,sizeof(LONG),PVOID); } break; default: ArcWrite(DeviceId,&b,sizeof(UCHAR),&Count); ArcWrite(DeviceId,&c,sizeof(UCHAR),&Count); break; } } else { if(!DbcsLangId || !GrIsDBCSLeadByte(cp[-1])) { ArcWrite(DeviceId,cp - 1,1,&Count); } else { ArcWrite(DeviceId,cp - 1,2,&Count); cp += 1; } } } }
VOID SlpDrawMenuItem( IN ULONG X, IN ULONG Y, IN ULONG TopItem, IN ULONG Height, IN ULONG Item, IN PSL_MENU Menu ) /*++ Routine Description: Redraws the given item Arguments: X - Supplies X coordinate of upper-left corner of menu Y - Supplies Y coordinate of upper-left corner of menu TopItem - Supplies index of item at the top of the menu Height - Supplies the height of the menu Item - Supplies the index of the item to be redrawn Menu - Supplies the menu to be displayed Return Value: None. --*/ { ULONG i; PSL_MENUITEM MenuItem; ULONG Count; CHAR Width[80]; // // Find item to display // MenuItem = CONTAINING_RECORD(Menu->ItemListHead.Flink, SL_MENUITEM, ListEntry); for (i=0;i<Item;i++) { MenuItem = CONTAINING_RECORD(MenuItem->ListEntry.Flink, SL_MENUITEM, ListEntry); #if DBG if (&MenuItem->ListEntry == &Menu->ItemListHead) { SlError(Item); } #endif } RtlFillMemory(Width,Menu->Width,' '); RtlCopyMemory(Width,MenuItem->Text,strlen(MenuItem->Text)); SlPositionCursor(X+2, Y+(Item-TopItem)+1); ArcWrite(ARC_CONSOLE_OUTPUT,Width,Menu->Width,&Count); }
VOID SlpDrawMenu( IN ULONG X, IN ULONG Y, IN ULONG TopItem, IN ULONG Height, IN PSL_MENU Menu ) /*++ Routine Description: Displays the menu on the screen Arguments: X - Supplies X coordinate of upper-left corner of menu Y - Supplies Y coordinate of upper-left corner of menu TopItem - Supplies index of item at the top of the menu Height - Supplies the height of the menu Menu - Supplies the menu to be displayed Return Value: None. --*/ { ULONG i; PSL_MENUITEM Item; ULONG Count; CHAR Output[80]; ULONG Length; ULONG MenuWidth; MenuWidth = Menu->Width+4; Output[0]=GetGraphicsChar(GraphicsCharDoubleRightDoubleDown); for (i=1;i<MenuWidth-1;i++) { Output[i]=GetGraphicsChar(GraphicsCharDoubleHorizontal); } Output[MenuWidth-1]=GetGraphicsChar(GraphicsCharDoubleLeftDoubleDown); SlPositionCursor(X,Y); ArcWrite(ARC_CONSOLE_OUTPUT,Output,MenuWidth,&Count); // // Find first item to display // Item = CONTAINING_RECORD(Menu->ItemListHead.Flink, SL_MENUITEM, ListEntry); for (i=0;i<TopItem;i++) { Item = CONTAINING_RECORD(Item->ListEntry.Flink, SL_MENUITEM, ListEntry); } // // Display items // Output[0]= Output[MenuWidth-1]=GetGraphicsChar(GraphicsCharDoubleVertical); for (i=Y+1;i<Y+Height-1;i++) { RtlFillMemory(Output+1,MenuWidth-2,' '); SlPositionCursor(X, i); if (&Item->ListEntry != &Menu->ItemListHead) { Length = strlen(Item->Text); RtlCopyMemory(Output+2,Item->Text,Length); Item = CONTAINING_RECORD(Item->ListEntry.Flink, SL_MENUITEM, ListEntry); } ArcWrite(ARC_CONSOLE_OUTPUT,Output,MenuWidth,&Count); } Output[0]=GetGraphicsChar(GraphicsCharDoubleRightDoubleUp); for (i=1;i<MenuWidth-1;i++) { Output[i]=GetGraphicsChar(GraphicsCharDoubleHorizontal); } Output[MenuWidth-1]=GetGraphicsChar(GraphicsCharDoubleLeftDoubleUp); SlPositionCursor(X,Y+Height-1); ArcWrite(ARC_CONSOLE_OUTPUT,Output,MenuWidth,&Count); }
ULONG SlDisplayMenu( IN ULONG HeaderId, IN PSL_MENU Menu, IN OUT PULONG Selection ) /*++ Routine Description: Displays a menu and allows the user to pick a selection Arguments: HeaderId - Supplies the message ID of the prompt header to be displayed above the menu. Menu - Supplies a pointer to the menu to be displayed Selection - Supplies the index of the default item. Returns the index of the selected item. Return Value: Key that terminated the menu display. --*/ { LONG X, Y; ULONG Height; ULONG Width; ULONG TopItem; ULONG c; ULONG PreviousSelection; ULONG Sel; PCHAR Header; ULONG HeaderLines; ULONG MaxHeaderLength; PCHAR HeaderText[20]; ULONG HeaderLength[20]; ULONG MaxMenuHeight; ULONG i; ULONG Count; Header = BlFindMessage(HeaderId); SlpSizeMessage(Header, &HeaderLines, &MaxHeaderLength, HeaderLength, HeaderText); X = (ScreenWidth-MaxHeaderLength)/2; for (i=0;i<HeaderLines;i++) { SlPositionCursor(X,i+4); ArcWrite(ARC_CONSOLE_OUTPUT,HeaderText[i],HeaderLength[i],&Count); } if (MaxHeaderLength > ScreenWidth) { MaxHeaderLength = ScreenWidth; } Width = Menu->Width+4; if (Width > ScreenWidth) { Width=ScreenWidth; } MaxMenuHeight = ScreenHeight-(HeaderLines+13); Height = Menu->ItemCount+2; if (Height > MaxMenuHeight) { Height = MaxMenuHeight; } X = ((ScreenWidth - Width)/2 > 0) ? (ScreenWidth-Width)/2 : 0; Y = (MaxMenuHeight - Height)/2 + HeaderLines + 4; TopItem = 0; Sel = *Selection; // // Make sure default item is in view; // if (Sel >= Height - 2) { TopItem = Sel - Height + 3; } SlpDrawMenu(X,Y, TopItem, Height, Menu); // // highlight default selection // SlSetCurrentAttribute(INVATT); SlpDrawMenuItem(X,Y, TopItem, Height, Sel, Menu); SlSetCurrentAttribute(DEFATT); SlFlushConsoleBuffer(); do { c = SlGetChar(); PreviousSelection = Sel; SlpDrawMenuItem(X, Y, TopItem, Height, Sel, Menu); switch (c) { case SL_KEY_UP: if(Sel > 0) { Sel--; } break; case SL_KEY_DOWN: if(Sel < Menu->ItemCount - 1) { Sel++; } break; case SL_KEY_HOME: Sel = 0; break; case SL_KEY_END: Sel = Menu->ItemCount - 1; break; case SL_KEY_PAGEUP: if (Menu->ItemCount > Height) { if (Sel > Height) { Sel -= Height; } else { Sel = 0; } } break; case SL_KEY_PAGEDOWN: if (Menu->ItemCount > Height) { Sel += Height; if (Sel >= Menu->ItemCount) { Sel = Menu->ItemCount - 1; } } break; case SL_KEY_F1: case SL_KEY_F3: case ASCI_CR: case ASCI_ESC: *Selection = Sel; return(c); } if (Sel < TopItem) { TopItem = Sel; SlpDrawMenu(X, Y, TopItem, Height, Menu); } else if (Sel > TopItem+Height-3) { TopItem = Sel - Height + 3; SlpDrawMenu(X, Y, TopItem, Height, Menu); } // // highlight default selection // SlSetCurrentAttribute(INVATT); SlpDrawMenuItem(X,Y, TopItem, Height, Sel, Menu); SlSetCurrentAttribute(DEFATT); } while ( TRUE ); }
VOID SlGenericMessageBox( IN ULONG MessageId, OPTIONAL IN va_list *args, OPTIONAL IN PCHAR Message, OPTIONAL IN OUT PULONG xLeft, OPTIONAL IN OUT PULONG yTop, OPTIONAL OUT PULONG yBottom, OPTIONAL IN BOOLEAN bCenterMsg ) /*++ Routine Description: Formats and displays a message box. The longest line in the string of characters will be centered on the screen if bCenterMsg is TRUE. The status text line will be erased. Arguments: NOTE: Either the MessageId/args pair or the Message string must be specified. Message string will be used if non-NULL. MessageId - Supplies the MessageId that will be looked up to provide a NULL-terminated string of characters. Each \r\n delimited string will be displayed on its own line. args - Supplies the argument list that will be passed to vsprintf. Message - Supplies the actual text of the message to be displayed xLeft - If bCenterMsg is FALSE, then xLeft is used for the starting x coordinate of the message (if specified, otherwise, x = 1). Also, if specified, it receives the x coordinate of the left edge of all lines that were displayed. yTop - If bCenterMsg is FALSE, then yTop is used for the starting y coordinate of the message (if specified, otherwise, y = 3). Also, if specified, receives the y coordinate of the top line where the message box was displayed. yBottom - if specified, receives the y coordinate of the bottom line of the message box. bCenterMsg - if TRUE, center message on the screen. Return Value: None. --*/ { PCHAR p; ULONG NumLines; ULONG MaxLength; ULONG x; ULONG y; ULONG i; PCHAR Line[20]; ULONG LineLength[20]; ULONG Count; if(!Message) { // then look up the message p=BlFindMessage(MessageId); if (p==NULL) { SlError(MessageId); x=3; y=ScreenHeight/2; NumLines=0; } else { _vsnprintf(MessageBuffer,sizeof(MessageBuffer),p,*args); Message = MessageBuffer; } } else { // // Just make p non-NULL, so we'll know it's OK to continue. // p = Message; } if(p) { SlWriteStatusText(""); // Clear status bar SlpSizeMessage(Message, &NumLines, &MaxLength, LineLength, Line); if (MaxLength > ScreenWidth) { MaxLength = ScreenWidth; } if(bCenterMsg) { x = (ScreenWidth-MaxLength)/2; y = (ScreenHeight-NumLines)/2; } else { if(xLeft) { x = *xLeft; } else { x = 1; } if(yTop) { y = *yTop; } else { y = 3; } } } for (i=0; i<NumLines; i++) { SlPositionCursor(x, y+i); ArcWrite(ARC_CONSOLE_OUTPUT,Line[i],LineLength[i],&Count); } if(xLeft) { *xLeft = x; } if(yTop) { *yTop = y; } if(yBottom) { *yBottom = NumLines ? y+NumLines-1 : 0; } }