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