]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Ebl/Dir.c
Updated to support passing PE/COFF and LZMA decompress up via HOBS. Currently turned...
[mirror_edk2.git] / EmbeddedPkg / Ebl / Dir.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Dir for EBL (Embedded Boot Loader)\r
3\r
4 Copyright (c) 2007, Intel Corporation<BR>\r
5 Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
6\r
7\r
8 All rights reserved. This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16 Module Name: CmdTemplate.c\r
17\r
18 Search/Replace Dir with the name of your new command\r
19\r
20**/\r
21\r
22#include "Ebl.h"\r
23\r
24\r
25GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gFvFileType[] = {\r
26 "All",\r
27 "Raw",\r
28 "Freeform",\r
29 "SEC",\r
30 "PeiCore",\r
31 "DxeCore",\r
32 "PEIM",\r
33 "Driver",\r
34 "Combo Driver",\r
35 "Application",\r
36 "NULL",\r
37 "FV"\r
38};\r
39\r
40\r
41/**\r
42 Perform a dir on a device. The device must support Simple File System Protocol\r
43 or the FV protocol. \r
44\r
45 Argv[0] - "dir"\r
46 Argv[1] - Device Name:path. Path is optional \r
47 Argv[2] - Optional filename to match on. A leading * means match substring\r
48 Argv[3] - Optional FV file type\r
49\r
50 dir fs1:\efi ; perform a dir on fs1: device in the efi directory\r
51 dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but \r
52 only print out files that contain the string *.efi\r
53 dir fv1:\ ; perform a dir on fv1: device in the efi directory \r
54 NOTE: fv devices do not contian subdirs \r
55 dir fv1:\ * PEIM ; will match all files of type SEC\r
56\r
57 @param Argc Number of command arguments in Argv\r
58 @param Argv Array of strings that represent the parsed command line. \r
59 Argv[0] is the comamnd name\r
60\r
61 @return EFI_SUCCESS\r
62\r
63**/\r
64EFI_STATUS\r
65EblDirCmd (\r
66 IN UINTN Argc,\r
67 IN CHAR8 **Argv\r
68 )\r
69{\r
70 EFI_STATUS Status;\r
71 EFI_OPEN_FILE *File;\r
72 EFI_FILE_INFO *DirInfo;\r
73 UINTN ReadSize;\r
74 UINTN CurrentRow; \r
75 CHAR16 *MatchSubString;\r
76 EFI_STATUS GetNextFileStatus;\r
77 UINTN Key;\r
78 EFI_FV_FILETYPE SearchType;\r
79 EFI_FV_FILETYPE Type;\r
80 EFI_FV_FILE_ATTRIBUTES Attributes;\r
81 UINTN Size;\r
82 EFI_GUID NameGuid;\r
83 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
84 UINT32 AuthenticationStatus;\r
85 VOID *Section;\r
86 UINTN SectionSize;\r
87 EFI_FV_FILETYPE Index;\r
88 UINTN Length;\r
89 UINTN BestMatchCount;\r
90 CHAR16 UnicodeFileName[MAX_CMD_LINE];\r
91\r
92\r
93 if (Argc <= 1) {\r
94 // CWD not currently supported \r
95 return EFI_SUCCESS;\r
96 }\r
97\r
98 File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);\r
99 if (File == NULL) {\r
100 return EFI_SUCCESS;\r
101 }\r
102\r
103 if (File->Type == EfiOpenFirmwareVolume) {\r
104 // FV Dir\r
105\r
106 SearchType = EFI_FV_FILETYPE_ALL;\r
107 UnicodeFileName[0] = '\0';\r
108 MatchSubString = &UnicodeFileName[0];\r
109 if (Argc > 2) {\r
110 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
111 if (UnicodeFileName[0] == '*') {\r
112 // Handle *Name substring matching\r
113 MatchSubString = &UnicodeFileName[1];\r
114 }\r
115\r
116 // Handle file type matchs\r
117 if (Argc > 3) {\r
118 // match a specific file type, always last argument\r
119 Length = AsciiStrLen (Argv[3]);\r
120 for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {\r
121 if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {\r
122 // exact match\r
123 SearchType = Index;\r
124 break;\r
125 }\r
126\r
127 if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {\r
128 // partial match, so keep looking to make sure there is only one partial match\r
129 BestMatchCount++;\r
130 SearchType = Index;\r
131 }\r
132 }\r
133\r
134 if (BestMatchCount > 1) {\r
135 SearchType = EFI_FV_FILETYPE_ALL;\r
136 }\r
137 }\r
138 }\r
139\r
140 Fv = File->Fv;\r
141 Key = 0;\r
142 CurrentRow = 0;\r
143 do {\r
144 Type = SearchType;\r
145 GetNextFileStatus = Fv->GetNextFile (\r
146 Fv, \r
147 &Key,\r
148 &Type, \r
149 &NameGuid, \r
150 &Attributes, \r
151 &Size\r
152 );\r
153 if (!EFI_ERROR (GetNextFileStatus)) {\r
154 // Calculate size of entire file\r
155 Section = NULL;\r
156 Size = 0;\r
157 Status = Fv->ReadFile (\r
158 Fv,\r
159 &NameGuid, \r
160 Section,\r
161 &Size,\r
162 &Type,\r
163 &Attributes,\r
164 &AuthenticationStatus\r
165 );\r
166 if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {\r
167 // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid \r
168 Size = 0;\r
169 }\r
170\r
171 // read the UI seciton to do a name match.\r
172 Section = NULL;\r
173 Status = Fv->ReadSection (\r
174 Fv,\r
175 &NameGuid,\r
176 EFI_SECTION_USER_INTERFACE,\r
177 0,\r
178 &Section,\r
179 &SectionSize,\r
180 &AuthenticationStatus\r
181 );\r
182 if (!EFI_ERROR (Status)) {\r
183 if (StrStr (Section, MatchSubString) != NULL) {\r
184 AsciiPrint (" %g %s %a %,d\n", &NameGuid, Section, gFvFileType[Type], Size);\r
185 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
186 break;\r
187 }\r
188 }\r
189 FreePool (Section);\r
190 } else {\r
191 if (*MatchSubString == '\0') {\r
192 AsciiPrint (" %g %a %,d\n", &NameGuid, gFvFileType[Type], Size);\r
193 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
194 break;\r
195 }\r
196 }\r
197 }\r
198 }\r
199 } while (!EFI_ERROR (GetNextFileStatus));\r
200 \r
201 } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {\r
202 // Simple File System DIR\r
203\r
204 if (File->FsFileInfo == NULL) {\r
205 return EFI_SUCCESS;\r
206 }\r
207\r
208 if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
209 return EFI_SUCCESS;\r
210 }\r
211\r
212 // Handle *Name substring matching\r
213 MatchSubString = NULL;\r
214 UnicodeFileName[0] = '\0';\r
215 if (Argc > 2) {\r
216 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
217 if (UnicodeFileName[0] == '*') {\r
218 MatchSubString = &UnicodeFileName[1];\r
219 }\r
220 } \r
221\r
222 File->FsFileHandle->SetPosition (File->FsFileHandle, 0);\r
223 for (CurrentRow = 0;;) {\r
224 // First read gets the size\r
225 DirInfo = NULL;\r
226 ReadSize = 0;\r
227 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
228 if (Status == EFI_BUFFER_TOO_SMALL) {\r
229 // Allocate the buffer for the real read\r
230 DirInfo = AllocatePool (ReadSize);\r
231 if (DirInfo == NULL) {\r
232 goto Done;\r
233 }\r
234 \r
235 // Read the data\r
236 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
237 if ((EFI_ERROR (Status)) || (ReadSize == 0)) {\r
238 break;\r
239 }\r
240 } else {\r
241 break;\r
242 }\r
243 \r
244 if (MatchSubString != NULL) {\r
245 if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {\r
246 // does not match *name argument, so skip\r
247 continue;\r
248 }\r
249 } else if (UnicodeFileName[0] != '\0') {\r
250 // is not an exact match for name argument, so skip\r
251 if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {\r
252 continue;\r
253 }\r
254 }\r
255\r
256 if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {\r
257 AsciiPrint (" <DIR> %s\n", &DirInfo->FileName[0]);\r
258 } else {\r
259 AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);\r
260 }\r
261\r
262 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
263 break;\r
264 }\r
265 \r
266 FreePool (DirInfo);\r
267 }\r
268\r
269Done:\r
270 if (DirInfo != NULL) {\r
271 FreePool (DirInfo);\r
272 }\r
273 }\r
274\r
275 EfiClose (File);\r
276\r
277 return EFI_SUCCESS;\r
278}\r
279\r
280\r
281\r
282GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =\r
283{\r
284 {\r
285 "dir",\r
286 " dirdev [*match]; directory listing of dirdev. opt match a substring",\r
287 NULL,\r
288 EblDirCmd\r
289 }\r
290};\r
291\r
292\r
293/**\r
294 Initialize the commands in this in this file\r
295**/\r
296VOID\r
297EblInitializeDirCmd (\r
298 VOID\r
299 )\r
300{ \r
301 if (FeaturePcdGet (PcdEmbeddedDirCmd)) {\r
302 EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));\r
303 }\r
304}\r
305\r