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