2 Functions to deal with Disk buffer.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Protocol/BlockIo.h>
12 extern EFI_HANDLE HImageHandleBackup
;
13 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage
;
15 extern BOOLEAN HBufferImageNeedRefresh
;
16 extern BOOLEAN HBufferImageOnlyLineNeedRefresh
;
17 extern BOOLEAN HBufferImageMouseNeedRefresh
;
19 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor
;
21 HEFI_EDITOR_DISK_IMAGE HDiskImage
;
22 HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar
;
25 // for basic initialization of HDiskImage
27 HEFI_EDITOR_DISK_IMAGE HDiskImageConst
= {
35 Initialization function for HDiskImage.
37 @retval EFI_SUCCESS The operation was successful.
38 @retval EFI_LOAD_ERROR A load error occurred.
46 // basically initialize the HDiskImage
48 CopyMem (&HDiskImage
, &HDiskImageConst
, sizeof (HDiskImage
));
50 CopyMem (&HDiskImageBackupVar
, &HDiskImageConst
, sizeof (HDiskImageBackupVar
));
56 Backup function for HDiskImage. Only a few fields need to be backup.
57 This is for making the Disk buffer refresh as few as possible.
59 @retval EFI_SUCCESS The operation was successful.
60 @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
68 // backup the disk name, offset and size
71 SHELL_FREE_NON_NULL (HDiskImageBackupVar
.Name
);
73 HDiskImageBackupVar
.Name
= CatSPrint(NULL
, L
"%s", HDiskImage
.Name
);
74 if (HDiskImageBackupVar
.Name
== NULL
) {
75 return EFI_OUT_OF_RESOURCES
;
78 HDiskImageBackupVar
.Offset
= HDiskImage
.Offset
;
79 HDiskImageBackupVar
.Size
= HDiskImage
.Size
;
85 Cleanup function for HDiskImage.
87 @retval EFI_SUCCESS The operation was successful.
94 SHELL_FREE_NON_NULL (HDiskImage
.Name
);
95 SHELL_FREE_NON_NULL (HDiskImageBackupVar
.Name
);
101 Set FileName field in HFileImage.
103 @param[in] Str File name to set.
104 @param[in] Offset The offset.
105 @param[in] Size The size.
107 @retval EFI_SUCCESS The operation was successful.
108 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
111 HDiskImageSetDiskNameOffsetSize (
112 IN CONST CHAR16
*Str
,
117 if (Str
== HDiskImage
.Name
) {
119 // This function might be called using HDiskImage.FileName as Str.
120 // Directly return without updating HDiskImage.FileName.
126 // free the old file name
128 SHELL_FREE_NON_NULL (HDiskImage
.Name
);
129 HDiskImage
.Name
= AllocateCopyPool (StrSize (Str
), Str
);
130 if (HDiskImage
.Name
== NULL
) {
131 return EFI_OUT_OF_RESOURCES
;
134 HDiskImage
.Offset
= Offset
;
135 HDiskImage
.Size
= Size
;
141 Read a disk from disk into HBufferImage.
143 @param[in] DeviceName filename to read.
144 @param[in] Offset The offset.
145 @param[in] Size The size.
146 @param[in] Recover if is for recover, no information print.
148 @retval EFI_SUCCESS The operation was successful.
149 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
150 @retval EFI_LOAD_ERROR A load error occurred.
151 @retval EFI_INVALID_PARAMETER A parameter was invalid.
155 IN CONST CHAR16
*DeviceName
,
161 CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
162 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePath
;
163 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePathForFree
;
165 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
172 HEFI_EDITOR_LINE
*Line
;
174 HBufferImage
.BufferType
= FileTypeDiskBuffer
;
176 DevicePath
= gEfiShellProtocol
->GetDevicePathFromMap(DeviceName
);
177 if (DevicePath
== NULL
) {
178 StatusBarSetStatusString (L
"Cannot Find Device");
179 return EFI_INVALID_PARAMETER
;
181 DupDevicePath
= DuplicateDevicePath(DevicePath
);
182 DupDevicePathForFree
= DupDevicePath
;
184 // get blkio interface
186 Status
= gBS
->LocateDevicePath(&gEfiBlockIoProtocolGuid
,&DupDevicePath
,&Handle
);
187 FreePool(DupDevicePathForFree
);
188 if (EFI_ERROR (Status
)) {
189 StatusBarSetStatusString (L
"Read Disk Failed");
192 Status
= gBS
->OpenProtocol(Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
193 if (EFI_ERROR (Status
)) {
194 StatusBarSetStatusString (L
"Read Disk Failed");
198 // if Offset exceeds LastBlock,
201 if (Offset
> BlkIo
->Media
->LastBlock
|| Offset
+ Size
> BlkIo
->Media
->LastBlock
) {
202 StatusBarSetStatusString (L
"Invalid Offset + Size");
203 return EFI_LOAD_ERROR
;
206 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
207 Buffer
= AllocateZeroPool (Bytes
);
209 if (Buffer
== NULL
) {
210 StatusBarSetStatusString (L
"Read Disk Failed");
211 return EFI_OUT_OF_RESOURCES
;
217 Status
= BlkIo
->ReadBlocks (
219 BlkIo
->Media
->MediaId
,
225 if (EFI_ERROR (Status
)) {
227 StatusBarSetStatusString (L
"Read Disk Failed");
228 return EFI_LOAD_ERROR
;
234 // convert buffer to line list
236 Status
= HBufferImageBufferToList (Buffer
, Bytes
);
239 if (EFI_ERROR (Status
)) {
240 StatusBarSetStatusString (L
"Read Disk Failed");
244 Status
= HDiskImageSetDiskNameOffsetSize (DeviceName
, Offset
, Size
);
245 if (EFI_ERROR (Status
)) {
246 StatusBarSetStatusString (L
"Read Disk Failed");
247 return EFI_OUT_OF_RESOURCES
;
250 // initialize some variables
252 HDiskImage
.BlockSize
= BlkIo
->Media
->BlockSize
;
254 HBufferImage
.DisplayPosition
.Row
= 2;
255 HBufferImage
.DisplayPosition
.Column
= 10;
257 HBufferImage
.MousePosition
.Row
= 2;
258 HBufferImage
.MousePosition
.Column
= 10;
260 HBufferImage
.LowVisibleRow
= 1;
261 HBufferImage
.HighBits
= TRUE
;
263 HBufferImage
.BufferPosition
.Row
= 1;
264 HBufferImage
.BufferPosition
.Column
= 1;
267 Str
= CatSPrint(NULL
, L
"%d Lines Read", HBufferImage
.NumLines
);
269 StatusBarSetStatusString (L
"Read Disk Failed");
270 return EFI_OUT_OF_RESOURCES
;
273 StatusBarSetStatusString (Str
);
274 SHELL_FREE_NON_NULL (Str
);
276 HMainEditor
.SelectStart
= 0;
277 HMainEditor
.SelectEnd
= 0;
284 if (HBufferImage
.Lines
!= NULL
) {
285 HBufferImage
.CurrentLine
= CR (
286 HBufferImage
.ListHead
->ForwardLink
,
293 // create a dummy line
295 Line
= HBufferImageCreateLine ();
297 StatusBarSetStatusString (L
"Read Disk Failed");
298 return EFI_OUT_OF_RESOURCES
;
301 HBufferImage
.CurrentLine
= Line
;
304 HBufferImage
.Modified
= FALSE
;
305 HBufferImageNeedRefresh
= TRUE
;
306 HBufferImageOnlyLineNeedRefresh
= FALSE
;
307 HBufferImageMouseNeedRefresh
= TRUE
;
313 Save lines in HBufferImage to disk.
314 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
316 @param[in] DeviceName The device name.
317 @param[in] Offset The offset.
318 @param[in] Size The size.
320 @retval EFI_SUCCESS The operation was successful.
321 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
322 @retval EFI_LOAD_ERROR A load error occurred.
323 @retval EFI_INVALID_PARAMETER A parameter was invalid.
327 IN CHAR16
*DeviceName
,
333 CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
334 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePath
;
335 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePathForFree
;
336 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
343 // if not modified, directly return
345 if (HBufferImage
.Modified
== FALSE
) {
349 HBufferImage
.BufferType
= FileTypeDiskBuffer
;
351 DevicePath
= gEfiShellProtocol
->GetDevicePathFromMap(DeviceName
);
352 if (DevicePath
== NULL
) {
353 // StatusBarSetStatusString (L"Cannot Find Device");
354 return EFI_INVALID_PARAMETER
;
356 DupDevicePath
= DuplicateDevicePath(DevicePath
);
357 DupDevicePathForFree
= DupDevicePath
;
360 // get blkio interface
362 Status
= gBS
->LocateDevicePath(&gEfiBlockIoProtocolGuid
,&DupDevicePath
,&Handle
);
363 FreePool(DupDevicePathForFree
);
364 if (EFI_ERROR (Status
)) {
365 // StatusBarSetStatusString (L"Read Disk Failed");
368 Status
= gBS
->OpenProtocol(Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
369 if (EFI_ERROR (Status
)) {
370 // StatusBarSetStatusString (L"Read Disk Failed");
374 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
375 Buffer
= AllocateZeroPool (Bytes
);
377 if (Buffer
== NULL
) {
378 return EFI_OUT_OF_RESOURCES
;
381 // concatenate the line list to a buffer
383 Status
= HBufferImageListToBuffer (Buffer
, Bytes
);
384 if (EFI_ERROR (Status
)) {
390 // write the buffer to disk
392 Status
= BlkIo
->WriteBlocks (
394 BlkIo
->Media
->MediaId
,
402 if (EFI_ERROR (Status
)) {
403 return EFI_LOAD_ERROR
;
408 HBufferImage
.Modified
= FALSE
;