TianoCore EDK2 master
Loading...
Searching...
No Matches
FileImage.c
Go to the documentation of this file.
1
9#include "HexEditor.h"
10
11extern EFI_HANDLE HImageHandleBackup;
12extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
13
14extern BOOLEAN HBufferImageNeedRefresh;
15extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
16extern BOOLEAN HBufferImageMouseNeedRefresh;
17
18extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
19
20HEFI_EDITOR_FILE_IMAGE HFileImage;
21HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;
22
23//
24// for basic initialization of HFileImage
25//
26HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = {
27 NULL,
28 0,
29 FALSE
30};
31
39 VOID
40 )
41{
42 //
43 // basically initialize the HFileImage
44 //
45 CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));
46
47 CopyMem (
48 &HFileImageBackupVar,
49 &HFileImageConst,
50 sizeof (HFileImageBackupVar)
51 );
52
53 return EFI_SUCCESS;
54}
55
65 VOID
66 )
67{
68 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
69 HFileImageBackupVar.FileName = CatSPrint (NULL, L"%s", HFileImage.FileName);
70 if (HFileImageBackupVar.FileName == NULL) {
71 return EFI_OUT_OF_RESOURCES;
72 }
73
74 return EFI_SUCCESS;
75}
76
84 VOID
85 )
86{
87 SHELL_FREE_NON_NULL (HFileImage.FileName);
88 SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
89
90 return EFI_SUCCESS;
91}
92
103 IN CONST CHAR16 *Str
104 )
105{
106 if (Str == HFileImage.FileName) {
107 //
108 // This function might be called using HFileImage.FileName as Str.
109 // Directly return without updating HFileImage.FileName.
110 //
111 return EFI_SUCCESS;
112 }
113
114 //
115 // free the old file name
116 //
117 SHELL_FREE_NON_NULL (HFileImage.FileName);
118 HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str);
119 if (HFileImage.FileName == NULL) {
120 return EFI_OUT_OF_RESOURCES;
121 }
122
123 return EFI_SUCCESS;
124}
125
138 IN CONST CHAR16 *FileName,
139 IN BOOLEAN Recover
140 )
141{
142 HEFI_EDITOR_LINE *Line;
143 UINT8 *Buffer;
144 CHAR16 *UnicodeBuffer;
145 EFI_STATUS Status;
146
147 //
148 // variable initialization
149 //
150 Line = NULL;
151
152 //
153 // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
154 // you should set status string
155 // since this function maybe called before the editorhandleinput loop
156 // so any error will cause editor return
157 // so if you want to print the error status
158 // you should set the status string
159 //
160 Status = ReadFileIntoBuffer (FileName, (VOID **)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);
161 //
162 // NULL pointer is only also a failure for a non-zero file size.
163 //
164 if ((EFI_ERROR (Status)) || ((Buffer == NULL) && (HFileImage.Size != 0))) {
165 UnicodeBuffer = CatSPrint (NULL, L"Read error on file %s: %r", FileName, Status);
166 if (UnicodeBuffer == NULL) {
167 SHELL_FREE_NON_NULL (Buffer);
168 return EFI_OUT_OF_RESOURCES;
169 }
170
171 StatusBarSetStatusString (UnicodeBuffer);
172 FreePool (UnicodeBuffer);
173 return EFI_OUT_OF_RESOURCES;
174 }
175
176 HFileImageSetFileName (FileName);
177
178 //
179 // free the old lines
180 //
182
183 Status = HBufferImageBufferToList (Buffer, HFileImage.Size);
184 SHELL_FREE_NON_NULL (Buffer);
185 if (EFI_ERROR (Status)) {
186 StatusBarSetStatusString (L"Error parsing file.");
187 return Status;
188 }
189
190 HBufferImage.DisplayPosition.Row = 2;
191 HBufferImage.DisplayPosition.Column = 10;
192 HBufferImage.MousePosition.Row = 2;
193 HBufferImage.MousePosition.Column = 10;
194 HBufferImage.LowVisibleRow = 1;
195 HBufferImage.HighBits = TRUE;
196 HBufferImage.BufferPosition.Row = 1;
197 HBufferImage.BufferPosition.Column = 1;
198 HBufferImage.BufferType = FileTypeFileBuffer;
199
200 if (!Recover) {
201 UnicodeBuffer = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines);
202 if (UnicodeBuffer == NULL) {
203 SHELL_FREE_NON_NULL (Buffer);
204 return EFI_OUT_OF_RESOURCES;
205 }
206
207 StatusBarSetStatusString (UnicodeBuffer);
208 FreePool (UnicodeBuffer);
209
210 HMainEditor.SelectStart = 0;
211 HMainEditor.SelectEnd = 0;
212 }
213
214 //
215 // has line
216 //
217 if (HBufferImage.Lines != 0) {
218 HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
219 } else {
220 //
221 // create a dummy line
222 //
223 Line = HBufferImageCreateLine ();
224 if (Line == NULL) {
225 SHELL_FREE_NON_NULL (Buffer);
226 return EFI_OUT_OF_RESOURCES;
227 }
228
229 HBufferImage.CurrentLine = Line;
230 }
231
232 HBufferImage.Modified = FALSE;
233 HBufferImageNeedRefresh = TRUE;
234 HBufferImageOnlyLineNeedRefresh = FALSE;
235 HBufferImageMouseNeedRefresh = TRUE;
236
237 return EFI_SUCCESS;
238}
239
251 IN CHAR16 *FileName
252 )
253{
254 LIST_ENTRY *Link;
255 HEFI_EDITOR_LINE *Line;
256 CHAR16 *Str;
257 EFI_STATUS Status;
258 UINTN NumLines;
259 SHELL_FILE_HANDLE FileHandle;
260 UINTN TotalSize;
261 UINT8 *Buffer;
262 UINT8 *Ptr;
263 EDIT_FILE_TYPE BufferTypeBackup;
264
265 BufferTypeBackup = HBufferImage.BufferType;
266 HBufferImage.BufferType = FileTypeFileBuffer;
267
268 //
269 // if is the old file
270 //
271 if ((HFileImage.FileName != NULL) && (FileName != NULL) && (StrCmp (FileName, HFileImage.FileName) == 0)) {
272 //
273 // check whether file exists on disk
274 //
275 if (ShellIsFile (FileName) == EFI_SUCCESS) {
276 //
277 // current file exists on disk
278 // so if not modified, then not save
279 //
280 if (HBufferImage.Modified == FALSE) {
281 return EFI_SUCCESS;
282 }
283
284 //
285 // if file is read-only, set error
286 //
287 if (HFileImage.ReadOnly == TRUE) {
288 StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
289 return EFI_SUCCESS;
290 }
291 }
292 }
293
294 if (ShellIsDirectory (FileName) == EFI_SUCCESS) {
295 StatusBarSetStatusString (L"Directory Can Not Be Saved");
296 return EFI_LOAD_ERROR;
297 }
298
299 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);
300
301 if (!EFI_ERROR (Status)) {
302 //
303 // the file exits, delete it
304 //
305 Status = ShellDeleteFile (&FileHandle);
306 if (EFI_ERROR (Status) || (Status == EFI_WARN_DELETE_FAILURE)) {
307 StatusBarSetStatusString (L"Write File Failed");
308 return EFI_LOAD_ERROR;
309 }
310 }
311
312 //
313 // write all the lines back to disk
314 //
315 NumLines = 0;
316 TotalSize = 0;
317 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
318 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
319
320 if (Line->Size != 0) {
321 TotalSize += Line->Size;
322 }
323
324 //
325 // end of if Line -> Size != 0
326 //
327 NumLines++;
328 }
329
330 //
331 // end of for Link
332 //
333 Buffer = AllocateZeroPool (TotalSize);
334 if (Buffer == NULL) {
335 return EFI_OUT_OF_RESOURCES;
336 }
337
338 Ptr = Buffer;
339 for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
340 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
341
342 if (Line->Size != 0) {
343 CopyMem (Ptr, Line->Buffer, Line->Size);
344 Ptr += Line->Size;
345 }
346
347 //
348 // end of if Line -> Size != 0
349 //
350 }
351
352 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
353
354 if (EFI_ERROR (Status)) {
355 StatusBarSetStatusString (L"Create File Failed");
356 return EFI_LOAD_ERROR;
357 }
358
359 Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);
360 FreePool (Buffer);
361 if (EFI_ERROR (Status)) {
362 ShellDeleteFile (&FileHandle);
363 return EFI_LOAD_ERROR;
364 }
365
366 ShellCloseFile (&FileHandle);
367
368 HBufferImage.Modified = FALSE;
369
370 //
371 // set status string
372 //
373 Str = CatSPrint (NULL, L"%d Lines Written", NumLines);
374 if (Str == NULL) {
375 return EFI_OUT_OF_RESOURCES;
376 }
377
379 FreePool (Str);
380
381 //
382 // now everything is ready , you can set the new file name to filebuffer
383 //
384 if (((BufferTypeBackup != FileTypeFileBuffer) && (FileName != NULL)) ||
385 ((FileName != NULL) && (HFileImage.FileName != NULL) && (StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)))
386 {
387 //
388 // not the same
389 //
390 HFileImageSetFileName (FileName);
391 if (HFileImage.FileName == NULL) {
392 return EFI_OUT_OF_RESOURCES;
393 }
394 }
395
396 HFileImage.ReadOnly = FALSE;
397
398 return EFI_SUCCESS;
399}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS HBufferImageFree(VOID)
Definition: BufferImage.c:1082
EFI_STATUS HBufferImageBufferToList(IN VOID *Buffer, IN UINTN Bytes)
Definition: BufferImage.c:2175
HEFI_EDITOR_LINE * HBufferImageCreateLine(VOID)
Definition: BufferImage.c:1040
EFI_STATUS StatusBarSetStatusString(IN CHAR16 *Str)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS HFileImageRead(IN CONST CHAR16 *FileName, IN BOOLEAN Recover)
Definition: FileImage.c:137
EFI_STATUS HFileImageBackup(VOID)
Definition: FileImage.c:64
EFI_STATUS HFileImageSetFileName(IN CONST CHAR16 *Str)
Definition: FileImage.c:102
EFI_STATUS HFileImageCleanup(VOID)
Definition: FileImage.c:83
EFI_STATUS HFileImageSave(IN CHAR16 *FileName)
Definition: FileImage.c:250
EFI_STATUS HFileImageInit(VOID)
Definition: FileImage.c:38
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
EFI_STATUS EFIAPI ShellDeleteFile(IN SHELL_FILE_HANDLE *FileHandle)
Definition: UefiShellLib.c:992
EFI_STATUS EFIAPI ShellOpenFileByName(IN CONST CHAR16 *FileName, OUT SHELL_FILE_HANDLE *FileHandle, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition: UefiShellLib.c:720
EFI_STATUS EFIAPI ShellIsFile(IN CONST CHAR16 *Name)
EFI_STATUS EFIAPI ShellIsDirectory(IN CONST CHAR16 *DirName)
EFI_STATUS EFIAPI ShellWriteFile(IN SHELL_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, IN VOID *Buffer)
Definition: UefiShellLib.c:947
EFI_STATUS EFIAPI ShellCloseFile(IN SHELL_FILE_HANDLE *FileHandle)
Definition: UefiShellLib.c:969
INTN EFIAPI StringNoCaseCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
Definition: BaseSortLib.c:92
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
CHAR16 *EFIAPI CatSPrint(IN CHAR16 *String OPTIONAL, IN CONST CHAR16 *FormatString,...)
Definition: UefiLibPrint.c:827
EFI_STATUS ReadFileIntoBuffer(IN CONST CHAR16 *FileName, OUT VOID **Buffer, OUT UINTN *BufferSize OPTIONAL, OUT BOOLEAN *ReadOnly)