/** Initialization function for Status Bar. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @sa StatusBarSetStatusString **/ EFI_STATUS StatusBarInit ( VOID ) { // // initialize the statusbar // StatusString = NULL; StatusBarNeedRefresh = TRUE; StatusStringChanged = FALSE; // // status string set to "" // return (StatusBarSetStatusString (L"")); }
/** Function to dispatch the correct function based on a function key (F1...) @param[in] Key The pressed key. @retval EFI_NOT_FOUND The key was not a valid function key (an error was sent to the status bar). @return The return value from the called dispatch function. **/ EFI_STATUS MenuBarDispatchFunctionKey ( IN CONST EFI_INPUT_KEY *Key ) { UINTN Index; Index = Key->ScanCode - SCAN_F1; // // check whether in range // if (Index > (NumItems - 1)) { StatusBarSetStatusString (L"Unknown Command"); return EFI_SUCCESS; } return (MenuItems[Index].Function ()); }
/** Read a disk from disk into HBufferImage. @param[in] DeviceName filename to read. @param[in] Offset The offset. @param[in] Size The size. @param[in] Recover if is for recover, no information print. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @retval EFI_LOAD_ERROR A load error occured. @retval EFI_INVALID_PARAMETER A parameter was invalid. **/ EFI_STATUS HDiskImageRead ( IN CONST CHAR16 *DeviceName, IN UINTN Offset, IN UINTN Size, IN BOOLEAN Recover ) { CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; EFI_HANDLE Handle; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_STATUS Status; VOID *Buffer; CHAR16 *Str; UINTN Bytes; HEFI_EDITOR_LINE *Line; UINT64 ByteOffset; EDIT_FILE_TYPE BufferTypeBackup; BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = FileTypeDiskBuffer; DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName); if (DevicePath == NULL) { StatusBarSetStatusString (L"Cannot Find Device"); return EFI_INVALID_PARAMETER; } DupDevicePath = DuplicateDevicePath(DevicePath); DupDevicePathForFree = DupDevicePath; // // get blkio interface // Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle); FreePool(DupDevicePathForFree); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } // // if Offset exceeds LastBlock, // return error // if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) { StatusBarSetStatusString (L"Invalid Offset + Size"); return EFI_LOAD_ERROR; } Bytes = BlkIo->Media->BlockSize * Size; Buffer = AllocateZeroPool (Bytes); if (Buffer == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize); // // read from disk // Status = BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, Offset, Bytes, Buffer ); if (EFI_ERROR (Status)) { FreePool (Buffer); StatusBarSetStatusString (L"Read Disk Failed"); return EFI_LOAD_ERROR; } HBufferImageFree (); // // convert buffer to line list // Status = HBufferImageBufferToList (Buffer, Bytes); FreePool (Buffer); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } // // initialize some variables // HDiskImage.BlockSize = BlkIo->Media->BlockSize; HBufferImage.DisplayPosition.Row = 2; HBufferImage.DisplayPosition.Column = 10; HBufferImage.MousePosition.Row = 2; HBufferImage.MousePosition.Column = 10; HBufferImage.LowVisibleRow = 1; HBufferImage.HighBits = TRUE; HBufferImage.BufferPosition.Row = 1; HBufferImage.BufferPosition.Column = 1; if (!Recover) { Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); if (Str == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } StatusBarSetStatusString (Str); SHELL_FREE_NON_NULL (Str); HMainEditor.SelectStart = 0; HMainEditor.SelectEnd = 0; } // // has line // if (HBufferImage.Lines != NULL) { HBufferImage.CurrentLine = CR ( HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST ); } else { // // create a dummy line // Line = HBufferImageCreateLine (); if (Line == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } HBufferImage.CurrentLine = Line; } HBufferImage.Modified = FALSE; HBufferImageNeedRefresh = TRUE; HBufferImageOnlyLineNeedRefresh = FALSE; HBufferImageMouseNeedRefresh = TRUE; return EFI_SUCCESS; }
/** Save lines in HBufferImage to disk. @param[in] FileName The file name. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @retval EFI_LOAD_ERROR A load error occured. **/ EFI_STATUS HFileImageSave ( IN CHAR16 *FileName ) { LIST_ENTRY *Link; HEFI_EDITOR_LINE *Line; CHAR16 *Str; EFI_STATUS Status; UINTN NumLines; SHELL_FILE_HANDLE FileHandle; UINTN TotalSize; UINT8 *Buffer; UINT8 *Ptr; EDIT_FILE_TYPE BufferTypeBackup; BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = FileTypeFileBuffer; // // if is the old file // if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) { // // check whether file exists on disk // if (ShellIsFile(FileName) == EFI_SUCCESS) { // // current file exists on disk // so if not modified, then not save // if (HBufferImage.Modified == FALSE) { return EFI_SUCCESS; } // // if file is read-only, set error // if (HFileImage.ReadOnly == TRUE) { StatusBarSetStatusString (L"Read Only File Can Not Be Saved"); return EFI_SUCCESS; } } } if (ShellIsDirectory(FileName) == EFI_SUCCESS) { StatusBarSetStatusString (L"Directory Can Not Be Saved"); return EFI_LOAD_ERROR; } Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); if (!EFI_ERROR (Status)) { // // the file exits, delete it // Status = ShellDeleteFile (&FileHandle); if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) { StatusBarSetStatusString (L"Write File Failed"); return EFI_LOAD_ERROR; } } // // write all the lines back to disk // NumLines = 0; TotalSize = 0; for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); if (Line->Size != 0) { TotalSize += Line->Size; } // // end of if Line -> Size != 0 // NumLines++; } // // end of for Link // Buffer = AllocateZeroPool (TotalSize); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } Ptr = Buffer; for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); if (Line->Size != 0) { CopyMem (Ptr, Line->Buffer, Line->Size); Ptr += Line->Size; } // // end of if Line -> Size != 0 // } Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Create File Failed"); return EFI_LOAD_ERROR; } Status = ShellWriteFile (FileHandle, &TotalSize, Buffer); FreePool (Buffer); if (EFI_ERROR (Status)) { ShellDeleteFile (&FileHandle); return EFI_LOAD_ERROR; } ShellCloseFile(&FileHandle); HBufferImage.Modified = FALSE; // // set status string // Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines); StatusBarSetStatusString (Str); FreePool (Str); // // now everything is ready , you can set the new file name to filebuffer // if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) || (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){ // // not the same // HFileImageSetFileName (FileName); if (HFileImage.FileName == NULL) { return EFI_OUT_OF_RESOURCES; } } HFileImage.ReadOnly = FALSE; return EFI_SUCCESS; }
/** Read a file from disk into HBufferImage. @param[in] FileName filename to read. @param[in] Recover if is for recover, no information print. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @retval EFI_LOAD_ERROR A load error occured. **/ EFI_STATUS HFileImageRead ( IN CONST CHAR16 *FileName, IN BOOLEAN Recover ) { HEFI_EDITOR_LINE *Line; UINT8 *Buffer; CHAR16 *UnicodeBuffer; EFI_STATUS Status; // // variable initialization // Line = NULL; // // in this function, when you return error ( except EFI_OUT_OF_RESOURCES ) // you should set status string // since this function maybe called before the editorhandleinput loop // so any error will cause editor return // so if you want to print the error status // you should set the status string // Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly); // // NULL pointer is only also a failure for a non-zero file size. // if ((EFI_ERROR(Status)) || (Buffer == NULL && HFileImage.Size != 0)) { UnicodeBuffer = CatSPrint(NULL, L"Read error on file &s: %r", FileName, Status); if (UnicodeBuffer == NULL) { SHELL_FREE_NON_NULL(Buffer); return EFI_OUT_OF_RESOURCES; } StatusBarSetStatusString (UnicodeBuffer); FreePool (UnicodeBuffer); return EFI_OUT_OF_RESOURCES; } HFileImageSetFileName (FileName); // // free the old lines // HBufferImageFree (); Status = HBufferImageBufferToList (Buffer, HFileImage.Size); SHELL_FREE_NON_NULL (Buffer); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Error parsing file."); return Status; } HBufferImage.DisplayPosition.Row = 2; HBufferImage.DisplayPosition.Column = 10; HBufferImage.MousePosition.Row = 2; HBufferImage.MousePosition.Column = 10; HBufferImage.LowVisibleRow = 1; HBufferImage.HighBits = TRUE; HBufferImage.BufferPosition.Row = 1; HBufferImage.BufferPosition.Column = 1; HBufferImage.BufferType = FileTypeFileBuffer; if (!Recover) { UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); if (UnicodeBuffer == NULL) { SHELL_FREE_NON_NULL(Buffer); return EFI_OUT_OF_RESOURCES; } StatusBarSetStatusString (UnicodeBuffer); FreePool (UnicodeBuffer); HMainEditor.SelectStart = 0; HMainEditor.SelectEnd = 0; } // // has line // if (HBufferImage.Lines != 0) { HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); } else { // // create a dummy line // Line = HBufferImageCreateLine (); if (Line == NULL) { SHELL_FREE_NON_NULL(Buffer); return EFI_OUT_OF_RESOURCES; } HBufferImage.CurrentLine = Line; } HBufferImage.Modified = FALSE; HBufferImageNeedRefresh = TRUE; HBufferImageOnlyLineNeedRefresh = FALSE; HBufferImageMouseNeedRefresh = TRUE; return EFI_SUCCESS; }
/** Read a disk from disk into HBufferImage. @param[in] Offset The offset. @param[in] Size The size. @param[in] Recover if is for recover, no information print. @retval EFI_LOAD_ERROR A load error occured. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. **/ EFI_STATUS HMemImageRead ( IN UINTN Offset, IN UINTN Size, IN BOOLEAN Recover ) { EFI_STATUS Status; void *Buffer; CHAR16 *Str; HEFI_EDITOR_LINE *Line; HBufferImage.BufferType = FileTypeMemBuffer; Buffer = AllocateZeroPool (Size); if (Buffer == NULL) { StatusBarSetStatusString (L"Read Memory Failed"); return EFI_OUT_OF_RESOURCES; } Status = HMemImage.IoFncs->Mem.Read ( HMemImage.IoFncs, EfiCpuIoWidthUint8, Offset, Size, Buffer ); if (EFI_ERROR (Status)) { FreePool (Buffer); StatusBarSetStatusString (L"Memory Specified Not Accessible"); return EFI_LOAD_ERROR; } HBufferImageFree (); Status = HBufferImageBufferToList (Buffer, Size); FreePool (Buffer); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Memory Failed"); return Status; } Status = HMemImageSetMemOffsetSize (Offset, Size); HBufferImage.DisplayPosition.Row = 2; HBufferImage.DisplayPosition.Column = 10; HBufferImage.MousePosition.Row = 2; HBufferImage.MousePosition.Column = 10; HBufferImage.LowVisibleRow = 1; HBufferImage.HighBits = TRUE; HBufferImage.BufferPosition.Row = 1; HBufferImage.BufferPosition.Column = 1; if (!Recover) { Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); if (Str == NULL) { StatusBarSetStatusString (L"Read Memory Failed"); return EFI_OUT_OF_RESOURCES; } StatusBarSetStatusString (Str); SHELL_FREE_NON_NULL (Str); HMainEditor.SelectStart = 0; HMainEditor.SelectEnd = 0; } // // has line // if (HBufferImage.Lines != NULL) { HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); } else { // // create a dummy line // Line = HBufferImageCreateLine (); if (Line == NULL) { StatusBarSetStatusString (L"Read Memory Failed"); return EFI_OUT_OF_RESOURCES; } HBufferImage.CurrentLine = Line; } HBufferImage.Modified = FALSE; HBufferImageNeedRefresh = TRUE; HBufferImageOnlyLineNeedRefresh = FALSE; HBufferImageMouseNeedRefresh = TRUE; return EFI_SUCCESS; }
/** Cause the status bar to refresh it's printing on the screen. @param[in] EditorFirst TRUE to indicate the first launch of the editor. FALSE otherwise. @param[in] LastRow LastPrintable row. @param[in] LastCol Last printable column. @param[in] FileRow Row in the file. @param[in] FileCol Column in the file. @param[in] InsertMode TRUE to indicate InsertMode. FALSE otherwise. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS EFIAPI StatusBarRefresh ( IN BOOLEAN EditorFirst, IN UINTN LastRow, IN UINTN LastCol, IN UINTN FileRow, IN UINTN FileCol, IN BOOLEAN InsertMode ) { STATUS_BAR_COLOR_UNION Orig; STATUS_BAR_COLOR_UNION New; if (!StatusStringChanged && StatusBarNeedRefresh) { StatusBarSetStatusString (L"\0"); } // // when it's called first time after editor launch, so refresh is mandatory // if (!StatusBarNeedRefresh && !StatusStringChanged) { return EFI_SUCCESS; } // // back up the screen attributes // Orig.Data = gST->ConOut->Mode->Attribute; New.Data = 0; New.Colors.Foreground = Orig.Colors.Background; New.Colors.Background = Orig.Colors.Foreground; gST->ConOut->EnableCursor (gST->ConOut, FALSE); gST->ConOut->SetAttribute (gST->ConOut, New.Data); // // clear status bar // EditorClearLine (LastRow, LastCol, LastRow); // // print row, column fields // if (FileRow != (UINTN)(-1) && FileCol != (UINTN)(-1)) { ShellPrintEx ( 0, (INT32)(LastRow) - 1, L" %d,%d %s", FileRow, FileCol, StatusString ); } else { ShellPrintEx ( 0, (INT32)(LastRow) - 1, L" %s", StatusString ); } // // print insert mode field // if (InsertMode) { ShellPrintEx ((INT32)(LastCol) - 21, (INT32)(LastRow) - 1, L"|%s| Help: Ctrl-E", L"INS"); } else { ShellPrintEx ((INT32)(LastCol) - 21, (INT32)(LastRow) - 1, L"|%s| Help: Ctrl-E", L"OVR"); } // // restore the old screen attributes // gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); // // restore position in edit area // gST->ConOut->EnableCursor (gST->ConOut, TRUE); StatusBarNeedRefresh = FALSE; StatusStringChanged = FALSE; return EFI_SUCCESS; }