2 Functions to deal with file buffer.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "HexEditor.h"
17 extern EFI_HANDLE HImageHandleBackup
;
18 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage
;
20 extern BOOLEAN HBufferImageNeedRefresh
;
21 extern BOOLEAN HBufferImageOnlyLineNeedRefresh
;
22 extern BOOLEAN HBufferImageMouseNeedRefresh
;
24 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor
;
26 HEFI_EDITOR_FILE_IMAGE HFileImage
;
27 HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar
;
30 // for basic initialization of HFileImage
32 HEFI_EDITOR_BUFFER_IMAGE HFileImageConst
= {
39 Initialization function for HFileImage
41 @retval EFI_SUCCESS The operation was successful.
49 // basically initialize the HFileImage
51 CopyMem (&HFileImage
, &HFileImageConst
, sizeof (HFileImage
));
56 sizeof (HFileImageBackupVar
)
63 Backup function for HFileImage. Only a few fields need to be backup.
64 This is for making the file buffer refresh as few as possible.
66 @retval EFI_SUCCESS The operation was successful.
67 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
74 SHELL_FREE_NON_NULL (HFileImageBackupVar
.FileName
);
75 HFileImageBackupVar
.FileName
= CatSPrint(NULL
, L
"%s", HFileImage
.FileName
);
76 if (HFileImageBackupVar
.FileName
== NULL
) {
77 return EFI_OUT_OF_RESOURCES
;
84 Cleanup function for HFileImage.
86 @retval EFI_SUCCESS The operation was successful.
94 SHELL_FREE_NON_NULL (HFileImage
.FileName
);
95 SHELL_FREE_NON_NULL (HFileImageBackupVar
.FileName
);
101 Set FileName field in HFileImage
103 @param[in] Str File name to set.
105 @retval EFI_SUCCESS The operation was successful.
106 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
109 HFileImageSetFileName (
113 if (Str
== HFileImage
.FileName
) {
115 // This function might be called using HFileImage.FileName as Str.
116 // Directly return without updating HFileImage.FileName.
121 // free the old file name
123 SHELL_FREE_NON_NULL (HFileImage
.FileName
);
124 HFileImage
.FileName
= AllocateCopyPool (StrSize (Str
), Str
);
125 if (HFileImage
.FileName
== NULL
) {
126 return EFI_OUT_OF_RESOURCES
;
133 Read a file from disk into HBufferImage.
135 @param[in] FileName filename to read.
136 @param[in] Recover if is for recover, no information print.
138 @retval EFI_SUCCESS The operation was successful.
139 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
140 @retval EFI_LOAD_ERROR A load error occured.
144 IN CONST CHAR16
*FileName
,
148 HEFI_EDITOR_LINE
*Line
;
150 CHAR16
*UnicodeBuffer
;
154 // variable initialization
159 // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
160 // you should set status string
161 // since this function maybe called before the editorhandleinput loop
162 // so any error will cause editor return
163 // so if you want to print the error status
164 // you should set the status string
166 Status
= ReadFileIntoBuffer (FileName
, (VOID
**)&Buffer
, &HFileImage
.Size
, &HFileImage
.ReadOnly
);
168 // NULL pointer is only also a failure for a non-zero file size.
170 if ((EFI_ERROR(Status
)) || (Buffer
== NULL
&& HFileImage
.Size
!= 0)) {
171 UnicodeBuffer
= CatSPrint(NULL
, L
"Read error on file %s: %r", FileName
, Status
);
172 if (UnicodeBuffer
== NULL
) {
173 SHELL_FREE_NON_NULL(Buffer
);
174 return EFI_OUT_OF_RESOURCES
;
177 StatusBarSetStatusString (UnicodeBuffer
);
178 FreePool (UnicodeBuffer
);
179 return EFI_OUT_OF_RESOURCES
;
182 HFileImageSetFileName (FileName
);
185 // free the old lines
189 Status
= HBufferImageBufferToList (Buffer
, HFileImage
.Size
);
190 SHELL_FREE_NON_NULL (Buffer
);
191 if (EFI_ERROR (Status
)) {
192 StatusBarSetStatusString (L
"Error parsing file.");
196 HBufferImage
.DisplayPosition
.Row
= 2;
197 HBufferImage
.DisplayPosition
.Column
= 10;
198 HBufferImage
.MousePosition
.Row
= 2;
199 HBufferImage
.MousePosition
.Column
= 10;
200 HBufferImage
.LowVisibleRow
= 1;
201 HBufferImage
.HighBits
= TRUE
;
202 HBufferImage
.BufferPosition
.Row
= 1;
203 HBufferImage
.BufferPosition
.Column
= 1;
204 HBufferImage
.BufferType
= FileTypeFileBuffer
;
207 UnicodeBuffer
= CatSPrint(NULL
, L
"%d Lines Read", HBufferImage
.NumLines
);
208 if (UnicodeBuffer
== NULL
) {
209 SHELL_FREE_NON_NULL(Buffer
);
210 return EFI_OUT_OF_RESOURCES
;
213 StatusBarSetStatusString (UnicodeBuffer
);
214 FreePool (UnicodeBuffer
);
216 HMainEditor
.SelectStart
= 0;
217 HMainEditor
.SelectEnd
= 0;
223 if (HBufferImage
.Lines
!= 0) {
224 HBufferImage
.CurrentLine
= CR (HBufferImage
.ListHead
->ForwardLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
227 // create a dummy line
229 Line
= HBufferImageCreateLine ();
231 SHELL_FREE_NON_NULL(Buffer
);
232 return EFI_OUT_OF_RESOURCES
;
235 HBufferImage
.CurrentLine
= Line
;
238 HBufferImage
.Modified
= FALSE
;
239 HBufferImageNeedRefresh
= TRUE
;
240 HBufferImageOnlyLineNeedRefresh
= FALSE
;
241 HBufferImageMouseNeedRefresh
= TRUE
;
247 Save lines in HBufferImage to disk.
249 @param[in] FileName The file name.
251 @retval EFI_SUCCESS The operation was successful.
252 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
253 @retval EFI_LOAD_ERROR A load error occured.
262 HEFI_EDITOR_LINE
*Line
;
266 SHELL_FILE_HANDLE FileHandle
;
270 EDIT_FILE_TYPE BufferTypeBackup
;
272 BufferTypeBackup
= HBufferImage
.BufferType
;
273 HBufferImage
.BufferType
= FileTypeFileBuffer
;
276 // if is the old file
278 if (HFileImage
.FileName
!= NULL
&& FileName
!= NULL
&& StrCmp (FileName
, HFileImage
.FileName
) == 0) {
280 // check whether file exists on disk
282 if (ShellIsFile(FileName
) == EFI_SUCCESS
) {
284 // current file exists on disk
285 // so if not modified, then not save
287 if (HBufferImage
.Modified
== FALSE
) {
291 // if file is read-only, set error
293 if (HFileImage
.ReadOnly
== TRUE
) {
294 StatusBarSetStatusString (L
"Read Only File Can Not Be Saved");
300 if (ShellIsDirectory(FileName
) == EFI_SUCCESS
) {
301 StatusBarSetStatusString (L
"Directory Can Not Be Saved");
302 return EFI_LOAD_ERROR
;
305 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
, 0);
307 if (!EFI_ERROR (Status
)) {
309 // the file exits, delete it
311 Status
= ShellDeleteFile (&FileHandle
);
312 if (EFI_ERROR (Status
) || Status
== EFI_WARN_DELETE_FAILURE
) {
313 StatusBarSetStatusString (L
"Write File Failed");
314 return EFI_LOAD_ERROR
;
319 // write all the lines back to disk
323 for (Link
= HBufferImage
.ListHead
->ForwardLink
; Link
!= HBufferImage
.ListHead
; Link
= Link
->ForwardLink
) {
324 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
326 if (Line
->Size
!= 0) {
327 TotalSize
+= Line
->Size
;
330 // end of if Line -> Size != 0
337 Buffer
= AllocateZeroPool (TotalSize
);
338 if (Buffer
== NULL
) {
339 return EFI_OUT_OF_RESOURCES
;
343 for (Link
= HBufferImage
.ListHead
->ForwardLink
; Link
!= HBufferImage
.ListHead
; Link
= Link
->ForwardLink
) {
344 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
346 if (Line
->Size
!= 0) {
347 CopyMem (Ptr
, Line
->Buffer
, Line
->Size
);
351 // end of if Line -> Size != 0
356 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_CREATE
, 0);
358 if (EFI_ERROR (Status
)) {
359 StatusBarSetStatusString (L
"Create File Failed");
360 return EFI_LOAD_ERROR
;
363 Status
= ShellWriteFile (FileHandle
, &TotalSize
, Buffer
);
365 if (EFI_ERROR (Status
)) {
366 ShellDeleteFile (&FileHandle
);
367 return EFI_LOAD_ERROR
;
370 ShellCloseFile(&FileHandle
);
372 HBufferImage
.Modified
= FALSE
;
377 Str
= CatSPrint(NULL
, L
"%d Lines Wrote", NumLines
);
378 StatusBarSetStatusString (Str
);
382 // now everything is ready , you can set the new file name to filebuffer
384 if ((BufferTypeBackup
!= FileTypeFileBuffer
&& FileName
!= NULL
) ||
385 (FileName
!= NULL
&& HFileImage
.FileName
!= NULL
&& StringNoCaseCompare (&FileName
, &HFileImage
.FileName
) != 0)){
389 HFileImageSetFileName (FileName
);
390 if (HFileImage
.FileName
== NULL
) {
391 return EFI_OUT_OF_RESOURCES
;
395 HFileImage
.ReadOnly
= FALSE
;