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