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