]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Ebl/Dir.c
MdeModulePkg: Do not dump NULL padding resource descriptor
[mirror_edk2.git] / EmbeddedPkg / Ebl / Dir.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Dir for EBL (Embedded Boot Loader)\r
3\r
60274cca
HT
4 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
2ef2b01e
A
6\r
7\r
60274cca 8 This program and the accompanying materials\r
2ef2b01e
A
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
3575301c 27 "Bin",\r
28 "section",\r
2ef2b01e
A
29 "SEC",\r
30 "PeiCore",\r
31 "DxeCore",\r
32 "PEIM",\r
33 "Driver",\r
3575301c 34 "Combo",\r
35 "App",\r
2ef2b01e
A
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
3402aac7 43 or the FV protocol.\r
2ef2b01e
A
44\r
45 Argv[0] - "dir"\r
3402aac7 46 Argv[1] - Device Name:path. Path is optional\r
2ef2b01e
A
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
3402aac7 51 dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but\r
2ef2b01e 52 only print out files that contain the string *.efi\r
3402aac7 53 dir fv1:\ ; perform a dir on fv1: device in the efi directory\r
7ca9e5a4 54 NOTE: fv devices do not contain subdirs\r
16ccac42 55 dir fv1:\ * PEIM ; will match all files of type PEIM\r
2ef2b01e
A
56\r
57 @param Argc Number of command arguments in Argv\r
3402aac7 58 @param Argv Array of strings that represent the parsed command line.\r
7ca9e5a4 59 Argv[0] is the command name\r
2ef2b01e
A
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
3402aac7 74 UINTN CurrentRow;\r
2ef2b01e
A
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
16ccac42 91 CHAR8 *Path;\r
3575301c 92 CHAR8 *TypeStr;\r
60428d00 93 UINTN TotalSize;\r
2ef2b01e
A
94\r
95\r
96 if (Argc <= 1) {\r
16ccac42 97 Path = EfiGetCwd ();\r
98 if (Path == NULL) {\r
99 return EFI_SUCCESS;\r
100 }\r
101 } else {\r
102 Path = Argv[1];\r
2ef2b01e
A
103 }\r
104\r
16ccac42 105 File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);\r
2ef2b01e
A
106 if (File == NULL) {\r
107 return EFI_SUCCESS;\r
108 }\r
109\r
110 if (File->Type == EfiOpenFirmwareVolume) {\r
111 // FV Dir\r
112\r
113 SearchType = EFI_FV_FILETYPE_ALL;\r
114 UnicodeFileName[0] = '\0';\r
115 MatchSubString = &UnicodeFileName[0];\r
116 if (Argc > 2) {\r
117 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
118 if (UnicodeFileName[0] == '*') {\r
119 // Handle *Name substring matching\r
120 MatchSubString = &UnicodeFileName[1];\r
121 }\r
122\r
123 // Handle file type matchs\r
124 if (Argc > 3) {\r
125 // match a specific file type, always last argument\r
126 Length = AsciiStrLen (Argv[3]);\r
127 for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {\r
128 if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {\r
129 // exact match\r
130 SearchType = Index;\r
131 break;\r
132 }\r
133\r
134 if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {\r
135 // partial match, so keep looking to make sure there is only one partial match\r
136 BestMatchCount++;\r
137 SearchType = Index;\r
138 }\r
139 }\r
140\r
141 if (BestMatchCount > 1) {\r
142 SearchType = EFI_FV_FILETYPE_ALL;\r
143 }\r
144 }\r
145 }\r
146\r
60428d00 147 TotalSize = 0;\r
2ef2b01e
A
148 Fv = File->Fv;\r
149 Key = 0;\r
150 CurrentRow = 0;\r
151 do {\r
152 Type = SearchType;\r
153 GetNextFileStatus = Fv->GetNextFile (\r
3402aac7 154 Fv,\r
2ef2b01e 155 &Key,\r
3402aac7
RC
156 &Type,\r
157 &NameGuid,\r
158 &Attributes,\r
2ef2b01e
A
159 &Size\r
160 );\r
161 if (!EFI_ERROR (GetNextFileStatus)) {\r
60428d00 162 TotalSize += Size;\r
3575301c 163 // Calculate size of entire file\r
164 Section = NULL;\r
165 Size = 0;\r
166 Status = Fv->ReadFile (\r
2ef2b01e 167 Fv,\r
3402aac7 168 &NameGuid,\r
2ef2b01e
A
169 Section,\r
170 &Size,\r
171 &Type,\r
172 &Attributes,\r
173 &AuthenticationStatus\r
174 );\r
3575301c 175 if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {\r
3402aac7 176 // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid\r
60428d00 177 Size = 0;\r
3575301c 178 }\r
3402aac7 179\r
3575301c 180 TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";\r
2ef2b01e
A
181\r
182 // read the UI seciton to do a name match.\r
183 Section = NULL;\r
184 Status = Fv->ReadSection (\r
185 Fv,\r
186 &NameGuid,\r
187 EFI_SECTION_USER_INTERFACE,\r
188 0,\r
189 &Section,\r
190 &SectionSize,\r
191 &AuthenticationStatus\r
192 );\r
193 if (!EFI_ERROR (Status)) {\r
194 if (StrStr (Section, MatchSubString) != NULL) {\r
60428d00 195 AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);\r
2ef2b01e
A
196 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
197 break;\r
198 }\r
199 }\r
200 FreePool (Section);\r
201 } else {\r
202 if (*MatchSubString == '\0') {\r
60428d00 203 AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);\r
2ef2b01e
A
204 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
205 break;\r
206 }\r
207 }\r
208 }\r
209 }\r
210 } while (!EFI_ERROR (GetNextFileStatus));\r
3402aac7 211\r
60428d00 212 if (SearchType == EFI_FV_FILETYPE_ALL) {\r
213 AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);\r
214 }\r
3402aac7
RC
215\r
216\r
2ef2b01e
A
217 } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {\r
218 // Simple File System DIR\r
219\r
220 if (File->FsFileInfo == NULL) {\r
221 return EFI_SUCCESS;\r
222 }\r
223\r
224 if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
225 return EFI_SUCCESS;\r
226 }\r
227\r
228 // Handle *Name substring matching\r
229 MatchSubString = NULL;\r
230 UnicodeFileName[0] = '\0';\r
231 if (Argc > 2) {\r
232 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
233 if (UnicodeFileName[0] == '*') {\r
234 MatchSubString = &UnicodeFileName[1];\r
235 }\r
3402aac7 236 }\r
2ef2b01e
A
237\r
238 File->FsFileHandle->SetPosition (File->FsFileHandle, 0);\r
239 for (CurrentRow = 0;;) {\r
240 // First read gets the size\r
241 DirInfo = NULL;\r
242 ReadSize = 0;\r
243 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
244 if (Status == EFI_BUFFER_TOO_SMALL) {\r
245 // Allocate the buffer for the real read\r
246 DirInfo = AllocatePool (ReadSize);\r
247 if (DirInfo == NULL) {\r
248 goto Done;\r
249 }\r
3402aac7 250\r
2ef2b01e
A
251 // Read the data\r
252 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
253 if ((EFI_ERROR (Status)) || (ReadSize == 0)) {\r
254 break;\r
255 }\r
256 } else {\r
257 break;\r
258 }\r
3402aac7 259\r
2ef2b01e
A
260 if (MatchSubString != NULL) {\r
261 if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {\r
262 // does not match *name argument, so skip\r
263 continue;\r
264 }\r
265 } else if (UnicodeFileName[0] != '\0') {\r
266 // is not an exact match for name argument, so skip\r
267 if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {\r
268 continue;\r
269 }\r
270 }\r
271\r
272 if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {\r
273 AsciiPrint (" <DIR> %s\n", &DirInfo->FileName[0]);\r
274 } else {\r
275 AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);\r
276 }\r
277\r
278 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
279 break;\r
280 }\r
3402aac7 281\r
2ef2b01e
A
282 FreePool (DirInfo);\r
283 }\r
284\r
285Done:\r
286 if (DirInfo != NULL) {\r
287 FreePool (DirInfo);\r
288 }\r
289 }\r
290\r
291 EfiClose (File);\r
292\r
293 return EFI_SUCCESS;\r
294}\r
295\r
16ccac42 296/**\r
297 Change the Current Working Directory\r
298\r
299 Argv[0] - "cd"\r
3402aac7 300 Argv[1] - Device Name:path. Path is optional\r
16ccac42 301\r
302 @param Argc Number of command arguments in Argv\r
3402aac7 303 @param Argv Array of strings that represent the parsed command line.\r
7ca9e5a4 304 Argv[0] is the command name\r
16ccac42 305\r
306 @return EFI_SUCCESS\r
307\r
308**/\r
309EFI_STATUS\r
310EblCdCmd (\r
311 IN UINTN Argc,\r
312 IN CHAR8 **Argv\r
313 )\r
314{\r
315 if (Argc <= 1) {\r
316 return EFI_SUCCESS;\r
3402aac7
RC
317 }\r
318\r
16ccac42 319 return EfiSetCwd (Argv[1]);\r
320}\r
321\r
2ef2b01e
A
322\r
323\r
324GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =\r
325{\r
326 {\r
327 "dir",\r
328 " dirdev [*match]; directory listing of dirdev. opt match a substring",\r
329 NULL,\r
330 EblDirCmd\r
16ccac42 331 },\r
332 {\r
333 "cd",\r
334 " device - set the current working directory",\r
335 NULL,\r
336 EblCdCmd\r
2ef2b01e
A
337 }\r
338};\r
339\r
340\r
341/**\r
342 Initialize the commands in this in this file\r
343**/\r
344VOID\r
345EblInitializeDirCmd (\r
346 VOID\r
347 )\r
3402aac7 348{\r
2ef2b01e
A
349 if (FeaturePcdGet (PcdEmbeddedDirCmd)) {\r
350 EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));\r
351 }\r
352}\r
353\r