]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c
86db6aadf25edebcac67209b85ac3be749b16d15
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / DiskImage.c
1 /** @file
2 Functions to deal with Disk buffer.
3
4 Copyright (c) 2005 - 2011, 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 EFI_STATUS
41 HDiskImageInit (
42 VOID
43 )
44 /*++
45
46 Routine Description:
47
48 Initialization function for HDiskImage
49
50 Arguments:
51
52 None
53
54 Returns:
55
56 EFI_SUCCESS
57 EFI_LOAD_ERROR
58
59 --*/
60 {
61 //
62 // basically initialize the HDiskImage
63 //
64 CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
65
66 CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
67
68 return EFI_SUCCESS;
69 }
70
71 EFI_STATUS
72 HDiskImageBackup (
73 VOID
74 )
75 /*++
76
77 Routine Description:
78
79 Backup function for HDiskImage
80 Only a few fields need to be backup.
81 This is for making the Disk buffer refresh
82 as few as possible.
83
84 Arguments:
85
86 None
87
88 Returns:
89
90 EFI_SUCCESS - Success
91 EFI_OUT_OF_RESOURCES - gST->ConOut of resources
92
93 --*/
94 {
95 //
96 // backup the disk name, offset and size
97 //
98 //
99 SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
100
101 HDiskImageBackupVar.Name = CatSPrint(NULL, L"%s", HDiskImage.Name);
102 if (HDiskImageBackupVar.Name == NULL) {
103 return EFI_OUT_OF_RESOURCES;
104 }
105
106 HDiskImageBackupVar.Offset = HDiskImage.Offset;
107 HDiskImageBackupVar.Size = HDiskImage.Size;
108
109 return EFI_SUCCESS;
110 }
111
112 EFI_STATUS
113 HDiskImageCleanup (
114 VOID
115 )
116 /*++
117
118 Routine Description:
119
120 Cleanup function for HDiskImage
121
122 Arguments:
123
124 None
125
126 Returns:
127
128 EFI_SUCCESS
129
130 --*/
131 {
132 SHELL_FREE_NON_NULL (HDiskImage.Name);
133 SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
134
135 return EFI_SUCCESS;
136 }
137
138 EFI_STATUS
139 EFIAPI
140 HDiskImageSetDiskNameOffsetSize (
141 IN CONST CHAR16 *Str,
142 IN UINTN Offset,
143 IN UINTN Size
144 )
145 /*++
146
147 Routine Description:
148
149 Set FileName field in HFileImage
150
151 Arguments:
152
153 Str - File name to set
154 Offset - The offset
155 Size - The size
156
157 Returns:
158
159 EFI_SUCCESS
160 EFI_OUT_OF_RESOURCES
161
162 --*/
163 {
164 UINTN Len;
165 UINTN Index;
166
167 //
168 // free the old file name
169 //
170 SHELL_FREE_NON_NULL (HDiskImage.Name);
171
172 Len = StrLen (Str);
173
174 HDiskImage.Name = AllocateZeroPool (2 * (Len + 1));
175 if (HDiskImage.Name == NULL) {
176 return EFI_OUT_OF_RESOURCES;
177 }
178
179 for (Index = 0; Index < Len; Index++) {
180 HDiskImage.Name[Index] = Str[Index];
181 }
182
183 HDiskImage.Name[Len] = L'\0';
184
185 HDiskImage.Offset = Offset;
186 HDiskImage.Size = Size;
187
188 return EFI_SUCCESS;
189 }
190
191 EFI_STATUS
192 HDiskImageRead (
193 IN CONST CHAR16 *DeviceName,
194 IN UINTN Offset,
195 IN UINTN Size,
196 IN BOOLEAN Recover
197 )
198 /*++
199
200 Routine Description:
201
202 Read a disk from disk into HBufferImage
203
204 Arguments:
205
206 DeviceName - filename to read
207 Offset - The offset
208 Size - The size
209 Recover - if is for recover, no information print
210
211 Returns:
212
213 EFI_SUCCESS
214 EFI_LOAD_ERROR
215 EFI_OUT_OF_RESOURCES
216 EFI_INVALID_PARAMETER
217
218 --*/
219 {
220 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
221 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
222 EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
223 EFI_HANDLE Handle;
224 EFI_BLOCK_IO_PROTOCOL *BlkIo;
225 EFI_STATUS Status;
226
227 VOID *Buffer;
228 CHAR16 *Str;
229 UINTN Bytes;
230
231 HEFI_EDITOR_LINE *Line;
232 UINT64 ByteOffset;
233
234 EDIT_FILE_TYPE BufferTypeBackup;
235
236 BufferTypeBackup = HBufferImage.BufferType;
237 HBufferImage.BufferType = FileTypeDiskBuffer;
238
239 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
240 if (DevicePath == NULL) {
241 StatusBarSetStatusString (L"Cannot Find Device");
242 return EFI_INVALID_PARAMETER;
243 }
244 DupDevicePath = DuplicateDevicePath(DevicePath);
245 DupDevicePathForFree = DupDevicePath;
246 //
247 // get blkio interface
248 //
249 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
250 FreePool(DupDevicePathForFree);
251 if (EFI_ERROR (Status)) {
252 StatusBarSetStatusString (L"Read Disk Failed");
253 return Status;
254 }
255 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
256 if (EFI_ERROR (Status)) {
257 StatusBarSetStatusString (L"Read Disk Failed");
258 return Status;
259 }
260 //
261 // if Offset exceeds LastBlock,
262 // return error
263 //
264 if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
265 StatusBarSetStatusString (L"Invalid Offset + Size");
266 return EFI_LOAD_ERROR;
267 }
268
269 Bytes = BlkIo->Media->BlockSize * Size;
270 Buffer = AllocateZeroPool (Bytes);
271
272 if (Buffer == NULL) {
273 StatusBarSetStatusString (L"Read Disk Failed");
274 return EFI_OUT_OF_RESOURCES;
275 }
276
277 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
278
279 //
280 // read from disk
281 //
282 Status = BlkIo->ReadBlocks (
283 BlkIo,
284 BlkIo->Media->MediaId,
285 Offset,
286 Bytes,
287 Buffer
288 );
289
290 if (EFI_ERROR (Status)) {
291 FreePool (Buffer);
292 StatusBarSetStatusString (L"Read Disk Failed");
293 return EFI_LOAD_ERROR;
294 }
295
296 HBufferImageFree ();
297
298 //
299 // convert buffer to line list
300 //
301 Status = HBufferImageBufferToList (Buffer, Bytes);
302 FreePool (Buffer);
303
304 if (EFI_ERROR (Status)) {
305 StatusBarSetStatusString (L"Read Disk Failed");
306 return Status;
307 }
308
309 Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
310 if (EFI_ERROR (Status)) {
311 StatusBarSetStatusString (L"Read Disk Failed");
312 return EFI_OUT_OF_RESOURCES;
313 }
314 //
315 // initialize some variables
316 //
317 HDiskImage.BlockSize = BlkIo->Media->BlockSize;
318
319 HBufferImage.DisplayPosition.Row = 2;
320 HBufferImage.DisplayPosition.Column = 10;
321
322 HBufferImage.MousePosition.Row = 2;
323 HBufferImage.MousePosition.Column = 10;
324
325 HBufferImage.LowVisibleRow = 1;
326 HBufferImage.HighBits = TRUE;
327
328 HBufferImage.BufferPosition.Row = 1;
329 HBufferImage.BufferPosition.Column = 1;
330
331 if (!Recover) {
332 Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
333 if (Str == NULL) {
334 StatusBarSetStatusString (L"Read Disk Failed");
335 return EFI_OUT_OF_RESOURCES;
336 }
337
338 StatusBarSetStatusString (Str);
339 SHELL_FREE_NON_NULL (Str);
340
341 HMainEditor.SelectStart = 0;
342 HMainEditor.SelectEnd = 0;
343
344 }
345
346 //
347 // has line
348 //
349 if (HBufferImage.Lines != NULL) {
350 HBufferImage.CurrentLine = CR (
351 HBufferImage.ListHead->ForwardLink,
352 HEFI_EDITOR_LINE,
353 Link,
354 EFI_EDITOR_LINE_LIST
355 );
356 } else {
357 //
358 // create a dummy line
359 //
360 Line = HBufferImageCreateLine ();
361 if (Line == NULL) {
362 StatusBarSetStatusString (L"Read Disk Failed");
363 return EFI_OUT_OF_RESOURCES;
364 }
365
366 HBufferImage.CurrentLine = Line;
367 }
368
369 HBufferImage.Modified = FALSE;
370 HBufferImageNeedRefresh = TRUE;
371 HBufferImageOnlyLineNeedRefresh = FALSE;
372 HBufferImageMouseNeedRefresh = TRUE;
373
374 return EFI_SUCCESS;
375 }
376
377 EFI_STATUS
378 HDiskImageSave (
379 IN CHAR16 *DeviceName,
380 IN UINTN Offset,
381 IN UINTN Size
382 )
383 /*++
384
385 Routine Description:
386
387 Save lines in HBufferImage to disk
388 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
389
390 Arguments:
391
392 DeviceName - The device name
393 Offset - The offset
394 Size - The size
395
396 Returns:
397
398 EFI_SUCCESS
399 EFI_LOAD_ERROR
400 EFI_OUT_OF_RESOURCES
401 EFI_INVALID_PARAMETER
402
403 --*/
404 {
405
406 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
407 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
408 EFI_BLOCK_IO_PROTOCOL *BlkIo;
409 EFI_STATUS Status;
410 EFI_HANDLE Handle;
411 VOID *Buffer;
412 UINTN Bytes;
413
414 UINT64 ByteOffset;
415
416 EDIT_FILE_TYPE BufferTypeBackup;
417
418 //
419 // if not modified, directly return
420 //
421 if (HBufferImage.Modified == FALSE) {
422 return EFI_SUCCESS;
423 }
424
425 BufferTypeBackup = HBufferImage.BufferType;
426 HBufferImage.BufferType = FileTypeDiskBuffer;
427
428 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
429 if (DevicePath == NULL) {
430 // StatusBarSetStatusString (L"Cannot Find Device");
431 return EFI_INVALID_PARAMETER;
432 }
433 DupDevicePath = DuplicateDevicePath(DevicePath);
434
435 //
436 // get blkio interface
437 //
438 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
439 FreePool(DupDevicePath);
440 if (EFI_ERROR (Status)) {
441 // StatusBarSetStatusString (L"Read Disk Failed");
442 return Status;
443 }
444 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
445 if (EFI_ERROR (Status)) {
446 // StatusBarSetStatusString (L"Read Disk Failed");
447 return Status;
448 }
449
450 Bytes = BlkIo->Media->BlockSize * Size;
451 Buffer = AllocateZeroPool (Bytes);
452
453 if (Buffer == NULL) {
454 return EFI_OUT_OF_RESOURCES;
455 }
456 //
457 // concatenate the line list to a buffer
458 //
459 Status = HBufferImageListToBuffer (Buffer, Bytes);
460 if (EFI_ERROR (Status)) {
461 FreePool (Buffer);
462 return Status;
463 }
464
465 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
466
467 //
468 // write the buffer to disk
469 //
470 Status = BlkIo->WriteBlocks (
471 BlkIo,
472 BlkIo->Media->MediaId,
473 Offset,
474 Bytes,
475 Buffer
476 );
477
478 FreePool (Buffer);
479
480 if (EFI_ERROR (Status)) {
481 return EFI_LOAD_ERROR;
482 }
483 //
484 // now not modified
485 //
486 HBufferImage.Modified = FALSE;
487
488 return EFI_SUCCESS;
489 }