]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c
140db71671247678478d3dfa7747152b3763e5df
[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_HANDLE Handle;
223 EFI_BLOCK_IO_PROTOCOL *BlkIo;
224 EFI_STATUS Status;
225
226 VOID *Buffer;
227 CHAR16 *Str;
228 UINTN Bytes;
229
230 HEFI_EDITOR_LINE *Line;
231 UINT64 ByteOffset;
232
233 EDIT_FILE_TYPE BufferTypeBackup;
234
235 BufferTypeBackup = HBufferImage.BufferType;
236 HBufferImage.BufferType = FileTypeDiskBuffer;
237
238 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
239 if (DevicePath == NULL) {
240 StatusBarSetStatusString (L"Cannot Find Device");
241 return EFI_INVALID_PARAMETER;
242 }
243 DupDevicePath = DuplicateDevicePath(DevicePath);
244 //
245 // get blkio interface
246 //
247 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
248 FreePool(DupDevicePath);
249 if (EFI_ERROR (Status)) {
250 StatusBarSetStatusString (L"Read Disk Failed");
251 return Status;
252 }
253 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
254 if (EFI_ERROR (Status)) {
255 StatusBarSetStatusString (L"Read Disk Failed");
256 return Status;
257 }
258 //
259 // if Offset exceeds LastBlock,
260 // return error
261 //
262 if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
263 StatusBarSetStatusString (L"Invalid Offset + Size");
264 return EFI_LOAD_ERROR;
265 }
266
267 Bytes = BlkIo->Media->BlockSize * Size;
268 Buffer = AllocateZeroPool (Bytes);
269
270 if (Buffer == NULL) {
271 StatusBarSetStatusString (L"Read Disk Failed");
272 return EFI_OUT_OF_RESOURCES;
273 }
274
275 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
276
277 //
278 // read from disk
279 //
280 Status = BlkIo->ReadBlocks (
281 BlkIo,
282 BlkIo->Media->MediaId,
283 Offset,
284 Bytes,
285 Buffer
286 );
287
288 if (EFI_ERROR (Status)) {
289 FreePool (Buffer);
290 StatusBarSetStatusString (L"Read Disk Failed");
291 return EFI_LOAD_ERROR;
292 }
293
294 HBufferImageFree ();
295
296 //
297 // convert buffer to line list
298 //
299 Status = HBufferImageBufferToList (Buffer, Bytes);
300 FreePool (Buffer);
301
302 if (EFI_ERROR (Status)) {
303 StatusBarSetStatusString (L"Read Disk Failed");
304 return Status;
305 }
306
307 Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
308 if (EFI_ERROR (Status)) {
309 StatusBarSetStatusString (L"Read Disk Failed");
310 return EFI_OUT_OF_RESOURCES;
311 }
312 //
313 // initialize some variables
314 //
315 HDiskImage.BlockSize = BlkIo->Media->BlockSize;
316
317 HBufferImage.DisplayPosition.Row = 2;
318 HBufferImage.DisplayPosition.Column = 10;
319
320 HBufferImage.MousePosition.Row = 2;
321 HBufferImage.MousePosition.Column = 10;
322
323 HBufferImage.LowVisibleRow = 1;
324 HBufferImage.HighBits = TRUE;
325
326 HBufferImage.BufferPosition.Row = 1;
327 HBufferImage.BufferPosition.Column = 1;
328
329 if (!Recover) {
330 Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
331 if (Str == NULL) {
332 StatusBarSetStatusString (L"Read Disk Failed");
333 return EFI_OUT_OF_RESOURCES;
334 }
335
336 StatusBarSetStatusString (Str);
337 SHELL_FREE_NON_NULL (Str);
338
339 HMainEditor.SelectStart = 0;
340 HMainEditor.SelectEnd = 0;
341
342 }
343
344 //
345 // has line
346 //
347 if (HBufferImage.Lines != NULL) {
348 HBufferImage.CurrentLine = CR (
349 HBufferImage.ListHead->ForwardLink,
350 HEFI_EDITOR_LINE,
351 Link,
352 EFI_EDITOR_LINE_LIST
353 );
354 } else {
355 //
356 // create a dummy line
357 //
358 Line = HBufferImageCreateLine ();
359 if (Line == NULL) {
360 StatusBarSetStatusString (L"Read Disk Failed");
361 return EFI_OUT_OF_RESOURCES;
362 }
363
364 HBufferImage.CurrentLine = Line;
365 }
366
367 HBufferImage.Modified = FALSE;
368 HBufferImageNeedRefresh = TRUE;
369 HBufferImageOnlyLineNeedRefresh = FALSE;
370 HBufferImageMouseNeedRefresh = TRUE;
371
372 return EFI_SUCCESS;
373 }
374
375 EFI_STATUS
376 HDiskImageSave (
377 IN CHAR16 *DeviceName,
378 IN UINTN Offset,
379 IN UINTN Size
380 )
381 /*++
382
383 Routine Description:
384
385 Save lines in HBufferImage to disk
386 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
387
388 Arguments:
389
390 DeviceName - The device name
391 Offset - The offset
392 Size - The size
393
394 Returns:
395
396 EFI_SUCCESS
397 EFI_LOAD_ERROR
398 EFI_OUT_OF_RESOURCES
399 EFI_INVALID_PARAMETER
400
401 --*/
402 {
403
404 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
405 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
406 EFI_BLOCK_IO_PROTOCOL *BlkIo;
407 EFI_STATUS Status;
408 EFI_HANDLE Handle;
409 VOID *Buffer;
410 UINTN Bytes;
411
412 UINT64 ByteOffset;
413
414 EDIT_FILE_TYPE BufferTypeBackup;
415
416 //
417 // if not modified, directly return
418 //
419 if (HBufferImage.Modified == FALSE) {
420 return EFI_SUCCESS;
421 }
422
423 BufferTypeBackup = HBufferImage.BufferType;
424 HBufferImage.BufferType = FileTypeDiskBuffer;
425
426 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
427 if (DevicePath == NULL) {
428 // StatusBarSetStatusString (L"Cannot Find Device");
429 return EFI_INVALID_PARAMETER;
430 }
431 DupDevicePath = DuplicateDevicePath(DevicePath);
432
433 //
434 // get blkio interface
435 //
436 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
437 FreePool(DupDevicePath);
438 if (EFI_ERROR (Status)) {
439 // StatusBarSetStatusString (L"Read Disk Failed");
440 return Status;
441 }
442 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
443 if (EFI_ERROR (Status)) {
444 // StatusBarSetStatusString (L"Read Disk Failed");
445 return Status;
446 }
447
448 Bytes = BlkIo->Media->BlockSize * Size;
449 Buffer = AllocateZeroPool (Bytes);
450
451 if (Buffer == NULL) {
452 return EFI_OUT_OF_RESOURCES;
453 }
454 //
455 // concatenate the line list to a buffer
456 //
457 Status = HBufferImageListToBuffer (Buffer, Bytes);
458 if (EFI_ERROR (Status)) {
459 FreePool (Buffer);
460 return Status;
461 }
462
463 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
464
465 //
466 // write the buffer to disk
467 //
468 Status = BlkIo->WriteBlocks (
469 BlkIo,
470 BlkIo->Media->MediaId,
471 Offset,
472 Bytes,
473 Buffer
474 );
475
476 FreePool (Buffer);
477
478 if (EFI_ERROR (Status)) {
479 return EFI_LOAD_ERROR;
480 }
481 //
482 // now not modified
483 //
484 HBufferImage.Modified = FALSE;
485
486 return EFI_SUCCESS;
487 }