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
;
182 DupDevicePath
= DuplicateDevicePath (DevicePath
);
183 DupDevicePathForFree
= DupDevicePath
;
185 // get blkio interface
187 Status
= gBS
->LocateDevicePath (&gEfiBlockIoProtocolGuid
, &DupDevicePath
, &Handle
);
188 FreePool (DupDevicePathForFree
);
189 if (EFI_ERROR (Status
)) {
190 StatusBarSetStatusString (L
"Read Disk Failed");
194 Status
= gBS
->OpenProtocol (Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
195 if (EFI_ERROR (Status
)) {
196 StatusBarSetStatusString (L
"Read Disk Failed");
201 // if Offset exceeds LastBlock,
204 if ((Offset
> BlkIo
->Media
->LastBlock
) || (Offset
+ Size
> BlkIo
->Media
->LastBlock
)) {
205 StatusBarSetStatusString (L
"Invalid Offset + Size");
206 return EFI_LOAD_ERROR
;
209 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
210 Buffer
= AllocateZeroPool (Bytes
);
212 if (Buffer
== NULL
) {
213 StatusBarSetStatusString (L
"Read Disk Failed");
214 return EFI_OUT_OF_RESOURCES
;
220 Status
= BlkIo
->ReadBlocks (
222 BlkIo
->Media
->MediaId
,
228 if (EFI_ERROR (Status
)) {
230 StatusBarSetStatusString (L
"Read Disk Failed");
231 return EFI_LOAD_ERROR
;
237 // convert buffer to line list
239 Status
= HBufferImageBufferToList (Buffer
, Bytes
);
242 if (EFI_ERROR (Status
)) {
243 StatusBarSetStatusString (L
"Read Disk Failed");
247 Status
= HDiskImageSetDiskNameOffsetSize (DeviceName
, Offset
, Size
);
248 if (EFI_ERROR (Status
)) {
249 StatusBarSetStatusString (L
"Read Disk Failed");
250 return EFI_OUT_OF_RESOURCES
;
254 // initialize some variables
256 HDiskImage
.BlockSize
= BlkIo
->Media
->BlockSize
;
258 HBufferImage
.DisplayPosition
.Row
= 2;
259 HBufferImage
.DisplayPosition
.Column
= 10;
261 HBufferImage
.MousePosition
.Row
= 2;
262 HBufferImage
.MousePosition
.Column
= 10;
264 HBufferImage
.LowVisibleRow
= 1;
265 HBufferImage
.HighBits
= TRUE
;
267 HBufferImage
.BufferPosition
.Row
= 1;
268 HBufferImage
.BufferPosition
.Column
= 1;
271 Str
= CatSPrint (NULL
, L
"%d Lines Read", HBufferImage
.NumLines
);
273 StatusBarSetStatusString (L
"Read Disk Failed");
274 return EFI_OUT_OF_RESOURCES
;
277 StatusBarSetStatusString (Str
);
278 SHELL_FREE_NON_NULL (Str
);
280 HMainEditor
.SelectStart
= 0;
281 HMainEditor
.SelectEnd
= 0;
287 if (HBufferImage
.Lines
!= NULL
) {
288 HBufferImage
.CurrentLine
= CR (
289 HBufferImage
.ListHead
->ForwardLink
,
296 // create a dummy line
298 Line
= HBufferImageCreateLine ();
300 StatusBarSetStatusString (L
"Read Disk Failed");
301 return EFI_OUT_OF_RESOURCES
;
304 HBufferImage
.CurrentLine
= Line
;
307 HBufferImage
.Modified
= FALSE
;
308 HBufferImageNeedRefresh
= TRUE
;
309 HBufferImageOnlyLineNeedRefresh
= FALSE
;
310 HBufferImageMouseNeedRefresh
= TRUE
;
316 Save lines in HBufferImage to disk.
317 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
319 @param[in] DeviceName The device name.
320 @param[in] Offset The offset.
321 @param[in] Size The size.
323 @retval EFI_SUCCESS The operation was successful.
324 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
325 @retval EFI_LOAD_ERROR A load error occurred.
326 @retval EFI_INVALID_PARAMETER A parameter was invalid.
330 IN CHAR16
*DeviceName
,
335 CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
336 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePath
;
337 EFI_DEVICE_PATH_PROTOCOL
*DupDevicePathForFree
;
338 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
345 // if not modified, directly return
347 if (HBufferImage
.Modified
== FALSE
) {
351 HBufferImage
.BufferType
= FileTypeDiskBuffer
;
353 DevicePath
= gEfiShellProtocol
->GetDevicePathFromMap (DeviceName
);
354 if (DevicePath
== NULL
) {
355 // StatusBarSetStatusString (L"Cannot Find Device");
356 return EFI_INVALID_PARAMETER
;
359 DupDevicePath
= DuplicateDevicePath (DevicePath
);
360 DupDevicePathForFree
= DupDevicePath
;
363 // get blkio interface
365 Status
= gBS
->LocateDevicePath (&gEfiBlockIoProtocolGuid
, &DupDevicePath
, &Handle
);
366 FreePool (DupDevicePathForFree
);
367 if (EFI_ERROR (Status
)) {
368 // StatusBarSetStatusString (L"Read Disk Failed");
372 Status
= gBS
->OpenProtocol (Handle
, &gEfiBlockIoProtocolGuid
, (VOID
**)&BlkIo
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
373 if (EFI_ERROR (Status
)) {
374 // StatusBarSetStatusString (L"Read Disk Failed");
378 Bytes
= BlkIo
->Media
->BlockSize
* Size
;
379 Buffer
= AllocateZeroPool (Bytes
);
381 if (Buffer
== NULL
) {
382 return EFI_OUT_OF_RESOURCES
;
386 // concatenate the line list to a buffer
388 Status
= HBufferImageListToBuffer (Buffer
, Bytes
);
389 if (EFI_ERROR (Status
)) {
395 // write the buffer to disk
397 Status
= BlkIo
->WriteBlocks (
399 BlkIo
->Media
->MediaId
,
407 if (EFI_ERROR (Status
)) {
408 return EFI_LOAD_ERROR
;
414 HBufferImage
.Modified
= FALSE
;