blob: 36095b6330194d47c0e4b599151f0dcb6e21b8d0 [file] [log] [blame]
AJFISH2ef2b012009-12-06 01:57:05 +00001/** @file
2 Dir for EBL (Embedded Boot Loader)
3
hhtian60274cc2010-04-29 12:40:51 +00004 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Thomas Palmer50c6a4d2015-10-29 12:59:06 +00006 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
AJFISH2ef2b012009-12-06 01:57:05 +00007
8
hhtian60274cc2010-04-29 12:40:51 +00009 This program and the accompanying materials
AJFISH2ef2b012009-12-06 01:57:05 +000010 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 Module Name: CmdTemplate.c
18
19 Search/Replace Dir with the name of your new command
20
21**/
22
23#include "Ebl.h"
24
25
26GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gFvFileType[] = {
27 "All",
andrewfish35753012010-02-12 00:12:14 +000028 "Bin",
29 "section",
AJFISH2ef2b012009-12-06 01:57:05 +000030 "SEC",
31 "PeiCore",
32 "DxeCore",
33 "PEIM",
34 "Driver",
andrewfish35753012010-02-12 00:12:14 +000035 "Combo",
36 "App",
AJFISH2ef2b012009-12-06 01:57:05 +000037 "NULL",
38 "FV"
39};
40
41
42/**
43 Perform a dir on a device. The device must support Simple File System Protocol
Ronald Cron3402aac2014-08-19 13:29:52 +000044 or the FV protocol.
AJFISH2ef2b012009-12-06 01:57:05 +000045
46 Argv[0] - "dir"
Ronald Cron3402aac2014-08-19 13:29:52 +000047 Argv[1] - Device Name:path. Path is optional
AJFISH2ef2b012009-12-06 01:57:05 +000048 Argv[2] - Optional filename to match on. A leading * means match substring
49 Argv[3] - Optional FV file type
50
51 dir fs1:\efi ; perform a dir on fs1: device in the efi directory
Ronald Cron3402aac2014-08-19 13:29:52 +000052 dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but
AJFISH2ef2b012009-12-06 01:57:05 +000053 only print out files that contain the string *.efi
Ronald Cron3402aac2014-08-19 13:29:52 +000054 dir fv1:\ ; perform a dir on fv1: device in the efi directory
oliviermartin7ca9e5a2011-08-08 18:29:14 +000055 NOTE: fv devices do not contain subdirs
andrewfish16ccac42010-02-10 00:46:41 +000056 dir fv1:\ * PEIM ; will match all files of type PEIM
AJFISH2ef2b012009-12-06 01:57:05 +000057
58 @param Argc Number of command arguments in Argv
Ronald Cron3402aac2014-08-19 13:29:52 +000059 @param Argv Array of strings that represent the parsed command line.
oliviermartin7ca9e5a2011-08-08 18:29:14 +000060 Argv[0] is the command name
AJFISH2ef2b012009-12-06 01:57:05 +000061
62 @return EFI_SUCCESS
63
64**/
65EFI_STATUS
Thomas Palmer50c6a4d2015-10-29 12:59:06 +000066EFIAPI
AJFISH2ef2b012009-12-06 01:57:05 +000067EblDirCmd (
68 IN UINTN Argc,
69 IN CHAR8 **Argv
70 )
71{
72 EFI_STATUS Status;
73 EFI_OPEN_FILE *File;
74 EFI_FILE_INFO *DirInfo;
75 UINTN ReadSize;
Ronald Cron3402aac2014-08-19 13:29:52 +000076 UINTN CurrentRow;
AJFISH2ef2b012009-12-06 01:57:05 +000077 CHAR16 *MatchSubString;
78 EFI_STATUS GetNextFileStatus;
79 UINTN Key;
80 EFI_FV_FILETYPE SearchType;
81 EFI_FV_FILETYPE Type;
82 EFI_FV_FILE_ATTRIBUTES Attributes;
83 UINTN Size;
84 EFI_GUID NameGuid;
85 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
86 UINT32 AuthenticationStatus;
87 VOID *Section;
88 UINTN SectionSize;
89 EFI_FV_FILETYPE Index;
90 UINTN Length;
91 UINTN BestMatchCount;
92 CHAR16 UnicodeFileName[MAX_CMD_LINE];
andrewfish16ccac42010-02-10 00:46:41 +000093 CHAR8 *Path;
andrewfish35753012010-02-12 00:12:14 +000094 CHAR8 *TypeStr;
andrewfish60428d02010-02-12 20:13:55 +000095 UINTN TotalSize;
AJFISH2ef2b012009-12-06 01:57:05 +000096
97
98 if (Argc <= 1) {
andrewfish16ccac42010-02-10 00:46:41 +000099 Path = EfiGetCwd ();
100 if (Path == NULL) {
101 return EFI_SUCCESS;
102 }
103 } else {
104 Path = Argv[1];
AJFISH2ef2b012009-12-06 01:57:05 +0000105 }
106
andrewfish16ccac42010-02-10 00:46:41 +0000107 File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
AJFISH2ef2b012009-12-06 01:57:05 +0000108 if (File == NULL) {
109 return EFI_SUCCESS;
110 }
111
112 if (File->Type == EfiOpenFirmwareVolume) {
113 // FV Dir
114
115 SearchType = EFI_FV_FILETYPE_ALL;
116 UnicodeFileName[0] = '\0';
117 MatchSubString = &UnicodeFileName[0];
118 if (Argc > 2) {
119 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
120 if (UnicodeFileName[0] == '*') {
121 // Handle *Name substring matching
122 MatchSubString = &UnicodeFileName[1];
123 }
124
125 // Handle file type matchs
126 if (Argc > 3) {
127 // match a specific file type, always last argument
128 Length = AsciiStrLen (Argv[3]);
129 for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {
130 if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {
131 // exact match
132 SearchType = Index;
133 break;
134 }
135
136 if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {
137 // partial match, so keep looking to make sure there is only one partial match
138 BestMatchCount++;
139 SearchType = Index;
140 }
141 }
142
143 if (BestMatchCount > 1) {
144 SearchType = EFI_FV_FILETYPE_ALL;
145 }
146 }
147 }
148
andrewfish60428d02010-02-12 20:13:55 +0000149 TotalSize = 0;
AJFISH2ef2b012009-12-06 01:57:05 +0000150 Fv = File->Fv;
151 Key = 0;
152 CurrentRow = 0;
153 do {
154 Type = SearchType;
155 GetNextFileStatus = Fv->GetNextFile (
Ronald Cron3402aac2014-08-19 13:29:52 +0000156 Fv,
AJFISH2ef2b012009-12-06 01:57:05 +0000157 &Key,
Ronald Cron3402aac2014-08-19 13:29:52 +0000158 &Type,
159 &NameGuid,
160 &Attributes,
AJFISH2ef2b012009-12-06 01:57:05 +0000161 &Size
162 );
163 if (!EFI_ERROR (GetNextFileStatus)) {
andrewfish60428d02010-02-12 20:13:55 +0000164 TotalSize += Size;
andrewfish35753012010-02-12 00:12:14 +0000165 // Calculate size of entire file
166 Section = NULL;
167 Size = 0;
168 Status = Fv->ReadFile (
AJFISH2ef2b012009-12-06 01:57:05 +0000169 Fv,
Ronald Cron3402aac2014-08-19 13:29:52 +0000170 &NameGuid,
AJFISH2ef2b012009-12-06 01:57:05 +0000171 Section,
172 &Size,
173 &Type,
174 &Attributes,
175 &AuthenticationStatus
176 );
andrewfish35753012010-02-12 00:12:14 +0000177 if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {
Ronald Cron3402aac2014-08-19 13:29:52 +0000178 // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid
andrewfish60428d02010-02-12 20:13:55 +0000179 Size = 0;
andrewfish35753012010-02-12 00:12:14 +0000180 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000181
andrewfish35753012010-02-12 00:12:14 +0000182 TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";
AJFISH2ef2b012009-12-06 01:57:05 +0000183
184 // read the UI seciton to do a name match.
185 Section = NULL;
186 Status = Fv->ReadSection (
187 Fv,
188 &NameGuid,
189 EFI_SECTION_USER_INTERFACE,
190 0,
191 &Section,
192 &SectionSize,
193 &AuthenticationStatus
194 );
195 if (!EFI_ERROR (Status)) {
196 if (StrStr (Section, MatchSubString) != NULL) {
andrewfish60428d02010-02-12 20:13:55 +0000197 AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);
AJFISH2ef2b012009-12-06 01:57:05 +0000198 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
199 break;
200 }
201 }
202 FreePool (Section);
203 } else {
204 if (*MatchSubString == '\0') {
andrewfish60428d02010-02-12 20:13:55 +0000205 AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);
AJFISH2ef2b012009-12-06 01:57:05 +0000206 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
207 break;
208 }
209 }
210 }
211 }
212 } while (!EFI_ERROR (GetNextFileStatus));
Ronald Cron3402aac2014-08-19 13:29:52 +0000213
andrewfish60428d02010-02-12 20:13:55 +0000214 if (SearchType == EFI_FV_FILETYPE_ALL) {
215 AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);
216 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000217
218
AJFISH2ef2b012009-12-06 01:57:05 +0000219 } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {
220 // Simple File System DIR
221
222 if (File->FsFileInfo == NULL) {
223 return EFI_SUCCESS;
224 }
225
226 if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
227 return EFI_SUCCESS;
228 }
229
230 // Handle *Name substring matching
231 MatchSubString = NULL;
232 UnicodeFileName[0] = '\0';
233 if (Argc > 2) {
234 AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
235 if (UnicodeFileName[0] == '*') {
236 MatchSubString = &UnicodeFileName[1];
237 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000238 }
AJFISH2ef2b012009-12-06 01:57:05 +0000239
240 File->FsFileHandle->SetPosition (File->FsFileHandle, 0);
241 for (CurrentRow = 0;;) {
242 // First read gets the size
243 DirInfo = NULL;
244 ReadSize = 0;
245 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
246 if (Status == EFI_BUFFER_TOO_SMALL) {
247 // Allocate the buffer for the real read
248 DirInfo = AllocatePool (ReadSize);
249 if (DirInfo == NULL) {
250 goto Done;
251 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000252
AJFISH2ef2b012009-12-06 01:57:05 +0000253 // Read the data
254 Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
255 if ((EFI_ERROR (Status)) || (ReadSize == 0)) {
256 break;
257 }
258 } else {
259 break;
260 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000261
AJFISH2ef2b012009-12-06 01:57:05 +0000262 if (MatchSubString != NULL) {
263 if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {
264 // does not match *name argument, so skip
265 continue;
266 }
267 } else if (UnicodeFileName[0] != '\0') {
268 // is not an exact match for name argument, so skip
269 if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {
270 continue;
271 }
272 }
273
274 if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {
275 AsciiPrint (" <DIR> %s\n", &DirInfo->FileName[0]);
276 } else {
277 AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);
278 }
279
280 if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
281 break;
282 }
Ronald Cron3402aac2014-08-19 13:29:52 +0000283
AJFISH2ef2b012009-12-06 01:57:05 +0000284 FreePool (DirInfo);
285 }
286
287Done:
288 if (DirInfo != NULL) {
289 FreePool (DirInfo);
290 }
291 }
292
293 EfiClose (File);
294
295 return EFI_SUCCESS;
296}
297
andrewfish16ccac42010-02-10 00:46:41 +0000298/**
299 Change the Current Working Directory
300
301 Argv[0] - "cd"
Ronald Cron3402aac2014-08-19 13:29:52 +0000302 Argv[1] - Device Name:path. Path is optional
andrewfish16ccac42010-02-10 00:46:41 +0000303
304 @param Argc Number of command arguments in Argv
Ronald Cron3402aac2014-08-19 13:29:52 +0000305 @param Argv Array of strings that represent the parsed command line.
oliviermartin7ca9e5a2011-08-08 18:29:14 +0000306 Argv[0] is the command name
andrewfish16ccac42010-02-10 00:46:41 +0000307
308 @return EFI_SUCCESS
309
310**/
311EFI_STATUS
Thomas Palmer50c6a4d2015-10-29 12:59:06 +0000312EFIAPI
andrewfish16ccac42010-02-10 00:46:41 +0000313EblCdCmd (
314 IN UINTN Argc,
315 IN CHAR8 **Argv
316 )
317{
318 if (Argc <= 1) {
319 return EFI_SUCCESS;
Ronald Cron3402aac2014-08-19 13:29:52 +0000320 }
321
andrewfish16ccac42010-02-10 00:46:41 +0000322 return EfiSetCwd (Argv[1]);
323}
324
AJFISH2ef2b012009-12-06 01:57:05 +0000325
326
327GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =
328{
329 {
330 "dir",
331 " dirdev [*match]; directory listing of dirdev. opt match a substring",
332 NULL,
333 EblDirCmd
andrewfish16ccac42010-02-10 00:46:41 +0000334 },
335 {
336 "cd",
337 " device - set the current working directory",
338 NULL,
339 EblCdCmd
AJFISH2ef2b012009-12-06 01:57:05 +0000340 }
341};
342
343
344/**
345 Initialize the commands in this in this file
346**/
347VOID
348EblInitializeDirCmd (
349 VOID
350 )
Ronald Cron3402aac2014-08-19 13:29:52 +0000351{
AJFISH2ef2b012009-12-06 01:57:05 +0000352 if (FeaturePcdGet (PcdEmbeddedDirCmd)) {
353 EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));
354 }
355}
356