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