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