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