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