1 /** @file 2 Main file for vol shell level 2 function. 3 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2011 - 2015, 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 #include <Guid/FileSystemInfo.h> 18 #include <Guid/FileSystemVolumeLabelInfo.h> 19 20 /** 21 Print the info or change the volume info. 22 23 @param[in] Path String with starting path. 24 @param[in] Delete TRUE to delete the volume label. FALSE otherwise. 25 @param[in] Name New name to set to the volume label. 26 27 @retval SHELL_SUCCESS The operation was sucessful. 28 **/ 29 SHELL_STATUS 30 EFIAPI 31 HandleVol( 32 IN CONST CHAR16 *Path, 33 IN CONST BOOLEAN Delete, 34 IN CONST CHAR16 *Name OPTIONAL 35 ) 36 { 37 EFI_STATUS Status; 38 SHELL_STATUS ShellStatus; 39 EFI_FILE_SYSTEM_INFO *SysInfo; 40 UINTN SysInfoSize; 41 SHELL_FILE_HANDLE ShellFileHandle; 42 EFI_FILE_PROTOCOL *EfiFpHandle; 43 UINTN Size1; 44 UINTN Size2; 45 46 ShellStatus = SHELL_SUCCESS; 47 48 if ( 49 Name != NULL && ( 50 StrStr(Name, L"%") != NULL || 51 StrStr(Name, L"^") != NULL || 52 StrStr(Name, L"*") != NULL || 53 StrStr(Name, L"+") != NULL || 54 StrStr(Name, L"=") != NULL || 55 StrStr(Name, L"[") != NULL || 56 StrStr(Name, L"]") != NULL || 57 StrStr(Name, L"|") != NULL || 58 StrStr(Name, L":") != NULL || 59 StrStr(Name, L";") != NULL || 60 StrStr(Name, L"\"") != NULL || 61 StrStr(Name, L"<") != NULL || 62 StrStr(Name, L">") != NULL || 63 StrStr(Name, L"?") != NULL || 64 StrStr(Name, L"/") != NULL || 65 StrStr(Name, L" ") != NULL ) 66 ){ 67 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"vol", Name); 68 return (SHELL_INVALID_PARAMETER); 69 } 70 71 Status = gEfiShellProtocol->OpenFileByName( 72 Path, 73 &ShellFileHandle, 74 Name != NULL?EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE:EFI_FILE_MODE_READ); 75 76 if (EFI_ERROR(Status) || ShellFileHandle == NULL) { 77 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"vol", Path); 78 return (SHELL_ACCESS_DENIED); 79 } 80 81 // 82 // Get the Volume Info from ShellFileHandle 83 // 84 SysInfo = NULL; 85 SysInfoSize = 0; 86 EfiFpHandle = ConvertShellHandleToEfiFileProtocol(ShellFileHandle); 87 Status = EfiFpHandle->GetInfo( 88 EfiFpHandle, 89 &gEfiFileSystemInfoGuid, 90 &SysInfoSize, 91 SysInfo); 92 93 if (Status == EFI_BUFFER_TOO_SMALL) { 94 SysInfo = AllocateZeroPool(SysInfoSize); 95 Status = EfiFpHandle->GetInfo( 96 EfiFpHandle, 97 &gEfiFileSystemInfoGuid, 98 &SysInfoSize, 99 SysInfo); 100 } 101 102 ASSERT(SysInfo != NULL); 103 104 if (Delete) { 105 *((CHAR16 *) SysInfo->VolumeLabel) = CHAR_NULL; 106 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(SysInfo->VolumeLabel); 107 Status = EfiFpHandle->SetInfo( 108 EfiFpHandle, 109 &gEfiFileSystemInfoGuid, 110 (UINTN)SysInfo->Size, 111 SysInfo); 112 } else if (Name != NULL) { 113 Size1 = StrSize(Name); 114 Size2 = StrSize(SysInfo->VolumeLabel); 115 if (Size1 > Size2) { 116 SysInfo = ReallocatePool((UINTN)SysInfo->Size, (UINTN)SysInfo->Size + Size1 - Size2, SysInfo); 117 if (SysInfo == NULL) { 118 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"vol"); 119 ShellStatus = SHELL_OUT_OF_RESOURCES; 120 } 121 } 122 if (SysInfo != NULL) { 123 StrCpyS ( (CHAR16 *) SysInfo->VolumeLabel, 124 (Size1>Size2? Size1/sizeof(CHAR16) : Size2/sizeof(CHAR16)), 125 Name 126 ); 127 SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + Size1; 128 Status = EfiFpHandle->SetInfo( 129 EfiFpHandle, 130 &gEfiFileSystemInfoGuid, 131 (UINTN)SysInfo->Size, 132 SysInfo); 133 } 134 } 135 136 FreePool(SysInfo); 137 138 if (Delete || Name != NULL) { 139 if (EFI_ERROR(Status)) { 140 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"vol", Path); 141 ShellStatus = SHELL_ACCESS_DENIED; 142 } 143 } 144 145 SysInfoSize = 0; 146 SysInfo = NULL; 147 148 Status = EfiFpHandle->GetInfo( 149 EfiFpHandle, 150 &gEfiFileSystemInfoGuid, 151 &SysInfoSize, 152 SysInfo); 153 154 if (Status == EFI_BUFFER_TOO_SMALL) { 155 SysInfo = AllocateZeroPool(SysInfoSize); 156 Status = EfiFpHandle->GetInfo( 157 EfiFpHandle, 158 &gEfiFileSystemInfoGuid, 159 &SysInfoSize, 160 SysInfo); 161 } 162 163 gEfiShellProtocol->CloseFile(ShellFileHandle); 164 165 ASSERT(SysInfo != NULL); 166 167 if (SysInfo != NULL) { 168 // 169 // print VolumeInfo table 170 // 171 ShellPrintHiiEx ( 172 0, 173 gST->ConOut->Mode->CursorRow, 174 NULL, 175 STRING_TOKEN (STR_VOL_VOLINFO), 176 gShellLevel2HiiHandle, 177 SysInfo->VolumeLabel, 178 SysInfo->ReadOnly?L"r":L"rw", 179 SysInfo->VolumeSize, 180 SysInfo->FreeSpace, 181 SysInfo->BlockSize 182 ); 183 SHELL_FREE_NON_NULL(SysInfo); 184 } 185 186 return (ShellStatus); 187 } 188 189 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 190 {L"-d", TypeFlag}, 191 {L"-n", TypeValue}, 192 {NULL, TypeMax} 193 }; 194 195 /** 196 Function for 'Vol' command. 197 198 @param[in] ImageHandle Handle to the Image (NULL if Internal). 199 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 200 **/ 201 SHELL_STATUS 202 EFIAPI 203 ShellCommandRunVol ( 204 IN EFI_HANDLE ImageHandle, 205 IN EFI_SYSTEM_TABLE *SystemTable 206 ) 207 { 208 EFI_STATUS Status; 209 LIST_ENTRY *Package; 210 CHAR16 *ProblemParam; 211 SHELL_STATUS ShellStatus; 212 CONST CHAR16 *PathName; 213 CONST CHAR16 *CurDir; 214 BOOLEAN DeleteMode; 215 CHAR16 *FullPath; 216 CHAR16 *TempSpot; 217 UINTN Length; 218 CONST CHAR16 *NewName; 219 220 Length = 0; 221 ProblemParam = NULL; 222 ShellStatus = SHELL_SUCCESS; 223 PathName = NULL; 224 CurDir = NULL; 225 FullPath = NULL; 226 227 // 228 // initialize the shell lib (we must be in non-auto-init...) 229 // 230 Status = ShellInitialize(); 231 ASSERT_EFI_ERROR(Status); 232 233 // 234 // Fix local copies of the protocol pointers 235 // 236 Status = CommandInit(); 237 ASSERT_EFI_ERROR(Status); 238 239 // 240 // parse the command line 241 // 242 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 243 if (EFI_ERROR(Status)) { 244 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 245 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"vol", ProblemParam); 246 FreePool(ProblemParam); 247 ShellStatus = SHELL_INVALID_PARAMETER; 248 } else { 249 ASSERT(FALSE); 250 } 251 } else { 252 // 253 // check for "-?" 254 // 255 if (ShellCommandLineGetFlag(Package, L"-?")) { 256 ASSERT(FALSE); 257 } 258 259 if (ShellCommandLineGetCount(Package) > 2) { 260 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"vol"); 261 ShellStatus = SHELL_INVALID_PARAMETER; 262 } else { 263 PathName = ShellCommandLineGetRawValue(Package, 1); 264 if (PathName == NULL) { 265 CurDir = gEfiShellProtocol->GetCurDir(NULL); 266 if (CurDir == NULL) { 267 ShellStatus = SHELL_NOT_FOUND; 268 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"vol"); 269 } else { 270 PathName = CurDir; 271 } 272 } 273 if (PathName != NULL) { 274 TempSpot = StrStr(PathName, L":"); 275 if (TempSpot != NULL) { 276 *TempSpot = CHAR_NULL; 277 } 278 TempSpot = StrStr(PathName, L"\\"); 279 if (TempSpot != NULL) { 280 *TempSpot = CHAR_NULL; 281 } 282 StrnCatGrow(&FullPath, &Length, PathName, 0); 283 StrnCatGrow(&FullPath, &Length, L":\\", 0); 284 DeleteMode = ShellCommandLineGetFlag(Package, L"-d"); 285 NewName = ShellCommandLineGetValue(Package, L"-n"); 286 if (DeleteMode && ShellCommandLineGetFlag(Package, L"-n")) { 287 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellLevel2HiiHandle, L"vol", L"-d", L"-n"); 288 ShellStatus = SHELL_INVALID_PARAMETER; 289 } else if (ShellCommandLineGetFlag(Package, L"-n") && NewName == NULL) { 290 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"vol", L"-n"); 291 ShellStatus = SHELL_INVALID_PARAMETER; 292 } else if (NewName != NULL && StrLen(NewName) > 11) { 293 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"vol", NewName, L"-n"); 294 ShellStatus = SHELL_INVALID_PARAMETER; 295 } else if (ShellStatus == SHELL_SUCCESS) { 296 ShellStatus = HandleVol( 297 FullPath, 298 DeleteMode, 299 NewName 300 ); 301 } 302 } 303 } 304 } 305 306 SHELL_FREE_NON_NULL(FullPath); 307 308 // 309 // free the command line package 310 // 311 ShellCommandLineFreeVarList (Package); 312 313 return (ShellStatus); 314 } 315