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