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>
|
Thomas Palmer | 50c6a4d | 2015-10-29 12:59:06 +0000 | [diff] [blame] | 6 | (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 7 |
|
| 8 |
|
hhtian | 60274cc | 2010-04-29 12:40:51 +0000 | [diff] [blame] | 9 | This program and the accompanying materials
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 10 | 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 |
|
| 26 | GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gFvFileType[] = {
|
| 27 | "All",
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 28 | "Bin",
|
| 29 | "section",
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 30 | "SEC",
|
| 31 | "PeiCore",
|
| 32 | "DxeCore",
|
| 33 | "PEIM",
|
| 34 | "Driver",
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 35 | "Combo",
|
| 36 | "App",
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 37 | "NULL",
|
| 38 | "FV"
|
| 39 | };
|
| 40 |
|
| 41 |
|
| 42 | /**
|
| 43 | 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] | 44 | or the FV protocol.
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 45 |
|
| 46 | Argv[0] - "dir"
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 47 | Argv[1] - Device Name:path. Path is optional
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 48 | 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 52 | 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] | 53 | only print out files that contain the string *.efi
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 54 | dir fv1:\ ; perform a dir on fv1: device in the efi directory
|
oliviermartin | 7ca9e5a | 2011-08-08 18:29:14 +0000 | [diff] [blame] | 55 | NOTE: fv devices do not contain subdirs
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 56 | dir fv1:\ * PEIM ; will match all files of type PEIM
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 57 |
|
| 58 | @param Argc Number of command arguments in Argv
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 59 | @param Argv Array of strings that represent the parsed command line.
|
oliviermartin | 7ca9e5a | 2011-08-08 18:29:14 +0000 | [diff] [blame] | 60 | Argv[0] is the command name
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 61 |
|
| 62 | @return EFI_SUCCESS
|
| 63 |
|
| 64 | **/
|
| 65 | EFI_STATUS
|
Thomas Palmer | 50c6a4d | 2015-10-29 12:59:06 +0000 | [diff] [blame] | 66 | EFIAPI
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 67 | EblDirCmd (
|
| 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 76 | UINTN CurrentRow;
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 77 | 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];
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 93 | CHAR8 *Path;
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 94 | CHAR8 *TypeStr;
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 95 | UINTN TotalSize;
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 96 |
|
| 97 |
|
| 98 | if (Argc <= 1) {
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 99 | Path = EfiGetCwd ();
|
| 100 | if (Path == NULL) {
|
| 101 | return EFI_SUCCESS;
|
| 102 | }
|
| 103 | } else {
|
| 104 | Path = Argv[1];
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 105 | }
|
| 106 |
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 107 | File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 108 | 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 |
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 149 | TotalSize = 0;
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 150 | Fv = File->Fv;
|
| 151 | Key = 0;
|
| 152 | CurrentRow = 0;
|
| 153 | do {
|
| 154 | Type = SearchType;
|
| 155 | GetNextFileStatus = Fv->GetNextFile (
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 156 | Fv,
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 157 | &Key,
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 158 | &Type,
|
| 159 | &NameGuid,
|
| 160 | &Attributes,
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 161 | &Size
|
| 162 | );
|
| 163 | if (!EFI_ERROR (GetNextFileStatus)) {
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 164 | TotalSize += Size;
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 165 | // Calculate size of entire file
|
| 166 | Section = NULL;
|
| 167 | Size = 0;
|
| 168 | Status = Fv->ReadFile (
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 169 | Fv,
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 170 | &NameGuid,
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 171 | Section,
|
| 172 | &Size,
|
| 173 | &Type,
|
| 174 | &Attributes,
|
| 175 | &AuthenticationStatus
|
| 176 | );
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 177 | if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 178 | // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 179 | Size = 0;
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 180 | }
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 181 |
|
andrewfish | 3575301 | 2010-02-12 00:12:14 +0000 | [diff] [blame] | 182 | TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 183 |
|
| 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) {
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 197 | AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 198 | if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
|
| 199 | break;
|
| 200 | }
|
| 201 | }
|
| 202 | FreePool (Section);
|
| 203 | } else {
|
| 204 | if (*MatchSubString == '\0') {
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 205 | AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 206 | if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
|
| 207 | break;
|
| 208 | }
|
| 209 | }
|
| 210 | }
|
| 211 | }
|
| 212 | } while (!EFI_ERROR (GetNextFileStatus));
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 213 |
|
andrewfish | 60428d0 | 2010-02-12 20:13:55 +0000 | [diff] [blame] | 214 | if (SearchType == EFI_FV_FILETYPE_ALL) {
|
| 215 | AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);
|
| 216 | }
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 217 |
|
| 218 |
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 219 | } 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 238 | }
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 239 |
|
| 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 252 |
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 253 | // 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 261 |
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 262 | 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 Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 283 |
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 284 | FreePool (DirInfo);
|
| 285 | }
|
| 286 |
|
| 287 | Done:
|
| 288 | if (DirInfo != NULL) {
|
| 289 | FreePool (DirInfo);
|
| 290 | }
|
| 291 | }
|
| 292 |
|
| 293 | EfiClose (File);
|
| 294 |
|
| 295 | return EFI_SUCCESS;
|
| 296 | }
|
| 297 |
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 298 | /**
|
| 299 | Change the Current Working Directory
|
| 300 |
|
| 301 | Argv[0] - "cd"
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 302 | Argv[1] - Device Name:path. Path is optional
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 303 |
|
| 304 | @param Argc Number of command arguments in Argv
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 305 | @param Argv Array of strings that represent the parsed command line.
|
oliviermartin | 7ca9e5a | 2011-08-08 18:29:14 +0000 | [diff] [blame] | 306 | Argv[0] is the command name
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 307 |
|
| 308 | @return EFI_SUCCESS
|
| 309 |
|
| 310 | **/
|
| 311 | EFI_STATUS
|
Thomas Palmer | 50c6a4d | 2015-10-29 12:59:06 +0000 | [diff] [blame] | 312 | EFIAPI
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 313 | EblCdCmd (
|
| 314 | IN UINTN Argc,
|
| 315 | IN CHAR8 **Argv
|
| 316 | )
|
| 317 | {
|
| 318 | if (Argc <= 1) {
|
| 319 | return EFI_SUCCESS;
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 320 | }
|
| 321 |
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 322 | return EfiSetCwd (Argv[1]);
|
| 323 | }
|
| 324 |
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 325 |
|
| 326 |
|
| 327 | GLOBAL_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
|
andrewfish | 16ccac4 | 2010-02-10 00:46:41 +0000 | [diff] [blame] | 334 | },
|
| 335 | {
|
| 336 | "cd",
|
| 337 | " device - set the current working directory",
|
| 338 | NULL,
|
| 339 | EblCdCmd
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 340 | }
|
| 341 | };
|
| 342 |
|
| 343 |
|
| 344 | /**
|
| 345 | Initialize the commands in this in this file
|
| 346 | **/
|
| 347 | VOID
|
| 348 | EblInitializeDirCmd (
|
| 349 | VOID
|
| 350 | )
|
Ronald Cron | 3402aac | 2014-08-19 13:29:52 +0000 | [diff] [blame] | 351 | {
|
AJFISH | 2ef2b01 | 2009-12-06 01:57:05 +0000 | [diff] [blame] | 352 | if (FeaturePcdGet (PcdEmbeddedDirCmd)) {
|
| 353 | EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));
|
| 354 | }
|
| 355 | }
|
| 356 |
|