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 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