]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c
ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / FileImage.c
CommitLineData
632820d1 1/** @file\r
2 Functions to deal with file buffer.\r
3\r
3ab016b2 4 Copyright (c) 2005 - 2015, 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\r
17extern EFI_HANDLE HImageHandleBackup;\r
18extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;\r
19\r
20extern BOOLEAN HBufferImageNeedRefresh;\r
21extern BOOLEAN HBufferImageOnlyLineNeedRefresh;\r
22extern BOOLEAN HBufferImageMouseNeedRefresh;\r
23\r
24extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;\r
25\r
26HEFI_EDITOR_FILE_IMAGE HFileImage;\r
27HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;\r
28\r
29//\r
30// for basic initialization of HFileImage\r
31//\r
32HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = {\r
33 NULL,\r
34 0,\r
35 FALSE\r
36};\r
37\r
a1d4bfcc 38/**\r
39 Initialization function for HFileImage\r
40 \r
41 @retval EFI_SUCCESS The operation was successful.\r
42**/\r
632820d1 43EFI_STATUS\r
44HFileImageInit (\r
45 VOID\r
46 )\r
632820d1 47{\r
48 //\r
49 // basically initialize the HFileImage\r
50 //\r
51 CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));\r
52\r
53 CopyMem (\r
54 &HFileImageBackupVar,\r
55 &HFileImageConst,\r
56 sizeof (HFileImageBackupVar)\r
57 );\r
58\r
59 return EFI_SUCCESS;\r
60}\r
61\r
a1d4bfcc 62/**\r
63 Backup function for HFileImage. Only a few fields need to be backup. \r
64 This is for making the file buffer refresh as few as possible.\r
65\r
66 @retval EFI_SUCCESS The operation was successful.\r
67 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
68**/\r
632820d1 69EFI_STATUS\r
70HFileImageBackup (\r
71 VOID\r
72 )\r
632820d1 73{\r
74 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);\r
75 HFileImageBackupVar.FileName = CatSPrint(NULL, L"%s", HFileImage.FileName);\r
76 if (HFileImageBackupVar.FileName == NULL) {\r
77 return EFI_OUT_OF_RESOURCES;\r
78 }\r
79\r
80 return EFI_SUCCESS;\r
81}\r
82\r
a1d4bfcc 83/**\r
84 Cleanup function for HFileImage.\r
85\r
86 @retval EFI_SUCCESS The operation was successful.\r
87**/\r
632820d1 88EFI_STATUS\r
89HFileImageCleanup (\r
90 VOID\r
91 )\r
632820d1 92{\r
93\r
94 SHELL_FREE_NON_NULL (HFileImage.FileName);\r
95 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);\r
96\r
97 return EFI_SUCCESS;\r
98}\r
99\r
a1d4bfcc 100/**\r
101 Set FileName field in HFileImage\r
102\r
103 @param[in] Str File name to set.\r
104\r
105 @retval EFI_SUCCESS The operation was successful.\r
106 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
107**/\r
632820d1 108EFI_STATUS\r
109HFileImageSetFileName (\r
110 IN CONST CHAR16 *Str\r
111 )\r
632820d1 112{\r
113 UINTN Size;\r
114 UINTN Index;\r
115\r
116 //\r
117 // free the old file name\r
118 //\r
119 SHELL_FREE_NON_NULL (HFileImage.FileName);\r
120\r
121 Size = StrLen (Str);\r
122\r
123 HFileImage.FileName = AllocateZeroPool (2 * (Size + 1));\r
124 if (HFileImage.FileName == NULL) {\r
125 return EFI_OUT_OF_RESOURCES;\r
126 }\r
127\r
128 for (Index = 0; Index < Size; Index++) {\r
129 HFileImage.FileName[Index] = Str[Index];\r
130 }\r
131\r
132 HFileImage.FileName[Size] = L'\0';\r
133\r
134 return EFI_SUCCESS;\r
135}\r
136\r
a1d4bfcc 137/**\r
138 Read a file from disk into HBufferImage.\r
632820d1 139\r
a1d4bfcc 140 @param[in] FileName filename to read.\r
141 @param[in] Recover if is for recover, no information print.\r
632820d1 142\r
a1d4bfcc 143 @retval EFI_SUCCESS The operation was successful.\r
144 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
145 @retval EFI_LOAD_ERROR A load error occured.\r
146**/\r
632820d1 147EFI_STATUS\r
148HFileImageRead (\r
149 IN CONST CHAR16 *FileName,\r
150 IN BOOLEAN Recover\r
151 )\r
632820d1 152{\r
153 HEFI_EDITOR_LINE *Line;\r
154 UINT8 *Buffer;\r
155 CHAR16 *UnicodeBuffer;\r
156 EFI_STATUS Status;\r
157\r
158 //\r
159 // variable initialization\r
160 //\r
161 Line = NULL;\r
162\r
163 //\r
164 // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )\r
165 // you should set status string\r
166 // since this function maybe called before the editorhandleinput loop\r
167 // so any error will cause editor return\r
168 // so if you want to print the error status\r
169 // you should set the status string\r
170 //\r
171 Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);\r
2e5c97ed 172 //\r
173 // NULL pointer is only also a failure for a non-zero file size.\r
174 //\r
175 if ((EFI_ERROR(Status)) || (Buffer == NULL && HFileImage.Size != 0)) {\r
3ab016b2 176 UnicodeBuffer = CatSPrint(NULL, L"Read error on file %s: %r", FileName, Status);\r
632820d1 177 if (UnicodeBuffer == NULL) {\r
178 SHELL_FREE_NON_NULL(Buffer);\r
179 return EFI_OUT_OF_RESOURCES;\r
180 }\r
181\r
182 StatusBarSetStatusString (UnicodeBuffer);\r
183 FreePool (UnicodeBuffer);\r
532691c8 184 return EFI_OUT_OF_RESOURCES;\r
632820d1 185 }\r
186\r
187 HFileImageSetFileName (FileName);\r
188\r
189 //\r
190 // free the old lines\r
191 //\r
192 HBufferImageFree ();\r
193\r
194 Status = HBufferImageBufferToList (Buffer, HFileImage.Size);\r
195 SHELL_FREE_NON_NULL (Buffer);\r
196 if (EFI_ERROR (Status)) {\r
197 StatusBarSetStatusString (L"Error parsing file.");\r
198 return Status;\r
199 }\r
200\r
201 HBufferImage.DisplayPosition.Row = 2;\r
202 HBufferImage.DisplayPosition.Column = 10;\r
203 HBufferImage.MousePosition.Row = 2;\r
204 HBufferImage.MousePosition.Column = 10;\r
205 HBufferImage.LowVisibleRow = 1;\r
206 HBufferImage.HighBits = TRUE;\r
207 HBufferImage.BufferPosition.Row = 1;\r
208 HBufferImage.BufferPosition.Column = 1;\r
980d554e 209 HBufferImage.BufferType = FileTypeFileBuffer;\r
632820d1 210\r
211 if (!Recover) {\r
212 UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);\r
213 if (UnicodeBuffer == NULL) {\r
214 SHELL_FREE_NON_NULL(Buffer);\r
215 return EFI_OUT_OF_RESOURCES;\r
216 }\r
217\r
218 StatusBarSetStatusString (UnicodeBuffer);\r
219 FreePool (UnicodeBuffer);\r
220\r
221 HMainEditor.SelectStart = 0;\r
222 HMainEditor.SelectEnd = 0;\r
223 }\r
224\r
225 //\r
226 // has line\r
227 //\r
228 if (HBufferImage.Lines != 0) {\r
229 HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
230 } else {\r
231 //\r
232 // create a dummy line\r
233 //\r
234 Line = HBufferImageCreateLine ();\r
235 if (Line == NULL) {\r
236 SHELL_FREE_NON_NULL(Buffer);\r
237 return EFI_OUT_OF_RESOURCES;\r
238 }\r
239\r
240 HBufferImage.CurrentLine = Line;\r
241 }\r
242\r
243 HBufferImage.Modified = FALSE;\r
244 HBufferImageNeedRefresh = TRUE;\r
245 HBufferImageOnlyLineNeedRefresh = FALSE;\r
246 HBufferImageMouseNeedRefresh = TRUE;\r
247\r
248 return EFI_SUCCESS;\r
249}\r
250\r
a1d4bfcc 251/**\r
252 Save lines in HBufferImage to disk.\r
253\r
254 @param[in] FileName The file name.\r
255\r
256 @retval EFI_SUCCESS The operation was successful.\r
257 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
258 @retval EFI_LOAD_ERROR A load error occured.\r
259**/\r
632820d1 260EFI_STATUS\r
261HFileImageSave (\r
262 IN CHAR16 *FileName\r
263 )\r
632820d1 264{\r
265\r
266 LIST_ENTRY *Link;\r
267 HEFI_EDITOR_LINE *Line;\r
268 CHAR16 *Str;\r
269 EFI_STATUS Status;\r
270 UINTN NumLines;\r
271 SHELL_FILE_HANDLE FileHandle;\r
272 UINTN TotalSize;\r
273 UINT8 *Buffer;\r
274 UINT8 *Ptr;\r
275 EDIT_FILE_TYPE BufferTypeBackup;\r
276\r
277 BufferTypeBackup = HBufferImage.BufferType;\r
278 HBufferImage.BufferType = FileTypeFileBuffer;\r
279\r
280 //\r
281 // if is the old file\r
282 //\r
33c031ee 283 if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {\r
632820d1 284 //\r
285 // check whether file exists on disk\r
286 //\r
287 if (ShellIsFile(FileName) == EFI_SUCCESS) {\r
288 //\r
289 // current file exists on disk\r
290 // so if not modified, then not save\r
291 //\r
292 if (HBufferImage.Modified == FALSE) {\r
293 return EFI_SUCCESS;\r
294 }\r
295 //\r
296 // if file is read-only, set error\r
297 //\r
298 if (HFileImage.ReadOnly == TRUE) {\r
299 StatusBarSetStatusString (L"Read Only File Can Not Be Saved");\r
300 return EFI_SUCCESS;\r
301 }\r
302 }\r
303 }\r
304\r
305 if (ShellIsDirectory(FileName) == EFI_SUCCESS) {\r
306 StatusBarSetStatusString (L"Directory Can Not Be Saved");\r
307 return EFI_LOAD_ERROR;\r
308 }\r
309\r
310 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
311\r
312 if (!EFI_ERROR (Status)) {\r
313 //\r
314 // the file exits, delete it\r
315 //\r
316 Status = ShellDeleteFile (&FileHandle);\r
317 if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {\r
318 StatusBarSetStatusString (L"Write File Failed");\r
319 return EFI_LOAD_ERROR;\r
320 }\r
321 }\r
322\r
323 //\r
324 // write all the lines back to disk\r
325 //\r
326 NumLines = 0;\r
327 TotalSize = 0;\r
328 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
329 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
330\r
331 if (Line->Size != 0) {\r
332 TotalSize += Line->Size;\r
333 }\r
334 //\r
335 // end of if Line -> Size != 0\r
336 //\r
337 NumLines++;\r
338 }\r
339 //\r
340 // end of for Link\r
341 //\r
342 Buffer = AllocateZeroPool (TotalSize);\r
343 if (Buffer == NULL) {\r
344 return EFI_OUT_OF_RESOURCES;\r
345 }\r
346\r
347 Ptr = Buffer;\r
348 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
349 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
350\r
351 if (Line->Size != 0) {\r
352 CopyMem (Ptr, Line->Buffer, Line->Size);\r
353 Ptr += Line->Size;\r
354 }\r
355 //\r
356 // end of if Line -> Size != 0\r
357 //\r
358 }\r
359\r
360\r
361 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
362\r
363 if (EFI_ERROR (Status)) {\r
364 StatusBarSetStatusString (L"Create File Failed");\r
365 return EFI_LOAD_ERROR;\r
366 }\r
367\r
368 Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);\r
369 FreePool (Buffer);\r
370 if (EFI_ERROR (Status)) {\r
371 ShellDeleteFile (&FileHandle);\r
372 return EFI_LOAD_ERROR;\r
373 }\r
374\r
375 ShellCloseFile(&FileHandle);\r
376\r
377 HBufferImage.Modified = FALSE;\r
378\r
379 //\r
380 // set status string\r
381 //\r
382 Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines);\r
383 StatusBarSetStatusString (Str);\r
384 FreePool (Str);\r
385\r
386 //\r
387 // now everything is ready , you can set the new file name to filebuffer\r
388 //\r
ae724571 389 if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||\r
390 (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){\r
632820d1 391 //\r
392 // not the same\r
393 //\r
394 HFileImageSetFileName (FileName);\r
395 if (HFileImage.FileName == NULL) {\r
396 return EFI_OUT_OF_RESOURCES;\r
397 }\r
398 }\r
399\r
400 HFileImage.ReadOnly = FALSE;\r
401\r
402 return EFI_SUCCESS;\r
403}\r