]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c
Comment's added and fixed.
[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
38EFI_STATUS\r
39HFileImageInit (\r
40 VOID\r
41 )\r
42/*++\r
43\r
44Routine Description: \r
45\r
46 Initialization function for HFileImage\r
47\r
48Arguments: \r
49\r
50 None\r
51\r
52Returns: \r
53\r
54 EFI_SUCCESS\r
55 EFI_LOAD_ERROR\r
56\r
57--*/\r
58{\r
59 //\r
60 // basically initialize the HFileImage\r
61 //\r
62 CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));\r
63\r
64 CopyMem (\r
65 &HFileImageBackupVar,\r
66 &HFileImageConst,\r
67 sizeof (HFileImageBackupVar)\r
68 );\r
69\r
70 return EFI_SUCCESS;\r
71}\r
72\r
73EFI_STATUS\r
74HFileImageBackup (\r
75 VOID\r
76 )\r
77/*++\r
78\r
79Routine Description: \r
80\r
81 Backup function for HFileImage\r
82 Only a few fields need to be backup. \r
83 This is for making the file buffer refresh \r
84 as few as possible.\r
85\r
86Arguments: \r
87\r
88 None\r
89\r
90Returns: \r
91\r
92 EFI_SUCCESS\r
93 EFI_OUT_OF_RESOURCES\r
94\r
95--*/\r
96{\r
97 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);\r
98 HFileImageBackupVar.FileName = CatSPrint(NULL, L"%s", HFileImage.FileName);\r
99 if (HFileImageBackupVar.FileName == NULL) {\r
100 return EFI_OUT_OF_RESOURCES;\r
101 }\r
102\r
103 return EFI_SUCCESS;\r
104}\r
105\r
106EFI_STATUS\r
107HFileImageCleanup (\r
108 VOID\r
109 )\r
110/*++\r
111\r
112Routine Description: \r
113\r
114 Cleanup function for HFileImage\r
115\r
116Arguments: \r
117\r
118 None\r
119\r
120Returns: \r
121\r
122 EFI_SUCCESS\r
123\r
124--*/\r
125{\r
126\r
127 SHELL_FREE_NON_NULL (HFileImage.FileName);\r
128 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);\r
129\r
130 return EFI_SUCCESS;\r
131}\r
132\r
133EFI_STATUS\r
134HFileImageSetFileName (\r
135 IN CONST CHAR16 *Str\r
136 )\r
137/*++\r
138\r
139Routine Description: \r
140\r
141 Set FileName field in HFileImage\r
142\r
143Arguments: \r
144\r
145 Str -- File name to set\r
146\r
147Returns: \r
148\r
149 EFI_SUCCESS\r
150 EFI_OUT_OF_RESOURCES\r
151\r
152--*/\r
153{\r
154 UINTN Size;\r
155 UINTN Index;\r
156\r
157 //\r
158 // free the old file name\r
159 //\r
160 SHELL_FREE_NON_NULL (HFileImage.FileName);\r
161\r
162 Size = StrLen (Str);\r
163\r
164 HFileImage.FileName = AllocateZeroPool (2 * (Size + 1));\r
165 if (HFileImage.FileName == NULL) {\r
166 return EFI_OUT_OF_RESOURCES;\r
167 }\r
168\r
169 for (Index = 0; Index < Size; Index++) {\r
170 HFileImage.FileName[Index] = Str[Index];\r
171 }\r
172\r
173 HFileImage.FileName[Size] = L'\0';\r
174\r
175 return EFI_SUCCESS;\r
176}\r
177\r
178EFI_STATUS\r
179HFileImageGetFileInfo (\r
180 IN EFI_FILE_HANDLE Handle,\r
181 IN CHAR16 *FileName,\r
182 OUT EFI_FILE_INFO **InfoOut\r
183 )\r
184/*++\r
185\r
186Routine Description: \r
187\r
188 Get this file's information\r
189\r
190Arguments: \r
191\r
192 Handle - in NT32 mode Directory handle, in other mode File Handle\r
193 FileName - The file name\r
194 InfoOut - parameter to pass file information out\r
195\r
196Returns: \r
197\r
198 EFI_SUCCESS\r
199 EFI_OUT_OF_RESOURCES\r
200 EFI_LOAD_ERROR\r
201\r
202--*/\r
203{\r
204\r
205 VOID *Info;\r
206 UINTN Size;\r
207 EFI_STATUS Status;\r
208\r
209 Size = SIZE_OF_EFI_FILE_INFO + 1024;\r
210 Info = AllocateZeroPool (Size);\r
211 if (!Info) {\r
212 return EFI_OUT_OF_RESOURCES;\r
213 }\r
214 //\r
215 // get file information\r
216 //\r
217 Status = Handle->GetInfo (Handle, &gEfiFileInfoGuid, &Size, Info);\r
218 if (EFI_ERROR (Status)) {\r
219 return EFI_LOAD_ERROR;\r
220 }\r
221\r
222 *InfoOut = (EFI_FILE_INFO *) Info;\r
223\r
224 return EFI_SUCCESS;\r
225\r
226}\r
227\r
228EFI_STATUS\r
229HFileImageRead (\r
230 IN CONST CHAR16 *FileName,\r
231 IN BOOLEAN Recover\r
232 )\r
233/*++\r
234\r
235Routine Description: \r
236\r
237 Read a file from disk into HBufferImage\r
238\r
239Arguments: \r
240\r
241 FileName -- filename to read\r
242 Recover -- if is for recover, no information print\r
243\r
244Returns: \r
245\r
246 EFI_SUCCESS\r
247 EFI_LOAD_ERROR\r
248 EFI_OUT_OF_RESOURCES\r
249 \r
250--*/\r
251{\r
252 HEFI_EDITOR_LINE *Line;\r
253 UINT8 *Buffer;\r
254 CHAR16 *UnicodeBuffer;\r
255 EFI_STATUS Status;\r
256\r
257 //\r
258 // variable initialization\r
259 //\r
260 Line = NULL;\r
261\r
262 //\r
263 // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )\r
264 // you should set status string\r
265 // since this function maybe called before the editorhandleinput loop\r
266 // so any error will cause editor return\r
267 // so if you want to print the error status\r
268 // you should set the status string\r
269 //\r
270 Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);\r
271 if (EFI_ERROR(Status)) {\r
272 UnicodeBuffer = CatSPrint(NULL, L"Read error on file &s: %r", FileName, Status);\r
273 if (UnicodeBuffer == NULL) {\r
274 SHELL_FREE_NON_NULL(Buffer);\r
275 return EFI_OUT_OF_RESOURCES;\r
276 }\r
277\r
278 StatusBarSetStatusString (UnicodeBuffer);\r
279 FreePool (UnicodeBuffer);\r
280 }\r
281\r
282 HFileImageSetFileName (FileName);\r
283\r
284 //\r
285 // free the old lines\r
286 //\r
287 HBufferImageFree ();\r
288\r
289 Status = HBufferImageBufferToList (Buffer, HFileImage.Size);\r
290 SHELL_FREE_NON_NULL (Buffer);\r
291 if (EFI_ERROR (Status)) {\r
292 StatusBarSetStatusString (L"Error parsing file.");\r
293 return Status;\r
294 }\r
295\r
296 HBufferImage.DisplayPosition.Row = 2;\r
297 HBufferImage.DisplayPosition.Column = 10;\r
298 HBufferImage.MousePosition.Row = 2;\r
299 HBufferImage.MousePosition.Column = 10;\r
300 HBufferImage.LowVisibleRow = 1;\r
301 HBufferImage.HighBits = TRUE;\r
302 HBufferImage.BufferPosition.Row = 1;\r
303 HBufferImage.BufferPosition.Column = 1;\r
980d554e 304 HBufferImage.BufferType = FileTypeFileBuffer;\r
632820d1 305\r
306 if (!Recover) {\r
307 UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);\r
308 if (UnicodeBuffer == NULL) {\r
309 SHELL_FREE_NON_NULL(Buffer);\r
310 return EFI_OUT_OF_RESOURCES;\r
311 }\r
312\r
313 StatusBarSetStatusString (UnicodeBuffer);\r
314 FreePool (UnicodeBuffer);\r
315\r
316 HMainEditor.SelectStart = 0;\r
317 HMainEditor.SelectEnd = 0;\r
318 }\r
319\r
320 //\r
321 // has line\r
322 //\r
323 if (HBufferImage.Lines != 0) {\r
324 HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
325 } else {\r
326 //\r
327 // create a dummy line\r
328 //\r
329 Line = HBufferImageCreateLine ();\r
330 if (Line == NULL) {\r
331 SHELL_FREE_NON_NULL(Buffer);\r
332 return EFI_OUT_OF_RESOURCES;\r
333 }\r
334\r
335 HBufferImage.CurrentLine = Line;\r
336 }\r
337\r
338 HBufferImage.Modified = FALSE;\r
339 HBufferImageNeedRefresh = TRUE;\r
340 HBufferImageOnlyLineNeedRefresh = FALSE;\r
341 HBufferImageMouseNeedRefresh = TRUE;\r
342\r
343 return EFI_SUCCESS;\r
344}\r
345\r
346EFI_STATUS\r
347HFileImageSave (\r
348 IN CHAR16 *FileName\r
349 )\r
350/*++\r
351\r
352Routine Description: \r
353\r
354 Save lines in HBufferImage to disk\r
355\r
356Arguments: \r
357\r
358 FileName - The file name\r
359\r
360Returns: \r
361\r
362 EFI_SUCCESS\r
363 EFI_LOAD_ERROR\r
364 EFI_OUT_OF_RESOURCES\r
365\r
366--*/\r
367{\r
368\r
369 LIST_ENTRY *Link;\r
370 HEFI_EDITOR_LINE *Line;\r
371 CHAR16 *Str;\r
372 EFI_STATUS Status;\r
373 UINTN NumLines;\r
374 SHELL_FILE_HANDLE FileHandle;\r
375 UINTN TotalSize;\r
376 UINT8 *Buffer;\r
377 UINT8 *Ptr;\r
378 EDIT_FILE_TYPE BufferTypeBackup;\r
379\r
380 BufferTypeBackup = HBufferImage.BufferType;\r
381 HBufferImage.BufferType = FileTypeFileBuffer;\r
382\r
383 //\r
384 // if is the old file\r
385 //\r
33c031ee 386 if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {\r
632820d1 387 //\r
388 // check whether file exists on disk\r
389 //\r
390 if (ShellIsFile(FileName) == EFI_SUCCESS) {\r
391 //\r
392 // current file exists on disk\r
393 // so if not modified, then not save\r
394 //\r
395 if (HBufferImage.Modified == FALSE) {\r
396 return EFI_SUCCESS;\r
397 }\r
398 //\r
399 // if file is read-only, set error\r
400 //\r
401 if (HFileImage.ReadOnly == TRUE) {\r
402 StatusBarSetStatusString (L"Read Only File Can Not Be Saved");\r
403 return EFI_SUCCESS;\r
404 }\r
405 }\r
406 }\r
407\r
408 if (ShellIsDirectory(FileName) == EFI_SUCCESS) {\r
409 StatusBarSetStatusString (L"Directory Can Not Be Saved");\r
410 return EFI_LOAD_ERROR;\r
411 }\r
412\r
413 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
414\r
415 if (!EFI_ERROR (Status)) {\r
416 //\r
417 // the file exits, delete it\r
418 //\r
419 Status = ShellDeleteFile (&FileHandle);\r
420 if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {\r
421 StatusBarSetStatusString (L"Write File Failed");\r
422 return EFI_LOAD_ERROR;\r
423 }\r
424 }\r
425\r
426 //\r
427 // write all the lines back to disk\r
428 //\r
429 NumLines = 0;\r
430 TotalSize = 0;\r
431 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
432 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
433\r
434 if (Line->Size != 0) {\r
435 TotalSize += Line->Size;\r
436 }\r
437 //\r
438 // end of if Line -> Size != 0\r
439 //\r
440 NumLines++;\r
441 }\r
442 //\r
443 // end of for Link\r
444 //\r
445 Buffer = AllocateZeroPool (TotalSize);\r
446 if (Buffer == NULL) {\r
447 return EFI_OUT_OF_RESOURCES;\r
448 }\r
449\r
450 Ptr = Buffer;\r
451 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {\r
452 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
453\r
454 if (Line->Size != 0) {\r
455 CopyMem (Ptr, Line->Buffer, Line->Size);\r
456 Ptr += Line->Size;\r
457 }\r
458 //\r
459 // end of if Line -> Size != 0\r
460 //\r
461 }\r
462\r
463\r
464 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
465\r
466 if (EFI_ERROR (Status)) {\r
467 StatusBarSetStatusString (L"Create File Failed");\r
468 return EFI_LOAD_ERROR;\r
469 }\r
470\r
471 Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);\r
472 FreePool (Buffer);\r
473 if (EFI_ERROR (Status)) {\r
474 ShellDeleteFile (&FileHandle);\r
475 return EFI_LOAD_ERROR;\r
476 }\r
477\r
478 ShellCloseFile(&FileHandle);\r
479\r
480 HBufferImage.Modified = FALSE;\r
481\r
482 //\r
483 // set status string\r
484 //\r
485 Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines);\r
486 StatusBarSetStatusString (Str);\r
487 FreePool (Str);\r
488\r
489 //\r
490 // now everything is ready , you can set the new file name to filebuffer\r
491 //\r
ae724571 492 if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||\r
493 (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){\r
632820d1 494 //\r
495 // not the same\r
496 //\r
497 HFileImageSetFileName (FileName);\r
498 if (HFileImage.FileName == NULL) {\r
499 return EFI_OUT_OF_RESOURCES;\r
500 }\r
501 }\r
502\r
503 HFileImage.ReadOnly = FALSE;\r
504\r
505 return EFI_SUCCESS;\r
506}\r