2 Functions to deal with Disk buffer.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "HexEditor.h"
16 #include <Protocol/BlockIo.h>
18 extern EFI_HANDLE HImageHandleBackup
;
19 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage
;
21 extern BOOLEAN HBufferImageNeedRefresh
;
22 extern BOOLEAN HBufferImageOnlyLineNeedRefresh
;
23 extern BOOLEAN HBufferImageMouseNeedRefresh
;
25 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor
;
27 HEFI_EDITOR_DISK_IMAGE HDiskImage
;
28 HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar
;
31 // for basic initialization of HDiskImage
33 HEFI_EDITOR_DISK_IMAGE HDiskImageConst
= {
41 Initialization function for HDiskImage.
43 @retval EFI_SUCCESS The operation was successful.
44 @retval EFI_LOAD_ERROR A load error occured.
52 // basically initialize the HDiskImage
54 CopyMem (&HDiskImage
, &HDiskImageConst
, sizeof (HDiskImage
));
56 CopyMem (&HDiskImageBackupVar
, &HDiskImageConst
, sizeof (HDiskImageBackupVar
));
62 Backup function for HDiskImage. Only a few fields need to be backup.
63 This is for making the Disk buffer refresh as few as possible.
65 @retval EFI_SUCCESS The operation was successful.
66 @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
74 // backup the disk name, offset and size
77 SHELL_FREE_NON_NULL (HDiskImageBackupVar
.Name
);
79 HDiskImageBackupVar
.Name
= CatSPrint(NULL
, L
"%s", HDiskImage
.Name
);
80 if (HDiskImageBackupVar
.Name
== NULL
) {
81 return EFI_OUT_OF_RESOURCES
;
84 HDiskImageBackupVar
.Offset
= HDiskImage
.Offset
;
85 HDiskImageBackupVar
.Size
= HDiskImage
.Size
;
91 Cleanup function for HDiskImage.
93 @retval EFI_SUCCESS The operation was successful.
100 SHELL_FREE_NON_NULL (HDiskImage
.Name
);
101 SHELL_FREE_NON_NULL (HDiskImageBackupVar
.Name
);
107 Set FileName field in HFileImage.
109 @param[in] Str File name to set.
110 @param[in] Offset The offset.
111 @param[in] Size The size.
113 @retval EFI_SUCCESS The operation was successful.
114 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
117 HDiskImageSetDiskNameOffsetSize (
118 IN CONST CHAR16
*Str
,
123 if (Str
== HDiskImage
.Name
) {
125 // This function might be called using HDiskImage.FileName as Str.
126 // Directly return without updating HDiskImage.FileName.
132 // free the old file name
134 SHELL_FREE_NON_NULL (HDiskImage
.Name
);
135 HDiskImage
.Name
= AllocateCopyPool (StrSize (Str
), Str
);
136 if (HDiskImage
.Name
== NULL
) {
137 return EFI_OUT_OF_RESOURCES
;
140 HDiskImage
.Offset
= Offset
;
141 HDiskImage
.Size
= Size
;
147 Read a disk from disk into HBufferImage.
149 @param[in] DeviceName filename to read.
150 @param[in] Offset The offset.
151 @param[in] Size The size.
152 @param[in] Recover if is for recover, no information print.
154 @retval EFI_SUCCESS The operation was successful.
155 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
156 @retval EFI_LOAD_ERROR A load error occured.
157 @retval EFI_INVALID_PARAMETER A parameter was invalid.
161 IN CONST CHAR16
*DeviceName
,
167 CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
168 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePath
;
169 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePathForFree
;
171 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
178 HEFI_EDITOR_LINE
*Line
;
180 HBufferImage
.BufferType
= FileTypeDiskBuffer
;
182 DevicePath
= gEfiShellProtocol
->GetDevicePathFromMap(DeviceName
);
183 if (DevicePath
== NULL
) {
184 StatusBarSetStatusString (L
"Cannot Find Device");
185 return EFI_INVALID_PARAMETER
;
187 DupDevicePath
= DuplicateDevicePath(DevicePath
);
188 DupDevicePathForFree
= DupDevicePath
;
190 // get blkio interface
192 Status
= gBS
->LocateDevicePath(&gEfiBlockIoProtocolGuid
,&DupDevicePath
,&Handle
);
193 FreePool(DupDevicePathForFree
);
194 if (EFI_ERROR (Status
)) {
195 StatusBarSetStatusString (L
"Read Disk Failed");
198 Status
= gBS
->OpenProtocol(Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
199 if (EFI_ERROR (Status
)) {
200 StatusBarSetStatusString (L
"Read Disk Failed");
204 // if Offset exceeds LastBlock,
207 if (Offset
> BlkIo
->Media
->LastBlock
|| Offset
+ Size
> BlkIo
->Media
->LastBlock
) {
208 StatusBarSetStatusString (L
"Invalid Offset + Size");
209 return EFI_LOAD_ERROR
;
212 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
213 Buffer
= AllocateZeroPool (Bytes
);
215 if (Buffer
== NULL
) {
216 StatusBarSetStatusString (L
"Read Disk Failed");
217 return EFI_OUT_OF_RESOURCES
;
223 Status
= BlkIo
->ReadBlocks (
225 BlkIo
->Media
->MediaId
,
231 if (EFI_ERROR (Status
)) {
233 StatusBarSetStatusString (L
"Read Disk Failed");
234 return EFI_LOAD_ERROR
;
240 // convert buffer to line list
242 Status
= HBufferImageBufferToList (Buffer
, Bytes
);
245 if (EFI_ERROR (Status
)) {
246 StatusBarSetStatusString (L
"Read Disk Failed");
250 Status
= HDiskImageSetDiskNameOffsetSize (DeviceName
, Offset
, Size
);
251 if (EFI_ERROR (Status
)) {
252 StatusBarSetStatusString (L
"Read Disk Failed");
253 return EFI_OUT_OF_RESOURCES
;
256 // initialize some variables
258 HDiskImage
.BlockSize
= BlkIo
->Media
->BlockSize
;
260 HBufferImage
.DisplayPosition
.Row
= 2;
261 HBufferImage
.DisplayPosition
.Column
= 10;
263 HBufferImage
.MousePosition
.Row
= 2;
264 HBufferImage
.MousePosition
.Column
= 10;
266 HBufferImage
.LowVisibleRow
= 1;
267 HBufferImage
.HighBits
= TRUE
;
269 HBufferImage
.BufferPosition
.Row
= 1;
270 HBufferImage
.BufferPosition
.Column
= 1;
273 Str
= CatSPrint(NULL
, L
"%d Lines Read", HBufferImage
.NumLines
);
275 StatusBarSetStatusString (L
"Read Disk Failed");
276 return EFI_OUT_OF_RESOURCES
;
279 StatusBarSetStatusString (Str
);
280 SHELL_FREE_NON_NULL (Str
);
282 HMainEditor
.SelectStart
= 0;
283 HMainEditor
.SelectEnd
= 0;
290 if (HBufferImage
.Lines
!= NULL
) {
291 HBufferImage
.CurrentLine
= CR (
292 HBufferImage
.ListHead
->ForwardLink
,
299 // create a dummy line
301 Line
= HBufferImageCreateLine ();
303 StatusBarSetStatusString (L
"Read Disk Failed");
304 return EFI_OUT_OF_RESOURCES
;
307 HBufferImage
.CurrentLine
= Line
;
310 HBufferImage
.Modified
= FALSE
;
311 HBufferImageNeedRefresh
= TRUE
;
312 HBufferImageOnlyLineNeedRefresh
= FALSE
;
313 HBufferImageMouseNeedRefresh
= TRUE
;
319 Save lines in HBufferImage to disk.
320 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
322 @param[in] DeviceName The device name.
323 @param[in] Offset The offset.
324 @param[in] Size The size.
326 @retval EFI_SUCCESS The operation was successful.
327 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
328 @retval EFI_LOAD_ERROR A load error occured.
329 @retval EFI_INVALID_PARAMETER A parameter was invalid.
333 IN CHAR16
*DeviceName
,
339 CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
340 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePath
;
341 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePathForFree
;
342 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
349 // if not modified, directly return
351 if (HBufferImage
.Modified
== FALSE
) {
355 HBufferImage
.BufferType
= FileTypeDiskBuffer
;
357 DevicePath
= gEfiShellProtocol
->GetDevicePathFromMap(DeviceName
);
358 if (DevicePath
== NULL
) {
359 // StatusBarSetStatusString (L"Cannot Find Device");
360 return EFI_INVALID_PARAMETER
;
362 DupDevicePath
= DuplicateDevicePath(DevicePath
);
363 DupDevicePathForFree
= DupDevicePath
;
366 // get blkio interface
368 Status
= gBS
->LocateDevicePath(&gEfiBlockIoProtocolGuid
,&DupDevicePath
,&Handle
);
369 FreePool(DupDevicePathForFree
);
370 if (EFI_ERROR (Status
)) {
371 // StatusBarSetStatusString (L"Read Disk Failed");
374 Status
= gBS
->OpenProtocol(Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
375 if (EFI_ERROR (Status
)) {
376 // StatusBarSetStatusString (L"Read Disk Failed");
380 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
381 Buffer
= AllocateZeroPool (Bytes
);
383 if (Buffer
== NULL
) {
384 return EFI_OUT_OF_RESOURCES
;
387 // concatenate the line list to a buffer
389 Status
= HBufferImageListToBuffer (Buffer
, Bytes
);
390 if (EFI_ERROR (Status
)) {
396 // write the buffer to disk
398 Status
= BlkIo
->WriteBlocks (
400 BlkIo
->Media
->MediaId
,
408 if (EFI_ERROR (Status
)) {
409 return EFI_LOAD_ERROR
;
414 HBufferImage
.Modified
= FALSE
;