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 - 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
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.
16 #include "UefiShellLevel2CommandsLib.h"
18 STATIC CONST CHAR16 AllFiles
[] = L
"*";
20 STATIC CONST SHELL_PARAM_ITEM AttribParamList
[] = {
33 Function for 'attrib' command.
35 @param[in] ImageHandle Handle to the Image (NULL if Internal).
36 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
40 ShellCommandRunAttrib (
41 IN EFI_HANDLE ImageHandle
,
42 IN EFI_SYSTEM_TABLE
*SystemTable
45 UINT64 FileAttributesToAdd
;
46 UINT64 FileAttributesToRemove
;
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
;
58 ShellStatus
= SHELL_SUCCESS
;
62 // initialize the shell lib (we must be in non-auto-init...)
64 Status
= ShellInitialize();
65 ASSERT_EFI_ERROR(Status
);
68 // parse the command line
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
;
84 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
87 FileAttributesToAdd
= 0;
88 FileAttributesToRemove
= 0;
91 // apply or remove each flag
93 if (ShellCommandLineGetFlag(Package
, L
"+a")) {
94 FileAttributesToAdd
|= EFI_FILE_ARCHIVE
;
96 if (ShellCommandLineGetFlag(Package
, L
"-a")) {
97 FileAttributesToRemove
|= EFI_FILE_ARCHIVE
;
99 if (ShellCommandLineGetFlag(Package
, L
"+s")) {
100 FileAttributesToAdd
|= EFI_FILE_SYSTEM
;
102 if (ShellCommandLineGetFlag(Package
, L
"-s")) {
103 FileAttributesToRemove
|= EFI_FILE_SYSTEM
;
105 if (ShellCommandLineGetFlag(Package
, L
"+h")) {
106 FileAttributesToAdd
|= EFI_FILE_HIDDEN
;
108 if (ShellCommandLineGetFlag(Package
, L
"-h")) {
109 FileAttributesToRemove
|= EFI_FILE_HIDDEN
;
111 if (ShellCommandLineGetFlag(Package
, L
"+r")) {
112 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
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
) {
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
;
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
)
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
' ',
157 if (ShellGetExecutionBreakFlag()) {
158 ShellStatus
= SHELL_ABORTED
;
162 Status
= ShellCloseFileMetaArg(&ListOfFiles
);
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
;
168 } // for loop for handling wildcard filenames
169 } // for loop for printing out the info
170 } else if ((FileAttributesToRemove
& FileAttributesToAdd
) != 0) {
172 // fail as we have conflcting params.
174 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel2HiiHandle
, L
"attrib");
175 ShellStatus
= SHELL_INVALID_PARAMETER
;
178 // enumerate through all the files/directories and apply the attributes
180 for ( ParamNumberCount
= 1
184 FileName
= ShellCommandLineGetRawValue(Package
, ParamNumberCount
);
185 // if we dont have anything left, move on...
186 if (FileName
== NULL
) {
188 // make sure we are not failing on the first one we do... if yes that's an error...
190 if (ParamNumberCount
== 1) {
191 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"attrib");
192 ShellStatus
= SHELL_INVALID_PARAMETER
;
198 // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory
199 // for each file or directory on the line.
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
;
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
)
216 // skip the directory traversing stuff...
218 if (StrCmp(FileNode
->FileName
, L
".") == 0 || StrCmp(FileNode
->FileName
, L
"..") == 0) {
222 FileInfo
= gEfiShellProtocol
->GetFileInfo(FileNode
->Handle
);
225 // if we are removing Read-Only we need to do that alone
227 if ((FileAttributesToRemove
& EFI_FILE_READ_ONLY
) == EFI_FILE_READ_ONLY
) {
228 FileInfo
->Attribute
&= ~EFI_FILE_READ_ONLY
;
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
;
240 // change the attribute
242 FileInfo
->Attribute
&= ~FileAttributesToRemove
;
243 FileInfo
->Attribute
|= FileAttributesToAdd
;
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
;
254 SHELL_FREE_NON_NULL(FileInfo
);
256 Status
= ShellCloseFileMetaArg(&ListOfFiles
);
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
;
262 } // for loop for handling wildcard filenames
269 // free the command line package
271 ShellCommandLineFreeVarList (Package
);
276 return (ShellStatus
);