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