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.
88 SHELL_FREE_NON_NULL (HFileImage
.FileName
);
89 SHELL_FREE_NON_NULL (HFileImageBackupVar
.FileName
);
95 Set FileName field in HFileImage
97 @param[in] Str File name to set.
99 @retval EFI_SUCCESS The operation was successful.
100 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
103 HFileImageSetFileName (
107 if (Str
== HFileImage
.FileName
) {
109 // This function might be called using HFileImage.FileName as Str.
110 // 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 occured.
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 occured.
256 HEFI_EDITOR_LINE
*Line
;
260 SHELL_FILE_HANDLE FileHandle
;
264 EDIT_FILE_TYPE BufferTypeBackup
;
266 BufferTypeBackup
= HBufferImage
.BufferType
;
267 HBufferImage
.BufferType
= FileTypeFileBuffer
;
270 // if is the old file
272 if (HFileImage
.FileName
!= NULL
&& FileName
!= NULL
&& StrCmp (FileName
, HFileImage
.FileName
) == 0) {
274 // check whether file exists on disk
276 if (ShellIsFile(FileName
) == EFI_SUCCESS
) {
278 // current file exists on disk
279 // so if not modified, then not save
281 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
;
324 // end of if Line -> Size != 0
331 Buffer
= AllocateZeroPool (TotalSize
);
332 if (Buffer
== NULL
) {
333 return EFI_OUT_OF_RESOURCES
;
337 for (Link
= HBufferImage
.ListHead
->ForwardLink
; Link
!= HBufferImage
.ListHead
; Link
= Link
->ForwardLink
) {
338 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
340 if (Line
->Size
!= 0) {
341 CopyMem (Ptr
, Line
->Buffer
, Line
->Size
);
345 // end of if Line -> Size != 0
350 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_CREATE
, 0);
352 if (EFI_ERROR (Status
)) {
353 StatusBarSetStatusString (L
"Create File Failed");
354 return EFI_LOAD_ERROR
;
357 Status
= ShellWriteFile (FileHandle
, &TotalSize
, Buffer
);
359 if (EFI_ERROR (Status
)) {
360 ShellDeleteFile (&FileHandle
);
361 return EFI_LOAD_ERROR
;
364 ShellCloseFile(&FileHandle
);
366 HBufferImage
.Modified
= FALSE
;
371 Str
= CatSPrint(NULL
, L
"%d Lines Written", NumLines
);
372 StatusBarSetStatusString (Str
);
376 // now everything is ready , you can set the new file name to filebuffer
378 if ((BufferTypeBackup
!= FileTypeFileBuffer
&& FileName
!= NULL
) ||
379 (FileName
!= NULL
&& HFileImage
.FileName
!= NULL
&& StringNoCaseCompare (&FileName
, &HFileImage
.FileName
) != 0)){
383 HFileImageSetFileName (FileName
);
384 if (HFileImage
.FileName
== NULL
) {
385 return EFI_OUT_OF_RESOURCES
;
389 HFileImage
.ReadOnly
= FALSE
;