]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c
ShellPkg: Clean up source files
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / FileImage.c
CommitLineData
632820d1 1/** @file\r
2 Functions to deal with file buffer.\r
3\r
1efda641 4 Copyright (c) 2005 - 2018, 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
ba0014b9 40\r
a1d4bfcc 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
ba0014b9 63 Backup function for HFileImage. Only a few fields need to be backup.\r
a1d4bfcc 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
1efda641
RN
113 if (Str == HFileImage.FileName) {\r
114 //\r
115 // This function might be called using HFileImage.FileName as Str.\r
116 // Directly return without updating HFileImage.FileName.\r
117 //\r
118 return EFI_SUCCESS;\r
119 }\r
632820d1 120 //\r
121 // free the old file name\r
122 //\r
123 SHELL_FREE_NON_NULL (HFileImage.FileName);\r
1efda641 124 HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str);\r
632820d1 125 if (HFileImage.FileName == NULL) {\r
126 return EFI_OUT_OF_RESOURCES;\r
127 }\r
128\r
632820d1 129 return EFI_SUCCESS;\r
130}\r
131\r
a1d4bfcc 132/**\r
133 Read a file from disk into HBufferImage.\r
632820d1 134\r
a1d4bfcc 135 @param[in] FileName filename to read.\r
136 @param[in] Recover if is for recover, no information print.\r
632820d1 137\r
a1d4bfcc 138 @retval EFI_SUCCESS The operation was successful.\r
139 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
140 @retval EFI_LOAD_ERROR A load error occured.\r
141**/\r
632820d1 142EFI_STATUS\r
143HFileImageRead (\r
144 IN CONST CHAR16 *FileName,\r
145 IN BOOLEAN Recover\r
146 )\r
632820d1 147{\r
148 HEFI_EDITOR_LINE *Line;\r
149 UINT8 *Buffer;\r
150 CHAR16 *UnicodeBuffer;\r
151 EFI_STATUS Status;\r
152\r
153 //\r
154 // variable initialization\r
155 //\r
156 Line = NULL;\r
157\r
158 //\r
159 // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )\r
160 // you should set status string\r
161 // since this function maybe called before the editorhandleinput loop\r
162 // so any error will cause editor return\r
163 // so if you want to print the error status\r
164 // you should set the status string\r
165 //\r
166 Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);\r
2e5c97ed 167 //\r
168 // NULL pointer is only also a failure for a non-zero file size.\r
169 //\r
170 if ((EFI_ERROR(Status)) || (Buffer == NULL && HFileImage.Size != 0)) {\r
3ab016b2 171 UnicodeBuffer = CatSPrint(NULL, L"Read error on file %s: %r", FileName, Status);\r
632820d1 172 if (UnicodeBuffer == NULL) {\r
173 SHELL_FREE_NON_NULL(Buffer);\r
174 return EFI_OUT_OF_RESOURCES;\r
175 }\r
176\r
177 StatusBarSetStatusString (UnicodeBuffer);\r
178 FreePool (UnicodeBuffer);\r
532691c8 179 return EFI_OUT_OF_RESOURCES;\r
632820d1 180 }\r
181\r
182 HFileImageSetFileName (FileName);\r
183\r
184 //\r
185 // free the old lines\r
186 //\r
187 HBufferImageFree ();\r
188\r
189 Status = HBufferImageBufferToList (Buffer, HFileImage.Size);\r
190 SHELL_FREE_NON_NULL (Buffer);\r
191 if (EFI_ERROR (Status)) {\r
192 StatusBarSetStatusString (L"Error parsing file.");\r
193 return Status;\r
194 }\r
195\r
196 HBufferImage.DisplayPosition.Row = 2;\r
197 HBufferImage.DisplayPosition.Column = 10;\r
198 HBufferImage.MousePosition.Row = 2;\r
199 HBufferImage.MousePosition.Column = 10;\r
200 HBufferImage.LowVisibleRow = 1;\r
201 HBufferImage.HighBits = TRUE;\r
202 HBufferImage.BufferPosition.Row = 1;\r
203 HBufferImage.BufferPosition.Column = 1;\r
980d554e 204 HBufferImage.BufferType = FileTypeFileBuffer;\r
632820d1 205\r
206 if (!Recover) {\r
207 UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);\r
208 if (UnicodeBuffer == NULL) {\r
209 SHELL_FREE_NON_NULL(Buffer);\r
210 return EFI_OUT_OF_RESOURCES;\r
211 }\r
212\r
213 StatusBarSetStatusString (UnicodeBuffer);\r
214 FreePool (UnicodeBuffer);\r
215\r
216 HMainEditor.SelectStart = 0;\r
217 HMainEditor.SelectEnd = 0;\r
218 }\r
219\r
220 //\r
221 // has line\r
222 //\r
223 if (HBufferImage.Lines != 0) {\r
224 HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
225 } else {\r
226 //\r
227 // create a dummy line\r
228 //\r
229 Line = HBufferImageCreateLine ();\r
230 if (Line == NULL) {\r
231 SHELL_FREE_NON_NULL(Buffer);\r
232 return EFI_OUT_OF_RESOURCES;\r
233 }\r
234\r
235 HBufferImage.CurrentLine = Line;\r
236 }\r
237\r
238 HBufferImage.Modified = FALSE;\r
239 HBufferImageNeedRefresh = TRUE;\r
240 HBufferImageOnlyLineNeedRefresh = FALSE;\r
241 HBufferImageMouseNeedRefresh = TRUE;\r
242\r
243 return EFI_SUCCESS;\r
244}\r
245\r
a1d4bfcc 246/**\r
247 Save lines in HBufferImage to disk.\r
248\r
249 @param[in] FileName The file name.\r
250\r
251 @retval EFI_SUCCESS The operation was successful.\r
252 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
253 @retval EFI_LOAD_ERROR A load error occured.\r
254**/\r
632820d1 255EFI_STATUS\r
256HFileImageSave (\r
257 IN CHAR16 *FileName\r
258 )\r
632820d1 259{\r
260\r
261 LIST_ENTRY *Link;\r
262 HEFI_EDITOR_LINE *Line;\r
263 CHAR16 *Str;\r
264 EFI_STATUS Status;\r
265 UINTN NumLines;\r
266 SHELL_FILE_HANDLE FileHandle;\r
267 UINTN TotalSize;\r
268 UINT8 *Buffer;\r
269 UINT8 *Ptr;\r
270 EDIT_FILE_TYPE BufferTypeBackup;\r
271\r
272 BufferTypeBackup = HBufferImage.BufferType;\r
273 HBufferImage.BufferType = FileTypeFileBuffer;\r
274\r
275 //\r
276 // if is the old file\r
277 //\r
33c031ee 278 if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {\r
632820d1 279 //\r
280 // check whether file exists on disk\r
281 //\r
282 if (ShellIsFile(FileName) == EFI_SUCCESS) {\r
283 //\r
284 // current file exists on disk\r
285 // so if not modified, then not save\r
286 //\r
287 if (HBufferImage.Modified == FALSE) {\r
288 return EFI_SUCCESS;\r
289 }\r
290 //\r
291 // if file is read-only, set error\r
292 //\r
293 if (HFileImage.ReadOnly == TRUE) {\r
294 StatusBarSetStatusString (L"Read Only File Can Not Be Saved");\r
295 return EFI_SUCCESS;\r
296 }\r
297 }\r
298 }\r
299\r
300 if (ShellIsDirectory(FileName) == EFI_SUCCESS) {\r
301 StatusBarSetStatusString (L"Directory Can Not Be Saved");\r
302 return EFI_LOAD_ERROR;\r
303 }\r
304\r
305 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
306\r
307 if (!EFI_ERROR (Status)) {\r
308 //\r
309 // the file exits, delete it\r
310 //\r
311 Status = ShellDeleteFile (&FileHandle);\r
312 if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {\r
313 StatusBarSetStatusString (L"Write File Failed");\r
314 return EFI_LOAD_ERROR;\r
315 }\r
316 }\r
317\r
318 //\r
319 // write all the lines back to disk\r
320 //\r
321 NumLines = 0;\r
322 TotalSize = 0;\r
323 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
324 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
325\r
326 if (Line->Size != 0) {\r
327 TotalSize += Line->Size;\r
328 }\r
329 //\r
330 // end of if Line -> Size != 0\r
331 //\r
332 NumLines++;\r
333 }\r
334 //\r
335 // end of for Link\r
336 //\r
337 Buffer = AllocateZeroPool (TotalSize);\r
338 if (Buffer == NULL) {\r
339 return EFI_OUT_OF_RESOURCES;\r
340 }\r
341\r
342 Ptr = Buffer;\r
343 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
344 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
345\r
346 if (Line->Size != 0) {\r
347 CopyMem (Ptr, Line->Buffer, Line->Size);\r
348 Ptr += Line->Size;\r
349 }\r
350 //\r
351 // end of if Line -> Size != 0\r
352 //\r
353 }\r
354\r
355\r
356 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
357\r
358 if (EFI_ERROR (Status)) {\r
359 StatusBarSetStatusString (L"Create File Failed");\r
360 return EFI_LOAD_ERROR;\r
361 }\r
362\r
363 Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);\r
364 FreePool (Buffer);\r
365 if (EFI_ERROR (Status)) {\r
366 ShellDeleteFile (&FileHandle);\r
367 return EFI_LOAD_ERROR;\r
368 }\r
369\r
370 ShellCloseFile(&FileHandle);\r
371\r
372 HBufferImage.Modified = FALSE;\r
373\r
374 //\r
375 // set status string\r
376 //\r
377 Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines);\r
378 StatusBarSetStatusString (Str);\r
379 FreePool (Str);\r
380\r
381 //\r
382 // now everything is ready , you can set the new file name to filebuffer\r
383 //\r
ae724571 384 if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||\r
385 (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){\r
632820d1 386 //\r
387 // not the same\r
388 //\r
389 HFileImageSetFileName (FileName);\r
390 if (HFileImage.FileName == NULL) {\r
391 return EFI_OUT_OF_RESOURCES;\r
392 }\r
393 }\r
394\r
395 HFileImage.ReadOnly = FALSE;\r
396\r
397 return EFI_SUCCESS;\r
398}\r