123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /** @file
- Functions to deal with Disk buffer.
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "HexEditor.h"
- #include <Protocol/BlockIo.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_DISK_IMAGE HDiskImage;
- HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
- //
- // for basic initialization of HDiskImage
- //
- HEFI_EDITOR_DISK_IMAGE HDiskImageConst = {
- NULL,
- 0,
- 0,
- 0
- };
- /**
- Initialization function for HDiskImage.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
- **/
- EFI_STATUS
- HDiskImageInit (
- VOID
- )
- {
- //
- // basically initialize the HDiskImage
- //
- CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
- CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
- return EFI_SUCCESS;
- }
- /**
- Backup function for HDiskImage. Only a few fields need to be backup.
- This is for making the Disk buffer refresh as few as possible.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
- **/
- EFI_STATUS
- HDiskImageBackup (
- VOID
- )
- {
- //
- // backup the disk name, offset and size
- //
- //
- SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
- HDiskImageBackupVar.Name = CatSPrint(NULL, L"%s", HDiskImage.Name);
- if (HDiskImageBackupVar.Name == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- HDiskImageBackupVar.Offset = HDiskImage.Offset;
- HDiskImageBackupVar.Size = HDiskImage.Size;
- return EFI_SUCCESS;
- }
- /**
- Cleanup function for HDiskImage.
- @retval EFI_SUCCESS The operation was successful.
- **/
- EFI_STATUS
- HDiskImageCleanup (
- VOID
- )
- {
- SHELL_FREE_NON_NULL (HDiskImage.Name);
- SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
- return EFI_SUCCESS;
- }
- /**
- Set FileName field in HFileImage.
- @param[in] Str File name to set.
- @param[in] Offset The offset.
- @param[in] Size The size.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- **/
- EFI_STATUS
- HDiskImageSetDiskNameOffsetSize (
- IN CONST CHAR16 *Str,
- IN UINTN Offset,
- IN UINTN Size
- )
- {
- if (Str == HDiskImage.Name) {
- //
- // This function might be called using HDiskImage.FileName as Str.
- // Directly return without updating HDiskImage.FileName.
- //
- return EFI_SUCCESS;
- }
- //
- // free the old file name
- //
- SHELL_FREE_NON_NULL (HDiskImage.Name);
- HDiskImage.Name = AllocateCopyPool (StrSize (Str), Str);
- if (HDiskImage.Name == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- HDiskImage.Offset = Offset;
- HDiskImage.Size = Size;
- return EFI_SUCCESS;
- }
- /**
- 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 occurred.
- @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;
- 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;
- }
- //
- // 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.
- NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
- @param[in] DeviceName The device name.
- @param[in] Offset The offset.
- @param[in] Size The size.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
- **/
- EFI_STATUS
- HDiskImageSave (
- IN CHAR16 *DeviceName,
- IN UINTN Offset,
- IN UINTN Size
- )
- {
- CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- EFI_STATUS Status;
- EFI_HANDLE Handle;
- VOID *Buffer;
- UINTN Bytes;
- //
- // if not modified, directly return
- //
- if (HBufferImage.Modified == FALSE) {
- return EFI_SUCCESS;
- }
- 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;
- }
- Bytes = BlkIo->Media->BlockSize * Size;
- Buffer = AllocateZeroPool (Bytes);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // concatenate the line list to a buffer
- //
- Status = HBufferImageListToBuffer (Buffer, Bytes);
- if (EFI_ERROR (Status)) {
- FreePool (Buffer);
- return Status;
- }
- //
- // write the buffer to disk
- //
- Status = BlkIo->WriteBlocks (
- BlkIo,
- BlkIo->Media->MediaId,
- Offset,
- Bytes,
- Buffer
- );
- FreePool (Buffer);
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
- //
- // now not modified
- //
- HBufferImage.Modified = FALSE;
- return EFI_SUCCESS;
- }
|