1 /** @file
2 Main file for attrib shell level 2 function.
3
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "UefiShellLevel2CommandsLib.h"
17
18 STATIC CONST CHAR16 AllFiles[] = L"*";
19
20 STATIC CONST SHELL_PARAM_ITEM AttribParamList[] = {
21 {L"-a", TypeFlag},
22 {L"+a", TypeFlag},
23 {L"-s", TypeFlag},
24 {L"+s", TypeFlag},
25 {L"-h", TypeFlag},
26 {L"+h", TypeFlag},
27 {L"-r", TypeFlag},
28 {L"+r", TypeFlag},
29 {NULL, TypeMax}
30 };
31
32 /**
33 Function for 'attrib' command.
34
35 @param[in] ImageHandle Handle to the Image (NULL if Internal).
36 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
37 **/
38 SHELL_STATUS
39 EFIAPI
ShellCommandRunAttrib(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)40 ShellCommandRunAttrib (
41 IN EFI_HANDLE ImageHandle,
42 IN EFI_SYSTEM_TABLE *SystemTable
43 )
44 {
45 UINT64 FileAttributesToAdd;
46 UINT64 FileAttributesToRemove;
47 EFI_STATUS Status;
48 LIST_ENTRY *Package;
49 CHAR16 *ProblemParam;
50 SHELL_STATUS ShellStatus;
51 UINTN ParamNumberCount;
52 CONST CHAR16 *FileName;
53 EFI_SHELL_FILE_INFO *ListOfFiles;
54 EFI_SHELL_FILE_INFO *FileNode;
55 EFI_FILE_INFO *FileInfo;
56
57 ListOfFiles = NULL;
58 ShellStatus = SHELL_SUCCESS;
59 ProblemParam = NULL;
60
61 //
62 // initialize the shell lib (we must be in non-auto-init...)
63 //
64 Status = ShellInitialize();
65 ASSERT_EFI_ERROR(Status);
66
67 //
68 // parse the command line
69 //
70 Status = ShellCommandLineParse (AttribParamList, &Package, &ProblemParam, TRUE);
71 if (EFI_ERROR(Status)) {
72 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
73 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"attrib", ProblemParam);
74 FreePool(ProblemParam);
75 ShellStatus = SHELL_INVALID_PARAMETER;
76 } else {
77 ASSERT(FALSE);
78 }
79 } else {
80
81 //
82 // check for "-?"
83 //
84 if (ShellCommandLineGetFlag(Package, L"-?")) {
85 ASSERT(FALSE);
86 } else {
87 FileAttributesToAdd = 0;
88 FileAttributesToRemove = 0;
89
90 //
91 // apply or remove each flag
92 //
93 if (ShellCommandLineGetFlag(Package, L"+a")) {
94 FileAttributesToAdd |= EFI_FILE_ARCHIVE;
95 }
96 if (ShellCommandLineGetFlag(Package, L"-a")) {
97 FileAttributesToRemove |= EFI_FILE_ARCHIVE;
98 }
99 if (ShellCommandLineGetFlag(Package, L"+s")) {
100 FileAttributesToAdd |= EFI_FILE_SYSTEM;
101 }
102 if (ShellCommandLineGetFlag(Package, L"-s")) {
103 FileAttributesToRemove |= EFI_FILE_SYSTEM;
104 }
105 if (ShellCommandLineGetFlag(Package, L"+h")) {
106 FileAttributesToAdd |= EFI_FILE_HIDDEN;
107 }
108 if (ShellCommandLineGetFlag(Package, L"-h")) {
109 FileAttributesToRemove |= EFI_FILE_HIDDEN;
110 }
111 if (ShellCommandLineGetFlag(Package, L"+r")) {
112 FileAttributesToAdd |= EFI_FILE_READ_ONLY;
113 }
114 if (ShellCommandLineGetFlag(Package, L"-r")) {
115 FileAttributesToRemove |= EFI_FILE_READ_ONLY;
116 }
117
118 if (FileAttributesToRemove == 0 && FileAttributesToAdd == 0) {
119 //
120 // Do display as we have no attributes to change
121 //
122 for ( ParamNumberCount = 1
123 ;
124 ; ParamNumberCount++
125 ){
126 FileName = ShellCommandLineGetRawValue(Package, ParamNumberCount);
127 // if we dont have anything left, move on...
128 if (FileName == NULL && ParamNumberCount == 1) {
129 FileName = (CHAR16*)AllFiles;
130 } else if (FileName == NULL) {
131 break;
132 }
133 ASSERT(ListOfFiles == NULL);
134 Status = ShellOpenFileMetaArg((CHAR16*)FileName, EFI_FILE_MODE_READ, &ListOfFiles);
135 if (EFI_ERROR(Status)) {
136 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
137 ShellStatus = SHELL_NOT_FOUND;
138 } else {
139 for (FileNode = (EFI_SHELL_FILE_INFO*)GetFirstNode(&ListOfFiles->Link)
140 ; !IsNull(&ListOfFiles->Link, &FileNode->Link)
141 ; FileNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ListOfFiles->Link, &FileNode->Link)
142 ){
143 ShellPrintHiiEx(
144 -1,
145 -1,
146 NULL,
147 STRING_TOKEN (STR_ATTRIB_OUTPUT_LINE),
148 gShellLevel2HiiHandle,
149 FileNode->Info->Attribute&EFI_FILE_DIRECTORY? L'D':L' ',
150 FileNode->Info->Attribute&EFI_FILE_ARCHIVE? L'A':L' ',
151 FileNode->Info->Attribute&EFI_FILE_SYSTEM? L'S':L' ',
152 FileNode->Info->Attribute&EFI_FILE_HIDDEN? L'H':L' ',
153 FileNode->Info->Attribute&EFI_FILE_READ_ONLY? L'R':L' ',
154 FileNode->FileName
155 );
156
157 if (ShellGetExecutionBreakFlag()) {
158 ShellStatus = SHELL_ABORTED;
159 break;
160 }
161 }
162 Status = ShellCloseFileMetaArg(&ListOfFiles);
163 ListOfFiles = NULL;
164 if (EFI_ERROR(Status)) {
165 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
166 ShellStatus = SHELL_NOT_FOUND;
167 }
168 } // for loop for handling wildcard filenames
169 } // for loop for printing out the info
170 } else if ((FileAttributesToRemove & FileAttributesToAdd) != 0) {
171 //
172 // fail as we have conflcting params.
173 //
174 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"attrib");
175 ShellStatus = SHELL_INVALID_PARAMETER;
176 } else {
177 //
178 // enumerate through all the files/directories and apply the attributes
179 //
180 for ( ParamNumberCount = 1
181 ;
182 ; ParamNumberCount++
183 ){
184 FileName = ShellCommandLineGetRawValue(Package, ParamNumberCount);
185 // if we dont have anything left, move on...
186 if (FileName == NULL) {
187 //
188 // make sure we are not failing on the first one we do... if yes that's an error...
189 //
190 if (ParamNumberCount == 1) {
191 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"attrib");
192 ShellStatus = SHELL_INVALID_PARAMETER;
193 }
194 break;
195 }
196
197 //
198 // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory
199 // for each file or directory on the line.
200 //
201
202 //
203 // Open the file(s)
204 //
205 ASSERT(ListOfFiles == NULL);
206 Status = ShellOpenFileMetaArg((CHAR16*)FileName, EFI_FILE_MODE_READ, &ListOfFiles);
207 if (EFI_ERROR(Status)) {
208 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
209 ShellStatus = SHELL_NOT_FOUND;
210 } else {
211 for (FileNode = (EFI_SHELL_FILE_INFO*)GetFirstNode(&ListOfFiles->Link)
212 ; !IsNull(&ListOfFiles->Link, &FileNode->Link)
213 ; FileNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ListOfFiles->Link, &FileNode->Link)
214 ){
215 //
216 // skip the directory traversing stuff...
217 //
218 if (StrCmp(FileNode->FileName, L".") == 0 || StrCmp(FileNode->FileName, L"..") == 0) {
219 continue;
220 }
221
222 FileInfo = gEfiShellProtocol->GetFileInfo(FileNode->Handle);
223
224 //
225 // if we are removing Read-Only we need to do that alone
226 //
227 if ((FileAttributesToRemove & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) {
228 FileInfo->Attribute &= ~EFI_FILE_READ_ONLY;
229 //
230 // SetFileInfo
231 //
232 Status = ShellSetFileInfo(FileNode->Handle, FileInfo);
233 if (EFI_ERROR(Status)) {
234 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
235 ShellStatus = SHELL_ACCESS_DENIED;
236 }
237 }
238
239 //
240 // change the attribute
241 //
242 FileInfo->Attribute &= ~FileAttributesToRemove;
243 FileInfo->Attribute |= FileAttributesToAdd;
244
245 //
246 // SetFileInfo
247 //
248 Status = ShellSetFileInfo(FileNode->Handle, FileInfo);
249 if (EFI_ERROR(Status)) {;
250 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
251 ShellStatus = SHELL_ACCESS_DENIED;
252 }
253
254 SHELL_FREE_NON_NULL(FileInfo);
255 }
256 Status = ShellCloseFileMetaArg(&ListOfFiles);
257 ListOfFiles = NULL;
258 if (EFI_ERROR(Status)) {
259 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount));
260 ShellStatus = SHELL_NOT_FOUND;
261 }
262 } // for loop for handling wildcard filenames
263 }
264 }
265 }
266 }
267
268 //
269 // free the command line package
270 //
271 ShellCommandLineFreeVarList (Package);
272
273 //
274 // return the status
275 //
276 return (ShellStatus);
277 }
278