]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c
ShellPkg: Add checking for memory allocation and pointer returns from functions.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / FileImage.c
CommitLineData
632820d1 1/** @file\r
2 Functions to deal with file 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\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
ecae5117 172 if (EFI_ERROR(Status) || Buffer == NULL) {\r
632820d1 173 UnicodeBuffer = CatSPrint(NULL, L"Read error on file &s: %r", FileName, Status);\r
174 if (UnicodeBuffer == NULL) {\r
175 SHELL_FREE_NON_NULL(Buffer);\r
176 return EFI_OUT_OF_RESOURCES;\r
177 }\r
178\r
179 StatusBarSetStatusString (UnicodeBuffer);\r
180 FreePool (UnicodeBuffer);\r
532691c8 181 return EFI_OUT_OF_RESOURCES;\r
632820d1 182 }\r
183\r
184 HFileImageSetFileName (FileName);\r
185\r
186 //\r
187 // free the old lines\r
188 //\r
189 HBufferImageFree ();\r
190\r
191 Status = HBufferImageBufferToList (Buffer, HFileImage.Size);\r
192 SHELL_FREE_NON_NULL (Buffer);\r
193 if (EFI_ERROR (Status)) {\r
194 StatusBarSetStatusString (L"Error parsing file.");\r
195 return Status;\r
196 }\r
197\r
198 HBufferImage.DisplayPosition.Row = 2;\r
199 HBufferImage.DisplayPosition.Column = 10;\r
200 HBufferImage.MousePosition.Row = 2;\r
201 HBufferImage.MousePosition.Column = 10;\r
202 HBufferImage.LowVisibleRow = 1;\r
203 HBufferImage.HighBits = TRUE;\r
204 HBufferImage.BufferPosition.Row = 1;\r
205 HBufferImage.BufferPosition.Column = 1;\r
980d554e 206 HBufferImage.BufferType = FileTypeFileBuffer;\r
632820d1 207\r
208 if (!Recover) {\r
209 UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);\r
210 if (UnicodeBuffer == NULL) {\r
211 SHELL_FREE_NON_NULL(Buffer);\r
212 return EFI_OUT_OF_RESOURCES;\r
213 }\r
214\r
215 StatusBarSetStatusString (UnicodeBuffer);\r
216 FreePool (UnicodeBuffer);\r
217\r
218 HMainEditor.SelectStart = 0;\r
219 HMainEditor.SelectEnd = 0;\r
220 }\r
221\r
222 //\r
223 // has line\r
224 //\r
225 if (HBufferImage.Lines != 0) {\r
226 HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
227 } else {\r
228 //\r
229 // create a dummy line\r
230 //\r
231 Line = HBufferImageCreateLine ();\r
232 if (Line == NULL) {\r
233 SHELL_FREE_NON_NULL(Buffer);\r
234 return EFI_OUT_OF_RESOURCES;\r
235 }\r
236\r
237 HBufferImage.CurrentLine = Line;\r
238 }\r
239\r
240 HBufferImage.Modified = FALSE;\r
241 HBufferImageNeedRefresh = TRUE;\r
242 HBufferImageOnlyLineNeedRefresh = FALSE;\r
243 HBufferImageMouseNeedRefresh = TRUE;\r
244\r
245 return EFI_SUCCESS;\r
246}\r
247\r
a1d4bfcc 248/**\r
249 Save lines in HBufferImage to disk.\r
250\r
251 @param[in] FileName The file name.\r
252\r
253 @retval EFI_SUCCESS The operation was successful.\r
254 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
255 @retval EFI_LOAD_ERROR A load error occured.\r
256**/\r
632820d1 257EFI_STATUS\r
258HFileImageSave (\r
259 IN CHAR16 *FileName\r
260 )\r
632820d1 261{\r
262\r
263 LIST_ENTRY *Link;\r
264 HEFI_EDITOR_LINE *Line;\r
265 CHAR16 *Str;\r
266 EFI_STATUS Status;\r
267 UINTN NumLines;\r
268 SHELL_FILE_HANDLE FileHandle;\r
269 UINTN TotalSize;\r
270 UINT8 *Buffer;\r
271 UINT8 *Ptr;\r
272 EDIT_FILE_TYPE BufferTypeBackup;\r
273\r
274 BufferTypeBackup = HBufferImage.BufferType;\r
275 HBufferImage.BufferType = FileTypeFileBuffer;\r
276\r
277 //\r
278 // if is the old file\r
279 //\r
33c031ee 280 if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {\r
632820d1 281 //\r
282 // check whether file exists on disk\r
283 //\r
284 if (ShellIsFile(FileName) == EFI_SUCCESS) {\r
285 //\r
286 // current file exists on disk\r
287 // so if not modified, then not save\r
288 //\r
289 if (HBufferImage.Modified == FALSE) {\r
290 return EFI_SUCCESS;\r
291 }\r
292 //\r
293 // if file is read-only, set error\r
294 //\r
295 if (HFileImage.ReadOnly == TRUE) {\r
296 StatusBarSetStatusString (L"Read Only File Can Not Be Saved");\r
297 return EFI_SUCCESS;\r
298 }\r
299 }\r
300 }\r
301\r
302 if (ShellIsDirectory(FileName) == EFI_SUCCESS) {\r
303 StatusBarSetStatusString (L"Directory Can Not Be Saved");\r
304 return EFI_LOAD_ERROR;\r
305 }\r
306\r
307 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
308\r
309 if (!EFI_ERROR (Status)) {\r
310 //\r
311 // the file exits, delete it\r
312 //\r
313 Status = ShellDeleteFile (&FileHandle);\r
314 if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {\r
315 StatusBarSetStatusString (L"Write File Failed");\r
316 return EFI_LOAD_ERROR;\r
317 }\r
318 }\r
319\r
320 //\r
321 // write all the lines back to disk\r
322 //\r
323 NumLines = 0;\r
324 TotalSize = 0;\r
325 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
326 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
327\r
328 if (Line->Size != 0) {\r
329 TotalSize += Line->Size;\r
330 }\r
331 //\r
332 // end of if Line -> Size != 0\r
333 //\r
334 NumLines++;\r
335 }\r
336 //\r
337 // end of for Link\r
338 //\r
339 Buffer = AllocateZeroPool (TotalSize);\r
340 if (Buffer == NULL) {\r
341 return EFI_OUT_OF_RESOURCES;\r
342 }\r
343\r
344 Ptr = Buffer;\r
345 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
346 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
347\r
348 if (Line->Size != 0) {\r
349 CopyMem (Ptr, Line->Buffer, Line->Size);\r
350 Ptr += Line->Size;\r
351 }\r
352 //\r
353 // end of if Line -> Size != 0\r
354 //\r
355 }\r
356\r
357\r
358 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
359\r
360 if (EFI_ERROR (Status)) {\r
361 StatusBarSetStatusString (L"Create File Failed");\r
362 return EFI_LOAD_ERROR;\r
363 }\r
364\r
365 Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);\r
366 FreePool (Buffer);\r
367 if (EFI_ERROR (Status)) {\r
368 ShellDeleteFile (&FileHandle);\r
369 return EFI_LOAD_ERROR;\r
370 }\r
371\r
372 ShellCloseFile(&FileHandle);\r
373\r
374 HBufferImage.Modified = FALSE;\r
375\r
376 //\r
377 // set status string\r
378 //\r
379 Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines);\r
380 StatusBarSetStatusString (Str);\r
381 FreePool (Str);\r
382\r
383 //\r
384 // now everything is ready , you can set the new file name to filebuffer\r
385 //\r
ae724571 386 if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||\r
387 (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){\r
632820d1 388 //\r
389 // not the same\r
390 //\r
391 HFileImageSetFileName (FileName);\r
392 if (HFileImage.FileName == NULL) {\r
393 return EFI_OUT_OF_RESOURCES;\r
394 }\r
395 }\r
396\r
397 HFileImage.ReadOnly = FALSE;\r
398\r
399 return EFI_SUCCESS;\r
400}\r