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