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