• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 
13 **/
14 
15 #include "Edb.h"
16 
17 /**
18   Read a file.
19 
20   @param  Vol             - File System Volume
21   @param  FileName        - The file to be read.
22   @param  BufferSize      - The file buffer size
23   @param  Buffer          - The file buffer
24 
25   @retval EFI_SUCCESS    - read file successfully
26   @retval EFI_NOT_FOUND  - file not found
27 
28 **/
29 EFI_STATUS
30 EFIAPI
ReadFileFromVol(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * Vol,IN CHAR16 * FileName,OUT UINTN * BufferSize,OUT VOID ** Buffer)31 ReadFileFromVol (
32   IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol,
33   IN  CHAR16                      *FileName,
34   OUT UINTN                       *BufferSize,
35   OUT VOID                        **Buffer
36   )
37 {
38   EFI_STATUS                        Status;
39   EFI_FILE_HANDLE                   RootDir;
40   EFI_FILE_HANDLE                   Handle;
41   UINTN                             FileInfoSize;
42   EFI_FILE_INFO                     *FileInfo;
43   UINTN                             TempBufferSize;
44   VOID                              *TempBuffer;
45 
46   //
47   // Open the root directory
48   //
49   Status = Vol->OpenVolume (Vol, &RootDir);
50   if (EFI_ERROR (Status)) {
51     return Status;
52   }
53 
54   //
55   // Open the file
56   //
57   Status = RootDir->Open (
58                       RootDir,
59                       &Handle,
60                       FileName,
61                       EFI_FILE_MODE_READ,
62                       0
63                       );
64   if (EFI_ERROR (Status)) {
65     RootDir->Close (RootDir);
66     return Status;
67   }
68 
69   RootDir->Close (RootDir);
70 
71   //
72   // Get the file information
73   //
74   FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;
75 
76   FileInfo = AllocateZeroPool (FileInfoSize);
77   if (FileInfo == NULL) {
78     Handle->Close (Handle);
79     return Status;
80   }
81 
82   Status = Handle->GetInfo (
83                      Handle,
84                      &gEfiFileInfoGuid,
85                      &FileInfoSize,
86                      FileInfo
87                      );
88   if (EFI_ERROR (Status)) {
89     Handle->Close (Handle);
90     gBS->FreePool (FileInfo);
91     return Status;
92   }
93 
94   //
95   // Allocate buffer for the file data. The last CHAR16 is for L'\0'
96   //
97   TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);
98   TempBuffer = AllocateZeroPool (TempBufferSize);
99   if (TempBuffer == NULL) {
100     Handle->Close (Handle);
101     gBS->FreePool (FileInfo);
102     return Status;
103   }
104 
105   gBS->FreePool (FileInfo);
106 
107   //
108   // Read the file data to the buffer
109   //
110   Status = Handle->Read (
111                      Handle,
112                      &TempBufferSize,
113                      TempBuffer
114                      );
115   if (EFI_ERROR (Status)) {
116     Handle->Close (Handle);
117     gBS->FreePool (TempBuffer);
118     return Status;
119   }
120 
121   Handle->Close (Handle);
122 
123   *BufferSize = TempBufferSize;
124   *Buffer     = TempBuffer;
125   return EFI_SUCCESS;
126 }
127 
128 /**
129 
130   Read a file.
131   If ScanFs is FLASE, it will use DebuggerPrivate->Vol as default Fs.
132   If ScanFs is TRUE, it will scan all FS and check the file.
133   If there is only one file match the name, it will be read.
134   If there is more than one file match the name, it will return Error.
135 
136   @param  DebuggerPrivate - EBC Debugger private data structure
137   @param  FileName        - The file to be read.
138   @param  BufferSize      - The file buffer size
139   @param  Buffer          - The file buffer
140   @param  ScanFs          - Need Scan all FS
141 
142   @retval EFI_SUCCESS    - read file successfully
143   @retval EFI_NOT_FOUND  - file not found
144   @retval EFI_NO_MAPPING - there is duplicated files found
145 
146 **/
147 EFI_STATUS
148 EFIAPI
ReadFileToBuffer(IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN CHAR16 * FileName,OUT UINTN * BufferSize,OUT VOID ** Buffer,IN BOOLEAN ScanFs)149 ReadFileToBuffer (
150   IN  EFI_DEBUGGER_PRIVATE_DATA   *DebuggerPrivate,
151   IN  CHAR16                      *FileName,
152   OUT UINTN                       *BufferSize,
153   OUT VOID                        **Buffer,
154   IN  BOOLEAN                     ScanFs
155   )
156 {
157   EFI_STATUS                        Status;
158   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
159   UINTN                             TempBufferSize;
160   VOID                              *TempBuffer;
161   UINTN                             NoHandles;
162   EFI_HANDLE                        *HandleBuffer;
163   UINTN                             Index;
164 
165   //
166   // Check parameters
167   //
168   if ((FileName == NULL) || (Buffer == NULL)) {
169     return EFI_INVALID_PARAMETER;
170   }
171 
172   //
173   // not scan fs
174   //
175   if (!ScanFs) {
176     if (DebuggerPrivate->Vol == NULL) {
177       return EFI_INVALID_PARAMETER;
178     }
179     //
180     // Read file directly from Vol
181     //
182     return ReadFileFromVol (DebuggerPrivate->Vol, FileName, BufferSize, Buffer);
183   }
184 
185   //
186   // need scan fs
187   //
188 
189   //
190   // Get all Vol handle
191   //
192   Status = gBS->LocateHandleBuffer (
193                    ByProtocol,
194                    &gEfiSimpleFileSystemProtocolGuid,
195                    NULL,
196                    &NoHandles,
197                    &HandleBuffer
198                    );
199   if (EFI_ERROR (Status) && (NoHandles == 0)) {
200     return EFI_NOT_FOUND;
201   }
202 
203   //
204   // Walk through each Vol
205   //
206   DebuggerPrivate->Vol = NULL;
207   *BufferSize = 0;
208   *Buffer     = NULL;
209   for (Index = 0; Index < NoHandles; Index++) {
210     Status = gBS->HandleProtocol (
211                     HandleBuffer[Index],
212                     &gEfiSimpleFileSystemProtocolGuid,
213                     (VOID**) &Vol
214                     );
215     if (EFI_ERROR(Status)) {
216       continue;
217     }
218 
219     Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);
220     if (!EFI_ERROR (Status)) {
221       //
222       // Read file OK, check duplication
223       //
224       if (DebuggerPrivate->Vol != NULL) {
225         //
226         // Find the duplicated file
227         //
228         gBS->FreePool (TempBuffer);
229         gBS->FreePool (*Buffer);
230         EDBPrint (L"Duplicated FileName found!\n");
231         return EFI_NO_MAPPING;
232       } else {
233         //
234         // Record value
235         //
236         DebuggerPrivate->Vol = Vol;
237         *BufferSize = TempBufferSize;
238         *Buffer     = TempBuffer;
239       }
240     }
241   }
242 
243   //
244   // Scan Fs done
245   //
246   if (DebuggerPrivate->Vol == NULL) {
247     return EFI_NOT_FOUND;
248   }
249 
250   //
251   // Done
252   //
253   return EFI_SUCCESS;
254 }
255 
256 /**
257 
258   Get file name under this dir with index
259 
260   @param  DebuggerPrivate - EBC Debugger private data structure
261   @param  DirName         - The dir to be read.
262   @param  FileName        - The file name pattern under this dir
263   @param  Index           - The file index under this dir
264 
265   @return File Name which match the pattern and index.
266 
267 **/
268 CHAR16 *
269 EFIAPI
GetFileNameUnderDir(IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN CHAR16 * DirName,IN CHAR16 * FileName,IN OUT UINTN * Index)270 GetFileNameUnderDir (
271   IN  EFI_DEBUGGER_PRIVATE_DATA   *DebuggerPrivate,
272   IN  CHAR16                      *DirName,
273   IN  CHAR16                      *FileName,
274   IN OUT UINTN                    *Index
275   )
276 {
277   EFI_STATUS                        Status;
278   EFI_FILE_HANDLE                   RootDir;
279   EFI_FILE_HANDLE                   Handle;
280   UINTN                             FileInfoSize;
281   EFI_FILE_INFO                     *FileInfo;
282   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
283   VOID                              *TempName;
284   UINTN                             FileIndex;
285 
286   if (DebuggerPrivate->Vol == NULL) {
287     Status = gBS->LocateProtocol (
288                     &gEfiSimpleFileSystemProtocolGuid,
289                     NULL,
290                     (VOID**) &DebuggerPrivate->Vol
291                     );
292     if (EFI_ERROR(Status)) {
293       return NULL;
294     }
295   }
296   Vol = DebuggerPrivate->Vol;
297 
298   //
299   // Open the root directory
300   //
301   Status = Vol->OpenVolume (Vol, &RootDir);
302   if (EFI_ERROR (Status)) {
303     return NULL;
304   }
305 
306   //
307   // Open the file
308   //
309   Status = RootDir->Open (
310                       RootDir,
311                       &Handle,
312                       DirName,
313                       EFI_FILE_MODE_READ,
314                       EFI_FILE_DIRECTORY
315                       );
316   if (EFI_ERROR (Status)) {
317     RootDir->Close (RootDir);
318     return NULL;
319   }
320   RootDir->Close (RootDir);
321 
322   //
323   // Set Dir Position
324   //
325   Status = Handle->SetPosition (Handle, 0);
326   if (EFI_ERROR (Status)) {
327     Handle->Close (Handle);
328     return NULL;
329   }
330 
331   //
332   // Get the file information
333   //
334   FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;
335 
336   FileInfo = AllocateZeroPool (FileInfoSize);
337   if (FileInfo == NULL) {
338     Handle->Close (Handle);
339     return NULL;
340   }
341 
342   //
343   // Walk through each file in the directory
344   //
345   FileIndex = 0;
346   TempName = NULL;
347   while (TRUE) {
348     //
349     // Read a file entry
350     //
351     FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;
352 
353     Status = Handle->Read (
354                        Handle,
355                        &FileInfoSize,
356                        FileInfo
357                        );
358     if (EFI_ERROR (Status) || (FileInfoSize == 0)) {
359       break;
360     }
361 
362     if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
363       //
364       // This is a file
365       //
366 
367       //
368       // Only deal with the EFI key file
369       //
370       if (!StrEndWith (FileInfo->FileName, FileName)) {
371         continue;
372       }
373 
374       if (FileIndex == *Index) {
375         TempName = StrDuplicate (FileInfo->FileName);
376         *Index = *Index + 1;
377         break;
378       }
379       FileIndex ++;
380     }
381   }
382 
383   //
384   // Free resources
385   //
386   gBS->FreePool (FileInfo);
387   Handle->Close (Handle);
388 
389   return TempName;
390 }
391