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