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