• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Functions to deal with Disk 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 #include <Protocol/BlockIo.h>
17 
18 extern EFI_HANDLE                 HImageHandleBackup;
19 extern HEFI_EDITOR_BUFFER_IMAGE   HBufferImage;
20 
21 extern BOOLEAN                    HBufferImageNeedRefresh;
22 extern BOOLEAN                    HBufferImageOnlyLineNeedRefresh;
23 extern BOOLEAN                    HBufferImageMouseNeedRefresh;
24 
25 extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditor;
26 
27 HEFI_EDITOR_DISK_IMAGE            HDiskImage;
28 HEFI_EDITOR_DISK_IMAGE            HDiskImageBackupVar;
29 
30 //
31 // for basic initialization of HDiskImage
32 //
33 HEFI_EDITOR_DISK_IMAGE            HDiskImageConst = {
34   NULL,
35   0,
36   0,
37   0
38 };
39 
40 /**
41   Initialization function for HDiskImage.
42 
43   @retval EFI_SUCCESS     The operation was successful.
44   @retval EFI_LOAD_ERROR  A load error occured.
45 **/
46 EFI_STATUS
HDiskImageInit(VOID)47 HDiskImageInit (
48   VOID
49   )
50 {
51   //
52   // basically initialize the HDiskImage
53   //
54   CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
55 
56   CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
57 
58   return EFI_SUCCESS;
59 }
60 
61 /**
62   Backup function for HDiskImage. Only a few fields need to be backup.
63   This is for making the Disk buffer refresh as few as possible.
64 
65   @retval EFI_SUCCESS           The operation was successful.
66   @retval EFI_OUT_OF_RESOURCES  gST->ConOut of resources.
67 **/
68 EFI_STATUS
HDiskImageBackup(VOID)69 HDiskImageBackup (
70   VOID
71   )
72 {
73   //
74   // backup the disk name, offset and size
75   //
76   //
77   SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
78 
79   HDiskImageBackupVar.Name = CatSPrint(NULL, L"%s", HDiskImage.Name);
80   if (HDiskImageBackupVar.Name == NULL) {
81     return EFI_OUT_OF_RESOURCES;
82   }
83 
84   HDiskImageBackupVar.Offset  = HDiskImage.Offset;
85   HDiskImageBackupVar.Size    = HDiskImage.Size;
86 
87   return EFI_SUCCESS;
88 }
89 
90 /**
91   Cleanup function for HDiskImage.
92 
93   @retval EFI_SUCCESS           The operation was successful.
94 **/
95 EFI_STATUS
HDiskImageCleanup(VOID)96 HDiskImageCleanup (
97   VOID
98   )
99 {
100   SHELL_FREE_NON_NULL (HDiskImage.Name);
101   SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
102 
103   return EFI_SUCCESS;
104 }
105 
106 /**
107   Set FileName field in HFileImage.
108 
109   @param[in] Str      File name to set.
110   @param[in] Offset   The offset.
111   @param[in] Size     The size.
112 
113   @retval EFI_SUCCESS           The operation was successful.
114   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
115 **/
116 EFI_STATUS
117 EFIAPI
HDiskImageSetDiskNameOffsetSize(IN CONST CHAR16 * Str,IN UINTN Offset,IN UINTN Size)118 HDiskImageSetDiskNameOffsetSize (
119   IN CONST CHAR16   *Str,
120   IN UINTN    Offset,
121   IN UINTN    Size
122   )
123 {
124   UINTN Len;
125   UINTN Index;
126 
127   //
128   // free the old file name
129   //
130   SHELL_FREE_NON_NULL (HDiskImage.Name);
131 
132   Len             = StrLen (Str);
133 
134   HDiskImage.Name = AllocateZeroPool (2 * (Len + 1));
135   if (HDiskImage.Name == NULL) {
136     return EFI_OUT_OF_RESOURCES;
137   }
138 
139   for (Index = 0; Index < Len; Index++) {
140     HDiskImage.Name[Index] = Str[Index];
141   }
142 
143   HDiskImage.Name[Len]  = L'\0';
144 
145   HDiskImage.Offset     = Offset;
146   HDiskImage.Size       = Size;
147 
148   return EFI_SUCCESS;
149 }
150 
151 /**
152   Read a disk from disk into HBufferImage.
153 
154   @param[in] DeviceName   filename to read.
155   @param[in] Offset       The offset.
156   @param[in] Size         The size.
157   @param[in] Recover      if is for recover, no information print.
158 
159   @retval EFI_SUCCESS           The operation was successful.
160   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
161   @retval EFI_LOAD_ERROR        A load error occured.
162   @retval EFI_INVALID_PARAMETER A parameter was invalid.
163 **/
164 EFI_STATUS
HDiskImageRead(IN CONST CHAR16 * DeviceName,IN UINTN Offset,IN UINTN Size,IN BOOLEAN Recover)165 HDiskImageRead (
166   IN CONST CHAR16   *DeviceName,
167   IN UINTN    Offset,
168   IN UINTN    Size,
169   IN BOOLEAN  Recover
170   )
171 {
172   CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
173   EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
174   EFI_DEVICE_PATH_PROTOCOL        *DupDevicePathForFree;
175   EFI_HANDLE                      Handle;
176   EFI_BLOCK_IO_PROTOCOL           *BlkIo;
177   EFI_STATUS                      Status;
178 
179   VOID                            *Buffer;
180   CHAR16                          *Str;
181   UINTN                           Bytes;
182 
183   HEFI_EDITOR_LINE                *Line;
184 
185   HBufferImage.BufferType = FileTypeDiskBuffer;
186 
187   DevicePath              = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
188   if (DevicePath == NULL) {
189     StatusBarSetStatusString (L"Cannot Find Device");
190     return EFI_INVALID_PARAMETER;
191   }
192   DupDevicePath = DuplicateDevicePath(DevicePath);
193   DupDevicePathForFree = DupDevicePath;
194   //
195   // get blkio interface
196   //
197   Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
198   FreePool(DupDevicePathForFree);
199   if (EFI_ERROR (Status)) {
200     StatusBarSetStatusString (L"Read Disk Failed");
201     return Status;
202   }
203   Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
204   if (EFI_ERROR (Status)) {
205     StatusBarSetStatusString (L"Read Disk Failed");
206     return Status;
207   }
208   //
209   // if Offset exceeds LastBlock,
210   //   return error
211   //
212   if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
213     StatusBarSetStatusString (L"Invalid Offset + Size");
214     return EFI_LOAD_ERROR;
215   }
216 
217   Bytes   = BlkIo->Media->BlockSize * Size;
218   Buffer  = AllocateZeroPool (Bytes);
219 
220   if (Buffer == NULL) {
221     StatusBarSetStatusString (L"Read Disk Failed");
222     return EFI_OUT_OF_RESOURCES;
223   }
224 
225   //
226   // read from disk
227   //
228   Status = BlkIo->ReadBlocks (
229                     BlkIo,
230                     BlkIo->Media->MediaId,
231                     Offset,
232                     Bytes,
233                     Buffer
234                     );
235 
236   if (EFI_ERROR (Status)) {
237     FreePool (Buffer);
238     StatusBarSetStatusString (L"Read Disk Failed");
239     return EFI_LOAD_ERROR;
240   }
241 
242   HBufferImageFree ();
243 
244   //
245   // convert buffer to line list
246   //
247   Status = HBufferImageBufferToList (Buffer, Bytes);
248   FreePool (Buffer);
249 
250   if (EFI_ERROR (Status)) {
251     StatusBarSetStatusString (L"Read Disk Failed");
252     return Status;
253   }
254 
255   Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
256   if (EFI_ERROR (Status)) {
257     StatusBarSetStatusString (L"Read Disk Failed");
258     return EFI_OUT_OF_RESOURCES;
259   }
260   //
261   // initialize some variables
262   //
263   HDiskImage.BlockSize                = BlkIo->Media->BlockSize;
264 
265   HBufferImage.DisplayPosition.Row    = 2;
266   HBufferImage.DisplayPosition.Column = 10;
267 
268   HBufferImage.MousePosition.Row      = 2;
269   HBufferImage.MousePosition.Column   = 10;
270 
271   HBufferImage.LowVisibleRow          = 1;
272   HBufferImage.HighBits               = TRUE;
273 
274   HBufferImage.BufferPosition.Row     = 1;
275   HBufferImage.BufferPosition.Column  = 1;
276 
277   if (!Recover) {
278     Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
279     if (Str == NULL) {
280       StatusBarSetStatusString (L"Read Disk Failed");
281       return EFI_OUT_OF_RESOURCES;
282     }
283 
284     StatusBarSetStatusString (Str);
285     SHELL_FREE_NON_NULL (Str);
286 
287     HMainEditor.SelectStart = 0;
288     HMainEditor.SelectEnd   = 0;
289 
290   }
291 
292   //
293   // has line
294   //
295   if (HBufferImage.Lines != NULL) {
296     HBufferImage.CurrentLine = CR (
297                                 HBufferImage.ListHead->ForwardLink,
298                                 HEFI_EDITOR_LINE,
299                                 Link,
300                                 EFI_EDITOR_LINE_LIST
301                                 );
302   } else {
303     //
304     // create a dummy line
305     //
306     Line = HBufferImageCreateLine ();
307     if (Line == NULL) {
308       StatusBarSetStatusString (L"Read Disk Failed");
309       return EFI_OUT_OF_RESOURCES;
310     }
311 
312     HBufferImage.CurrentLine = Line;
313   }
314 
315   HBufferImage.Modified           = FALSE;
316   HBufferImageNeedRefresh         = TRUE;
317   HBufferImageOnlyLineNeedRefresh = FALSE;
318   HBufferImageMouseNeedRefresh    = TRUE;
319 
320   return EFI_SUCCESS;
321 }
322 
323 /**
324   Save lines in HBufferImage to disk.
325   NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
326 
327   @param[in] DeviceName   The device name.
328   @param[in] Offset       The offset.
329   @param[in] Size         The size.
330 
331   @retval EFI_SUCCESS           The operation was successful.
332   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
333   @retval EFI_LOAD_ERROR        A load error occured.
334   @retval EFI_INVALID_PARAMETER A parameter was invalid.
335 **/
336 EFI_STATUS
HDiskImageSave(IN CHAR16 * DeviceName,IN UINTN Offset,IN UINTN Size)337 HDiskImageSave (
338   IN CHAR16 *DeviceName,
339   IN UINTN  Offset,
340   IN UINTN  Size
341   )
342 {
343 
344   CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
345   EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
346   EFI_BLOCK_IO_PROTOCOL           *BlkIo;
347   EFI_STATUS                      Status;
348   EFI_HANDLE                      Handle;
349   VOID                            *Buffer;
350   UINTN                           Bytes;
351 
352   //
353   // if not modified, directly return
354   //
355   if (HBufferImage.Modified == FALSE) {
356     return EFI_SUCCESS;
357   }
358 
359   HBufferImage.BufferType = FileTypeDiskBuffer;
360 
361   DevicePath              = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
362   if (DevicePath == NULL) {
363 //    StatusBarSetStatusString (L"Cannot Find Device");
364     return EFI_INVALID_PARAMETER;
365   }
366   DupDevicePath = DuplicateDevicePath(DevicePath);
367 
368   //
369   // get blkio interface
370   //
371   Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
372   FreePool(DupDevicePath);
373   if (EFI_ERROR (Status)) {
374 //    StatusBarSetStatusString (L"Read Disk Failed");
375     return Status;
376   }
377   Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
378   if (EFI_ERROR (Status)) {
379 //    StatusBarSetStatusString (L"Read Disk Failed");
380     return Status;
381   }
382 
383   Bytes   = BlkIo->Media->BlockSize * Size;
384   Buffer  = AllocateZeroPool (Bytes);
385 
386   if (Buffer == NULL) {
387     return EFI_OUT_OF_RESOURCES;
388   }
389   //
390   // concatenate the line list to a buffer
391   //
392   Status = HBufferImageListToBuffer (Buffer, Bytes);
393   if (EFI_ERROR (Status)) {
394     FreePool (Buffer);
395     return Status;
396   }
397 
398   //
399   // write the buffer to disk
400   //
401   Status = BlkIo->WriteBlocks (
402                     BlkIo,
403                     BlkIo->Media->MediaId,
404                     Offset,
405                     Bytes,
406                     Buffer
407                     );
408 
409   FreePool (Buffer);
410 
411   if (EFI_ERROR (Status)) {
412     return EFI_LOAD_ERROR;
413   }
414   //
415   // now not modified
416   //
417   HBufferImage.Modified = FALSE;
418 
419   return EFI_SUCCESS;
420 }
421