2 Main file for attrib shell level 2 function.
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel2CommandsLib.h"
12 STATIC CONST CHAR16 AllFiles
[] = L
"*";
14 STATIC CONST SHELL_PARAM_ITEM AttribParamList
[] = {
27 Function for 'attrib' command.
29 @param[in] ImageHandle Handle to the Image (NULL if Internal).
30 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
34 ShellCommandRunAttrib (
35 IN EFI_HANDLE ImageHandle
,
36 IN EFI_SYSTEM_TABLE
*SystemTable
39 UINT64 FileAttributesToAdd
;
40 UINT64 FileAttributesToRemove
;
44 SHELL_STATUS ShellStatus
;
45 UINTN ParamNumberCount
;
46 CONST CHAR16
*FileName
;
47 EFI_SHELL_FILE_INFO
*ListOfFiles
;
48 EFI_SHELL_FILE_INFO
*FileNode
;
49 EFI_FILE_INFO
*FileInfo
;
52 ShellStatus
= SHELL_SUCCESS
;
56 // initialize the shell lib (we must be in non-auto-init...)
58 Status
= ShellInitialize ();
59 ASSERT_EFI_ERROR (Status
);
62 // parse the command line
64 Status
= ShellCommandLineParse (AttribParamList
, &Package
, &ProblemParam
, TRUE
);
65 if (EFI_ERROR (Status
)) {
66 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
67 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"attrib", ProblemParam
);
68 FreePool (ProblemParam
);
69 ShellStatus
= SHELL_INVALID_PARAMETER
;
77 if (ShellCommandLineGetFlag (Package
, L
"-?")) {
80 FileAttributesToAdd
= 0;
81 FileAttributesToRemove
= 0;
84 // apply or remove each flag
86 if (ShellCommandLineGetFlag (Package
, L
"+a")) {
87 FileAttributesToAdd
|= EFI_FILE_ARCHIVE
;
90 if (ShellCommandLineGetFlag (Package
, L
"-a")) {
91 FileAttributesToRemove
|= EFI_FILE_ARCHIVE
;
94 if (ShellCommandLineGetFlag (Package
, L
"+s")) {
95 FileAttributesToAdd
|= EFI_FILE_SYSTEM
;
98 if (ShellCommandLineGetFlag (Package
, L
"-s")) {
99 FileAttributesToRemove
|= EFI_FILE_SYSTEM
;
102 if (ShellCommandLineGetFlag (Package
, L
"+h")) {
103 FileAttributesToAdd
|= EFI_FILE_HIDDEN
;
106 if (ShellCommandLineGetFlag (Package
, L
"-h")) {
107 FileAttributesToRemove
|= EFI_FILE_HIDDEN
;
110 if (ShellCommandLineGetFlag (Package
, L
"+r")) {
111 FileAttributesToAdd
|= EFI_FILE_READ_ONLY
;
114 if (ShellCommandLineGetFlag (Package
, L
"-r")) {
115 FileAttributesToRemove
|= EFI_FILE_READ_ONLY
;
118 if ((FileAttributesToRemove
== 0) && (FileAttributesToAdd
== 0)) {
120 // Do display as we have no attributes to change
122 for ( ParamNumberCount
= 1
127 FileName
= ShellCommandLineGetRawValue (Package
, ParamNumberCount
);
128 // if we dont have anything left, move on...
129 if ((FileName
== NULL
) && (ParamNumberCount
== 1)) {
130 FileName
= (CHAR16
*)AllFiles
;
131 } else if (FileName
== NULL
) {
135 ASSERT (ListOfFiles
== NULL
);
136 Status
= ShellOpenFileMetaArg ((CHAR16
*)FileName
, EFI_FILE_MODE_READ
, &ListOfFiles
);
137 if (EFI_ERROR (Status
)) {
138 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
139 ShellStatus
= SHELL_NOT_FOUND
;
141 for (FileNode
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&ListOfFiles
->Link
)
142 ; !IsNull (&ListOfFiles
->Link
, &FileNode
->Link
)
143 ; FileNode
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&ListOfFiles
->Link
, &FileNode
->Link
)
150 STRING_TOKEN (STR_ATTRIB_OUTPUT_LINE
),
151 gShellLevel2HiiHandle
,
152 FileNode
->Info
->Attribute
&EFI_FILE_DIRECTORY
? L
'D' : L
' ',
153 FileNode
->Info
->Attribute
&EFI_FILE_ARCHIVE
? L
'A' : L
' ',
154 FileNode
->Info
->Attribute
&EFI_FILE_SYSTEM
? L
'S' : L
' ',
155 FileNode
->Info
->Attribute
&EFI_FILE_HIDDEN
? L
'H' : L
' ',
156 FileNode
->Info
->Attribute
&EFI_FILE_READ_ONLY
? L
'R' : L
' ',
160 if (ShellGetExecutionBreakFlag ()) {
161 ShellStatus
= SHELL_ABORTED
;
166 Status
= ShellCloseFileMetaArg (&ListOfFiles
);
168 if (EFI_ERROR (Status
)) {
169 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
170 ShellStatus
= SHELL_NOT_FOUND
;
172 } // for loop for handling wildcard filenames
173 } // for loop for printing out the info
174 } else if ((FileAttributesToRemove
& FileAttributesToAdd
) != 0) {
176 // fail as we have conflcting params.
178 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel2HiiHandle
, L
"attrib");
179 ShellStatus
= SHELL_INVALID_PARAMETER
;
182 // enumerate through all the files/directories and apply the attributes
184 for ( ParamNumberCount
= 1
189 FileName
= ShellCommandLineGetRawValue (Package
, ParamNumberCount
);
190 // if we dont have anything left, move on...
191 if (FileName
== NULL
) {
193 // make sure we are not failing on the first one we do... if yes that's an error...
195 if (ParamNumberCount
== 1) {
196 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"attrib");
197 ShellStatus
= SHELL_INVALID_PARAMETER
;
204 // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory
205 // for each file or directory on the line.
211 ASSERT (ListOfFiles
== NULL
);
212 Status
= ShellOpenFileMetaArg ((CHAR16
*)FileName
, EFI_FILE_MODE_READ
, &ListOfFiles
);
213 if (EFI_ERROR (Status
)) {
214 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
215 ShellStatus
= SHELL_NOT_FOUND
;
217 for (FileNode
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&ListOfFiles
->Link
)
218 ; !IsNull (&ListOfFiles
->Link
, &FileNode
->Link
)
219 ; FileNode
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&ListOfFiles
->Link
, &FileNode
->Link
)
223 // skip the directory traversing stuff...
225 if ((StrCmp (FileNode
->FileName
, L
".") == 0) || (StrCmp (FileNode
->FileName
, L
"..") == 0)) {
229 FileInfo
= gEfiShellProtocol
->GetFileInfo (FileNode
->Handle
);
232 // if we are removing Read-Only we need to do that alone
234 if ((FileAttributesToRemove
& EFI_FILE_READ_ONLY
) == EFI_FILE_READ_ONLY
) {
235 FileInfo
->Attribute
&= ~EFI_FILE_READ_ONLY
;
239 Status
= ShellSetFileInfo (FileNode
->Handle
, FileInfo
);
240 if (EFI_ERROR (Status
)) {
241 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_AD
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
242 ShellStatus
= SHELL_ACCESS_DENIED
;
247 // change the attribute
249 FileInfo
->Attribute
&= ~FileAttributesToRemove
;
250 FileInfo
->Attribute
|= FileAttributesToAdd
;
255 Status
= ShellSetFileInfo (FileNode
->Handle
, FileInfo
);
256 if (EFI_ERROR (Status
)) {
257 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_AD
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
258 ShellStatus
= SHELL_ACCESS_DENIED
;
261 SHELL_FREE_NON_NULL (FileInfo
);
264 Status
= ShellCloseFileMetaArg (&ListOfFiles
);
266 if (EFI_ERROR (Status
)) {
267 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL
), gShellLevel2HiiHandle
, L
"attrib", ShellCommandLineGetRawValue (Package
, ParamNumberCount
));
268 ShellStatus
= SHELL_NOT_FOUND
;
270 } // for loop for handling wildcard filenames
277 // free the command line package
279 ShellCommandLineFreeVarList (Package
);
284 return (ShellStatus
);