• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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