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