]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / DiskImage.c
1 /** @file
2 Functions to deal with Disk buffer.
3
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "HexEditor.h"
10 #include <Protocol/BlockIo.h>
11
12 extern EFI_HANDLE HImageHandleBackup;
13 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
14
15 extern BOOLEAN HBufferImageNeedRefresh;
16 extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
17 extern BOOLEAN HBufferImageMouseNeedRefresh;
18
19 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
20
21 HEFI_EDITOR_DISK_IMAGE HDiskImage;
22 HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
23
24 //
25 // for basic initialization of HDiskImage
26 //
27 HEFI_EDITOR_DISK_IMAGE HDiskImageConst = {
28 NULL,
29 0,
30 0,
31 0
32 };
33
34 /**
35 Initialization function for HDiskImage.
36
37 @retval EFI_SUCCESS The operation was successful.
38 @retval EFI_LOAD_ERROR A load error occurred.
39 **/
40 EFI_STATUS
41 HDiskImageInit (
42 VOID
43 )
44 {
45 //
46 // basically initialize the HDiskImage
47 //
48 CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
49
50 CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
51
52 return EFI_SUCCESS;
53 }
54
55 /**
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.
58
59 @retval EFI_SUCCESS The operation was successful.
60 @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
61 **/
62 EFI_STATUS
63 HDiskImageBackup (
64 VOID
65 )
66 {
67 //
68 // backup the disk name, offset and size
69 //
70 //
71 SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
72
73 HDiskImageBackupVar.Name = CatSPrint (NULL, L"%s", HDiskImage.Name);
74 if (HDiskImageBackupVar.Name == NULL) {
75 return EFI_OUT_OF_RESOURCES;
76 }
77
78 HDiskImageBackupVar.Offset = HDiskImage.Offset;
79 HDiskImageBackupVar.Size = HDiskImage.Size;
80
81 return EFI_SUCCESS;
82 }
83
84 /**
85 Cleanup function for HDiskImage.
86
87 @retval EFI_SUCCESS The operation was successful.
88 **/
89 EFI_STATUS
90 HDiskImageCleanup (
91 VOID
92 )
93 {
94 SHELL_FREE_NON_NULL (HDiskImage.Name);
95 SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
96
97 return EFI_SUCCESS;
98 }
99
100 /**
101 Set FileName field in HFileImage.
102
103 @param[in] Str File name to set.
104 @param[in] Offset The offset.
105 @param[in] Size The size.
106
107 @retval EFI_SUCCESS The operation was successful.
108 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
109 **/
110 EFI_STATUS
111 HDiskImageSetDiskNameOffsetSize (
112 IN CONST CHAR16 *Str,
113 IN UINTN Offset,
114 IN UINTN Size
115 )
116 {
117 if (Str == HDiskImage.Name) {
118 //
119 // This function might be called using HDiskImage.FileName as Str.
120 // Directly return without updating HDiskImage.FileName.
121 //
122 return EFI_SUCCESS;
123 }
124
125 //
126 // free the old file name
127 //
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;
132 }
133
134 HDiskImage.Offset = Offset;
135 HDiskImage.Size = Size;
136
137 return EFI_SUCCESS;
138 }
139
140 /**
141 Read a disk from disk into HBufferImage.
142
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.
147
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.
152 **/
153 EFI_STATUS
154 HDiskImageRead (
155 IN CONST CHAR16 *DeviceName,
156 IN UINTN Offset,
157 IN UINTN Size,
158 IN BOOLEAN Recover
159 )
160 {
161 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
162 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
163 EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
164 EFI_HANDLE Handle;
165 EFI_BLOCK_IO_PROTOCOL *BlkIo;
166 EFI_STATUS Status;
167
168 VOID *Buffer;
169 CHAR16 *Str;
170 UINTN Bytes;
171
172 HEFI_EDITOR_LINE *Line;
173
174 HBufferImage.BufferType = FileTypeDiskBuffer;
175
176 DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName);
177 if (DevicePath == NULL) {
178 StatusBarSetStatusString (L"Cannot Find Device");
179 return EFI_INVALID_PARAMETER;
180 }
181
182 DupDevicePath = DuplicateDevicePath (DevicePath);
183 DupDevicePathForFree = DupDevicePath;
184 //
185 // get blkio interface
186 //
187 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle);
188 FreePool (DupDevicePathForFree);
189 if (EFI_ERROR (Status)) {
190 StatusBarSetStatusString (L"Read Disk Failed");
191 return Status;
192 }
193
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");
197 return Status;
198 }
199
200 //
201 // if Offset exceeds LastBlock,
202 // return error
203 //
204 if ((Offset > BlkIo->Media->LastBlock) || (Offset + Size > BlkIo->Media->LastBlock)) {
205 StatusBarSetStatusString (L"Invalid Offset + Size");
206 return EFI_LOAD_ERROR;
207 }
208
209 Bytes = BlkIo->Media->BlockSize * Size;
210 Buffer = AllocateZeroPool (Bytes);
211
212 if (Buffer == NULL) {
213 StatusBarSetStatusString (L"Read Disk Failed");
214 return EFI_OUT_OF_RESOURCES;
215 }
216
217 //
218 // read from disk
219 //
220 Status = BlkIo->ReadBlocks (
221 BlkIo,
222 BlkIo->Media->MediaId,
223 Offset,
224 Bytes,
225 Buffer
226 );
227
228 if (EFI_ERROR (Status)) {
229 FreePool (Buffer);
230 StatusBarSetStatusString (L"Read Disk Failed");
231 return EFI_LOAD_ERROR;
232 }
233
234 HBufferImageFree ();
235
236 //
237 // convert buffer to line list
238 //
239 Status = HBufferImageBufferToList (Buffer, Bytes);
240 FreePool (Buffer);
241
242 if (EFI_ERROR (Status)) {
243 StatusBarSetStatusString (L"Read Disk Failed");
244 return Status;
245 }
246
247 Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
248 if (EFI_ERROR (Status)) {
249 StatusBarSetStatusString (L"Read Disk Failed");
250 return EFI_OUT_OF_RESOURCES;
251 }
252
253 //
254 // initialize some variables
255 //
256 HDiskImage.BlockSize = BlkIo->Media->BlockSize;
257
258 HBufferImage.DisplayPosition.Row = 2;
259 HBufferImage.DisplayPosition.Column = 10;
260
261 HBufferImage.MousePosition.Row = 2;
262 HBufferImage.MousePosition.Column = 10;
263
264 HBufferImage.LowVisibleRow = 1;
265 HBufferImage.HighBits = TRUE;
266
267 HBufferImage.BufferPosition.Row = 1;
268 HBufferImage.BufferPosition.Column = 1;
269
270 if (!Recover) {
271 Str = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines);
272 if (Str == NULL) {
273 StatusBarSetStatusString (L"Read Disk Failed");
274 return EFI_OUT_OF_RESOURCES;
275 }
276
277 StatusBarSetStatusString (Str);
278 SHELL_FREE_NON_NULL (Str);
279
280 HMainEditor.SelectStart = 0;
281 HMainEditor.SelectEnd = 0;
282 }
283
284 //
285 // has line
286 //
287 if (HBufferImage.Lines != NULL) {
288 HBufferImage.CurrentLine = CR (
289 HBufferImage.ListHead->ForwardLink,
290 HEFI_EDITOR_LINE,
291 Link,
292 EFI_EDITOR_LINE_LIST
293 );
294 } else {
295 //
296 // create a dummy line
297 //
298 Line = HBufferImageCreateLine ();
299 if (Line == NULL) {
300 StatusBarSetStatusString (L"Read Disk Failed");
301 return EFI_OUT_OF_RESOURCES;
302 }
303
304 HBufferImage.CurrentLine = Line;
305 }
306
307 HBufferImage.Modified = FALSE;
308 HBufferImageNeedRefresh = TRUE;
309 HBufferImageOnlyLineNeedRefresh = FALSE;
310 HBufferImageMouseNeedRefresh = TRUE;
311
312 return EFI_SUCCESS;
313 }
314
315 /**
316 Save lines in HBufferImage to disk.
317 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
318
319 @param[in] DeviceName The device name.
320 @param[in] Offset The offset.
321 @param[in] Size The size.
322
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.
327 **/
328 EFI_STATUS
329 HDiskImageSave (
330 IN CHAR16 *DeviceName,
331 IN UINTN Offset,
332 IN UINTN Size
333 )
334 {
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;
339 EFI_STATUS Status;
340 EFI_HANDLE Handle;
341 VOID *Buffer;
342 UINTN Bytes;
343
344 //
345 // if not modified, directly return
346 //
347 if (HBufferImage.Modified == FALSE) {
348 return EFI_SUCCESS;
349 }
350
351 HBufferImage.BufferType = FileTypeDiskBuffer;
352
353 DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName);
354 if (DevicePath == NULL) {
355 // StatusBarSetStatusString (L"Cannot Find Device");
356 return EFI_INVALID_PARAMETER;
357 }
358
359 DupDevicePath = DuplicateDevicePath (DevicePath);
360 DupDevicePathForFree = DupDevicePath;
361
362 //
363 // get blkio interface
364 //
365 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle);
366 FreePool (DupDevicePathForFree);
367 if (EFI_ERROR (Status)) {
368 // StatusBarSetStatusString (L"Read Disk Failed");
369 return Status;
370 }
371
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");
375 return Status;
376 }
377
378 Bytes = BlkIo->Media->BlockSize * Size;
379 Buffer = AllocateZeroPool (Bytes);
380
381 if (Buffer == NULL) {
382 return EFI_OUT_OF_RESOURCES;
383 }
384
385 //
386 // concatenate the line list to a buffer
387 //
388 Status = HBufferImageListToBuffer (Buffer, Bytes);
389 if (EFI_ERROR (Status)) {
390 FreePool (Buffer);
391 return Status;
392 }
393
394 //
395 // write the buffer to disk
396 //
397 Status = BlkIo->WriteBlocks (
398 BlkIo,
399 BlkIo->Media->MediaId,
400 Offset,
401 Bytes,
402 Buffer
403 );
404
405 FreePool (Buffer);
406
407 if (EFI_ERROR (Status)) {
408 return EFI_LOAD_ERROR;
409 }
410
411 //
412 // now not modified
413 //
414 HBufferImage.Modified = FALSE;
415
416 return EFI_SUCCESS;
417 }