]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c
add comments to function declarations and definitions and updated to match coding...
[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 /**
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 EFIAPI
118 HDiskImageSetDiskNameOffsetSize (
119 IN CONST CHAR16 *Str,
120 IN UINTN Offset,
121 IN UINTN Size
122 )
123 {
124 UINTN Len;
125 UINTN Index;
126
127 //
128 // free the old file name
129 //
130 SHELL_FREE_NON_NULL (HDiskImage.Name);
131
132 Len = StrLen (Str);
133
134 HDiskImage.Name = AllocateZeroPool (2 * (Len + 1));
135 if (HDiskImage.Name == NULL) {
136 return EFI_OUT_OF_RESOURCES;
137 }
138
139 for (Index = 0; Index < Len; Index++) {
140 HDiskImage.Name[Index] = Str[Index];
141 }
142
143 HDiskImage.Name[Len] = L'\0';
144
145 HDiskImage.Offset = Offset;
146 HDiskImage.Size = Size;
147
148 return EFI_SUCCESS;
149 }
150
151 /**
152 Read a disk from disk into HBufferImage.
153
154 @param[in] DeviceName filename to read.
155 @param[in] Offset The offset.
156 @param[in] Size The size.
157 @param[in] Recover if is for recover, no information print.
158
159 @retval EFI_SUCCESS The operation was successful.
160 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
161 @retval EFI_LOAD_ERROR A load error occured.
162 @retval EFI_INVALID_PARAMETER A parameter was invalid.
163 **/
164 EFI_STATUS
165 HDiskImageRead (
166 IN CONST CHAR16 *DeviceName,
167 IN UINTN Offset,
168 IN UINTN Size,
169 IN BOOLEAN Recover
170 )
171 {
172 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
173 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
174 EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
175 EFI_HANDLE Handle;
176 EFI_BLOCK_IO_PROTOCOL *BlkIo;
177 EFI_STATUS Status;
178
179 VOID *Buffer;
180 CHAR16 *Str;
181 UINTN Bytes;
182
183 HEFI_EDITOR_LINE *Line;
184 UINT64 ByteOffset;
185
186 EDIT_FILE_TYPE BufferTypeBackup;
187
188 BufferTypeBackup = HBufferImage.BufferType;
189 HBufferImage.BufferType = FileTypeDiskBuffer;
190
191 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
192 if (DevicePath == NULL) {
193 StatusBarSetStatusString (L"Cannot Find Device");
194 return EFI_INVALID_PARAMETER;
195 }
196 DupDevicePath = DuplicateDevicePath(DevicePath);
197 DupDevicePathForFree = DupDevicePath;
198 //
199 // get blkio interface
200 //
201 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
202 FreePool(DupDevicePathForFree);
203 if (EFI_ERROR (Status)) {
204 StatusBarSetStatusString (L"Read Disk Failed");
205 return Status;
206 }
207 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
208 if (EFI_ERROR (Status)) {
209 StatusBarSetStatusString (L"Read Disk Failed");
210 return Status;
211 }
212 //
213 // if Offset exceeds LastBlock,
214 // return error
215 //
216 if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
217 StatusBarSetStatusString (L"Invalid Offset + Size");
218 return EFI_LOAD_ERROR;
219 }
220
221 Bytes = BlkIo->Media->BlockSize * Size;
222 Buffer = AllocateZeroPool (Bytes);
223
224 if (Buffer == NULL) {
225 StatusBarSetStatusString (L"Read Disk Failed");
226 return EFI_OUT_OF_RESOURCES;
227 }
228
229 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
230
231 //
232 // read from disk
233 //
234 Status = BlkIo->ReadBlocks (
235 BlkIo,
236 BlkIo->Media->MediaId,
237 Offset,
238 Bytes,
239 Buffer
240 );
241
242 if (EFI_ERROR (Status)) {
243 FreePool (Buffer);
244 StatusBarSetStatusString (L"Read Disk Failed");
245 return EFI_LOAD_ERROR;
246 }
247
248 HBufferImageFree ();
249
250 //
251 // convert buffer to line list
252 //
253 Status = HBufferImageBufferToList (Buffer, Bytes);
254 FreePool (Buffer);
255
256 if (EFI_ERROR (Status)) {
257 StatusBarSetStatusString (L"Read Disk Failed");
258 return Status;
259 }
260
261 Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
262 if (EFI_ERROR (Status)) {
263 StatusBarSetStatusString (L"Read Disk Failed");
264 return EFI_OUT_OF_RESOURCES;
265 }
266 //
267 // initialize some variables
268 //
269 HDiskImage.BlockSize = BlkIo->Media->BlockSize;
270
271 HBufferImage.DisplayPosition.Row = 2;
272 HBufferImage.DisplayPosition.Column = 10;
273
274 HBufferImage.MousePosition.Row = 2;
275 HBufferImage.MousePosition.Column = 10;
276
277 HBufferImage.LowVisibleRow = 1;
278 HBufferImage.HighBits = TRUE;
279
280 HBufferImage.BufferPosition.Row = 1;
281 HBufferImage.BufferPosition.Column = 1;
282
283 if (!Recover) {
284 Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
285 if (Str == NULL) {
286 StatusBarSetStatusString (L"Read Disk Failed");
287 return EFI_OUT_OF_RESOURCES;
288 }
289
290 StatusBarSetStatusString (Str);
291 SHELL_FREE_NON_NULL (Str);
292
293 HMainEditor.SelectStart = 0;
294 HMainEditor.SelectEnd = 0;
295
296 }
297
298 //
299 // has line
300 //
301 if (HBufferImage.Lines != NULL) {
302 HBufferImage.CurrentLine = CR (
303 HBufferImage.ListHead->ForwardLink,
304 HEFI_EDITOR_LINE,
305 Link,
306 EFI_EDITOR_LINE_LIST
307 );
308 } else {
309 //
310 // create a dummy line
311 //
312 Line = HBufferImageCreateLine ();
313 if (Line == NULL) {
314 StatusBarSetStatusString (L"Read Disk Failed");
315 return EFI_OUT_OF_RESOURCES;
316 }
317
318 HBufferImage.CurrentLine = Line;
319 }
320
321 HBufferImage.Modified = FALSE;
322 HBufferImageNeedRefresh = TRUE;
323 HBufferImageOnlyLineNeedRefresh = FALSE;
324 HBufferImageMouseNeedRefresh = TRUE;
325
326 return EFI_SUCCESS;
327 }
328
329 /**
330 Save lines in HBufferImage to disk.
331 NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
332
333 @param[in] DeviceName The device name.
334 @param[in] Offset The offset.
335 @param[in] Size The size.
336
337 @retval EFI_SUCCESS The operation was successful.
338 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
339 @retval EFI_LOAD_ERROR A load error occured.
340 @retval EFI_INVALID_PARAMETER A parameter was invalid.
341 **/
342 EFI_STATUS
343 HDiskImageSave (
344 IN CHAR16 *DeviceName,
345 IN UINTN Offset,
346 IN UINTN Size
347 )
348 {
349
350 CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
351 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
352 EFI_BLOCK_IO_PROTOCOL *BlkIo;
353 EFI_STATUS Status;
354 EFI_HANDLE Handle;
355 VOID *Buffer;
356 UINTN Bytes;
357
358 UINT64 ByteOffset;
359
360 EDIT_FILE_TYPE BufferTypeBackup;
361
362 //
363 // if not modified, directly return
364 //
365 if (HBufferImage.Modified == FALSE) {
366 return EFI_SUCCESS;
367 }
368
369 BufferTypeBackup = HBufferImage.BufferType;
370 HBufferImage.BufferType = FileTypeDiskBuffer;
371
372 DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
373 if (DevicePath == NULL) {
374 // StatusBarSetStatusString (L"Cannot Find Device");
375 return EFI_INVALID_PARAMETER;
376 }
377 DupDevicePath = DuplicateDevicePath(DevicePath);
378
379 //
380 // get blkio interface
381 //
382 Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
383 FreePool(DupDevicePath);
384 if (EFI_ERROR (Status)) {
385 // StatusBarSetStatusString (L"Read Disk Failed");
386 return Status;
387 }
388 Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
389 if (EFI_ERROR (Status)) {
390 // StatusBarSetStatusString (L"Read Disk Failed");
391 return Status;
392 }
393
394 Bytes = BlkIo->Media->BlockSize * Size;
395 Buffer = AllocateZeroPool (Bytes);
396
397 if (Buffer == NULL) {
398 return EFI_OUT_OF_RESOURCES;
399 }
400 //
401 // concatenate the line list to a buffer
402 //
403 Status = HBufferImageListToBuffer (Buffer, Bytes);
404 if (EFI_ERROR (Status)) {
405 FreePool (Buffer);
406 return Status;
407 }
408
409 ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);
410
411 //
412 // write the buffer to disk
413 //
414 Status = BlkIo->WriteBlocks (
415 BlkIo,
416 BlkIo->Media->MediaId,
417 Offset,
418 Bytes,
419 Buffer
420 );
421
422 FreePool (Buffer);
423
424 if (EFI_ERROR (Status)) {
425 return EFI_LOAD_ERROR;
426 }
427 //
428 // now not modified
429 //
430 HBufferImage.Modified = FALSE;
431
432 return EFI_SUCCESS;
433 }