2 Functions to deal with file buffer.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 extern EFI_HANDLE HImageHandleBackup
;
12 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage
;
14 extern BOOLEAN HBufferImageNeedRefresh
;
15 extern BOOLEAN HBufferImageOnlyLineNeedRefresh
;
16 extern BOOLEAN HBufferImageMouseNeedRefresh
;
18 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor
;
20 HEFI_EDITOR_FILE_IMAGE HFileImage
;
21 HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar
;
24 // for basic initialization of HFileImage
26 HEFI_EDITOR_BUFFER_IMAGE HFileImageConst
= {
33 Initialization function for HFileImage
35 @retval EFI_SUCCESS The operation was successful.
43 // basically initialize the HFileImage
45 CopyMem (&HFileImage
, &HFileImageConst
, sizeof (HFileImage
));
50 sizeof (HFileImageBackupVar
)
57 Backup function for HFileImage. Only a few fields need to be backup.
58 This is for making the file buffer refresh as few as possible.
60 @retval EFI_SUCCESS The operation was successful.
61 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
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
;
78 Cleanup function for HFileImage.
80 @retval EFI_SUCCESS The operation was successful.
87 SHELL_FREE_NON_NULL (HFileImage
.FileName
);
88 SHELL_FREE_NON_NULL (HFileImageBackupVar
.FileName
);
94 Set FileName field in HFileImage
96 @param[in] Str File name to set.
98 @retval EFI_SUCCESS The operation was successful.
99 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
102 HFileImageSetFileName (
106 if (Str
== HFileImage
.FileName
) {
108 // This function might be called using HFileImage.FileName as Str.
109 // Directly return without updating HFileImage.FileName.
115 // free the old file name
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
;
127 Read a file from disk into HBufferImage.
129 @param[in] FileName filename to read.
130 @param[in] Recover if is for recover, no information print.
132 @retval EFI_SUCCESS The operation was successful.
133 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
134 @retval EFI_LOAD_ERROR A load error occurred.
138 IN CONST CHAR16
*FileName
,
142 HEFI_EDITOR_LINE
*Line
;
144 CHAR16
*UnicodeBuffer
;
148 // variable initialization
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
160 Status
= ReadFileIntoBuffer (FileName
, (VOID
**)&Buffer
, &HFileImage
.Size
, &HFileImage
.ReadOnly
);
162 // NULL pointer is only also a failure for a non-zero file size.
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
;
171 StatusBarSetStatusString (UnicodeBuffer
);
172 FreePool (UnicodeBuffer
);
173 return EFI_OUT_OF_RESOURCES
;
176 HFileImageSetFileName (FileName
);
179 // free the old lines
183 Status
= HBufferImageBufferToList (Buffer
, HFileImage
.Size
);
184 SHELL_FREE_NON_NULL (Buffer
);
185 if (EFI_ERROR (Status
)) {
186 StatusBarSetStatusString (L
"Error parsing file.");
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
;
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
;
207 StatusBarSetStatusString (UnicodeBuffer
);
208 FreePool (UnicodeBuffer
);
210 HMainEditor
.SelectStart
= 0;
211 HMainEditor
.SelectEnd
= 0;
217 if (HBufferImage
.Lines
!= 0) {
218 HBufferImage
.CurrentLine
= CR (HBufferImage
.ListHead
->ForwardLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
221 // create a dummy line
223 Line
= HBufferImageCreateLine ();
225 SHELL_FREE_NON_NULL (Buffer
);
226 return EFI_OUT_OF_RESOURCES
;
229 HBufferImage
.CurrentLine
= Line
;
232 HBufferImage
.Modified
= FALSE
;
233 HBufferImageNeedRefresh
= TRUE
;
234 HBufferImageOnlyLineNeedRefresh
= FALSE
;
235 HBufferImageMouseNeedRefresh
= TRUE
;
241 Save lines in HBufferImage to disk.
243 @param[in] FileName The file name.
245 @retval EFI_SUCCESS The operation was successful.
246 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
247 @retval EFI_LOAD_ERROR A load error occurred.
255 HEFI_EDITOR_LINE
*Line
;
259 SHELL_FILE_HANDLE FileHandle
;
263 EDIT_FILE_TYPE BufferTypeBackup
;
265 BufferTypeBackup
= HBufferImage
.BufferType
;
266 HBufferImage
.BufferType
= FileTypeFileBuffer
;
269 // if is the old file
271 if ((HFileImage
.FileName
!= NULL
) && (FileName
!= NULL
) && (StrCmp (FileName
, HFileImage
.FileName
) == 0)) {
273 // check whether file exists on disk
275 if (ShellIsFile (FileName
) == EFI_SUCCESS
) {
277 // current file exists on disk
278 // so if not modified, then not save
280 if (HBufferImage
.Modified
== FALSE
) {
285 // if file is read-only, set error
287 if (HFileImage
.ReadOnly
== TRUE
) {
288 StatusBarSetStatusString (L
"Read Only File Can Not Be Saved");
294 if (ShellIsDirectory (FileName
) == EFI_SUCCESS
) {
295 StatusBarSetStatusString (L
"Directory Can Not Be Saved");
296 return EFI_LOAD_ERROR
;
299 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
, 0);
301 if (!EFI_ERROR (Status
)) {
303 // the file exits, delete it
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
;
313 // write all the lines back to disk
317 for (Link
= HBufferImage
.ListHead
->ForwardLink
; Link
!= HBufferImage
.ListHead
; Link
= Link
->ForwardLink
) {
318 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
320 if (Line
->Size
!= 0) {
321 TotalSize
+= Line
->Size
;
325 // end of if Line -> Size != 0
333 Buffer
= AllocateZeroPool (TotalSize
);
334 if (Buffer
== NULL
) {
335 return EFI_OUT_OF_RESOURCES
;
339 for (Link
= HBufferImage
.ListHead
->ForwardLink
; Link
!= HBufferImage
.ListHead
; Link
= Link
->ForwardLink
) {
340 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
342 if (Line
->Size
!= 0) {
343 CopyMem (Ptr
, Line
->Buffer
, Line
->Size
);
348 // end of if Line -> Size != 0
352 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_CREATE
, 0);
354 if (EFI_ERROR (Status
)) {
355 StatusBarSetStatusString (L
"Create File Failed");
356 return EFI_LOAD_ERROR
;
359 Status
= ShellWriteFile (FileHandle
, &TotalSize
, Buffer
);
361 if (EFI_ERROR (Status
)) {
362 ShellDeleteFile (&FileHandle
);
363 return EFI_LOAD_ERROR
;
366 ShellCloseFile (&FileHandle
);
368 HBufferImage
.Modified
= FALSE
;
373 Str
= CatSPrint (NULL
, L
"%d Lines Written", NumLines
);
374 StatusBarSetStatusString (Str
);
378 // now everything is ready , you can set the new file name to filebuffer
380 if (((BufferTypeBackup
!= FileTypeFileBuffer
) && (FileName
!= NULL
)) ||
381 ((FileName
!= NULL
) && (HFileImage
.FileName
!= NULL
) && (StringNoCaseCompare (&FileName
, &HFileImage
.FileName
) != 0)))
386 HFileImageSetFileName (FileName
);
387 if (HFileImage
.FileName
== NULL
) {
388 return EFI_OUT_OF_RESOURCES
;
392 HFileImage
.ReadOnly
= FALSE
;