123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /** @file
- Functions to deal with file buffer.
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "HexEditor.h"
- extern EFI_HANDLE HImageHandleBackup;
- extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
- extern BOOLEAN HBufferImageNeedRefresh;
- extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
- extern BOOLEAN HBufferImageMouseNeedRefresh;
- extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
- HEFI_EDITOR_FILE_IMAGE HFileImage;
- HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;
- //
- // for basic initialization of HFileImage
- //
- HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = {
- NULL,
- 0,
- FALSE
- };
- /**
- Initialization function for HFileImage
- @retval EFI_SUCCESS The operation was successful.
- **/
- EFI_STATUS
- HFileImageInit (
- VOID
- )
- {
- //
- // basically initialize the HFileImage
- //
- CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));
- CopyMem (
- &HFileImageBackupVar,
- &HFileImageConst,
- sizeof (HFileImageBackupVar)
- );
- return EFI_SUCCESS;
- }
- /**
- Backup function for HFileImage. Only a few fields need to be backup.
- This is for making the file buffer refresh as few as possible.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- **/
- EFI_STATUS
- HFileImageBackup (
- VOID
- )
- {
- SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
- HFileImageBackupVar.FileName = CatSPrint(NULL, L"%s", HFileImage.FileName);
- if (HFileImageBackupVar.FileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- return EFI_SUCCESS;
- }
- /**
- Cleanup function for HFileImage.
- @retval EFI_SUCCESS The operation was successful.
- **/
- EFI_STATUS
- HFileImageCleanup (
- VOID
- )
- {
- SHELL_FREE_NON_NULL (HFileImage.FileName);
- SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
- return EFI_SUCCESS;
- }
- /**
- Set FileName field in HFileImage
- @param[in] Str File name to set.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- **/
- EFI_STATUS
- HFileImageSetFileName (
- IN CONST CHAR16 *Str
- )
- {
- if (Str == HFileImage.FileName) {
- //
- // This function might be called using HFileImage.FileName as Str.
- // Directly return without updating HFileImage.FileName.
- //
- return EFI_SUCCESS;
- }
- //
- // free the old file name
- //
- SHELL_FREE_NON_NULL (HFileImage.FileName);
- HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str);
- if (HFileImage.FileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- 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 occurred.
- **/
- 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;
- }
- /**
- 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 occurred.
- **/
- 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 Written", 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;
- }
|