1 /** @file
2   Functions to deal with Mem 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 
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_MEM_IMAGE             HMemImage;
28 HEFI_EDITOR_MEM_IMAGE             HMemImageBackupVar;
29 
30 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   DummyPciRootBridgeIo;
31 
32 //
33 // for basic initialization of HDiskImage
34 //
35 HEFI_EDITOR_MEM_IMAGE             HMemImageConst = {
36   NULL,
37   0,
38   0
39 };
40 
41 /**
42   Empty function.  always returns the same.
43 
44   @param[in] This        Ignored.
45   @param[in] Width       Ignored.
46   @param[in] Address     Ignored.
47   @param[in] Count       Ignored.
48   @param[in, out] Buffer Ignored.
49 
50   @retval EFI_UNSUPPORTED.
51 **/
52 EFI_STATUS
53 EFIAPI
DummyMemRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)54 DummyMemRead (
55   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              * This,
56   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
57   IN     UINT64                                   Address,
58   IN     UINTN                                    Count,
59   IN OUT VOID                                     *Buffer
60   )
61 {
62   return EFI_UNSUPPORTED;
63 }
64 
65 /**
66   Empty function.  always returns the same.
67 
68   @param[in] This        Ignored.
69   @param[in] Width       Ignored.
70   @param[in] Address     Ignored.
71   @param[in] Count       Ignored.
72   @param[in, out] Buffer Ignored.
73 
74   @retval EFI_UNSUPPORTED.
75 **/
76 EFI_STATUS
77 EFIAPI
DummyMemWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)78 DummyMemWrite (
79   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              * This,
80   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
81   IN     UINT64                                   Address,
82   IN     UINTN                                    Count,
83   IN OUT VOID                                     *Buffer
84   )
85 {
86   return EFI_UNSUPPORTED;
87 }
88 
89 /**
90   Initialization function for HDiskImage.
91 
92   @retval EFI_SUCCESS       The operation was successful.
93   @retval EFI_LOAD_ERROR    A load error occured.
94 **/
95 EFI_STATUS
HMemImageInit(VOID)96 HMemImageInit (
97   VOID
98   )
99 {
100   EFI_STATUS  Status;
101 
102   //
103   // basically initialize the HMemImage
104   //
105   CopyMem (&HMemImage, &HMemImageConst, sizeof (HMemImage));
106 
107   Status = gBS->LocateProtocol (
108                 &gEfiPciRootBridgeIoProtocolGuid,
109                 NULL,
110                 (VOID**)&HMemImage.IoFncs
111                 );
112   if (Status == EFI_NOT_FOUND) {
113     //
114     // For NT32, no EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL is available
115     // Use Dummy PciRootBridgeIo for memory access
116     //
117     ZeroMem (&DummyPciRootBridgeIo, sizeof (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL));
118     DummyPciRootBridgeIo.Mem.Read  = DummyMemRead;
119     DummyPciRootBridgeIo.Mem.Write = DummyMemWrite;
120     HMemImage.IoFncs = &DummyPciRootBridgeIo;
121     Status = EFI_SUCCESS;
122   }
123   if (!EFI_ERROR (Status)) {
124     return EFI_SUCCESS;
125   } else {
126     return EFI_LOAD_ERROR;
127   }
128 }
129 
130 /**
131   Backup function for HDiskImage. Only a few fields need to be backup.
132   This is for making the Disk buffer refresh as few as possible.
133 
134   @retval EFI_SUCCESS       The operation was successful.
135 **/
136 EFI_STATUS
HMemImageBackup(VOID)137 HMemImageBackup (
138   VOID
139   )
140 {
141   HMemImageBackupVar.Offset = HMemImage.Offset;
142   HMemImageBackupVar.Size   = HMemImage.Size;
143 
144   return EFI_SUCCESS;
145 }
146 
147 /**
148   Set FileName field in HFileImage.
149 
150   @param[in] Offset   The offset.
151   @param[in] Size     The size.
152 
153   @retval EFI_SUCCESS           The operation was successful.
154   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
155 **/
156 EFI_STATUS
HMemImageSetMemOffsetSize(IN UINTN Offset,IN UINTN Size)157 HMemImageSetMemOffsetSize (
158   IN UINTN Offset,
159   IN UINTN Size
160   )
161 {
162 
163   HMemImage.Offset  = Offset;
164   HMemImage.Size    = Size;
165 
166   return EFI_SUCCESS;
167 }
168 
169 /**
170   Read a disk from disk into HBufferImage.
171 
172   @param[in] Offset   The offset.
173   @param[in] Size     The size.
174   @param[in] Recover  if is for recover, no information print.
175 
176   @retval EFI_LOAD_ERROR        A load error occured.
177   @retval EFI_SUCCESS           The operation was successful.
178   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
179 **/
180 EFI_STATUS
HMemImageRead(IN UINTN Offset,IN UINTN Size,IN BOOLEAN Recover)181 HMemImageRead (
182   IN UINTN     Offset,
183   IN UINTN     Size,
184   IN BOOLEAN   Recover
185   )
186 {
187 
188   EFI_STATUS                      Status;
189   void                            *Buffer;
190   CHAR16                          *Str;
191   HEFI_EDITOR_LINE                *Line;
192 
193   HBufferImage.BufferType = FileTypeMemBuffer;
194 
195   Buffer                  = AllocateZeroPool (Size);
196   if (Buffer == NULL) {
197     StatusBarSetStatusString (L"Read Memory Failed");
198     return EFI_OUT_OF_RESOURCES;
199   }
200 
201   Status = HMemImage.IoFncs->Mem.Read (
202                                   HMemImage.IoFncs,
203                                   EfiPciWidthUint8,
204                                   Offset,
205                                   Size,
206                                   Buffer
207                                   );
208 
209   if (EFI_ERROR (Status)) {
210     FreePool (Buffer);
211     StatusBarSetStatusString (L"Memory Specified Not Accessible");
212     return EFI_LOAD_ERROR;
213   }
214 
215   HBufferImageFree ();
216 
217   Status = HBufferImageBufferToList (Buffer, Size);
218   FreePool (Buffer);
219 
220   if (EFI_ERROR (Status)) {
221     StatusBarSetStatusString (L"Read Memory Failed");
222     return Status;
223   }
224 
225   Status  = HMemImageSetMemOffsetSize (Offset, Size);
226 
227   HBufferImage.DisplayPosition.Row    = 2;
228   HBufferImage.DisplayPosition.Column = 10;
229 
230   HBufferImage.MousePosition.Row      = 2;
231   HBufferImage.MousePosition.Column   = 10;
232 
233   HBufferImage.LowVisibleRow          = 1;
234   HBufferImage.HighBits               = TRUE;
235 
236   HBufferImage.BufferPosition.Row     = 1;
237   HBufferImage.BufferPosition.Column  = 1;
238 
239   if (!Recover) {
240     Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
241     if (Str == NULL) {
242       StatusBarSetStatusString (L"Read Memory Failed");
243       return EFI_OUT_OF_RESOURCES;
244     }
245 
246     StatusBarSetStatusString (Str);
247     SHELL_FREE_NON_NULL (Str);
248 
249     HMainEditor.SelectStart = 0;
250     HMainEditor.SelectEnd   = 0;
251 
252   }
253 
254   //
255   // has line
256   //
257   if (HBufferImage.Lines != NULL) {
258     HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
259   } else {
260     //
261     // create a dummy line
262     //
263     Line = HBufferImageCreateLine ();
264     if (Line == NULL) {
265       StatusBarSetStatusString (L"Read Memory Failed");
266       return EFI_OUT_OF_RESOURCES;
267     }
268 
269     HBufferImage.CurrentLine = Line;
270   }
271 
272   HBufferImage.Modified           = FALSE;
273   HBufferImageNeedRefresh         = TRUE;
274   HBufferImageOnlyLineNeedRefresh = FALSE;
275   HBufferImageMouseNeedRefresh    = TRUE;
276 
277   return EFI_SUCCESS;
278 
279 }
280 
281 /**
282   Save lines in HBufferImage to disk.
283 
284   @param[in] Offset   The offset.
285   @param[in] Size     The size.
286 
287   @retval EFI_LOAD_ERROR        A load error occured.
288   @retval EFI_SUCCESS           The operation was successful.
289   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
290 **/
291 EFI_STATUS
HMemImageSave(IN UINTN Offset,IN UINTN Size)292 HMemImageSave (
293   IN UINTN Offset,
294   IN UINTN Size
295   )
296 {
297 
298   EFI_STATUS                      Status;
299   VOID                            *Buffer;
300 
301   //
302   // not modified, so directly return
303   //
304   if (HBufferImage.Modified == FALSE) {
305     return EFI_SUCCESS;
306   }
307 
308   HBufferImage.BufferType = FileTypeMemBuffer;
309 
310   Buffer                  = AllocateZeroPool (Size);
311 
312   if (Buffer == NULL) {
313     return EFI_OUT_OF_RESOURCES;
314   }
315 
316   Status = HBufferImageListToBuffer (Buffer, Size);
317   if (EFI_ERROR (Status)) {
318     FreePool (Buffer);
319     return Status;
320   }
321   //
322   // write back to memory
323   //
324   Status = HMemImage.IoFncs->Mem.Write (
325                                   HMemImage.IoFncs,
326                                   EfiPciWidthUint8,
327                                   Offset,
328                                   Size,
329                                   Buffer
330                                   );
331 
332   FreePool (Buffer);
333 
334   if (EFI_ERROR (Status)) {
335     return EFI_LOAD_ERROR;
336   }
337   //
338   // now not modified
339   //
340   HBufferImage.Modified = FALSE;
341 
342   return EFI_SUCCESS;
343 }
344 
345 
346