diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellLevel2CommandsLib')
18 files changed, 9348 insertions, 9348 deletions
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Attrib.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Attrib.c index 724dc808ae..5515521d8d 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Attrib.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Attrib.c @@ -1,285 +1,285 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-STATIC CONST CHAR16 AllFiles[] = L"*";
-
-STATIC CONST SHELL_PARAM_ITEM AttribParamList[] = {
- { L"-a", TypeFlag },
- { L"+a", TypeFlag },
- { L"-s", TypeFlag },
- { L"+s", TypeFlag },
- { L"-h", TypeFlag },
- { L"+h", TypeFlag },
- { L"-r", TypeFlag },
- { L"+r", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'attrib' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunAttrib (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- UINT64 FileAttributesToAdd;
- UINT64 FileAttributesToRemove;
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINTN ParamNumberCount;
- CONST CHAR16 *FileName;
- EFI_SHELL_FILE_INFO *ListOfFiles;
- EFI_SHELL_FILE_INFO *FileNode;
- EFI_FILE_INFO *FileInfo;
-
- ListOfFiles = NULL;
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (AttribParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"attrib", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else {
- FileAttributesToAdd = 0;
- FileAttributesToRemove = 0;
-
- //
- // apply or remove each flag
- //
- if (ShellCommandLineGetFlag (Package, L"+a")) {
- FileAttributesToAdd |= EFI_FILE_ARCHIVE;
- }
-
- if (ShellCommandLineGetFlag (Package, L"-a")) {
- FileAttributesToRemove |= EFI_FILE_ARCHIVE;
- }
-
- if (ShellCommandLineGetFlag (Package, L"+s")) {
- FileAttributesToAdd |= EFI_FILE_SYSTEM;
- }
-
- if (ShellCommandLineGetFlag (Package, L"-s")) {
- FileAttributesToRemove |= EFI_FILE_SYSTEM;
- }
-
- if (ShellCommandLineGetFlag (Package, L"+h")) {
- FileAttributesToAdd |= EFI_FILE_HIDDEN;
- }
-
- if (ShellCommandLineGetFlag (Package, L"-h")) {
- FileAttributesToRemove |= EFI_FILE_HIDDEN;
- }
-
- if (ShellCommandLineGetFlag (Package, L"+r")) {
- FileAttributesToAdd |= EFI_FILE_READ_ONLY;
- }
-
- if (ShellCommandLineGetFlag (Package, L"-r")) {
- FileAttributesToRemove |= EFI_FILE_READ_ONLY;
- }
-
- if ((FileAttributesToRemove == 0) && (FileAttributesToAdd == 0)) {
- //
- // Do display as we have no attributes to change
- //
- for ( ParamNumberCount = 1
- ;
- ; ParamNumberCount++
- )
- {
- FileName = ShellCommandLineGetRawValue (Package, ParamNumberCount);
- // if we dont have anything left, move on...
- if ((FileName == NULL) && (ParamNumberCount == 1)) {
- FileName = (CHAR16 *)AllFiles;
- } else if (FileName == NULL) {
- break;
- }
-
- ASSERT (ListOfFiles == NULL);
- Status = ShellOpenFileMetaArg ((CHAR16 *)FileName, EFI_FILE_MODE_READ, &ListOfFiles);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- for (FileNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListOfFiles->Link)
- ; !IsNull (&ListOfFiles->Link, &FileNode->Link)
- ; FileNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListOfFiles->Link, &FileNode->Link)
- )
- {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_ATTRIB_OUTPUT_LINE),
- gShellLevel2HiiHandle,
- FileNode->Info->Attribute&EFI_FILE_DIRECTORY ? L'D' : L' ',
- FileNode->Info->Attribute&EFI_FILE_ARCHIVE ? L'A' : L' ',
- FileNode->Info->Attribute&EFI_FILE_SYSTEM ? L'S' : L' ',
- FileNode->Info->Attribute&EFI_FILE_HIDDEN ? L'H' : L' ',
- FileNode->Info->Attribute&EFI_FILE_READ_ONLY ? L'R' : L' ',
- FileNode->FileName
- );
-
- if (ShellGetExecutionBreakFlag ()) {
- ShellStatus = SHELL_ABORTED;
- break;
- }
- }
-
- Status = ShellCloseFileMetaArg (&ListOfFiles);
- ListOfFiles = NULL;
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_NOT_FOUND;
- }
- } // for loop for handling wildcard filenames
- } // for loop for printing out the info
- } else if ((FileAttributesToRemove & FileAttributesToAdd) != 0) {
- //
- // fail as we have conflcting params.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"attrib");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // enumerate through all the files/directories and apply the attributes
- //
- for ( ParamNumberCount = 1
- ;
- ; ParamNumberCount++
- )
- {
- FileName = ShellCommandLineGetRawValue (Package, ParamNumberCount);
- // if we dont have anything left, move on...
- if (FileName == NULL) {
- //
- // make sure we are not failing on the first one we do... if yes that's an error...
- //
- if (ParamNumberCount == 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"attrib");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- break;
- }
-
- //
- // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory
- // for each file or directory on the line.
- //
-
- //
- // Open the file(s)
- //
- ASSERT (ListOfFiles == NULL);
- Status = ShellOpenFileMetaArg ((CHAR16 *)FileName, EFI_FILE_MODE_READ, &ListOfFiles);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- for (FileNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListOfFiles->Link)
- ; !IsNull (&ListOfFiles->Link, &FileNode->Link)
- ; FileNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListOfFiles->Link, &FileNode->Link)
- )
- {
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (FileNode->FileName, L".") == 0) || (StrCmp (FileNode->FileName, L"..") == 0)) {
- continue;
- }
-
- FileInfo = gEfiShellProtocol->GetFileInfo (FileNode->Handle);
-
- //
- // if we are removing Read-Only we need to do that alone
- //
- if ((FileAttributesToRemove & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) {
- FileInfo->Attribute &= ~EFI_FILE_READ_ONLY;
- //
- // SetFileInfo
- //
- Status = ShellSetFileInfo (FileNode->Handle, FileInfo);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_ACCESS_DENIED;
- }
- }
-
- //
- // change the attribute
- //
- FileInfo->Attribute &= ~FileAttributesToRemove;
- FileInfo->Attribute |= FileAttributesToAdd;
-
- //
- // SetFileInfo
- //
- Status = ShellSetFileInfo (FileNode->Handle, FileInfo);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_ACCESS_DENIED;
- }
-
- SHELL_FREE_NON_NULL (FileInfo);
- }
-
- Status = ShellCloseFileMetaArg (&ListOfFiles);
- ListOfFiles = NULL;
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount));
- ShellStatus = SHELL_NOT_FOUND;
- }
- } // for loop for handling wildcard filenames
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- //
- // return the status
- //
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +STATIC CONST CHAR16 AllFiles[] = L"*"; + +STATIC CONST SHELL_PARAM_ITEM AttribParamList[] = { + { L"-a", TypeFlag }, + { L"+a", TypeFlag }, + { L"-s", TypeFlag }, + { L"+s", TypeFlag }, + { L"-h", TypeFlag }, + { L"+h", TypeFlag }, + { L"-r", TypeFlag }, + { L"+r", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'attrib' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunAttrib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT64 FileAttributesToAdd; + UINT64 FileAttributesToRemove; + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINTN ParamNumberCount; + CONST CHAR16 *FileName; + EFI_SHELL_FILE_INFO *ListOfFiles; + EFI_SHELL_FILE_INFO *FileNode; + EFI_FILE_INFO *FileInfo; + + ListOfFiles = NULL; + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (AttribParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"attrib", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else { + FileAttributesToAdd = 0; + FileAttributesToRemove = 0; + + // + // apply or remove each flag + // + if (ShellCommandLineGetFlag (Package, L"+a")) { + FileAttributesToAdd |= EFI_FILE_ARCHIVE; + } + + if (ShellCommandLineGetFlag (Package, L"-a")) { + FileAttributesToRemove |= EFI_FILE_ARCHIVE; + } + + if (ShellCommandLineGetFlag (Package, L"+s")) { + FileAttributesToAdd |= EFI_FILE_SYSTEM; + } + + if (ShellCommandLineGetFlag (Package, L"-s")) { + FileAttributesToRemove |= EFI_FILE_SYSTEM; + } + + if (ShellCommandLineGetFlag (Package, L"+h")) { + FileAttributesToAdd |= EFI_FILE_HIDDEN; + } + + if (ShellCommandLineGetFlag (Package, L"-h")) { + FileAttributesToRemove |= EFI_FILE_HIDDEN; + } + + if (ShellCommandLineGetFlag (Package, L"+r")) { + FileAttributesToAdd |= EFI_FILE_READ_ONLY; + } + + if (ShellCommandLineGetFlag (Package, L"-r")) { + FileAttributesToRemove |= EFI_FILE_READ_ONLY; + } + + if ((FileAttributesToRemove == 0) && (FileAttributesToAdd == 0)) { + // + // Do display as we have no attributes to change + // + for ( ParamNumberCount = 1 + ; + ; ParamNumberCount++ + ) + { + FileName = ShellCommandLineGetRawValue (Package, ParamNumberCount); + // if we dont have anything left, move on... + if ((FileName == NULL) && (ParamNumberCount == 1)) { + FileName = (CHAR16 *)AllFiles; + } else if (FileName == NULL) { + break; + } + + ASSERT (ListOfFiles == NULL); + Status = ShellOpenFileMetaArg ((CHAR16 *)FileName, EFI_FILE_MODE_READ, &ListOfFiles); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_NOT_FOUND; + } else { + for (FileNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListOfFiles->Link) + ; !IsNull (&ListOfFiles->Link, &FileNode->Link) + ; FileNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListOfFiles->Link, &FileNode->Link) + ) + { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_ATTRIB_OUTPUT_LINE), + gShellLevel2HiiHandle, + FileNode->Info->Attribute&EFI_FILE_DIRECTORY ? L'D' : L' ', + FileNode->Info->Attribute&EFI_FILE_ARCHIVE ? L'A' : L' ', + FileNode->Info->Attribute&EFI_FILE_SYSTEM ? L'S' : L' ', + FileNode->Info->Attribute&EFI_FILE_HIDDEN ? L'H' : L' ', + FileNode->Info->Attribute&EFI_FILE_READ_ONLY ? L'R' : L' ', + FileNode->FileName + ); + + if (ShellGetExecutionBreakFlag ()) { + ShellStatus = SHELL_ABORTED; + break; + } + } + + Status = ShellCloseFileMetaArg (&ListOfFiles); + ListOfFiles = NULL; + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_NOT_FOUND; + } + } // for loop for handling wildcard filenames + } // for loop for printing out the info + } else if ((FileAttributesToRemove & FileAttributesToAdd) != 0) { + // + // fail as we have conflcting params. + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"attrib"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // enumerate through all the files/directories and apply the attributes + // + for ( ParamNumberCount = 1 + ; + ; ParamNumberCount++ + ) + { + FileName = ShellCommandLineGetRawValue (Package, ParamNumberCount); + // if we dont have anything left, move on... + if (FileName == NULL) { + // + // make sure we are not failing on the first one we do... if yes that's an error... + // + if (ParamNumberCount == 1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"attrib"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + + break; + } + + // + // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory + // for each file or directory on the line. + // + + // + // Open the file(s) + // + ASSERT (ListOfFiles == NULL); + Status = ShellOpenFileMetaArg ((CHAR16 *)FileName, EFI_FILE_MODE_READ, &ListOfFiles); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_NOT_FOUND; + } else { + for (FileNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListOfFiles->Link) + ; !IsNull (&ListOfFiles->Link, &FileNode->Link) + ; FileNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListOfFiles->Link, &FileNode->Link) + ) + { + // + // skip the directory traversing stuff... + // + if ((StrCmp (FileNode->FileName, L".") == 0) || (StrCmp (FileNode->FileName, L"..") == 0)) { + continue; + } + + FileInfo = gEfiShellProtocol->GetFileInfo (FileNode->Handle); + + // + // if we are removing Read-Only we need to do that alone + // + if ((FileAttributesToRemove & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) { + FileInfo->Attribute &= ~EFI_FILE_READ_ONLY; + // + // SetFileInfo + // + Status = ShellSetFileInfo (FileNode->Handle, FileInfo); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_ACCESS_DENIED; + } + } + + // + // change the attribute + // + FileInfo->Attribute &= ~FileAttributesToRemove; + FileInfo->Attribute |= FileAttributesToAdd; + + // + // SetFileInfo + // + Status = ShellSetFileInfo (FileNode->Handle, FileInfo); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_ACCESS_DENIED; + } + + SHELL_FREE_NON_NULL (FileInfo); + } + + Status = ShellCloseFileMetaArg (&ListOfFiles); + ListOfFiles = NULL; + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue (Package, ParamNumberCount)); + ShellStatus = SHELL_NOT_FOUND; + } + } // for loop for handling wildcard filenames + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + // + // return the status + // + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c index 88791c4428..1fdc9b5da8 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c @@ -1,345 +1,345 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2018, Dell Technologies. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- Function will replace drive identifier with CWD.
-
- If FullPath beginning with ':' is invalid path, then ASSERT.
- If FullPath not include drive identifier , then do nothing.
- If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing.
- If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD.
-
- @param[in, out] FullPath The pointer to the string containing the path.
- @param[in] Cwd Current directory.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_OUT_OF_SOURCES A memory allocation failed.
-**/
-EFI_STATUS
-ReplaceDriveWithCwd (
- IN OUT CHAR16 **FullPath,
- IN CONST CHAR16 *Cwd
- )
-{
- CHAR16 *Splitter;
- CHAR16 *TempBuffer;
- UINTN TotalSize;
-
- Splitter = NULL;
- TempBuffer = NULL;
- TotalSize = 0;
-
- if ((FullPath == NULL) || (*FullPath == NULL)) {
- return EFI_SUCCESS;
- }
-
- Splitter = StrStr (*FullPath, L":");
- ASSERT (Splitter != *FullPath);
-
- if ((Splitter != NULL) && (*(Splitter + 1) != L'\\') && (*(Splitter + 1) != L'/')) {
- TotalSize = StrSize (Cwd) + StrSize (Splitter + 1);
- TempBuffer = AllocateZeroPool (TotalSize);
- if (TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd);
- StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\");
- StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Splitter + 1);
-
- FreePool (*FullPath);
- *FullPath = TempBuffer;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- function to determine if FullPath is under current filesystem.
-
- @param[in] FullPath The target location to determine.
- @param[in] Cwd Current directory.
-
- @retval TRUE The FullPath is in the current filesystem.
- @retval FALSE The FullPaht isn't in the current filesystem.
-**/
-BOOLEAN
-IsCurrentFileSystem (
- IN CONST CHAR16 *FullPath,
- IN CONST CHAR16 *Cwd
- )
-{
- CHAR16 *Splitter1;
- CHAR16 *Splitter2;
-
- Splitter1 = NULL;
- Splitter2 = NULL;
-
- ASSERT (FullPath != NULL);
-
- Splitter1 = StrStr (FullPath, L":");
- if (Splitter1 == NULL) {
- return TRUE;
- }
-
- Splitter2 = StrStr (Cwd, L":");
-
- if (((UINTN)Splitter1 - (UINTN)FullPath) != ((UINTN)Splitter2 - (UINTN)Cwd)) {
- return FALSE;
- } else {
- if (StrniCmp (FullPath, Cwd, ((UINTN)Splitter1 - (UINTN)FullPath) / sizeof (CHAR16)) == 0) {
- return TRUE;
- } else {
- return FALSE;
- }
- }
-}
-
-/**
- Extract drive string and path string from FullPath.
-
- The caller must be free Drive and Path.
-
- @param[in] FullPath A path to be extracted.
- @param[out] Drive Buffer to save drive identifier.
- @param[out] Path Buffer to save path.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_OUT_OF_RESOUCES A memory allocation failed.
-**/
-EFI_STATUS
-ExtractDriveAndPath (
- IN CONST CHAR16 *FullPath,
- OUT CHAR16 **Drive,
- OUT CHAR16 **Path
- )
-{
- CHAR16 *Splitter;
-
- ASSERT (FullPath != NULL);
-
- Splitter = StrStr (FullPath, L":");
-
- if (Splitter == NULL) {
- *Drive = NULL;
- *Path = AllocateCopyPool (StrSize (FullPath), FullPath);
- if (*Path == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- if (*(Splitter + 1) == CHAR_NULL) {
- *Drive = AllocateCopyPool (StrSize (FullPath), FullPath);
- *Path = NULL;
- if (*Drive == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- *Drive = AllocateCopyPool ((Splitter - FullPath + 2) * sizeof (CHAR16), FullPath);
- if (*Drive == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- (*Drive)[Splitter - FullPath + 1] = CHAR_NULL;
-
- *Path = AllocateCopyPool (StrSize (Splitter + 1), Splitter + 1);
- if (*Path == NULL) {
- FreePool (*Drive);
- return EFI_OUT_OF_RESOURCES;
- }
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Function for 'cd' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunCd (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CONST CHAR16 *Cwd;
- CHAR16 *Path;
- CHAR16 *Drive;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- CONST CHAR16 *Param1;
- CHAR16 *Param1Copy;
- CHAR16 *Walker;
- CHAR16 *Splitter;
- CHAR16 *TempBuffer;
- UINTN TotalSize;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- Cwd = NULL;
- Path = NULL;
- Drive = NULL;
- Splitter = NULL;
- TempBuffer = NULL;
- TotalSize = 0;
-
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cd", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- }
-
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // remember that param 0 is the command name
- // If there are 0 value parameters, then print the current directory
- // else If there are 2 value parameters, then print the error message
- // else If there is 1 value paramerer , then change the directory
- //
- Cwd = ShellGetCurrentDir (NULL);
- if (Cwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- Param1 = ShellCommandLineGetRawValue (Package, 1);
- if (Param1 == NULL) {
- //
- // display the current directory
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT), gShellLevel2HiiHandle, Cwd);
- } else {
- Param1Copy = CatSPrint (NULL, L"%s", Param1, NULL);
- for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
- if (*Walker == L'\"') {
- CopyMem (Walker, Walker + 1, StrSize (Walker) - sizeof (Walker[0]));
- }
- }
-
- if ((Param1Copy != NULL) && IsCurrentFileSystem (Param1Copy, Cwd)) {
- Status = ReplaceDriveWithCwd (&Param1Copy, Cwd);
- } else {
- //
- // Can't use cd command to change filesystem.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- Status = EFI_NOT_FOUND;
- }
-
- if (!EFI_ERROR (Status) && (Param1Copy != NULL)) {
- Splitter = StrStr (Cwd, L":");
- if (Param1Copy[0] == L'\\') {
- //
- // Absolute Path on current drive letter.
- //
- TotalSize = ((Splitter - Cwd + 1) * sizeof (CHAR16)) + StrSize (Param1Copy);
- TempBuffer = AllocateZeroPool (TotalSize);
- if (TempBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- StrnCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd, (Splitter - Cwd + 1));
- StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy);
-
- FreePool (Param1Copy);
- Param1Copy = TempBuffer;
- TempBuffer = NULL;
- }
- } else {
- if (StrStr (Param1Copy, L":") == NULL) {
- TotalSize = StrSize (Cwd) + StrSize (Param1Copy);
- TempBuffer = AllocateZeroPool (TotalSize);
- if (TempBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd);
- StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\");
- StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy);
-
- FreePool (Param1Copy);
- Param1Copy = TempBuffer;
- TempBuffer = NULL;
- }
- }
- }
- }
-
- if (!EFI_ERROR (Status)) {
- Param1Copy = PathCleanUpDirectories (Param1Copy);
- Status = ExtractDriveAndPath (Param1Copy, &Drive, &Path);
- }
-
- if (!EFI_ERROR (Status) && (Drive != NULL) && (Path != NULL)) {
- if (EFI_ERROR (ShellIsDirectory (Param1Copy))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Param1Copy);
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- Status = gEfiShellProtocol->SetCurDir (Drive, Path + 1);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy);
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
- }
-
- if (Drive != NULL) {
- FreePool (Drive);
- }
-
- if (Path != NULL) {
- FreePool (Path);
- }
-
- FreePool (Param1Copy);
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- //
- // return the status
- //
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2018, Dell Technologies. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + Function will replace drive identifier with CWD. + + If FullPath beginning with ':' is invalid path, then ASSERT. + If FullPath not include drive identifier , then do nothing. + If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing. + If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD. + + @param[in, out] FullPath The pointer to the string containing the path. + @param[in] Cwd Current directory. + + @retval EFI_SUCCESS Success. + @retval EFI_OUT_OF_SOURCES A memory allocation failed. +**/ +EFI_STATUS +ReplaceDriveWithCwd ( + IN OUT CHAR16 **FullPath, + IN CONST CHAR16 *Cwd + ) +{ + CHAR16 *Splitter; + CHAR16 *TempBuffer; + UINTN TotalSize; + + Splitter = NULL; + TempBuffer = NULL; + TotalSize = 0; + + if ((FullPath == NULL) || (*FullPath == NULL)) { + return EFI_SUCCESS; + } + + Splitter = StrStr (*FullPath, L":"); + ASSERT (Splitter != *FullPath); + + if ((Splitter != NULL) && (*(Splitter + 1) != L'\\') && (*(Splitter + 1) != L'/')) { + TotalSize = StrSize (Cwd) + StrSize (Splitter + 1); + TempBuffer = AllocateZeroPool (TotalSize); + if (TempBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd); + StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\"); + StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Splitter + 1); + + FreePool (*FullPath); + *FullPath = TempBuffer; + } + + return EFI_SUCCESS; +} + +/** + function to determine if FullPath is under current filesystem. + + @param[in] FullPath The target location to determine. + @param[in] Cwd Current directory. + + @retval TRUE The FullPath is in the current filesystem. + @retval FALSE The FullPaht isn't in the current filesystem. +**/ +BOOLEAN +IsCurrentFileSystem ( + IN CONST CHAR16 *FullPath, + IN CONST CHAR16 *Cwd + ) +{ + CHAR16 *Splitter1; + CHAR16 *Splitter2; + + Splitter1 = NULL; + Splitter2 = NULL; + + ASSERT (FullPath != NULL); + + Splitter1 = StrStr (FullPath, L":"); + if (Splitter1 == NULL) { + return TRUE; + } + + Splitter2 = StrStr (Cwd, L":"); + + if (((UINTN)Splitter1 - (UINTN)FullPath) != ((UINTN)Splitter2 - (UINTN)Cwd)) { + return FALSE; + } else { + if (StrniCmp (FullPath, Cwd, ((UINTN)Splitter1 - (UINTN)FullPath) / sizeof (CHAR16)) == 0) { + return TRUE; + } else { + return FALSE; + } + } +} + +/** + Extract drive string and path string from FullPath. + + The caller must be free Drive and Path. + + @param[in] FullPath A path to be extracted. + @param[out] Drive Buffer to save drive identifier. + @param[out] Path Buffer to save path. + + @retval EFI_SUCCESS Success. + @retval EFI_OUT_OF_RESOUCES A memory allocation failed. +**/ +EFI_STATUS +ExtractDriveAndPath ( + IN CONST CHAR16 *FullPath, + OUT CHAR16 **Drive, + OUT CHAR16 **Path + ) +{ + CHAR16 *Splitter; + + ASSERT (FullPath != NULL); + + Splitter = StrStr (FullPath, L":"); + + if (Splitter == NULL) { + *Drive = NULL; + *Path = AllocateCopyPool (StrSize (FullPath), FullPath); + if (*Path == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + if (*(Splitter + 1) == CHAR_NULL) { + *Drive = AllocateCopyPool (StrSize (FullPath), FullPath); + *Path = NULL; + if (*Drive == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + *Drive = AllocateCopyPool ((Splitter - FullPath + 2) * sizeof (CHAR16), FullPath); + if (*Drive == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + (*Drive)[Splitter - FullPath + 1] = CHAR_NULL; + + *Path = AllocateCopyPool (StrSize (Splitter + 1), Splitter + 1); + if (*Path == NULL) { + FreePool (*Drive); + return EFI_OUT_OF_RESOURCES; + } + } + } + + return EFI_SUCCESS; +} + +/** + Function for 'cd' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunCd ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CONST CHAR16 *Cwd; + CHAR16 *Path; + CHAR16 *Drive; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Param1; + CHAR16 *Param1Copy; + CHAR16 *Walker; + CHAR16 *Splitter; + CHAR16 *TempBuffer; + UINTN TotalSize; + + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + Cwd = NULL; + Path = NULL; + Drive = NULL; + Splitter = NULL; + TempBuffer = NULL; + TotalSize = 0; + + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cd", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } + + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"cd"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // remember that param 0 is the command name + // If there are 0 value parameters, then print the current directory + // else If there are 2 value parameters, then print the error message + // else If there is 1 value paramerer , then change the directory + // + Cwd = ShellGetCurrentDir (NULL); + if (Cwd == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd"); + ShellStatus = SHELL_NOT_FOUND; + } else { + Param1 = ShellCommandLineGetRawValue (Package, 1); + if (Param1 == NULL) { + // + // display the current directory + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT), gShellLevel2HiiHandle, Cwd); + } else { + Param1Copy = CatSPrint (NULL, L"%s", Param1, NULL); + for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL; Walker++) { + if (*Walker == L'\"') { + CopyMem (Walker, Walker + 1, StrSize (Walker) - sizeof (Walker[0])); + } + } + + if ((Param1Copy != NULL) && IsCurrentFileSystem (Param1Copy, Cwd)) { + Status = ReplaceDriveWithCwd (&Param1Copy, Cwd); + } else { + // + // Can't use cd command to change filesystem. + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd"); + Status = EFI_NOT_FOUND; + } + + if (!EFI_ERROR (Status) && (Param1Copy != NULL)) { + Splitter = StrStr (Cwd, L":"); + if (Param1Copy[0] == L'\\') { + // + // Absolute Path on current drive letter. + // + TotalSize = ((Splitter - Cwd + 1) * sizeof (CHAR16)) + StrSize (Param1Copy); + TempBuffer = AllocateZeroPool (TotalSize); + if (TempBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + StrnCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd, (Splitter - Cwd + 1)); + StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy); + + FreePool (Param1Copy); + Param1Copy = TempBuffer; + TempBuffer = NULL; + } + } else { + if (StrStr (Param1Copy, L":") == NULL) { + TotalSize = StrSize (Cwd) + StrSize (Param1Copy); + TempBuffer = AllocateZeroPool (TotalSize); + if (TempBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd); + StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\"); + StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy); + + FreePool (Param1Copy); + Param1Copy = TempBuffer; + TempBuffer = NULL; + } + } + } + } + + if (!EFI_ERROR (Status)) { + Param1Copy = PathCleanUpDirectories (Param1Copy); + Status = ExtractDriveAndPath (Param1Copy, &Drive, &Path); + } + + if (!EFI_ERROR (Status) && (Drive != NULL) && (Path != NULL)) { + if (EFI_ERROR (ShellIsDirectory (Param1Copy))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Param1Copy); + ShellStatus = SHELL_NOT_FOUND; + } else { + Status = gEfiShellProtocol->SetCurDir (Drive, Path + 1); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy); + ShellStatus = SHELL_NOT_FOUND; + } + } + } + + if (Drive != NULL) { + FreePool (Drive); + } + + if (Path != NULL) { + FreePool (Path); + } + + FreePool (Param1Copy); + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + // + // return the status + // + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c index c3927ca35b..3dc949b46d 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c @@ -1,799 +1,799 @@ -/** @file
- Main file for cp shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-#include <Guid/FileSystemInfo.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-
-/**
- Function to take a list of files to copy and a destination location and do
- the verification and copying of those files to that location. This function
- will report any errors to the user and halt.
-
- @param[in] FileList A LIST_ENTRY* based list of files to move.
- @param[in] DestDir The destination location.
- @param[in] SilentMode TRUE to eliminate screen output.
- @param[in] RecursiveMode TRUE to copy directories.
- @param[in] Resp The response to the overwrite query (if always).
-
- @retval SHELL_SUCCESS the files were all moved.
- @retval SHELL_INVALID_PARAMETER a parameter was invalid
- @retval SHELL_SECURITY_VIOLATION a security violation ocurred
- @retval SHELL_WRITE_PROTECTED the destination was write protected
- @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
-**/
-SHELL_STATUS
-ValidateAndCopyFiles (
- IN CONST EFI_SHELL_FILE_INFO *FileList,
- IN CONST CHAR16 *DestDir,
- IN BOOLEAN SilentMode,
- IN BOOLEAN RecursiveMode,
- IN VOID **Resp
- );
-
-/**
- Function to Copy one file to another location
-
- If the destination exists the user will be prompted and the result put into *resp
-
- @param[in] Source pointer to source file name
- @param[in] Dest pointer to destination file name
- @param[out] Resp pointer to response from question. Pass back on looped calling
- @param[in] SilentMode whether to run in quiet mode or not
- @param[in] CmdName Source command name requesting single file copy
-
- @retval SHELL_SUCCESS The source file was copied to the destination
-**/
-SHELL_STATUS
-CopySingleFile (
- IN CONST CHAR16 *Source,
- IN CONST CHAR16 *Dest,
- OUT VOID **Resp,
- IN BOOLEAN SilentMode,
- IN CONST CHAR16 *CmdName
- )
-{
- VOID *Response;
- UINTN ReadSize;
- SHELL_FILE_HANDLE SourceHandle;
- SHELL_FILE_HANDLE DestHandle;
- EFI_STATUS Status;
- VOID *Buffer;
- CHAR16 *TempName;
- UINTN Size;
- EFI_SHELL_FILE_INFO *List;
- SHELL_STATUS ShellStatus;
- UINT64 SourceFileSize;
- UINT64 DestFileSize;
- EFI_FILE_PROTOCOL *DestVolumeFP;
- EFI_FILE_SYSTEM_INFO *DestVolumeInfo;
- UINTN DestVolumeInfoSize;
-
- ASSERT (Resp != NULL);
-
- SourceHandle = NULL;
- DestHandle = NULL;
- Response = *Resp;
- List = NULL;
- DestVolumeInfo = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- ReadSize = PcdGet32 (PcdShellFileOperationSize);
- // Why bother copying a file to itself
- if (StrCmp (Source, Dest) == 0) {
- return (SHELL_SUCCESS);
- }
-
- //
- // if the destination file existed check response and possibly prompt user
- //
- if (ShellFileExists (Dest) == EFI_SUCCESS) {
- if ((Response == NULL) && !SilentMode) {
- Status = ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
- }
-
- //
- // possibly return based on response
- //
- if (!SilentMode) {
- if (Response == NULL) {
- return SHELL_ABORTED;
- }
-
- switch (*(SHELL_PROMPT_RESPONSE *)Response) {
- case ShellPromptResponseNo:
- //
- // return success here so we dont stop the process
- //
- return (SHELL_SUCCESS);
- case ShellPromptResponseCancel:
- *Resp = Response;
- //
- // indicate to stop everything
- //
- return (SHELL_ABORTED);
- case ShellPromptResponseAll:
- *Resp = Response;
- case ShellPromptResponseYes:
- break;
- default:
- return SHELL_ABORTED;
- }
- }
- }
-
- if (ShellIsDirectory (Source) == EFI_SUCCESS) {
- Status = ShellCreateDirectory (Dest, &DestHandle);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, CmdName, Dest);
- return (SHELL_ACCESS_DENIED);
- }
-
- //
- // Now copy all the files under the directory...
- //
- TempName = NULL;
- Size = 0;
- StrnCatGrow (&TempName, &Size, Source, 0);
- StrnCatGrow (&TempName, &Size, L"\\*", 0);
- if (TempName != NULL) {
- ShellOpenFileMetaArg ((CHAR16 *)TempName, EFI_FILE_MODE_READ, &List);
- *TempName = CHAR_NULL;
- StrnCatGrow (&TempName, &Size, Dest, 0);
- StrnCatGrow (&TempName, &Size, L"\\", 0);
- ShellStatus = ValidateAndCopyFiles (List, TempName, SilentMode, TRUE, Resp);
- ShellCloseFileMetaArg (&List);
- SHELL_FREE_NON_NULL (TempName);
- Size = 0;
- }
- } else {
- Status = ShellDeleteFileByName (Dest);
-
- //
- // open file with create enabled
- //
- Status = ShellOpenFileByName (Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Dest);
- return (SHELL_ACCESS_DENIED);
- }
-
- //
- // open source file
- //
- Status = ShellOpenFileByName (Source, &SourceHandle, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SRC_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Source);
- return (SHELL_ACCESS_DENIED);
- }
-
- //
- // get file size of source file and freespace available on destination volume
- //
- ShellGetFileSize (SourceHandle, &SourceFileSize);
- ShellGetFileSize (DestHandle, &DestFileSize);
-
- //
- // if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space
- //
- if (DestFileSize < SourceFileSize) {
- SourceFileSize -= DestFileSize;
- } else {
- SourceFileSize = 0;
- }
-
- //
- // get the system volume info to check the free space
- //
- DestVolumeFP = ConvertShellHandleToEfiFileProtocol (DestHandle);
- DestVolumeInfo = NULL;
- DestVolumeInfoSize = 0;
- Status = DestVolumeFP->GetInfo (
- DestVolumeFP,
- &gEfiFileSystemInfoGuid,
- &DestVolumeInfoSize,
- DestVolumeInfo
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- DestVolumeInfo = AllocateZeroPool (DestVolumeInfoSize);
- Status = DestVolumeFP->GetInfo (
- DestVolumeFP,
- &gEfiFileSystemInfoGuid,
- &DestVolumeInfoSize,
- DestVolumeInfo
- );
- }
-
- //
- // check if enough space available on destination drive to complete copy
- //
- if ((DestVolumeInfo != NULL) && (DestVolumeInfo->FreeSpace < SourceFileSize)) {
- //
- // not enough space on destination directory to copy file
- //
- SHELL_FREE_NON_NULL (DestVolumeInfo);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle, CmdName);
- return (SHELL_VOLUME_FULL);
- } else {
- //
- // copy data between files
- //
- Buffer = AllocateZeroPool (ReadSize);
- if (Buffer == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, CmdName);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- while (ReadSize == PcdGet32 (PcdShellFileOperationSize) && !EFI_ERROR (Status)) {
- Status = ShellReadFile (SourceHandle, &ReadSize, Buffer);
- if (!EFI_ERROR (Status)) {
- Status = ShellWriteFile (DestHandle, &ReadSize, Buffer);
- if (EFI_ERROR (Status)) {
- ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, CmdName, Dest);
- break;
- }
- } else {
- ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, CmdName, Source);
- break;
- }
- }
- }
-
- SHELL_FREE_NON_NULL (DestVolumeInfo);
- }
-
- //
- // close files
- //
- if (DestHandle != NULL) {
- ShellCloseFile (&DestHandle);
- DestHandle = NULL;
- }
-
- if (SourceHandle != NULL) {
- ShellCloseFile (&SourceHandle);
- SourceHandle = NULL;
- }
-
- //
- // return
- //
- return ShellStatus;
-}
-
-/**
- function to take a list of files to copy and a destination location and do
- the verification and copying of those files to that location. This function
- will report any errors to the user and halt.
-
- The key is to have this function called ONLY once. this allows for the parameter
- verification to happen correctly.
-
- @param[in] FileList A LIST_ENTRY* based list of files to move.
- @param[in] DestDir The destination location.
- @param[in] SilentMode TRUE to eliminate screen output.
- @param[in] RecursiveMode TRUE to copy directories.
- @param[in] Resp The response to the overwrite query (if always).
-
- @retval SHELL_SUCCESS the files were all moved.
- @retval SHELL_INVALID_PARAMETER a parameter was invalid
- @retval SHELL_SECURITY_VIOLATION a security violation ocurred
- @retval SHELL_WRITE_PROTECTED the destination was write protected
- @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
-**/
-SHELL_STATUS
-ValidateAndCopyFiles (
- IN CONST EFI_SHELL_FILE_INFO *FileList,
- IN CONST CHAR16 *DestDir,
- IN BOOLEAN SilentMode,
- IN BOOLEAN RecursiveMode,
- IN VOID **Resp
- )
-{
- CHAR16 *HiiOutput;
- CHAR16 *HiiResultOk;
- CONST EFI_SHELL_FILE_INFO *Node;
- SHELL_STATUS ShellStatus;
- EFI_STATUS Status;
- CHAR16 *DestPath;
- VOID *Response;
- UINTN PathSize;
- CONST CHAR16 *Cwd;
- UINTN NewSize;
- CHAR16 *CleanFilePathStr;
-
- if (Resp == NULL) {
- Response = NULL;
- } else {
- Response = *Resp;
- }
-
- DestPath = NULL;
- ShellStatus = SHELL_SUCCESS;
- PathSize = 0;
- Cwd = ShellGetCurrentDir (NULL);
- CleanFilePathStr = NULL;
-
- ASSERT (FileList != NULL);
- ASSERT (DestDir != NULL);
-
- Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_OUT_OF_RESOURCES) {
- return SHELL_OUT_OF_RESOURCES;
- } else {
- return SHELL_INVALID_PARAMETER;
- }
- }
-
- ASSERT (CleanFilePathStr != NULL);
-
- //
- // If we are trying to copy multiple files... make sure we got a directory for the target...
- //
- if (EFI_ERROR (ShellIsDirectory (CleanFilePathStr)) && (FileList->Link.ForwardLink != FileList->Link.BackLink)) {
- //
- // Error for destination not a directory
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
-
- for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
- ; !IsNull (&FileList->Link, &Node->Link)
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
- )
- {
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) {
- continue;
- }
-
- NewSize = StrSize (CleanFilePathStr);
- NewSize += StrSize (Node->FullName);
- NewSize += (Cwd == NULL) ? 0 : (StrSize (Cwd) + sizeof (CHAR16));
- if (NewSize > PathSize) {
- PathSize = NewSize;
- }
-
- //
- // Make sure got -r if required
- //
- if (!RecursiveMode && !EFI_ERROR (ShellIsDirectory (Node->FullName))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp");
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
-
- //
- // make sure got dest as dir if needed
- //
- if (!EFI_ERROR (ShellIsDirectory (Node->FullName)) && EFI_ERROR (ShellIsDirectory (CleanFilePathStr))) {
- //
- // Error for destination not a directory
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
- }
-
- HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL);
- HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);
- DestPath = AllocateZeroPool (PathSize);
-
- if ((DestPath == NULL) || (HiiOutput == NULL) || (HiiResultOk == NULL)) {
- SHELL_FREE_NON_NULL (DestPath);
- SHELL_FREE_NON_NULL (HiiOutput);
- SHELL_FREE_NON_NULL (HiiResultOk);
- FreePool (CleanFilePathStr);
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- //
- // Go through the list of files to copy...
- //
- for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
- ; !IsNull (&FileList->Link, &Node->Link)
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
- )
- {
- if (ShellGetExecutionBreakFlag ()) {
- break;
- }
-
- ASSERT (Node->FileName != NULL);
- ASSERT (Node->FullName != NULL);
-
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) {
- continue;
- }
-
- if ( (FileList->Link.ForwardLink == FileList->Link.BackLink) // 1 item
- && EFI_ERROR (ShellIsDirectory (CleanFilePathStr)) // not an existing directory
- )
- {
- if (StrStr (CleanFilePathStr, L":") == NULL) {
- //
- // simple copy of a single file
- //
- if (Cwd != NULL) {
- StrCpyS (DestPath, PathSize / sizeof (CHAR16), Cwd);
- StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\");
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
-
- if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) {
- StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\");
- } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) {
- ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
- }
-
- StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
- } else {
- StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
- }
- } else {
- //
- // we have multiple files or a directory in the DestDir
- //
-
- //
- // Check for leading slash
- //
- if (CleanFilePathStr[0] == L'\\') {
- //
- // Copy to the root of CWD
- //
- if (Cwd != NULL) {
- StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd);
- StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
-
- while (PathRemoveLastItem (DestPath)) {
- }
-
- StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr+1);
- StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
- } else if (StrStr (CleanFilePathStr, L":") == NULL) {
- if (Cwd != NULL) {
- StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd);
- StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
- FreePool (CleanFilePathStr);
- return (SHELL_INVALID_PARAMETER);
- }
-
- if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) {
- StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
- } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) {
- ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
- }
-
- StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
- if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) {
- StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
- } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) {
- ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
- }
-
- StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
- } else {
- StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
- if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) {
- StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
- } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) {
- ((CHAR16 *)CleanFilePathStr)[StrLen (CleanFilePathStr)-1] = CHAR_NULL;
- }
-
- StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
- }
- }
-
- //
- // Make sure the path exists
- //
- if (EFI_ERROR (VerifyIntermediateDirectories (DestPath))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath);
- ShellStatus = SHELL_DEVICE_ERROR;
- break;
- }
-
- if ( !EFI_ERROR (ShellIsDirectory (Node->FullName))
- && !EFI_ERROR (ShellIsDirectory (DestPath))
- && (StrniCmp (Node->FullName, DestPath, StrLen (DestPath)) == 0)
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- }
-
- if (StringNoCaseCompare (&Node->FullName, &DestPath) == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- }
-
- if ( (StrniCmp (Node->FullName, DestPath, StrLen (Node->FullName)) == 0)
- && ((DestPath[StrLen (Node->FullName)] == CHAR_NULL) || (DestPath[StrLen (Node->FullName)] == L'\\'))
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- }
-
- PathCleanUpDirectories (DestPath);
-
- if (!SilentMode) {
- ShellPrintEx (-1, -1, HiiOutput, Node->FullName, DestPath);
- }
-
- //
- // copy single file...
- //
- ShellStatus = CopySingleFile (Node->FullName, DestPath, &Response, SilentMode, L"cp");
- if (ShellStatus != SHELL_SUCCESS) {
- break;
- }
- }
-
- if ((ShellStatus == SHELL_SUCCESS) && (Resp == NULL)) {
- ShellPrintEx (-1, -1, L"%s", HiiResultOk);
- }
-
- SHELL_FREE_NON_NULL (DestPath);
- SHELL_FREE_NON_NULL (HiiOutput);
- SHELL_FREE_NON_NULL (HiiResultOk);
- SHELL_FREE_NON_NULL (CleanFilePathStr);
- if (Resp == NULL) {
- SHELL_FREE_NON_NULL (Response);
- }
-
- return (ShellStatus);
-}
-
-/**
- Validate and if successful copy all the files from the list into
- destination directory.
-
- @param[in] FileList The list of files to copy.
- @param[in] DestDir The directory to copy files to.
- @param[in] SilentMode TRUE to eliminate screen output.
- @param[in] RecursiveMode TRUE to copy directories.
-
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-ProcessValidateAndCopyFiles (
- IN EFI_SHELL_FILE_INFO *FileList,
- IN CONST CHAR16 *DestDir,
- IN BOOLEAN SilentMode,
- IN BOOLEAN RecursiveMode
- )
-{
- SHELL_STATUS ShellStatus;
- EFI_SHELL_FILE_INFO *List;
- EFI_FILE_INFO *FileInfo;
- CHAR16 *FullName;
-
- List = NULL;
- FullName = NULL;
- FileInfo = NULL;
-
- ShellOpenFileMetaArg ((CHAR16 *)DestDir, EFI_FILE_MODE_READ, &List);
- if ((List != NULL) && (List->Link.ForwardLink != List->Link.BackLink)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"cp", DestDir);
- ShellStatus = SHELL_INVALID_PARAMETER;
- ShellCloseFileMetaArg (&List);
- } else if (List != NULL) {
- ASSERT (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL);
- ASSERT (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL);
- FileInfo = gEfiShellProtocol->GetFileInfo (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle);
- ASSERT (FileInfo != NULL);
- StrnCatGrow (&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0);
- ShellCloseFileMetaArg (&List);
- if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) {
- ShellStatus = ValidateAndCopyFiles (FileList, FullName, SilentMode, RecursiveMode, NULL);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_ACCESS_DENIED;
- }
- } else {
- ShellCloseFileMetaArg (&List);
- ShellStatus = ValidateAndCopyFiles (FileList, DestDir, SilentMode, RecursiveMode, NULL);
- }
-
- SHELL_FREE_NON_NULL (FileInfo);
- SHELL_FREE_NON_NULL (FullName);
- return (ShellStatus);
-}
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-r", TypeFlag },
- { L"-q", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'cp' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunCp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINTN ParamCount;
- UINTN LoopCounter;
- EFI_SHELL_FILE_INFO *FileList;
- BOOLEAN SilentMode;
- BOOLEAN RecursiveMode;
- CONST CHAR16 *Cwd;
- CHAR16 *FullCwd;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- ParamCount = 0;
- FileList = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cp", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- //
- // Initialize SilentMode and RecursiveMode
- //
- if (gEfiShellProtocol->BatchIsActive ()) {
- SilentMode = TRUE;
- } else {
- SilentMode = ShellCommandLineGetFlag (Package, L"-q");
- }
-
- RecursiveMode = ShellCommandLineGetFlag (Package, L"-r");
-
- switch (ParamCount = ShellCommandLineGetCount (Package)) {
- case 0:
- case 1:
- //
- // we have insufficient parameters
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- case 2:
- //
- // must have valid CWD for single parameter...
- //
- Cwd = ShellGetCurrentDir (NULL);
- if (Cwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, 1));
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16));
- if (FullCwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (FullCwd, StrSize (Cwd) / sizeof (CHAR16) + 1, Cwd);
- ShellStatus = ProcessValidateAndCopyFiles (FileList, FullCwd, SilentMode, RecursiveMode);
- FreePool (FullCwd);
- }
- }
- }
-
- break;
- default:
- //
- // Make a big list of all the files...
- //
- for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS; LoopCounter++) {
- if (ShellGetExecutionBreakFlag ()) {
- break;
- }
-
- Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, LoopCounter));
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
-
- if (ShellStatus != SHELL_SUCCESS) {
- Status = ShellCloseFileMetaArg (&FileList);
- } else {
- //
- // now copy them all...
- //
- if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
- ShellStatus = ProcessValidateAndCopyFiles (FileList, PathCleanUpDirectories ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount)), SilentMode, RecursiveMode);
- Status = ShellCloseFileMetaArg (&FileList);
- if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, ParamCount), ShellStatus|MAX_BIT);
- ShellStatus = SHELL_ACCESS_DENIED;
- }
- }
- }
-
- break;
- } // switch on parameter count
-
- if (FileList != NULL) {
- ShellCloseFileMetaArg (&FileList);
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- return (SHELL_ABORTED);
- }
-
- return (ShellStatus);
-}
+/** @file + Main file for cp shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" +#include <Guid/FileSystemInfo.h> +#include <Guid/FileSystemVolumeLabelInfo.h> + +/** + Function to take a list of files to copy and a destination location and do + the verification and copying of those files to that location. This function + will report any errors to the user and halt. + + @param[in] FileList A LIST_ENTRY* based list of files to move. + @param[in] DestDir The destination location. + @param[in] SilentMode TRUE to eliminate screen output. + @param[in] RecursiveMode TRUE to copy directories. + @param[in] Resp The response to the overwrite query (if always). + + @retval SHELL_SUCCESS the files were all moved. + @retval SHELL_INVALID_PARAMETER a parameter was invalid + @retval SHELL_SECURITY_VIOLATION a security violation ocurred + @retval SHELL_WRITE_PROTECTED the destination was write protected + @retval SHELL_OUT_OF_RESOURCES a memory allocation failed +**/ +SHELL_STATUS +ValidateAndCopyFiles ( + IN CONST EFI_SHELL_FILE_INFO *FileList, + IN CONST CHAR16 *DestDir, + IN BOOLEAN SilentMode, + IN BOOLEAN RecursiveMode, + IN VOID **Resp + ); + +/** + Function to Copy one file to another location + + If the destination exists the user will be prompted and the result put into *resp + + @param[in] Source pointer to source file name + @param[in] Dest pointer to destination file name + @param[out] Resp pointer to response from question. Pass back on looped calling + @param[in] SilentMode whether to run in quiet mode or not + @param[in] CmdName Source command name requesting single file copy + + @retval SHELL_SUCCESS The source file was copied to the destination +**/ +SHELL_STATUS +CopySingleFile ( + IN CONST CHAR16 *Source, + IN CONST CHAR16 *Dest, + OUT VOID **Resp, + IN BOOLEAN SilentMode, + IN CONST CHAR16 *CmdName + ) +{ + VOID *Response; + UINTN ReadSize; + SHELL_FILE_HANDLE SourceHandle; + SHELL_FILE_HANDLE DestHandle; + EFI_STATUS Status; + VOID *Buffer; + CHAR16 *TempName; + UINTN Size; + EFI_SHELL_FILE_INFO *List; + SHELL_STATUS ShellStatus; + UINT64 SourceFileSize; + UINT64 DestFileSize; + EFI_FILE_PROTOCOL *DestVolumeFP; + EFI_FILE_SYSTEM_INFO *DestVolumeInfo; + UINTN DestVolumeInfoSize; + + ASSERT (Resp != NULL); + + SourceHandle = NULL; + DestHandle = NULL; + Response = *Resp; + List = NULL; + DestVolumeInfo = NULL; + ShellStatus = SHELL_SUCCESS; + + ReadSize = PcdGet32 (PcdShellFileOperationSize); + // Why bother copying a file to itself + if (StrCmp (Source, Dest) == 0) { + return (SHELL_SUCCESS); + } + + // + // if the destination file existed check response and possibly prompt user + // + if (ShellFileExists (Dest) == EFI_SUCCESS) { + if ((Response == NULL) && !SilentMode) { + Status = ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); + } + + // + // possibly return based on response + // + if (!SilentMode) { + if (Response == NULL) { + return SHELL_ABORTED; + } + + switch (*(SHELL_PROMPT_RESPONSE *)Response) { + case ShellPromptResponseNo: + // + // return success here so we dont stop the process + // + return (SHELL_SUCCESS); + case ShellPromptResponseCancel: + *Resp = Response; + // + // indicate to stop everything + // + return (SHELL_ABORTED); + case ShellPromptResponseAll: + *Resp = Response; + case ShellPromptResponseYes: + break; + default: + return SHELL_ABORTED; + } + } + } + + if (ShellIsDirectory (Source) == EFI_SUCCESS) { + Status = ShellCreateDirectory (Dest, &DestHandle); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, CmdName, Dest); + return (SHELL_ACCESS_DENIED); + } + + // + // Now copy all the files under the directory... + // + TempName = NULL; + Size = 0; + StrnCatGrow (&TempName, &Size, Source, 0); + StrnCatGrow (&TempName, &Size, L"\\*", 0); + if (TempName != NULL) { + ShellOpenFileMetaArg ((CHAR16 *)TempName, EFI_FILE_MODE_READ, &List); + *TempName = CHAR_NULL; + StrnCatGrow (&TempName, &Size, Dest, 0); + StrnCatGrow (&TempName, &Size, L"\\", 0); + ShellStatus = ValidateAndCopyFiles (List, TempName, SilentMode, TRUE, Resp); + ShellCloseFileMetaArg (&List); + SHELL_FREE_NON_NULL (TempName); + Size = 0; + } + } else { + Status = ShellDeleteFileByName (Dest); + + // + // open file with create enabled + // + Status = ShellOpenFileByName (Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Dest); + return (SHELL_ACCESS_DENIED); + } + + // + // open source file + // + Status = ShellOpenFileByName (Source, &SourceHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SRC_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Source); + return (SHELL_ACCESS_DENIED); + } + + // + // get file size of source file and freespace available on destination volume + // + ShellGetFileSize (SourceHandle, &SourceFileSize); + ShellGetFileSize (DestHandle, &DestFileSize); + + // + // if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space + // + if (DestFileSize < SourceFileSize) { + SourceFileSize -= DestFileSize; + } else { + SourceFileSize = 0; + } + + // + // get the system volume info to check the free space + // + DestVolumeFP = ConvertShellHandleToEfiFileProtocol (DestHandle); + DestVolumeInfo = NULL; + DestVolumeInfoSize = 0; + Status = DestVolumeFP->GetInfo ( + DestVolumeFP, + &gEfiFileSystemInfoGuid, + &DestVolumeInfoSize, + DestVolumeInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + DestVolumeInfo = AllocateZeroPool (DestVolumeInfoSize); + Status = DestVolumeFP->GetInfo ( + DestVolumeFP, + &gEfiFileSystemInfoGuid, + &DestVolumeInfoSize, + DestVolumeInfo + ); + } + + // + // check if enough space available on destination drive to complete copy + // + if ((DestVolumeInfo != NULL) && (DestVolumeInfo->FreeSpace < SourceFileSize)) { + // + // not enough space on destination directory to copy file + // + SHELL_FREE_NON_NULL (DestVolumeInfo); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle, CmdName); + return (SHELL_VOLUME_FULL); + } else { + // + // copy data between files + // + Buffer = AllocateZeroPool (ReadSize); + if (Buffer == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, CmdName); + return SHELL_OUT_OF_RESOURCES; + } + + while (ReadSize == PcdGet32 (PcdShellFileOperationSize) && !EFI_ERROR (Status)) { + Status = ShellReadFile (SourceHandle, &ReadSize, Buffer); + if (!EFI_ERROR (Status)) { + Status = ShellWriteFile (DestHandle, &ReadSize, Buffer); + if (EFI_ERROR (Status)) { + ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT)); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, CmdName, Dest); + break; + } + } else { + ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT)); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, CmdName, Source); + break; + } + } + } + + SHELL_FREE_NON_NULL (DestVolumeInfo); + } + + // + // close files + // + if (DestHandle != NULL) { + ShellCloseFile (&DestHandle); + DestHandle = NULL; + } + + if (SourceHandle != NULL) { + ShellCloseFile (&SourceHandle); + SourceHandle = NULL; + } + + // + // return + // + return ShellStatus; +} + +/** + function to take a list of files to copy and a destination location and do + the verification and copying of those files to that location. This function + will report any errors to the user and halt. + + The key is to have this function called ONLY once. this allows for the parameter + verification to happen correctly. + + @param[in] FileList A LIST_ENTRY* based list of files to move. + @param[in] DestDir The destination location. + @param[in] SilentMode TRUE to eliminate screen output. + @param[in] RecursiveMode TRUE to copy directories. + @param[in] Resp The response to the overwrite query (if always). + + @retval SHELL_SUCCESS the files were all moved. + @retval SHELL_INVALID_PARAMETER a parameter was invalid + @retval SHELL_SECURITY_VIOLATION a security violation ocurred + @retval SHELL_WRITE_PROTECTED the destination was write protected + @retval SHELL_OUT_OF_RESOURCES a memory allocation failed +**/ +SHELL_STATUS +ValidateAndCopyFiles ( + IN CONST EFI_SHELL_FILE_INFO *FileList, + IN CONST CHAR16 *DestDir, + IN BOOLEAN SilentMode, + IN BOOLEAN RecursiveMode, + IN VOID **Resp + ) +{ + CHAR16 *HiiOutput; + CHAR16 *HiiResultOk; + CONST EFI_SHELL_FILE_INFO *Node; + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + CHAR16 *DestPath; + VOID *Response; + UINTN PathSize; + CONST CHAR16 *Cwd; + UINTN NewSize; + CHAR16 *CleanFilePathStr; + + if (Resp == NULL) { + Response = NULL; + } else { + Response = *Resp; + } + + DestPath = NULL; + ShellStatus = SHELL_SUCCESS; + PathSize = 0; + Cwd = ShellGetCurrentDir (NULL); + CleanFilePathStr = NULL; + + ASSERT (FileList != NULL); + ASSERT (DestDir != NULL); + + Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); + if (EFI_ERROR (Status)) { + if (Status == EFI_OUT_OF_RESOURCES) { + return SHELL_OUT_OF_RESOURCES; + } else { + return SHELL_INVALID_PARAMETER; + } + } + + ASSERT (CleanFilePathStr != NULL); + + // + // If we are trying to copy multiple files... make sure we got a directory for the target... + // + if (EFI_ERROR (ShellIsDirectory (CleanFilePathStr)) && (FileList->Link.ForwardLink != FileList->Link.BackLink)) { + // + // Error for destination not a directory + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + + for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link) + ; !IsNull (&FileList->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link) + ) + { + // + // skip the directory traversing stuff... + // + if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) { + continue; + } + + NewSize = StrSize (CleanFilePathStr); + NewSize += StrSize (Node->FullName); + NewSize += (Cwd == NULL) ? 0 : (StrSize (Cwd) + sizeof (CHAR16)); + if (NewSize > PathSize) { + PathSize = NewSize; + } + + // + // Make sure got -r if required + // + if (!RecursiveMode && !EFI_ERROR (ShellIsDirectory (Node->FullName))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp"); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + + // + // make sure got dest as dir if needed + // + if (!EFI_ERROR (ShellIsDirectory (Node->FullName)) && EFI_ERROR (ShellIsDirectory (CleanFilePathStr))) { + // + // Error for destination not a directory + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + } + + HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL); + HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); + DestPath = AllocateZeroPool (PathSize); + + if ((DestPath == NULL) || (HiiOutput == NULL) || (HiiResultOk == NULL)) { + SHELL_FREE_NON_NULL (DestPath); + SHELL_FREE_NON_NULL (HiiOutput); + SHELL_FREE_NON_NULL (HiiResultOk); + FreePool (CleanFilePathStr); + return (SHELL_OUT_OF_RESOURCES); + } + + // + // Go through the list of files to copy... + // + for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link) + ; !IsNull (&FileList->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link) + ) + { + if (ShellGetExecutionBreakFlag ()) { + break; + } + + ASSERT (Node->FileName != NULL); + ASSERT (Node->FullName != NULL); + + // + // skip the directory traversing stuff... + // + if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) { + continue; + } + + if ( (FileList->Link.ForwardLink == FileList->Link.BackLink) // 1 item + && EFI_ERROR (ShellIsDirectory (CleanFilePathStr)) // not an existing directory + ) + { + if (StrStr (CleanFilePathStr, L":") == NULL) { + // + // simple copy of a single file + // + if (Cwd != NULL) { + StrCpyS (DestPath, PathSize / sizeof (CHAR16), Cwd); + StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\"); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + + if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) { + StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\"); + } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) { + ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL; + } + + StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr); + } else { + StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr); + } + } else { + // + // we have multiple files or a directory in the DestDir + // + + // + // Check for leading slash + // + if (CleanFilePathStr[0] == L'\\') { + // + // Copy to the root of CWD + // + if (Cwd != NULL) { + StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd); + StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\"); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + + while (PathRemoveLastItem (DestPath)) { + } + + StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr+1); + StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName); + } else if (StrStr (CleanFilePathStr, L":") == NULL) { + if (Cwd != NULL) { + StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd); + StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\"); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); + FreePool (CleanFilePathStr); + return (SHELL_INVALID_PARAMETER); + } + + if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) { + StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\"); + } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) { + ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL; + } + + StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr); + if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) { + StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\"); + } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) { + ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL; + } + + StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName); + } else { + StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr); + if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) { + StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\"); + } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) { + ((CHAR16 *)CleanFilePathStr)[StrLen (CleanFilePathStr)-1] = CHAR_NULL; + } + + StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName); + } + } + + // + // Make sure the path exists + // + if (EFI_ERROR (VerifyIntermediateDirectories (DestPath))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath); + ShellStatus = SHELL_DEVICE_ERROR; + break; + } + + if ( !EFI_ERROR (ShellIsDirectory (Node->FullName)) + && !EFI_ERROR (ShellIsDirectory (DestPath)) + && (StrniCmp (Node->FullName, DestPath, StrLen (DestPath)) == 0) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } + + if (StringNoCaseCompare (&Node->FullName, &DestPath) == 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } + + if ( (StrniCmp (Node->FullName, DestPath, StrLen (Node->FullName)) == 0) + && ((DestPath[StrLen (Node->FullName)] == CHAR_NULL) || (DestPath[StrLen (Node->FullName)] == L'\\')) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } + + PathCleanUpDirectories (DestPath); + + if (!SilentMode) { + ShellPrintEx (-1, -1, HiiOutput, Node->FullName, DestPath); + } + + // + // copy single file... + // + ShellStatus = CopySingleFile (Node->FullName, DestPath, &Response, SilentMode, L"cp"); + if (ShellStatus != SHELL_SUCCESS) { + break; + } + } + + if ((ShellStatus == SHELL_SUCCESS) && (Resp == NULL)) { + ShellPrintEx (-1, -1, L"%s", HiiResultOk); + } + + SHELL_FREE_NON_NULL (DestPath); + SHELL_FREE_NON_NULL (HiiOutput); + SHELL_FREE_NON_NULL (HiiResultOk); + SHELL_FREE_NON_NULL (CleanFilePathStr); + if (Resp == NULL) { + SHELL_FREE_NON_NULL (Response); + } + + return (ShellStatus); +} + +/** + Validate and if successful copy all the files from the list into + destination directory. + + @param[in] FileList The list of files to copy. + @param[in] DestDir The directory to copy files to. + @param[in] SilentMode TRUE to eliminate screen output. + @param[in] RecursiveMode TRUE to copy directories. + + @retval SHELL_INVALID_PARAMETER A parameter was invalid. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +ProcessValidateAndCopyFiles ( + IN EFI_SHELL_FILE_INFO *FileList, + IN CONST CHAR16 *DestDir, + IN BOOLEAN SilentMode, + IN BOOLEAN RecursiveMode + ) +{ + SHELL_STATUS ShellStatus; + EFI_SHELL_FILE_INFO *List; + EFI_FILE_INFO *FileInfo; + CHAR16 *FullName; + + List = NULL; + FullName = NULL; + FileInfo = NULL; + + ShellOpenFileMetaArg ((CHAR16 *)DestDir, EFI_FILE_MODE_READ, &List); + if ((List != NULL) && (List->Link.ForwardLink != List->Link.BackLink)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"cp", DestDir); + ShellStatus = SHELL_INVALID_PARAMETER; + ShellCloseFileMetaArg (&List); + } else if (List != NULL) { + ASSERT (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL); + ASSERT (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL); + FileInfo = gEfiShellProtocol->GetFileInfo (((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle); + ASSERT (FileInfo != NULL); + StrnCatGrow (&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0); + ShellCloseFileMetaArg (&List); + if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) { + ShellStatus = ValidateAndCopyFiles (FileList, FullName, SilentMode, RecursiveMode, NULL); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_ACCESS_DENIED; + } + } else { + ShellCloseFileMetaArg (&List); + ShellStatus = ValidateAndCopyFiles (FileList, DestDir, SilentMode, RecursiveMode, NULL); + } + + SHELL_FREE_NON_NULL (FileInfo); + SHELL_FREE_NON_NULL (FullName); + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-r", TypeFlag }, + { L"-q", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'cp' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunCp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINTN ParamCount; + UINTN LoopCounter; + EFI_SHELL_FILE_INFO *FileList; + BOOLEAN SilentMode; + BOOLEAN RecursiveMode; + CONST CHAR16 *Cwd; + CHAR16 *FullCwd; + + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + ParamCount = 0; + FileList = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cp", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + // + // Initialize SilentMode and RecursiveMode + // + if (gEfiShellProtocol->BatchIsActive ()) { + SilentMode = TRUE; + } else { + SilentMode = ShellCommandLineGetFlag (Package, L"-q"); + } + + RecursiveMode = ShellCommandLineGetFlag (Package, L"-r"); + + switch (ParamCount = ShellCommandLineGetCount (Package)) { + case 0: + case 1: + // + // we have insufficient parameters + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + case 2: + // + // must have valid CWD for single parameter... + // + Cwd = ShellGetCurrentDir (NULL); + if (Cwd == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, 1)); + ShellStatus = SHELL_NOT_FOUND; + } else { + FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16)); + if (FullCwd == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + } else { + StrCpyS (FullCwd, StrSize (Cwd) / sizeof (CHAR16) + 1, Cwd); + ShellStatus = ProcessValidateAndCopyFiles (FileList, FullCwd, SilentMode, RecursiveMode); + FreePool (FullCwd); + } + } + } + + break; + default: + // + // Make a big list of all the files... + // + for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS; LoopCounter++) { + if (ShellGetExecutionBreakFlag ()) { + break; + } + + Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, LoopCounter)); + ShellStatus = SHELL_NOT_FOUND; + } + } + + if (ShellStatus != SHELL_SUCCESS) { + Status = ShellCloseFileMetaArg (&FileList); + } else { + // + // now copy them all... + // + if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) { + ShellStatus = ProcessValidateAndCopyFiles (FileList, PathCleanUpDirectories ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount)), SilentMode, RecursiveMode); + Status = ShellCloseFileMetaArg (&FileList); + if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, ParamCount), ShellStatus|MAX_BIT); + ShellStatus = SHELL_ACCESS_DENIED; + } + } + } + + break; + } // switch on parameter count + + if (FileList != NULL) { + ShellCloseFileMetaArg (&FileList); + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + } + + if (ShellGetExecutionBreakFlag ()) { + return (SHELL_ABORTED); + } + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c index f92cfa502d..4d9dc4a09e 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c @@ -1,289 +1,289 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-// This function was from from the BdsLib implementation in
-// IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c
-// function name: BdsLibConnectAllEfi
-
-/**
- This function will connect all current system handles recursively. The
- connection will finish until every handle's child handle created if it have.
-
- @retval EFI_SUCCESS All handles and it's child handle have been
- connected
- @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
-
-**/
-EFI_STATUS
-ConnectAllEfi (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- UINTN Index;
-
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- function to load a .EFI driver into memory and possible connect the driver.
-
- if FileName is NULL then ASSERT.
-
- @param[in] FileName FileName of the driver to load
- @param[in] Connect Whether to connect or not
-
- @retval EFI_SUCCESS the driver was loaded and if Connect was
- true then connect was attempted. Connection may
- have failed.
- @retval EFI_OUT_OF_RESOURCES there was insufficient memory
-**/
-EFI_STATUS
-LoadDriver (
- IN CONST CHAR16 *FileName,
- IN CONST BOOLEAN Connect
- )
-{
- EFI_HANDLE LoadedDriverHandle;
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *FilePath;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedDriverImage;
-
- LoadedDriverImage = NULL;
- FilePath = NULL;
- LoadedDriverHandle = NULL;
- Status = EFI_SUCCESS;
-
- ASSERT (FileName != NULL);
-
- //
- // Fix local copies of the protocol pointers
- //
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Convert to DEVICE_PATH
- //
- FilePath = gEfiShellProtocol->GetDevicePathFromFilePath (FileName);
-
- if (FilePath == NULL) {
- ASSERT (FALSE);
- return (EFI_INVALID_PARAMETER);
- }
-
- //
- // Use LoadImage to get it into memory
- //
- Status = gBS->LoadImage (
- FALSE,
- gImageHandle,
- FilePath,
- NULL,
- 0,
- &LoadedDriverHandle
- );
-
- if (EFI_ERROR (Status)) {
- //
- // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
- // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
- // If the caller doesn't have the option to defer the execution of an image, we should
- // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
- //
- if (Status == EFI_SECURITY_VIOLATION) {
- gBS->UnloadImage (LoadedDriverHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status);
- } else {
- //
- // Make sure it is a driver image
- //
- Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *)&LoadedDriverImage);
-
- ASSERT (LoadedDriverImage != NULL);
-
- if ( EFI_ERROR (Status)
- || ( (LoadedDriverImage->ImageCodeType != EfiBootServicesCode)
- && (LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode))
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName);
-
- //
- // Exit and unload the non-driver image
- //
- gBS->Exit (LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL);
- Status = EFI_INVALID_PARAMETER;
- }
- }
-
- if (!EFI_ERROR (Status)) {
- //
- // Start the image
- //
- Status = gBS->StartImage (LoadedDriverHandle, NULL, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);
- }
- }
-
- if (!EFI_ERROR (Status) && Connect) {
- //
- // Connect it...
- //
- Status = ConnectAllEfi ();
- }
-
- //
- // clean up memory...
- //
- if (FilePath != NULL) {
- FreePool (FilePath);
- }
-
- return (Status);
-}
-
-STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = {
- { L"-nc", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'load' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunLoad (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINTN ParamCount;
- EFI_SHELL_FILE_INFO *ListHead;
- EFI_SHELL_FILE_INFO *Node;
-
- ListHead = NULL;
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"load", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
- //
- // we didnt get a single file to load parameter
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"load");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- for ( ParamCount = 1
- ; ShellCommandLineGetRawValue (Package, ParamCount) != NULL
- ; ParamCount++
- )
- {
- Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount), EFI_FILE_MODE_READ, &ListHead);
- if (!EFI_ERROR (Status)) {
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link)
- ; !IsNull (&ListHead->Link, &Node->Link)
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)
- )
- {
- //
- // once we have an error preserve that value, but finish the loop.
- //
- if (EFI_ERROR (Status)) {
- LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE));
- } else {
- Status = LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE));
- }
- } // for loop for multi-open
-
- if (EFI_ERROR (Status)) {
- ShellCloseFileMetaArg (&ListHead);
- } else {
- Status = ShellCloseFileMetaArg (&ListHead);
- }
- } else {
- //
- // no files found.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"load", (CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount));
- ShellStatus = SHELL_NOT_FOUND;
- }
- } // for loop for params
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
- }
-
- if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
- ShellStatus = SHELL_DEVICE_ERROR;
- }
-
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +// This function was from from the BdsLib implementation in +// IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c +// function name: BdsLibConnectAllEfi + +/** + This function will connect all current system handles recursively. The + connection will finish until every handle's child handle created if it have. + + @retval EFI_SUCCESS All handles and it's child handle have been + connected + @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer(). + +**/ +EFI_STATUS +ConnectAllEfi ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + function to load a .EFI driver into memory and possible connect the driver. + + if FileName is NULL then ASSERT. + + @param[in] FileName FileName of the driver to load + @param[in] Connect Whether to connect or not + + @retval EFI_SUCCESS the driver was loaded and if Connect was + true then connect was attempted. Connection may + have failed. + @retval EFI_OUT_OF_RESOURCES there was insufficient memory +**/ +EFI_STATUS +LoadDriver ( + IN CONST CHAR16 *FileName, + IN CONST BOOLEAN Connect + ) +{ + EFI_HANDLE LoadedDriverHandle; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_LOADED_IMAGE_PROTOCOL *LoadedDriverImage; + + LoadedDriverImage = NULL; + FilePath = NULL; + LoadedDriverHandle = NULL; + Status = EFI_SUCCESS; + + ASSERT (FileName != NULL); + + // + // Fix local copies of the protocol pointers + // + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // Convert to DEVICE_PATH + // + FilePath = gEfiShellProtocol->GetDevicePathFromFilePath (FileName); + + if (FilePath == NULL) { + ASSERT (FALSE); + return (EFI_INVALID_PARAMETER); + } + + // + // Use LoadImage to get it into memory + // + Status = gBS->LoadImage ( + FALSE, + gImageHandle, + FilePath, + NULL, + 0, + &LoadedDriverHandle + ); + + if (EFI_ERROR (Status)) { + // + // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created + // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now. + // If the caller doesn't have the option to defer the execution of an image, we should + // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak. + // + if (Status == EFI_SECURITY_VIOLATION) { + gBS->UnloadImage (LoadedDriverHandle); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status); + } else { + // + // Make sure it is a driver image + // + Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *)&LoadedDriverImage); + + ASSERT (LoadedDriverImage != NULL); + + if ( EFI_ERROR (Status) + || ( (LoadedDriverImage->ImageCodeType != EfiBootServicesCode) + && (LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode)) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName); + + // + // Exit and unload the non-driver image + // + gBS->Exit (LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL); + Status = EFI_INVALID_PARAMETER; + } + } + + if (!EFI_ERROR (Status)) { + // + // Start the image + // + Status = gBS->StartImage (LoadedDriverHandle, NULL, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status); + } + } + + if (!EFI_ERROR (Status) && Connect) { + // + // Connect it... + // + Status = ConnectAllEfi (); + } + + // + // clean up memory... + // + if (FilePath != NULL) { + FreePool (FilePath); + } + + return (Status); +} + +STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = { + { L"-nc", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'load' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLoad ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINTN ParamCount; + EFI_SHELL_FILE_INFO *ListHead; + EFI_SHELL_FILE_INFO *Node; + + ListHead = NULL; + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"load", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) { + // + // we didnt get a single file to load parameter + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"load"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + for ( ParamCount = 1 + ; ShellCommandLineGetRawValue (Package, ParamCount) != NULL + ; ParamCount++ + ) + { + Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount), EFI_FILE_MODE_READ, &ListHead); + if (!EFI_ERROR (Status)) { + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link) + ; !IsNull (&ListHead->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link) + ) + { + // + // once we have an error preserve that value, but finish the loop. + // + if (EFI_ERROR (Status)) { + LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE)); + } else { + Status = LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE)); + } + } // for loop for multi-open + + if (EFI_ERROR (Status)) { + ShellCloseFileMetaArg (&ListHead); + } else { + Status = ShellCloseFileMetaArg (&ListHead); + } + } else { + // + // no files found. + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"load", (CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount)); + ShellStatus = SHELL_NOT_FOUND; + } + } // for loop for params + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + } + + if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) { + ShellStatus = SHELL_DEVICE_ERROR; + } + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c index c03967ee3a..589402b4f9 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c @@ -1,940 +1,940 @@ -/** @file
- Main file for ls shell level 2 function.
-
- (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-#include <Guid/FileSystemInfo.h>
-
-UINTN mDayOfMonth[] = { 31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30 };
-
-/**
- print out the standard format output volume entry.
-
- @param[in] TheList a list of files from the volume.
-**/
-EFI_STATUS
-PrintSfoVolumeInfoTableEntry (
- IN CONST EFI_SHELL_FILE_INFO *TheList
- )
-{
- EFI_STATUS Status;
- EFI_SHELL_FILE_INFO *Node;
- CHAR16 *DirectoryName;
- EFI_FILE_SYSTEM_INFO *SysInfo;
- UINTN SysInfoSize;
- SHELL_FILE_HANDLE ShellFileHandle;
- EFI_FILE_PROTOCOL *EfiFpHandle;
-
- //
- // Get the first valid handle (directories)
- //
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link)
- ; !IsNull (&TheList->Link, &Node->Link) && Node->Handle == NULL
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&TheList->Link, &Node->Link)
- )
- {
- }
-
- if (Node->Handle == NULL) {
- DirectoryName = GetFullyQualifiedPath (((EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link))->FullName);
-
- //
- // We need to open something up to get system information
- //
- Status = gEfiShellProtocol->OpenFileByName (
- DirectoryName,
- &ShellFileHandle,
- EFI_FILE_MODE_READ
- );
-
- ASSERT_EFI_ERROR (Status);
- FreePool (DirectoryName);
-
- //
- // Get the Volume Info from ShellFileHandle
- //
- SysInfo = NULL;
- SysInfoSize = 0;
- EfiFpHandle = ConvertShellHandleToEfiFileProtocol (ShellFileHandle);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- SysInfo = AllocateZeroPool (SysInfoSize);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
- }
-
- ASSERT_EFI_ERROR (Status);
-
- gEfiShellProtocol->CloseFile (ShellFileHandle);
- } else {
- //
- // Get the Volume Info from Node->Handle
- //
- SysInfo = NULL;
- SysInfoSize = 0;
- EfiFpHandle = ConvertShellHandleToEfiFileProtocol (Node->Handle);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- SysInfo = AllocateZeroPool (SysInfoSize);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
- }
-
- ASSERT_EFI_ERROR (Status);
- }
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_SFO_HEADER),
- gShellLevel2HiiHandle,
- L"ls"
- );
- //
- // print VolumeInfo table
- //
- ASSERT (SysInfo != NULL);
- ShellPrintHiiEx (
- 0,
- gST->ConOut->Mode->CursorRow,
- NULL,
- STRING_TOKEN (STR_LS_SFO_VOLINFO),
- gShellLevel2HiiHandle,
- SysInfo->VolumeLabel,
- SysInfo->VolumeSize,
- SysInfo->ReadOnly ? L"TRUE" : L"FALSE",
- SysInfo->FreeSpace,
- SysInfo->BlockSize
- );
-
- SHELL_FREE_NON_NULL (SysInfo);
-
- return (Status);
-}
-
-/**
- print out the info on a single file.
-
- @param[in] Sfo TRUE if in SFO, false otherwise.
- @param[in] TheNode the EFI_SHELL_FILE_INFO node to print out information on.
- @param[in] Files incremented if a file is printed.
- @param[in] Size incremented by file size.
- @param[in] Dirs incremented if a directory is printed.
-
-**/
-VOID
-PrintFileInformation (
- IN CONST BOOLEAN Sfo,
- IN CONST EFI_SHELL_FILE_INFO *TheNode,
- IN UINT64 *Files,
- IN UINT64 *Size,
- IN UINT64 *Dirs
- )
-{
- ASSERT (Files != NULL);
- ASSERT (Size != NULL);
- ASSERT (Dirs != NULL);
- ASSERT (TheNode != NULL);
-
- if (Sfo) {
- //
- // Print the FileInfo Table
- //
- ShellPrintHiiEx (
- 0,
- gST->ConOut->Mode->CursorRow,
- NULL,
- STRING_TOKEN (STR_LS_SFO_FILEINFO),
- gShellLevel2HiiHandle,
- TheNode->FullName,
- TheNode->Info->FileSize,
- TheNode->Info->PhysicalSize,
- (TheNode->Info->Attribute & EFI_FILE_ARCHIVE) != 0 ? L"a" : L"",
- (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"d" : L"",
- (TheNode->Info->Attribute & EFI_FILE_HIDDEN) != 0 ? L"h" : L"",
- (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L"r" : L"",
- (TheNode->Info->Attribute & EFI_FILE_SYSTEM) != 0 ? L"s" : L"",
- TheNode->Info->CreateTime.Hour,
- TheNode->Info->CreateTime.Minute,
- TheNode->Info->CreateTime.Second,
- TheNode->Info->CreateTime.Day,
- TheNode->Info->CreateTime.Month,
- TheNode->Info->CreateTime.Year,
- TheNode->Info->LastAccessTime.Hour,
- TheNode->Info->LastAccessTime.Minute,
- TheNode->Info->LastAccessTime.Second,
- TheNode->Info->LastAccessTime.Day,
- TheNode->Info->LastAccessTime.Month,
- TheNode->Info->LastAccessTime.Year,
- TheNode->Info->ModificationTime.Hour,
- TheNode->Info->ModificationTime.Minute,
- TheNode->Info->ModificationTime.Second,
- TheNode->Info->ModificationTime.Day,
- TheNode->Info->ModificationTime.Month,
- TheNode->Info->ModificationTime.Year
- );
- } else {
- //
- // print this one out...
- // first print the universal start, next print the type specific name format, last print the CRLF
- //
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_LS_LINE_START_ALL),
- gShellLevel2HiiHandle,
- &TheNode->Info->ModificationTime,
- (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"<DIR>" : L"",
- (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L'r' : L' ',
- TheNode->Info->FileSize
- );
- if (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) {
- (*Dirs)++;
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_LS_LINE_END_DIR),
- gShellLevel2HiiHandle,
- TheNode->FileName
- );
- } else {
- (*Files)++;
- (*Size) += TheNode->Info->FileSize;
- if ( (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".nsh", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0)
- || (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".efi", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0)
- )
- {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_LS_LINE_END_EXE),
- gShellLevel2HiiHandle,
- TheNode->FileName
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_LS_LINE_END_FILE),
- gShellLevel2HiiHandle,
- TheNode->FileName
- );
- }
- }
- }
-}
-
-/**
- print out the header when not using standard format output.
-
- @param[in] Path String with starting path.
-**/
-VOID
-PrintNonSfoHeader (
- IN CONST CHAR16 *Path
- )
-{
- CHAR16 *DirectoryName;
-
- //
- // get directory name from path...
- //
- DirectoryName = GetFullyQualifiedPath (Path);
-
- if (DirectoryName != NULL) {
- //
- // print header
- //
- ShellPrintHiiEx (
- 0,
- gST->ConOut->Mode->CursorRow,
- NULL,
- STRING_TOKEN (STR_LS_HEADER_LINE1),
- gShellLevel2HiiHandle,
- DirectoryName
- );
-
- SHELL_FREE_NON_NULL (DirectoryName);
- }
-}
-
-/**
- print out the footer when not using standard format output.
-
- @param[in] Files The number of files.
- @param[in] Size The size of files in bytes.
- @param[in] Dirs The number of directories.
-**/
-VOID
-PrintNonSfoFooter (
- IN UINT64 Files,
- IN UINT64 Size,
- IN UINT64 Dirs
- )
-{
- //
- // print footer
- //
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_LS_FOOTER_LINE),
- gShellLevel2HiiHandle,
- Files,
- Size,
- Dirs
- );
-}
-
-/**
- Change the file time to local time based on the timezone.
-
- @param[in] Time The file time.
- @param[in] LocalTimeZone Local time zone.
-**/
-VOID
-FileTimeToLocalTime (
- IN EFI_TIME *Time,
- IN INT16 LocalTimeZone
- )
-{
- INTN MinuteDiff;
- INTN TempMinute;
- INTN HourNumberOfTempMinute;
- INTN TempHour;
- INTN DayNumberOfTempHour;
- INTN TempDay;
- INTN MonthNumberOfTempDay;
- INTN TempMonth;
- INTN YearNumberOfTempMonth;
- INTN MonthRecord;
-
- ASSERT ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440));
- ASSERT ((LocalTimeZone >= -1440) && (LocalTimeZone <= 1440));
- ASSERT ((Time->Month >= 1) && (Time->Month <= 12));
-
- if (Time->TimeZone == LocalTimeZone) {
- //
- // if the file timezone is equal to the local timezone, there is no need to adjust the file time.
- //
- return;
- }
-
- if (((Time->Year % 4 == 0) && (Time->Year / 100 != 0)) || (Time->Year % 400 == 0)) {
- //
- // Day in February of leap year is 29.
- //
- mDayOfMonth[1] = 29;
- }
-
- MinuteDiff = Time->TimeZone - LocalTimeZone;
- TempMinute = Time->Minute + MinuteDiff;
-
- //
- // Calculate Time->Minute
- // TempHour will be used to calculate Time->Hour
- //
- HourNumberOfTempMinute = TempMinute / 60;
- if (TempMinute < 0) {
- HourNumberOfTempMinute--;
- }
-
- TempHour = Time->Hour + HourNumberOfTempMinute;
- Time->Minute = (UINT8)(TempMinute - 60 * HourNumberOfTempMinute);
-
- //
- // Calculate Time->Hour
- // TempDay will be used to calculate Time->Day
- //
- DayNumberOfTempHour = TempHour / 24;
- if (TempHour < 0) {
- DayNumberOfTempHour--;
- }
-
- TempDay = Time->Day + DayNumberOfTempHour;
- Time->Hour = (UINT8)(TempHour - 24 * DayNumberOfTempHour);
-
- //
- // Calculate Time->Day
- // TempMonth will be used to calculate Time->Month
- //
- MonthNumberOfTempDay = (TempDay - 1) / (INTN)mDayOfMonth[Time->Month - 1];
- MonthRecord = (INTN)(Time->Month);
- if (TempDay - 1 < 0) {
- MonthNumberOfTempDay--;
- MonthRecord--;
- }
-
- TempMonth = Time->Month + MonthNumberOfTempDay;
- Time->Day = (UINT8)(TempDay - (INTN)mDayOfMonth[(MonthRecord - 1 + 12) % 12] * MonthNumberOfTempDay);
-
- //
- // Calculate Time->Month, Time->Year
- //
- YearNumberOfTempMonth = (TempMonth - 1) / 12;
- if (TempMonth - 1 < 0) {
- YearNumberOfTempMonth--;
- }
-
- Time->Month = (UINT8)(TempMonth - 12 * (YearNumberOfTempMonth));
- Time->Year = (UINT16)(Time->Year + YearNumberOfTempMonth);
-}
-
-/**
- print out the list of files and directories from the LS command
-
- @param[in] Rec TRUE to automatically recurse into each found directory
- FALSE to only list the specified directory.
- @param[in] Attribs List of required Attribute for display.
- If 0 then all non-system and non-hidden files will be printed.
- @param[in] Sfo TRUE to use Standard Format Output, FALSE otherwise
- @param[in] RootPath String with starting path to search in.
- @param[in] SearchString String with search string.
- @param[in] Found Set to TRUE, if anyone were found.
- @param[in] Count The count of bits enabled in Attribs.
- @param[in] TimeZone The current time zone offset.
- @param[in] ListUnfiltered TRUE to request listing the directory contents
- unfiltered.
-
- @retval SHELL_SUCCESS the printing was successful.
-**/
-SHELL_STATUS
-PrintLsOutput (
- IN CONST BOOLEAN Rec,
- IN CONST UINT64 Attribs,
- IN CONST BOOLEAN Sfo,
- IN CONST CHAR16 *RootPath,
- IN CONST CHAR16 *SearchString,
- IN BOOLEAN *Found,
- IN CONST UINTN Count,
- IN CONST INT16 TimeZone,
- IN CONST BOOLEAN ListUnfiltered
- )
-{
- EFI_STATUS Status;
- EFI_SHELL_FILE_INFO *ListHead;
- EFI_SHELL_FILE_INFO *Node;
- SHELL_STATUS ShellStatus;
- UINT64 FileCount;
- UINT64 DirCount;
- UINT64 FileSize;
- UINTN LongestPath;
- CHAR16 *CorrectedPath;
- BOOLEAN FoundOne;
- BOOLEAN HeaderPrinted;
- EFI_TIME LocalTime;
-
- HeaderPrinted = FALSE;
- FileCount = 0;
- DirCount = 0;
- FileSize = 0;
- ListHead = NULL;
- ShellStatus = SHELL_SUCCESS;
- LongestPath = 0;
- CorrectedPath = NULL;
-
- if (Found != NULL) {
- FoundOne = *Found;
- } else {
- FoundOne = FALSE;
- }
-
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, RootPath, 0);
- if (CorrectedPath == NULL) {
- return SHELL_OUT_OF_RESOURCES;
- }
-
- if ( (CorrectedPath[StrLen (CorrectedPath)-1] != L'\\')
- && (CorrectedPath[StrLen (CorrectedPath)-1] != L'/'))
- {
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"\\", 0);
- }
-
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, SearchString, 0);
- if (CorrectedPath == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- PathCleanUpDirectories (CorrectedPath);
-
- Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);
- if (!EFI_ERROR (Status)) {
- if ((ListHead == NULL) || IsListEmpty (&ListHead->Link)) {
- SHELL_FREE_NON_NULL (CorrectedPath);
- return (SHELL_SUCCESS);
- }
-
- if (Sfo && (Found == NULL)) {
- PrintSfoVolumeInfoTableEntry (ListHead);
- }
-
- if (!Sfo) {
- //
- // Sort the file list by FileName, stably.
- //
- // If the call below fails, then the EFI_SHELL_FILE_INFO list anchored to
- // ListHead will not be changed in any way.
- //
- ShellSortFileList (
- &ListHead,
- NULL, // Duplicates
- ShellSortFileListByFileName
- );
- }
-
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link), LongestPath = 0
- ; !IsNull (&ListHead->Link, &Node->Link)
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)
- )
- {
- if (ShellGetExecutionBreakFlag ()) {
- ShellStatus = SHELL_ABORTED;
- break;
- }
-
- ASSERT (Node != NULL);
-
- //
- // Change the file time to local time.
- //
- Status = gRT->GetTime (&LocalTime, NULL);
- if (!EFI_ERROR (Status) && (LocalTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE)) {
- if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
- ((Node->Info->CreateTime.Month >= 1) && (Node->Info->CreateTime.Month <= 12)))
- {
- //
- // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens.
- //
- FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone);
- }
-
- if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
- ((Node->Info->LastAccessTime.Month >= 1) && (Node->Info->LastAccessTime.Month <= 12)))
- {
- FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone);
- }
-
- if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
- ((Node->Info->ModificationTime.Month >= 1) && (Node->Info->ModificationTime.Month <= 12)))
- {
- FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone);
- }
- }
-
- if (LongestPath < StrSize (Node->FullName)) {
- LongestPath = StrSize (Node->FullName);
- }
-
- ASSERT (Node->Info != NULL);
- ASSERT ((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute);
- if (Attribs == 0) {
- //
- // NOT system & NOT hidden
- //
- if ( (Node->Info->Attribute & EFI_FILE_SYSTEM)
- || (Node->Info->Attribute & EFI_FILE_HIDDEN)
- )
- {
- continue;
- }
- } else if ((Attribs != EFI_FILE_VALID_ATTR) ||
- (Count == 5))
- {
- //
- // Only matches the bits which "Attribs" contains, not
- // all files/directories with any of the bits.
- // Count == 5 is used to tell the difference between a user
- // specifying all bits (EX: -arhsda) and just specifying
- // -a (means display all files with any attribute).
- //
- if ((Node->Info->Attribute & Attribs) != Attribs) {
- continue;
- }
- }
-
- if (!Sfo && !HeaderPrinted) {
- PathRemoveLastItem (CorrectedPath);
- PrintNonSfoHeader (CorrectedPath);
- }
-
- PrintFileInformation (Sfo, Node, &FileCount, &FileSize, &DirCount);
- FoundOne = TRUE;
- HeaderPrinted = TRUE;
- }
-
- if (!Sfo && (ShellStatus != SHELL_ABORTED) && HeaderPrinted) {
- PrintNonSfoFooter (FileCount, FileSize, DirCount);
- }
- }
-
- if (Rec && (ShellStatus != SHELL_ABORTED)) {
- //
- // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter
- //
- ShellCloseFileMetaArg (&ListHead);
- CorrectedPath[0] = CHAR_NULL;
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, RootPath, 0);
- if (CorrectedPath == NULL) {
- return SHELL_OUT_OF_RESOURCES;
- }
-
- if ( (CorrectedPath[StrLen (CorrectedPath)-1] != L'\\')
- && (CorrectedPath[StrLen (CorrectedPath)-1] != L'/'))
- {
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"\\", 0);
- }
-
- CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"*", 0);
- Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);
-
- if (!EFI_ERROR (Status)) {
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link)
- ; !IsNull (&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)
- )
- {
- if (ShellGetExecutionBreakFlag ()) {
- ShellStatus = SHELL_ABORTED;
- break;
- }
-
- //
- // recurse on any directory except the traversing ones...
- //
- if ( ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)
- && (StrCmp (Node->FileName, L".") != 0)
- && (StrCmp (Node->FileName, L"..") != 0)
- )
- {
- ShellStatus = PrintLsOutput (
- Rec,
- Attribs,
- Sfo,
- Node->FullName,
- SearchString,
- &FoundOne,
- Count,
- TimeZone,
- FALSE
- );
-
- //
- // Since it's running recursively, we have to break immediately when returned SHELL_ABORTED
- //
- if (ShellStatus == SHELL_ABORTED) {
- break;
- }
- }
- }
- }
- }
-
- SHELL_FREE_NON_NULL (CorrectedPath);
- ShellCloseFileMetaArg (&ListHead);
-
- if ((Found == NULL) && !FoundOne) {
- if (ListUnfiltered) {
- //
- // When running "ls" without any filtering request, avoid outputing
- // "File not found" when the directory is entirely empty, but print
- // header and footer stating "0 File(s), 0 Dir(s)".
- //
- if (!Sfo) {
- PrintNonSfoHeader (RootPath);
- if (ShellStatus != SHELL_ABORTED) {
- PrintNonSfoFooter (FileCount, FileSize, DirCount);
- }
- }
- } else {
- return (SHELL_NOT_FOUND);
- }
- }
-
- if (Found != NULL) {
- *Found = FoundOne;
- }
-
- return (ShellStatus);
-}
-
-STATIC CONST SHELL_PARAM_ITEM LsParamList[] = {
- { L"-r", TypeFlag },
- { L"-a", TypeStart },
- { L"-sfo", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'ls' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunLs (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- CONST CHAR16 *Attribs;
- SHELL_STATUS ShellStatus;
- UINT64 RequiredAttributes;
- CONST CHAR16 *PathName;
- CONST CHAR16 *CurDir;
- UINTN Count;
- CHAR16 *FullPath;
- UINTN Size;
- EFI_TIME TheTime;
- CHAR16 *SearchString;
- BOOLEAN ListUnfiltered;
-
- Size = 0;
- FullPath = NULL;
- ProblemParam = NULL;
- Attribs = NULL;
- ShellStatus = SHELL_SUCCESS;
- RequiredAttributes = 0;
- PathName = NULL;
- SearchString = NULL;
- CurDir = NULL;
- Count = 0;
- ListUnfiltered = FALSE;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Fix local copies of the protocol pointers
- //
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (LsParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"ls", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- if (ShellCommandLineGetCount (Package) > 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"ls");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // check for -a
- //
- if (ShellCommandLineGetFlag (Package, L"-a")) {
- for ( Attribs = ShellCommandLineGetValue (Package, L"-a")
- ; Attribs != NULL && *Attribs != CHAR_NULL && ShellStatus == SHELL_SUCCESS
- ; Attribs++
- )
- {
- switch (*Attribs) {
- case L'a':
- case L'A':
- RequiredAttributes |= EFI_FILE_ARCHIVE;
- Count++;
- continue;
- case L's':
- case L'S':
- RequiredAttributes |= EFI_FILE_SYSTEM;
- Count++;
- continue;
- case L'h':
- case L'H':
- RequiredAttributes |= EFI_FILE_HIDDEN;
- Count++;
- continue;
- case L'r':
- case L'R':
- RequiredAttributes |= EFI_FILE_READ_ONLY;
- Count++;
- continue;
- case L'd':
- case L'D':
- RequiredAttributes |= EFI_FILE_DIRECTORY;
- Count++;
- continue;
- default:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, L"ls", ShellCommandLineGetValue (Package, L"-a"));
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- } // switch
- } // for loop
-
- //
- // if nothing is specified all are specified
- //
- if (RequiredAttributes == 0) {
- RequiredAttributes = EFI_FILE_VALID_ATTR;
- }
- } // if -a present
-
- if (ShellStatus == SHELL_SUCCESS) {
- PathName = ShellCommandLineGetRawValue (Package, 1);
- if (PathName == NULL) {
- //
- // Nothing specified... must start from current directory
- //
- CurDir = gEfiShellProtocol->GetCurDir (NULL);
- if (CurDir == NULL) {
- ShellStatus = SHELL_NOT_FOUND;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls");
- }
-
- ListUnfiltered = TRUE;
- //
- // Copy to the 2 strings for starting path and file search string
- //
- ASSERT (SearchString == NULL);
- ASSERT (FullPath == NULL);
- StrnCatGrow (&SearchString, NULL, L"*", 0);
- StrnCatGrow (&FullPath, NULL, CurDir, 0);
- Size = FullPath != NULL ? StrSize (FullPath) : 0;
- StrnCatGrow (&FullPath, &Size, L"\\", 0);
- } else {
- if ((StrStr (PathName, L":") == NULL) && (gEfiShellProtocol->GetCurDir (NULL) == NULL)) {
- //
- // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD.
- //
- ShellStatus = SHELL_NOT_FOUND;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls");
- } else {
- //
- // We got a valid fully qualified path or we have a CWD
- //
- ASSERT ((FullPath == NULL && Size == 0) || (FullPath != NULL));
- if (StrStr (PathName, L":") == NULL) {
- StrnCatGrow (&FullPath, &Size, gEfiShellProtocol->GetCurDir (NULL), 0);
- if (FullPath == NULL) {
- ShellCommandLineFreeVarList (Package);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- Size = FullPath != NULL ? StrSize (FullPath) : 0;
- StrnCatGrow (&FullPath, &Size, L"\\", 0);
- }
-
- StrnCatGrow (&FullPath, &Size, PathName, 0);
- if (FullPath == NULL) {
- ShellCommandLineFreeVarList (Package);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- if (ShellIsDirectory (PathName) == EFI_SUCCESS) {
- //
- // is listing ends with a directory, then we list all files in that directory
- //
- ListUnfiltered = TRUE;
- StrnCatGrow (&SearchString, NULL, L"*", 0);
- } else {
- //
- // must split off the search part that applies to files from the end of the directory part
- //
- StrnCatGrow (&SearchString, NULL, FullPath, 0);
- if (SearchString == NULL) {
- FreePool (FullPath);
- ShellCommandLineFreeVarList (Package);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- PathRemoveLastItem (FullPath);
- CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath)));
- }
- }
- }
-
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"ls", L"gRT->GetTime", Status);
- TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = PrintLsOutput (
- ShellCommandLineGetFlag (Package, L"-r"),
- RequiredAttributes,
- ShellCommandLineGetFlag (Package, L"-sfo"),
- FullPath,
- SearchString,
- NULL,
- Count,
- TheTime.TimeZone,
- ListUnfiltered
- );
- if (ShellStatus == SHELL_NOT_FOUND) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle, L"ls", FullPath);
- } else if (ShellStatus == SHELL_INVALID_PARAMETER) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath);
- } else if (ShellStatus == SHELL_ABORTED) {
- //
- // Ignore aborting.
- //
- } else if (ShellStatus != SHELL_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath);
- }
- }
- }
- }
- }
-
- //
- // Free memory allocated
- //
- SHELL_FREE_NON_NULL (SearchString);
- SHELL_FREE_NON_NULL (FullPath);
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for ls shell level 2 function. + + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" +#include <Guid/FileSystemInfo.h> + +UINTN mDayOfMonth[] = { 31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30 }; + +/** + print out the standard format output volume entry. + + @param[in] TheList a list of files from the volume. +**/ +EFI_STATUS +PrintSfoVolumeInfoTableEntry ( + IN CONST EFI_SHELL_FILE_INFO *TheList + ) +{ + EFI_STATUS Status; + EFI_SHELL_FILE_INFO *Node; + CHAR16 *DirectoryName; + EFI_FILE_SYSTEM_INFO *SysInfo; + UINTN SysInfoSize; + SHELL_FILE_HANDLE ShellFileHandle; + EFI_FILE_PROTOCOL *EfiFpHandle; + + // + // Get the first valid handle (directories) + // + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link) + ; !IsNull (&TheList->Link, &Node->Link) && Node->Handle == NULL + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&TheList->Link, &Node->Link) + ) + { + } + + if (Node->Handle == NULL) { + DirectoryName = GetFullyQualifiedPath (((EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link))->FullName); + + // + // We need to open something up to get system information + // + Status = gEfiShellProtocol->OpenFileByName ( + DirectoryName, + &ShellFileHandle, + EFI_FILE_MODE_READ + ); + + ASSERT_EFI_ERROR (Status); + FreePool (DirectoryName); + + // + // Get the Volume Info from ShellFileHandle + // + SysInfo = NULL; + SysInfoSize = 0; + EfiFpHandle = ConvertShellHandleToEfiFileProtocol (ShellFileHandle); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + SysInfo = AllocateZeroPool (SysInfoSize); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + } + + ASSERT_EFI_ERROR (Status); + + gEfiShellProtocol->CloseFile (ShellFileHandle); + } else { + // + // Get the Volume Info from Node->Handle + // + SysInfo = NULL; + SysInfoSize = 0; + EfiFpHandle = ConvertShellHandleToEfiFileProtocol (Node->Handle); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + SysInfo = AllocateZeroPool (SysInfoSize); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + } + + ASSERT_EFI_ERROR (Status); + } + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_SFO_HEADER), + gShellLevel2HiiHandle, + L"ls" + ); + // + // print VolumeInfo table + // + ASSERT (SysInfo != NULL); + ShellPrintHiiEx ( + 0, + gST->ConOut->Mode->CursorRow, + NULL, + STRING_TOKEN (STR_LS_SFO_VOLINFO), + gShellLevel2HiiHandle, + SysInfo->VolumeLabel, + SysInfo->VolumeSize, + SysInfo->ReadOnly ? L"TRUE" : L"FALSE", + SysInfo->FreeSpace, + SysInfo->BlockSize + ); + + SHELL_FREE_NON_NULL (SysInfo); + + return (Status); +} + +/** + print out the info on a single file. + + @param[in] Sfo TRUE if in SFO, false otherwise. + @param[in] TheNode the EFI_SHELL_FILE_INFO node to print out information on. + @param[in] Files incremented if a file is printed. + @param[in] Size incremented by file size. + @param[in] Dirs incremented if a directory is printed. + +**/ +VOID +PrintFileInformation ( + IN CONST BOOLEAN Sfo, + IN CONST EFI_SHELL_FILE_INFO *TheNode, + IN UINT64 *Files, + IN UINT64 *Size, + IN UINT64 *Dirs + ) +{ + ASSERT (Files != NULL); + ASSERT (Size != NULL); + ASSERT (Dirs != NULL); + ASSERT (TheNode != NULL); + + if (Sfo) { + // + // Print the FileInfo Table + // + ShellPrintHiiEx ( + 0, + gST->ConOut->Mode->CursorRow, + NULL, + STRING_TOKEN (STR_LS_SFO_FILEINFO), + gShellLevel2HiiHandle, + TheNode->FullName, + TheNode->Info->FileSize, + TheNode->Info->PhysicalSize, + (TheNode->Info->Attribute & EFI_FILE_ARCHIVE) != 0 ? L"a" : L"", + (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"d" : L"", + (TheNode->Info->Attribute & EFI_FILE_HIDDEN) != 0 ? L"h" : L"", + (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L"r" : L"", + (TheNode->Info->Attribute & EFI_FILE_SYSTEM) != 0 ? L"s" : L"", + TheNode->Info->CreateTime.Hour, + TheNode->Info->CreateTime.Minute, + TheNode->Info->CreateTime.Second, + TheNode->Info->CreateTime.Day, + TheNode->Info->CreateTime.Month, + TheNode->Info->CreateTime.Year, + TheNode->Info->LastAccessTime.Hour, + TheNode->Info->LastAccessTime.Minute, + TheNode->Info->LastAccessTime.Second, + TheNode->Info->LastAccessTime.Day, + TheNode->Info->LastAccessTime.Month, + TheNode->Info->LastAccessTime.Year, + TheNode->Info->ModificationTime.Hour, + TheNode->Info->ModificationTime.Minute, + TheNode->Info->ModificationTime.Second, + TheNode->Info->ModificationTime.Day, + TheNode->Info->ModificationTime.Month, + TheNode->Info->ModificationTime.Year + ); + } else { + // + // print this one out... + // first print the universal start, next print the type specific name format, last print the CRLF + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_LS_LINE_START_ALL), + gShellLevel2HiiHandle, + &TheNode->Info->ModificationTime, + (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"<DIR>" : L"", + (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L'r' : L' ', + TheNode->Info->FileSize + ); + if (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) { + (*Dirs)++; + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_LS_LINE_END_DIR), + gShellLevel2HiiHandle, + TheNode->FileName + ); + } else { + (*Files)++; + (*Size) += TheNode->Info->FileSize; + if ( (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".nsh", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0) + || (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".efi", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0) + ) + { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_LS_LINE_END_EXE), + gShellLevel2HiiHandle, + TheNode->FileName + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_LS_LINE_END_FILE), + gShellLevel2HiiHandle, + TheNode->FileName + ); + } + } + } +} + +/** + print out the header when not using standard format output. + + @param[in] Path String with starting path. +**/ +VOID +PrintNonSfoHeader ( + IN CONST CHAR16 *Path + ) +{ + CHAR16 *DirectoryName; + + // + // get directory name from path... + // + DirectoryName = GetFullyQualifiedPath (Path); + + if (DirectoryName != NULL) { + // + // print header + // + ShellPrintHiiEx ( + 0, + gST->ConOut->Mode->CursorRow, + NULL, + STRING_TOKEN (STR_LS_HEADER_LINE1), + gShellLevel2HiiHandle, + DirectoryName + ); + + SHELL_FREE_NON_NULL (DirectoryName); + } +} + +/** + print out the footer when not using standard format output. + + @param[in] Files The number of files. + @param[in] Size The size of files in bytes. + @param[in] Dirs The number of directories. +**/ +VOID +PrintNonSfoFooter ( + IN UINT64 Files, + IN UINT64 Size, + IN UINT64 Dirs + ) +{ + // + // print footer + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_LS_FOOTER_LINE), + gShellLevel2HiiHandle, + Files, + Size, + Dirs + ); +} + +/** + Change the file time to local time based on the timezone. + + @param[in] Time The file time. + @param[in] LocalTimeZone Local time zone. +**/ +VOID +FileTimeToLocalTime ( + IN EFI_TIME *Time, + IN INT16 LocalTimeZone + ) +{ + INTN MinuteDiff; + INTN TempMinute; + INTN HourNumberOfTempMinute; + INTN TempHour; + INTN DayNumberOfTempHour; + INTN TempDay; + INTN MonthNumberOfTempDay; + INTN TempMonth; + INTN YearNumberOfTempMonth; + INTN MonthRecord; + + ASSERT ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)); + ASSERT ((LocalTimeZone >= -1440) && (LocalTimeZone <= 1440)); + ASSERT ((Time->Month >= 1) && (Time->Month <= 12)); + + if (Time->TimeZone == LocalTimeZone) { + // + // if the file timezone is equal to the local timezone, there is no need to adjust the file time. + // + return; + } + + if (((Time->Year % 4 == 0) && (Time->Year / 100 != 0)) || (Time->Year % 400 == 0)) { + // + // Day in February of leap year is 29. + // + mDayOfMonth[1] = 29; + } + + MinuteDiff = Time->TimeZone - LocalTimeZone; + TempMinute = Time->Minute + MinuteDiff; + + // + // Calculate Time->Minute + // TempHour will be used to calculate Time->Hour + // + HourNumberOfTempMinute = TempMinute / 60; + if (TempMinute < 0) { + HourNumberOfTempMinute--; + } + + TempHour = Time->Hour + HourNumberOfTempMinute; + Time->Minute = (UINT8)(TempMinute - 60 * HourNumberOfTempMinute); + + // + // Calculate Time->Hour + // TempDay will be used to calculate Time->Day + // + DayNumberOfTempHour = TempHour / 24; + if (TempHour < 0) { + DayNumberOfTempHour--; + } + + TempDay = Time->Day + DayNumberOfTempHour; + Time->Hour = (UINT8)(TempHour - 24 * DayNumberOfTempHour); + + // + // Calculate Time->Day + // TempMonth will be used to calculate Time->Month + // + MonthNumberOfTempDay = (TempDay - 1) / (INTN)mDayOfMonth[Time->Month - 1]; + MonthRecord = (INTN)(Time->Month); + if (TempDay - 1 < 0) { + MonthNumberOfTempDay--; + MonthRecord--; + } + + TempMonth = Time->Month + MonthNumberOfTempDay; + Time->Day = (UINT8)(TempDay - (INTN)mDayOfMonth[(MonthRecord - 1 + 12) % 12] * MonthNumberOfTempDay); + + // + // Calculate Time->Month, Time->Year + // + YearNumberOfTempMonth = (TempMonth - 1) / 12; + if (TempMonth - 1 < 0) { + YearNumberOfTempMonth--; + } + + Time->Month = (UINT8)(TempMonth - 12 * (YearNumberOfTempMonth)); + Time->Year = (UINT16)(Time->Year + YearNumberOfTempMonth); +} + +/** + print out the list of files and directories from the LS command + + @param[in] Rec TRUE to automatically recurse into each found directory + FALSE to only list the specified directory. + @param[in] Attribs List of required Attribute for display. + If 0 then all non-system and non-hidden files will be printed. + @param[in] Sfo TRUE to use Standard Format Output, FALSE otherwise + @param[in] RootPath String with starting path to search in. + @param[in] SearchString String with search string. + @param[in] Found Set to TRUE, if anyone were found. + @param[in] Count The count of bits enabled in Attribs. + @param[in] TimeZone The current time zone offset. + @param[in] ListUnfiltered TRUE to request listing the directory contents + unfiltered. + + @retval SHELL_SUCCESS the printing was successful. +**/ +SHELL_STATUS +PrintLsOutput ( + IN CONST BOOLEAN Rec, + IN CONST UINT64 Attribs, + IN CONST BOOLEAN Sfo, + IN CONST CHAR16 *RootPath, + IN CONST CHAR16 *SearchString, + IN BOOLEAN *Found, + IN CONST UINTN Count, + IN CONST INT16 TimeZone, + IN CONST BOOLEAN ListUnfiltered + ) +{ + EFI_STATUS Status; + EFI_SHELL_FILE_INFO *ListHead; + EFI_SHELL_FILE_INFO *Node; + SHELL_STATUS ShellStatus; + UINT64 FileCount; + UINT64 DirCount; + UINT64 FileSize; + UINTN LongestPath; + CHAR16 *CorrectedPath; + BOOLEAN FoundOne; + BOOLEAN HeaderPrinted; + EFI_TIME LocalTime; + + HeaderPrinted = FALSE; + FileCount = 0; + DirCount = 0; + FileSize = 0; + ListHead = NULL; + ShellStatus = SHELL_SUCCESS; + LongestPath = 0; + CorrectedPath = NULL; + + if (Found != NULL) { + FoundOne = *Found; + } else { + FoundOne = FALSE; + } + + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, RootPath, 0); + if (CorrectedPath == NULL) { + return SHELL_OUT_OF_RESOURCES; + } + + if ( (CorrectedPath[StrLen (CorrectedPath)-1] != L'\\') + && (CorrectedPath[StrLen (CorrectedPath)-1] != L'/')) + { + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"\\", 0); + } + + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, SearchString, 0); + if (CorrectedPath == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + PathCleanUpDirectories (CorrectedPath); + + Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); + if (!EFI_ERROR (Status)) { + if ((ListHead == NULL) || IsListEmpty (&ListHead->Link)) { + SHELL_FREE_NON_NULL (CorrectedPath); + return (SHELL_SUCCESS); + } + + if (Sfo && (Found == NULL)) { + PrintSfoVolumeInfoTableEntry (ListHead); + } + + if (!Sfo) { + // + // Sort the file list by FileName, stably. + // + // If the call below fails, then the EFI_SHELL_FILE_INFO list anchored to + // ListHead will not be changed in any way. + // + ShellSortFileList ( + &ListHead, + NULL, // Duplicates + ShellSortFileListByFileName + ); + } + + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link), LongestPath = 0 + ; !IsNull (&ListHead->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link) + ) + { + if (ShellGetExecutionBreakFlag ()) { + ShellStatus = SHELL_ABORTED; + break; + } + + ASSERT (Node != NULL); + + // + // Change the file time to local time. + // + Status = gRT->GetTime (&LocalTime, NULL); + if (!EFI_ERROR (Status) && (LocalTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE)) { + if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + ((Node->Info->CreateTime.Month >= 1) && (Node->Info->CreateTime.Month <= 12))) + { + // + // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens. + // + FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone); + } + + if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + ((Node->Info->LastAccessTime.Month >= 1) && (Node->Info->LastAccessTime.Month <= 12))) + { + FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone); + } + + if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && + ((Node->Info->ModificationTime.Month >= 1) && (Node->Info->ModificationTime.Month <= 12))) + { + FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone); + } + } + + if (LongestPath < StrSize (Node->FullName)) { + LongestPath = StrSize (Node->FullName); + } + + ASSERT (Node->Info != NULL); + ASSERT ((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute); + if (Attribs == 0) { + // + // NOT system & NOT hidden + // + if ( (Node->Info->Attribute & EFI_FILE_SYSTEM) + || (Node->Info->Attribute & EFI_FILE_HIDDEN) + ) + { + continue; + } + } else if ((Attribs != EFI_FILE_VALID_ATTR) || + (Count == 5)) + { + // + // Only matches the bits which "Attribs" contains, not + // all files/directories with any of the bits. + // Count == 5 is used to tell the difference between a user + // specifying all bits (EX: -arhsda) and just specifying + // -a (means display all files with any attribute). + // + if ((Node->Info->Attribute & Attribs) != Attribs) { + continue; + } + } + + if (!Sfo && !HeaderPrinted) { + PathRemoveLastItem (CorrectedPath); + PrintNonSfoHeader (CorrectedPath); + } + + PrintFileInformation (Sfo, Node, &FileCount, &FileSize, &DirCount); + FoundOne = TRUE; + HeaderPrinted = TRUE; + } + + if (!Sfo && (ShellStatus != SHELL_ABORTED) && HeaderPrinted) { + PrintNonSfoFooter (FileCount, FileSize, DirCount); + } + } + + if (Rec && (ShellStatus != SHELL_ABORTED)) { + // + // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter + // + ShellCloseFileMetaArg (&ListHead); + CorrectedPath[0] = CHAR_NULL; + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, RootPath, 0); + if (CorrectedPath == NULL) { + return SHELL_OUT_OF_RESOURCES; + } + + if ( (CorrectedPath[StrLen (CorrectedPath)-1] != L'\\') + && (CorrectedPath[StrLen (CorrectedPath)-1] != L'/')) + { + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"\\", 0); + } + + CorrectedPath = StrnCatGrow (&CorrectedPath, &LongestPath, L"*", 0); + Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); + + if (!EFI_ERROR (Status)) { + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link) + ; !IsNull (&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link) + ) + { + if (ShellGetExecutionBreakFlag ()) { + ShellStatus = SHELL_ABORTED; + break; + } + + // + // recurse on any directory except the traversing ones... + // + if ( ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) + && (StrCmp (Node->FileName, L".") != 0) + && (StrCmp (Node->FileName, L"..") != 0) + ) + { + ShellStatus = PrintLsOutput ( + Rec, + Attribs, + Sfo, + Node->FullName, + SearchString, + &FoundOne, + Count, + TimeZone, + FALSE + ); + + // + // Since it's running recursively, we have to break immediately when returned SHELL_ABORTED + // + if (ShellStatus == SHELL_ABORTED) { + break; + } + } + } + } + } + + SHELL_FREE_NON_NULL (CorrectedPath); + ShellCloseFileMetaArg (&ListHead); + + if ((Found == NULL) && !FoundOne) { + if (ListUnfiltered) { + // + // When running "ls" without any filtering request, avoid outputing + // "File not found" when the directory is entirely empty, but print + // header and footer stating "0 File(s), 0 Dir(s)". + // + if (!Sfo) { + PrintNonSfoHeader (RootPath); + if (ShellStatus != SHELL_ABORTED) { + PrintNonSfoFooter (FileCount, FileSize, DirCount); + } + } + } else { + return (SHELL_NOT_FOUND); + } + } + + if (Found != NULL) { + *Found = FoundOne; + } + + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM LsParamList[] = { + { L"-r", TypeFlag }, + { L"-a", TypeStart }, + { L"-sfo", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'ls' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLs ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *Attribs; + SHELL_STATUS ShellStatus; + UINT64 RequiredAttributes; + CONST CHAR16 *PathName; + CONST CHAR16 *CurDir; + UINTN Count; + CHAR16 *FullPath; + UINTN Size; + EFI_TIME TheTime; + CHAR16 *SearchString; + BOOLEAN ListUnfiltered; + + Size = 0; + FullPath = NULL; + ProblemParam = NULL; + Attribs = NULL; + ShellStatus = SHELL_SUCCESS; + RequiredAttributes = 0; + PathName = NULL; + SearchString = NULL; + CurDir = NULL; + Count = 0; + ListUnfiltered = FALSE; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // Fix local copies of the protocol pointers + // + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (LsParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"ls", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + if (ShellCommandLineGetCount (Package) > 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"ls"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // check for -a + // + if (ShellCommandLineGetFlag (Package, L"-a")) { + for ( Attribs = ShellCommandLineGetValue (Package, L"-a") + ; Attribs != NULL && *Attribs != CHAR_NULL && ShellStatus == SHELL_SUCCESS + ; Attribs++ + ) + { + switch (*Attribs) { + case L'a': + case L'A': + RequiredAttributes |= EFI_FILE_ARCHIVE; + Count++; + continue; + case L's': + case L'S': + RequiredAttributes |= EFI_FILE_SYSTEM; + Count++; + continue; + case L'h': + case L'H': + RequiredAttributes |= EFI_FILE_HIDDEN; + Count++; + continue; + case L'r': + case L'R': + RequiredAttributes |= EFI_FILE_READ_ONLY; + Count++; + continue; + case L'd': + case L'D': + RequiredAttributes |= EFI_FILE_DIRECTORY; + Count++; + continue; + default: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, L"ls", ShellCommandLineGetValue (Package, L"-a")); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } // switch + } // for loop + + // + // if nothing is specified all are specified + // + if (RequiredAttributes == 0) { + RequiredAttributes = EFI_FILE_VALID_ATTR; + } + } // if -a present + + if (ShellStatus == SHELL_SUCCESS) { + PathName = ShellCommandLineGetRawValue (Package, 1); + if (PathName == NULL) { + // + // Nothing specified... must start from current directory + // + CurDir = gEfiShellProtocol->GetCurDir (NULL); + if (CurDir == NULL) { + ShellStatus = SHELL_NOT_FOUND; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); + } + + ListUnfiltered = TRUE; + // + // Copy to the 2 strings for starting path and file search string + // + ASSERT (SearchString == NULL); + ASSERT (FullPath == NULL); + StrnCatGrow (&SearchString, NULL, L"*", 0); + StrnCatGrow (&FullPath, NULL, CurDir, 0); + Size = FullPath != NULL ? StrSize (FullPath) : 0; + StrnCatGrow (&FullPath, &Size, L"\\", 0); + } else { + if ((StrStr (PathName, L":") == NULL) && (gEfiShellProtocol->GetCurDir (NULL) == NULL)) { + // + // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD. + // + ShellStatus = SHELL_NOT_FOUND; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); + } else { + // + // We got a valid fully qualified path or we have a CWD + // + ASSERT ((FullPath == NULL && Size == 0) || (FullPath != NULL)); + if (StrStr (PathName, L":") == NULL) { + StrnCatGrow (&FullPath, &Size, gEfiShellProtocol->GetCurDir (NULL), 0); + if (FullPath == NULL) { + ShellCommandLineFreeVarList (Package); + return SHELL_OUT_OF_RESOURCES; + } + + Size = FullPath != NULL ? StrSize (FullPath) : 0; + StrnCatGrow (&FullPath, &Size, L"\\", 0); + } + + StrnCatGrow (&FullPath, &Size, PathName, 0); + if (FullPath == NULL) { + ShellCommandLineFreeVarList (Package); + return SHELL_OUT_OF_RESOURCES; + } + + if (ShellIsDirectory (PathName) == EFI_SUCCESS) { + // + // is listing ends with a directory, then we list all files in that directory + // + ListUnfiltered = TRUE; + StrnCatGrow (&SearchString, NULL, L"*", 0); + } else { + // + // must split off the search part that applies to files from the end of the directory part + // + StrnCatGrow (&SearchString, NULL, FullPath, 0); + if (SearchString == NULL) { + FreePool (FullPath); + ShellCommandLineFreeVarList (Package); + return SHELL_OUT_OF_RESOURCES; + } + + PathRemoveLastItem (FullPath); + CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath))); + } + } + } + + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"ls", L"gRT->GetTime", Status); + TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; + } + + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = PrintLsOutput ( + ShellCommandLineGetFlag (Package, L"-r"), + RequiredAttributes, + ShellCommandLineGetFlag (Package, L"-sfo"), + FullPath, + SearchString, + NULL, + Count, + TheTime.TimeZone, + ListUnfiltered + ); + if (ShellStatus == SHELL_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle, L"ls", FullPath); + } else if (ShellStatus == SHELL_INVALID_PARAMETER) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); + } else if (ShellStatus == SHELL_ABORTED) { + // + // Ignore aborting. + // + } else if (ShellStatus != SHELL_SUCCESS) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); + } + } + } + } + } + + // + // Free memory allocated + // + SHELL_FREE_NON_NULL (SearchString); + SHELL_FREE_NON_NULL (FullPath); + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c index 1e7168364d..4f0a8bb5d0 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c @@ -1,1371 +1,1371 @@ -/** @file
- Main file for map shell level 2 command.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/BlockIo.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HandleParsingLib.h>
-#include <Library/SortLib.h>
-
-/**
- Determine if a string has only numbers and letters.
-
- This is useful for such things as Map names which can only be letters and numbers.
-
- @param[in] String pointer to the string to analyze,
- @param[in] Len Number of characters to analyze.
-
- @retval TRUE String has only numbers and letters
- @retval FALSE String has at least one other character.
-**/
-BOOLEAN
-IsNumberLetterOnly (
- IN CONST CHAR16 *String,
- IN CONST UINTN Len
- )
-{
- UINTN Count;
-
- for (Count = 0; Count < Len && String != NULL && *String != CHAR_NULL; String++, Count++) {
- if (!(((*String >= L'a') && (*String <= L'z')) ||
- ((*String >= L'A') && (*String <= L'Z')) ||
- ((*String >= L'0') && (*String <= L'9')))
- )
- {
- return (FALSE);
- }
- }
-
- return (TRUE);
-}
-
-/**
- Do a search in the Target delimited list.
-
- @param[in] List The list to seatch in.
- @param[in] MetaTarget The item to search for. MetaMatching supported.
- @param[out] FullName Optional pointer to an allocated buffer containing
- the match.
- @param[in] Meta TRUE to use MetaMatching.
- @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget.
- @param[in] Target The single character that delimits list
- items (";" normally).
-**/
-BOOLEAN
-SearchList (
- IN CONST CHAR16 *List,
- IN CONST CHAR16 *MetaTarget,
- OUT CHAR16 **FullName OPTIONAL,
- IN CONST BOOLEAN Meta,
- IN CONST BOOLEAN SkipTrailingNumbers,
- IN CONST CHAR16 *Target
-
- )
-{
- CHAR16 *TempList;
- CONST CHAR16 *ListWalker;
- BOOLEAN Result;
- CHAR16 *TempSpot;
-
- for (ListWalker = List, TempList = NULL
- ; ListWalker != NULL && *ListWalker != CHAR_NULL
- ;
- )
- {
- TempList = StrnCatGrow (&TempList, NULL, ListWalker, 0);
- ASSERT (TempList != NULL);
- TempSpot = StrStr (TempList, Target);
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
-
- while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter (TempList[StrLen (TempList)-1]) || TempList[StrLen (TempList)-1] == L':')) {
- TempList[StrLen (TempList)-1] = CHAR_NULL;
- }
-
- ListWalker = StrStr (ListWalker, Target);
- while (ListWalker != NULL && *ListWalker == *Target) {
- ListWalker++;
- }
-
- if (Meta) {
- Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget);
- } else {
- Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0);
- }
-
- if (Result) {
- if (FullName != NULL) {
- *FullName = TempList;
- } else {
- FreePool (TempList);
- }
-
- return (TRUE);
- }
-
- FreePool (TempList);
- TempList = NULL;
- }
-
- return (FALSE);
-}
-
-/**
- Determine what type of device is represented and return it's string. The
- string is in allocated memory and must be callee freed. The HII is is listed below.
- The actual string cannot be determined.
-
- @param[in] DevicePath The device to analyze.
-
- @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown.
- @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive.
- @retval STR_MAP_MEDIA_CDROM The media is a CD ROM.
- @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive.
-**/
-CHAR16 *
-GetDeviceMediaType (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- ACPI_HID_DEVICE_PATH *Acpi;
-
- //
- // Parse the device path:
- // Devicepath sub type mediatype
- // MEDIA_HANRDDRIVE_DP -> Hard Disk
- // MEDIA_CDROM_DP -> CD Rom
- // Acpi.HID = 0X0604 -> Floppy
- //
- if (NULL == DevicePath) {
- return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);
- }
-
- for ( ; !IsDevicePathEndType (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
- if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {
- switch (DevicePathSubType (DevicePath)) {
- case MEDIA_HARDDRIVE_DP:
- return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_HARDDISK), NULL);
- case MEDIA_CDROM_DP:
- return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_CDROM), NULL);
- }
- } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) {
- Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;
- if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
- return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_FLOPPY), NULL);
- }
- }
- }
-
- return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);
-}
-
-/**
- Function to detemine if a handle has removable storage.
-
- @param[in] DevicePath DevicePath to test.
-
- @retval TRUE The handle has removable storage.
- @retval FALSE The handle does not have removable storage.
-**/
-BOOLEAN
-IsRemoveableDevice (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- if (NULL == DevicePath) {
- return FALSE;
- }
-
- while (!IsDevicePathEndType (DevicePath)) {
- if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) {
- switch (DevicePathSubType (DevicePath)) {
- case MSG_USB_DP:
- case MSG_SCSI_DP:
- return TRUE;
- default:
- return FALSE;
- }
- }
-
- DevicePath = NextDevicePathNode (DevicePath);
- }
-
- return FALSE;
-}
-
-/**
- Function to detemine if a something on the map list matches.
-
- @param[in] MapList The pointer to the list to test.
- @param[in] Specific The pointer to a specific name to test for.
- @param[in] TypeString The pointer to the list of types.
- @param[in] Normal Always show normal mappings.
- @param[in] Consist Always show consistent mappings.
-
- @retval TRUE The map should be displayed.
- @retval FALSE The map should not be displayed.
-**/
-BOOLEAN
-MappingListHasType (
- IN CONST CHAR16 *MapList,
- IN CONST CHAR16 *Specific,
- IN CONST CHAR16 *TypeString,
- IN CONST BOOLEAN Normal,
- IN CONST BOOLEAN Consist
- )
-{
- CHAR16 *NewSpecific;
- RETURN_STATUS Status;
- UINTN Length;
-
- //
- // specific has priority
- //
- if (Specific != NULL) {
- Length = StrLen (Specific);
- //
- // Allocate enough buffer for Specific and potential ":"
- //
- NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16));
- if (NewSpecific == NULL) {
- return FALSE;
- }
-
- StrCpyS (NewSpecific, Length + 2, Specific);
- if (Specific[Length - 1] != L':') {
- Status = StrnCatS (NewSpecific, Length + 2, L":", StrLen (L":"));
- if (EFI_ERROR (Status)) {
- FreePool (NewSpecific);
- return FALSE;
- }
- }
-
- if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {
- FreePool (NewSpecific);
- return (TRUE);
- }
-
- FreePool (NewSpecific);
- }
-
- if ( Consist
- && (Specific == NULL)
- && ( SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";")
- || SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";")
- || SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";")
- || SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";")))
- {
- return (TRUE);
- }
-
- if ( Normal
- && (Specific == NULL)
- && ( SearchList (MapList, L"FS", NULL, FALSE, TRUE, L";")
- || SearchList (MapList, L"BLK", NULL, FALSE, TRUE, L";")))
- {
- return (TRUE);
- }
-
- if ((TypeString != NULL) && SearchList (MapList, TypeString, NULL, TRUE, TRUE, L";")) {
- return (TRUE);
- }
-
- return (FALSE);
-}
-
-/**
- Display a single map line for device Handle if conditions are met.
-
- @param[in] Verbose TRUE to display (extra) verbose information.
- @param[in] Consist TRUE to display consistent mappings.
- @param[in] Normal TRUE to display normal (not consist) mappings.
- @param[in] TypeString pointer to string of filter types.
- @param[in] SFO TRUE to display output in Standard Output Format.
- @param[in] Specific pointer to string for specific map to display.
- @param[in] Handle The handle to display from.
-
- @retval EFI_SUCCESS The mapping was displayed.
-**/
-EFI_STATUS
-PerformSingleMappingDisplay (
- IN CONST BOOLEAN Verbose,
- IN CONST BOOLEAN Consist,
- IN CONST BOOLEAN Normal,
- IN CONST CHAR16 *TypeString,
- IN CONST BOOLEAN SFO,
- IN CONST CHAR16 *Specific OPTIONAL,
- IN CONST EFI_HANDLE Handle
- )
-{
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_DEVICE_PATH_PROTOCOL *DevPathCopy;
- CONST CHAR16 *MapList;
- CHAR16 *CurrentName;
- CHAR16 *MediaType;
- CHAR16 *DevPathString;
- CHAR16 *TempSpot;
- CHAR16 *Alias;
- UINTN TempLen;
- BOOLEAN Removable;
- CONST CHAR16 *TempSpot2;
-
- Alias = NULL;
- TempSpot2 = NULL;
- CurrentName = NULL;
- DevPath = DevicePathFromHandle (Handle);
- DevPathCopy = DevPath;
- MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);
- if (MapList == NULL) {
- return EFI_NOT_FOUND;
- }
-
- if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) {
- return EFI_NOT_FOUND;
- }
-
- if (Normal || !Consist) {
- //
- // need the Normal here since people can use both on command line. otherwise unused.
- //
-
- //
- // Allocate a name
- //
- CurrentName = NULL;
- CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);
- if (CurrentName == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- //
- // Chop off the other names that become "Alias(s)"
- // leaving just the normal name
- //
- TempSpot = StrStr (CurrentName, L";");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
- } else {
- CurrentName = NULL;
-
- //
- // Skip the first name. This is the standard name.
- //
- TempSpot = StrStr (MapList, L";");
- if (TempSpot != NULL) {
- TempSpot++;
- }
-
- SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");
- if (CurrentName == NULL) {
- SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");
- }
-
- if (CurrentName == NULL) {
- SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");
- }
-
- if (CurrentName == NULL) {
- SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";");
- }
-
- if (CurrentName == NULL) {
- //
- // We didnt find anything, so just the first one in the list...
- //
- CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);
- if (CurrentName == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- TempSpot = StrStr (CurrentName, L";");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
- } else {
- Alias = StrnCatGrow (&Alias, 0, MapList, 0);
- if (Alias == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TempSpot = StrStr (Alias, CurrentName);
- if (TempSpot != NULL) {
- TempSpot2 = StrStr (TempSpot, L";");
- if (TempSpot2 != NULL) {
- TempSpot2++; // Move past ";" from CurrentName
- CopyMem (TempSpot, TempSpot2, StrSize (TempSpot2));
- } else {
- *TempSpot = CHAR_NULL;
- }
- }
-
- if (Alias[StrLen (Alias)-1] == L';') {
- Alias[StrLen (Alias)-1] = CHAR_NULL;
- }
- }
- }
-
- DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE);
- TempLen = StrLen (CurrentName);
- if (!SFO) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_MAP_ENTRY),
- gShellLevel2HiiHandle,
- CurrentName,
- Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""),
- DevPathString
- );
- if (Verbose) {
- //
- // also print handle, media type, removable (y/n), and current directory
- //
- MediaType = GetDeviceMediaType (DevPath);
- if (((TypeString != NULL) && (MediaType != NULL) && (StrStr (TypeString, MediaType) != NULL)) || (TypeString == NULL)) {
- Removable = IsRemoveableDevice (DevPath);
- TempSpot2 = ShellGetCurrentDir (CurrentName);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),
- gShellLevel2HiiHandle,
- ConvertHandleToHandleIndex (Handle),
- MediaType,
- Removable ? L"Yes" : L"No",
- TempSpot2
- );
- }
-
- SHELL_FREE_NON_NULL (MediaType);
- }
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_MAP_SFO_MAPPINGS),
- gShellLevel2HiiHandle,
- CurrentName,
- DevPathString,
- Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"")
- );
- }
-
- SHELL_FREE_NON_NULL (DevPathString);
- SHELL_FREE_NON_NULL (CurrentName);
- SHELL_FREE_NON_NULL (Alias);
- return EFI_SUCCESS;
-}
-
-/**
- Delete Specific from the list of maps for device Handle.
-
- @param[in] Specific The name to delete.
- @param[in] Handle The device to look on.
-
- @retval EFI_SUCCESS The delete was successful.
- @retval EFI_NOT_FOUND Name was not a map on Handle.
-**/
-EFI_STATUS
-PerformSingleMappingDelete (
- IN CONST CHAR16 *Specific,
- IN CONST EFI_HANDLE Handle
- )
-{
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_DEVICE_PATH_PROTOCOL *DevPathCopy;
- CONST CHAR16 *MapList;
- CHAR16 *CurrentName;
-
- DevPath = DevicePathFromHandle (Handle);
- DevPathCopy = DevPath;
- MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);
- CurrentName = NULL;
-
- if (MapList == NULL) {
- return (EFI_NOT_FOUND);
- }
-
- //
- // if there is a specific and its not on the list...
- //
- if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {
- return (EFI_NOT_FOUND);
- }
-
- return (gEfiShellProtocol->SetMap (NULL, CurrentName));
-}
-
-CONST CHAR16 Cd[] = L"cd*";
-CONST CHAR16 Hd[] = L"hd*";
-CONST CHAR16 Fp[] = L"fp*";
-CONST CHAR16 AnyF[] = L"F*";
-
-/**
- Function to display mapping information to the user.
-
- If Specific is specified then Consist and Normal will be ignored since information will
- be printed for the specific item only.
-
- @param[in] Verbose TRUE to display (extra) verbose information.
- @param[in] Consist TRUE to display consistent mappings.
- @param[in] Normal TRUE to display normal (not consist) mappings.
- @param[in] TypeString Pointer to string of filter types.
- @param[in] SFO TRUE to display output in Standard Output Format.
- @param[in] Specific Pointer to string for specific map to display.
- @param[in] Header TRUE to print the header block.
-
- @retval SHELL_SUCCESS The display was printed.
- @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific.
-
-**/
-SHELL_STATUS
-PerformMappingDisplay (
- IN CONST BOOLEAN Verbose,
- IN CONST BOOLEAN Consist,
- IN CONST BOOLEAN Normal,
- IN CONST CHAR16 *TypeString,
- IN CONST BOOLEAN SFO,
- IN CONST CHAR16 *Specific OPTIONAL,
- IN CONST BOOLEAN Header
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN BufferSize;
- UINTN LoopVar;
- CHAR16 *Test;
- BOOLEAN Found;
-
- if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
- return (SHELL_INVALID_PARAMETER);
- }
-
- if (TypeString != NULL) {
- Test = (CHAR16 *)Cd;
- if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
- Test = (CHAR16 *)Hd;
- if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
- Test = (CHAR16 *)Fp;
- if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString);
- return (SHELL_INVALID_PARAMETER);
- }
- } else if (Test == NULL) {
- Test = (CHAR16 *)AnyF;
- }
- }
- } else {
- Test = NULL;
- }
-
- if (Header) {
- //
- // Print the header
- //
- if (!SFO) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");
- }
- }
-
- BufferSize = 0;
- HandleBuffer = NULL;
-
- //
- // Look up all SimpleFileSystems in the platform
- //
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiSimpleFileSystemProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HandleBuffer = AllocateZeroPool (BufferSize);
- if (HandleBuffer == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiSimpleFileSystemProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- }
-
- //
- // Get the map name(s) for each one.
- //
- for ( LoopVar = 0, Found = FALSE
- ; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL
- ; LoopVar++
- )
- {
- Status = PerformSingleMappingDisplay (
- Verbose,
- Consist,
- Normal,
- Test,
- SFO,
- Specific,
- HandleBuffer[LoopVar]
- );
- if (!EFI_ERROR (Status)) {
- Found = TRUE;
- }
- }
-
- //
- // Look up all BlockIo in the platform
- //
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiBlockIoProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- SHELL_FREE_NON_NULL (HandleBuffer);
- HandleBuffer = AllocateZeroPool (BufferSize);
- if (HandleBuffer == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiBlockIoProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- }
-
- if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) {
- //
- // Get the map name(s) for each one.
- //
- for ( LoopVar = 0
- ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
- ; LoopVar++
- )
- {
- //
- // Skip any that were already done...
- //
- if (gBS->OpenProtocol (
- HandleBuffer[LoopVar],
- &gEfiSimpleFileSystemProtocolGuid,
- NULL,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- ) == EFI_SUCCESS)
- {
- continue;
- }
-
- Status = PerformSingleMappingDisplay (
- Verbose,
- Consist,
- Normal,
- Test,
- SFO,
- Specific,
- HandleBuffer[LoopVar]
- );
- if (!EFI_ERROR (Status)) {
- Found = TRUE;
- }
- }
-
- FreePool (HandleBuffer);
- }
-
- if (!Found) {
- if (Specific != NULL) {
- ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific);
- } else {
- ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");
- }
- }
-
- return (SHELL_SUCCESS);
-}
-
-/**
- Perform a mapping display and parse for multiple types in the TypeString.
-
- @param[in] Verbose TRUE to use verbose output.
- @param[in] Consist TRUE to display consistent names.
- @param[in] Normal TRUE to display normal names.
- @param[in] TypeString An optional comma-delimited list of types.
- @param[in] SFO TRUE to display in SFO format. See Spec.
- @param[in] Specific An optional specific map name to display alone.
-
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
- @retval SHELL_SUCCESS The display was successful.
- @sa PerformMappingDisplay
-**/
-SHELL_STATUS
-PerformMappingDisplay2 (
- IN CONST BOOLEAN Verbose,
- IN CONST BOOLEAN Consist,
- IN CONST BOOLEAN Normal,
- IN CONST CHAR16 *TypeString,
- IN CONST BOOLEAN SFO,
- IN CONST CHAR16 *Specific OPTIONAL
- )
-{
- CONST CHAR16 *TypeWalker;
- SHELL_STATUS ShellStatus;
- CHAR16 *Comma;
-
- if (TypeString == NULL) {
- return (PerformMappingDisplay (Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));
- }
-
- ShellStatus = SHELL_SUCCESS;
- for (TypeWalker = TypeString; TypeWalker != NULL && *TypeWalker != CHAR_NULL;) {
- Comma = StrStr (TypeWalker, L",");
- if (Comma == NULL) {
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
- } else {
- PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
- }
-
- break;
- } else {
- *Comma = CHAR_NULL;
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
- } else {
- PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
- }
-
- *Comma = L',';
- TypeWalker = Comma + 1;
- }
- }
-
- return (ShellStatus);
-}
-
-/**
- Delete a specific map.
-
- @param[in] Specific The pointer to the name of the map to delete.
-
- @retval EFI_INVALID_PARAMETER Specific was NULL.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_NOT_FOUND Specific could not be found.
-**/
-EFI_STATUS
-PerformMappingDelete (
- IN CONST CHAR16 *Specific
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN BufferSize;
- UINTN LoopVar;
- BOOLEAN Deleted;
-
- if (Specific == NULL) {
- return (EFI_INVALID_PARAMETER);
- }
-
- BufferSize = 0;
- HandleBuffer = NULL;
- Deleted = FALSE;
-
- //
- // Look up all SimpleFileSystems in the platform
- //
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiDevicePathProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HandleBuffer = AllocateZeroPool (BufferSize);
- if (HandleBuffer == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiDevicePathProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- }
-
- if (EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (HandleBuffer);
- return (Status);
- }
-
- if (HandleBuffer != NULL) {
- //
- // Get the map name(s) for each one.
- //
- for ( LoopVar = 0
- ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
- ; LoopVar++
- )
- {
- if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
- Deleted = TRUE;
- }
- }
- }
-
- //
- // Look up all BlockIo in the platform
- //
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiBlockIoProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (HandleBuffer);
- HandleBuffer = AllocateZeroPool (BufferSize);
- if (HandleBuffer == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- Status = gBS->LocateHandle (
- ByProtocol,
- &gEfiBlockIoProtocolGuid,
- NULL,
- &BufferSize,
- HandleBuffer
- );
- }
-
- if (EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (HandleBuffer);
- return (Status);
- }
-
- if (HandleBuffer != NULL) {
- //
- // Get the map name(s) for each one.
- //
- for ( LoopVar = 0
- ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
- ; LoopVar++
- )
- {
- //
- // Skip any that were already done...
- //
- if (gBS->OpenProtocol (
- HandleBuffer[LoopVar],
- &gEfiDevicePathProtocolGuid,
- NULL,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- ) == EFI_SUCCESS)
- {
- continue;
- }
-
- if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
- Deleted = TRUE;
- }
- }
- }
-
- SHELL_FREE_NON_NULL (HandleBuffer);
- if (!Deleted) {
- return (EFI_NOT_FOUND);
- }
-
- return (EFI_SUCCESS);
-}
-
-/**
- function to add a mapping from mapping.
-
- This function will get the device path associated with the mapping and call SetMap.
-
- @param[in] Map The Map to add a mapping for
- @param[in] SName The name of the new mapping
-
- @retval SHELL_SUCCESS the mapping was added
- @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved.
- @return Shell version of a return value from EfiShellProtocol->SetMap
-
-**/
-SHELL_STATUS
-AddMappingFromMapping (
- IN CONST CHAR16 *Map,
- IN CONST CHAR16 *SName
- )
-{
- CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_STATUS Status;
- CHAR16 *NewSName;
- RETURN_STATUS StrRetStatus;
-
- NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
- if (NewSName == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- if (NewSName[StrLen (NewSName)-1] != L':') {
- StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));
- if (EFI_ERROR (StrRetStatus)) {
- FreePool (NewSName);
- return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));
- }
- }
-
- if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
- FreePool (NewSName);
- return (SHELL_INVALID_PARAMETER);
- }
-
- DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map);
- if (DevPath == NULL) {
- FreePool (NewSName);
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
- FreePool (NewSName);
- if (EFI_ERROR (Status)) {
- return (SHELL_DEVICE_ERROR);
- }
-
- return (SHELL_SUCCESS);
-}
-
-/**
- function to add a mapping from an EFI_HANDLE.
-
- This function will get the device path associated with the Handle and call SetMap.
-
- @param[in] Handle The handle to add a mapping for
- @param[in] SName The name of the new mapping
-
- @retval SHELL_SUCCESS the mapping was added
- @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.
- @return Shell version of a return value from either
- gBS->OpenProtocol or EfiShellProtocol->SetMap
-
-**/
-SHELL_STATUS
-AddMappingFromHandle (
- IN CONST EFI_HANDLE Handle,
- IN CONST CHAR16 *SName
- )
-{
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_STATUS Status;
- CHAR16 *NewSName;
- RETURN_STATUS StrRetStatus;
-
- NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
- if (NewSName == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- if (NewSName[StrLen (NewSName)-1] != L':') {
- StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));
- if (EFI_ERROR (StrRetStatus)) {
- FreePool (NewSName);
- return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));
- }
- }
-
- if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
- FreePool (NewSName);
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gBS->OpenProtocol (
- Handle,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&DevPath,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- FreePool (NewSName);
- return (SHELL_DEVICE_ERROR);
- }
-
- Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
- FreePool (NewSName);
- if (EFI_ERROR (Status)) {
- return (SHELL_DEVICE_ERROR);
- }
-
- return (SHELL_SUCCESS);
-}
-
-STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {
- { L"-d", TypeValue },
- { L"-r", TypeFlag },
- { L"-v", TypeFlag },
- { L"-c", TypeFlag },
- { L"-f", TypeFlag },
- { L"-u", TypeFlag },
- { L"-t", TypeValue },
- { L"-sfo", TypeValue },
- { NULL, TypeMax }
-};
-
-/**
- The routine issues dummy read for every physical block device to cause
- the BlockIo re-installed if media change happened.
-**/
-VOID
-ProbeForMediaChange (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *Handles;
- EFI_BLOCK_IO_PROTOCOL *BlockIo;
- UINTN Index;
-
- gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiBlockIoProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- //
- // Probe for media change for every physical block io
- //
- for (Index = 0; Index < HandleCount; Index++) {
- Status = gBS->HandleProtocol (
- Handles[Index],
- &gEfiBlockIoProtocolGuid,
- (VOID **)&BlockIo
- );
- if (!EFI_ERROR (Status)) {
- if (!BlockIo->Media->LogicalPartition) {
- //
- // Per spec:
- // The function (ReadBlocks) must return EFI_NO_MEDIA or
- // EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe
- // for changes in media state.
- //
- BlockIo->ReadBlocks (
- BlockIo,
- BlockIo->Media->MediaId,
- 0,
- 0,
- NULL
- );
- }
- }
- }
-}
-
-/**
- Function for 'map' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMap (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- CONST CHAR16 *SName;
- CONST CHAR16 *Mapping;
- EFI_HANDLE MapAsHandle;
- SHELL_STATUS ShellStatus;
- BOOLEAN SfoMode;
- BOOLEAN ConstMode;
- BOOLEAN NormlMode;
- CONST CHAR16 *Param1;
- CONST CHAR16 *TypeString;
- UINTN TempStringLength;
-
- ProblemParam = NULL;
- Mapping = NULL;
- SName = NULL;
- ShellStatus = SHELL_SUCCESS;
- MapAsHandle = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- SfoMode = ShellCommandLineGetFlag (Package, L"-sfo");
- ConstMode = ShellCommandLineGetFlag (Package, L"-c");
- NormlMode = ShellCommandLineGetFlag (Package, L"-f");
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // Deleting a map name...
- //
- if (ShellCommandLineGetFlag (Package, L"-d")) {
- if ( ShellCommandLineGetFlag (Package, L"-r")
- || ShellCommandLineGetFlag (Package, L"-v")
- || ConstMode
- || NormlMode
- || ShellCommandLineGetFlag (Package, L"-u")
- || ShellCommandLineGetFlag (Package, L"-t")
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- SName = ShellCommandLineGetValue (Package, L"-d");
- if (SName != NULL) {
- Status = PerformMappingDelete (SName);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_ACCESS_DENIED) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
- ShellStatus = SHELL_ACCESS_DENIED;
- } else if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
- ShellStatus = SHELL_UNSUPPORTED;
- }
- }
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- } else if ( ShellCommandLineGetFlag (Package, L"-r")
- // || ShellCommandLineGetFlag(Package, L"-v")
- || ConstMode
- || NormlMode
- || ShellCommandLineGetFlag (Package, L"-u")
- || ShellCommandLineGetFlag (Package, L"-t")
- )
- {
- ProbeForMediaChange ();
- if ( ShellCommandLineGetFlag (Package, L"-r")) {
- //
- // Do the reset
- //
- Status = ShellCommandCreateInitialMappingsAndPaths ();
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
- ShellStatus = SHELL_UNSUPPORTED;
- }
- }
-
- if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) {
- //
- // Do the Update
- //
- Status = ShellCommandUpdateMapping ();
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
- ShellStatus = SHELL_UNSUPPORTED;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- Param1 = ShellCommandLineGetRawValue (Package, 1);
- TypeString = ShellCommandLineGetValue (Package, L"-t");
- if ( !ConstMode
- && !NormlMode
- && (TypeString == NULL)
- )
- {
- //
- // now do the display...
- //
- ShellStatus = PerformMappingDisplay (
- ShellCommandLineGetFlag (Package, L"-v"),
- TRUE,
- TRUE,
- NULL,
- SfoMode,
- Param1,
- TRUE
- );
- } else {
- //
- // now do the display...
- //
- ShellStatus = PerformMappingDisplay2 (
- ShellCommandLineGetFlag (Package, L"-v"),
- ConstMode,
- NormlMode,
- TypeString,
- SfoMode,
- Param1
- );
- }
- }
- } else {
- //
- // adding or displaying (there were no flags)
- //
- SName = ShellCommandLineGetRawValue (Package, 1);
- Mapping = ShellCommandLineGetRawValue (Package, 2);
- if ( (SName == NULL)
- && (Mapping == NULL)
- )
- {
- //
- // display only since no flags
- //
- ShellStatus = PerformMappingDisplay (
- ShellCommandLineGetFlag (Package, L"-v"),
- TRUE,
- TRUE,
- NULL,
- SfoMode,
- NULL,
- TRUE
- );
- } else if ( (SName == NULL)
- || (Mapping == NULL)
- )
- {
- //
- // Display only the one specified
- //
- ShellStatus = PerformMappingDisplay (
- FALSE,
- FALSE,
- FALSE,
- NULL,
- SfoMode,
- SName, // note the variable here...
- TRUE
- );
- } else {
- if (ShellIsHexOrDecimalNumber (Mapping, TRUE, FALSE)) {
- MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping));
- } else {
- MapAsHandle = NULL;
- }
-
- if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- TempStringLength = StrLen (SName);
- if (!IsNumberLetterOnly (SName, TempStringLength-((SName[TempStringLength-1] == L':') ? 1 : 0))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- if (MapAsHandle != NULL) {
- ShellStatus = AddMappingFromHandle (MapAsHandle, SName);
- } else {
- ShellStatus = AddMappingFromMapping (Mapping, SName);
- }
-
- if (ShellStatus != SHELL_SUCCESS) {
- switch (ShellStatus) {
- case SHELL_ACCESS_DENIED:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
- break;
- case SHELL_INVALID_PARAMETER:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
- break;
- case SHELL_DEVICE_ERROR:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);
- break;
- default:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT);
- }
- } else {
- //
- // now do the display...
- //
- ShellStatus = PerformMappingDisplay (
- FALSE,
- FALSE,
- FALSE,
- NULL,
- SfoMode,
- SName,
- TRUE
- );
- } // we were successful so do an output
- }
- } // got a valid map target
- } // got 2 variables
- } // we are adding a mapping
- } // got valid parameters
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for map shell level 2 command. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" +#include <Protocol/SimpleFileSystem.h> +#include <Protocol/BlockIo.h> +#include <Library/DevicePathLib.h> +#include <Library/HandleParsingLib.h> +#include <Library/SortLib.h> + +/** + Determine if a string has only numbers and letters. + + This is useful for such things as Map names which can only be letters and numbers. + + @param[in] String pointer to the string to analyze, + @param[in] Len Number of characters to analyze. + + @retval TRUE String has only numbers and letters + @retval FALSE String has at least one other character. +**/ +BOOLEAN +IsNumberLetterOnly ( + IN CONST CHAR16 *String, + IN CONST UINTN Len + ) +{ + UINTN Count; + + for (Count = 0; Count < Len && String != NULL && *String != CHAR_NULL; String++, Count++) { + if (!(((*String >= L'a') && (*String <= L'z')) || + ((*String >= L'A') && (*String <= L'Z')) || + ((*String >= L'0') && (*String <= L'9'))) + ) + { + return (FALSE); + } + } + + return (TRUE); +} + +/** + Do a search in the Target delimited list. + + @param[in] List The list to seatch in. + @param[in] MetaTarget The item to search for. MetaMatching supported. + @param[out] FullName Optional pointer to an allocated buffer containing + the match. + @param[in] Meta TRUE to use MetaMatching. + @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget. + @param[in] Target The single character that delimits list + items (";" normally). +**/ +BOOLEAN +SearchList ( + IN CONST CHAR16 *List, + IN CONST CHAR16 *MetaTarget, + OUT CHAR16 **FullName OPTIONAL, + IN CONST BOOLEAN Meta, + IN CONST BOOLEAN SkipTrailingNumbers, + IN CONST CHAR16 *Target + + ) +{ + CHAR16 *TempList; + CONST CHAR16 *ListWalker; + BOOLEAN Result; + CHAR16 *TempSpot; + + for (ListWalker = List, TempList = NULL + ; ListWalker != NULL && *ListWalker != CHAR_NULL + ; + ) + { + TempList = StrnCatGrow (&TempList, NULL, ListWalker, 0); + ASSERT (TempList != NULL); + TempSpot = StrStr (TempList, Target); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + + while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter (TempList[StrLen (TempList)-1]) || TempList[StrLen (TempList)-1] == L':')) { + TempList[StrLen (TempList)-1] = CHAR_NULL; + } + + ListWalker = StrStr (ListWalker, Target); + while (ListWalker != NULL && *ListWalker == *Target) { + ListWalker++; + } + + if (Meta) { + Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget); + } else { + Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0); + } + + if (Result) { + if (FullName != NULL) { + *FullName = TempList; + } else { + FreePool (TempList); + } + + return (TRUE); + } + + FreePool (TempList); + TempList = NULL; + } + + return (FALSE); +} + +/** + Determine what type of device is represented and return it's string. The + string is in allocated memory and must be callee freed. The HII is is listed below. + The actual string cannot be determined. + + @param[in] DevicePath The device to analyze. + + @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown. + @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive. + @retval STR_MAP_MEDIA_CDROM The media is a CD ROM. + @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive. +**/ +CHAR16 * +GetDeviceMediaType ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + ACPI_HID_DEVICE_PATH *Acpi; + + // + // Parse the device path: + // Devicepath sub type mediatype + // MEDIA_HANRDDRIVE_DP -> Hard Disk + // MEDIA_CDROM_DP -> CD Rom + // Acpi.HID = 0X0604 -> Floppy + // + if (NULL == DevicePath) { + return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL); + } + + for ( ; !IsDevicePathEndType (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { + if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) { + switch (DevicePathSubType (DevicePath)) { + case MEDIA_HARDDRIVE_DP: + return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_HARDDISK), NULL); + case MEDIA_CDROM_DP: + return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_CDROM), NULL); + } + } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) { + Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath; + if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) { + return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_FLOPPY), NULL); + } + } + } + + return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL); +} + +/** + Function to detemine if a handle has removable storage. + + @param[in] DevicePath DevicePath to test. + + @retval TRUE The handle has removable storage. + @retval FALSE The handle does not have removable storage. +**/ +BOOLEAN +IsRemoveableDevice ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + if (NULL == DevicePath) { + return FALSE; + } + + while (!IsDevicePathEndType (DevicePath)) { + if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) { + switch (DevicePathSubType (DevicePath)) { + case MSG_USB_DP: + case MSG_SCSI_DP: + return TRUE; + default: + return FALSE; + } + } + + DevicePath = NextDevicePathNode (DevicePath); + } + + return FALSE; +} + +/** + Function to detemine if a something on the map list matches. + + @param[in] MapList The pointer to the list to test. + @param[in] Specific The pointer to a specific name to test for. + @param[in] TypeString The pointer to the list of types. + @param[in] Normal Always show normal mappings. + @param[in] Consist Always show consistent mappings. + + @retval TRUE The map should be displayed. + @retval FALSE The map should not be displayed. +**/ +BOOLEAN +MappingListHasType ( + IN CONST CHAR16 *MapList, + IN CONST CHAR16 *Specific, + IN CONST CHAR16 *TypeString, + IN CONST BOOLEAN Normal, + IN CONST BOOLEAN Consist + ) +{ + CHAR16 *NewSpecific; + RETURN_STATUS Status; + UINTN Length; + + // + // specific has priority + // + if (Specific != NULL) { + Length = StrLen (Specific); + // + // Allocate enough buffer for Specific and potential ":" + // + NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16)); + if (NewSpecific == NULL) { + return FALSE; + } + + StrCpyS (NewSpecific, Length + 2, Specific); + if (Specific[Length - 1] != L':') { + Status = StrnCatS (NewSpecific, Length + 2, L":", StrLen (L":")); + if (EFI_ERROR (Status)) { + FreePool (NewSpecific); + return FALSE; + } + } + + if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) { + FreePool (NewSpecific); + return (TRUE); + } + + FreePool (NewSpecific); + } + + if ( Consist + && (Specific == NULL) + && ( SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";") + || SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";") + || SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";") + || SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";"))) + { + return (TRUE); + } + + if ( Normal + && (Specific == NULL) + && ( SearchList (MapList, L"FS", NULL, FALSE, TRUE, L";") + || SearchList (MapList, L"BLK", NULL, FALSE, TRUE, L";"))) + { + return (TRUE); + } + + if ((TypeString != NULL) && SearchList (MapList, TypeString, NULL, TRUE, TRUE, L";")) { + return (TRUE); + } + + return (FALSE); +} + +/** + Display a single map line for device Handle if conditions are met. + + @param[in] Verbose TRUE to display (extra) verbose information. + @param[in] Consist TRUE to display consistent mappings. + @param[in] Normal TRUE to display normal (not consist) mappings. + @param[in] TypeString pointer to string of filter types. + @param[in] SFO TRUE to display output in Standard Output Format. + @param[in] Specific pointer to string for specific map to display. + @param[in] Handle The handle to display from. + + @retval EFI_SUCCESS The mapping was displayed. +**/ +EFI_STATUS +PerformSingleMappingDisplay ( + IN CONST BOOLEAN Verbose, + IN CONST BOOLEAN Consist, + IN CONST BOOLEAN Normal, + IN CONST CHAR16 *TypeString, + IN CONST BOOLEAN SFO, + IN CONST CHAR16 *Specific OPTIONAL, + IN CONST EFI_HANDLE Handle + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_DEVICE_PATH_PROTOCOL *DevPathCopy; + CONST CHAR16 *MapList; + CHAR16 *CurrentName; + CHAR16 *MediaType; + CHAR16 *DevPathString; + CHAR16 *TempSpot; + CHAR16 *Alias; + UINTN TempLen; + BOOLEAN Removable; + CONST CHAR16 *TempSpot2; + + Alias = NULL; + TempSpot2 = NULL; + CurrentName = NULL; + DevPath = DevicePathFromHandle (Handle); + DevPathCopy = DevPath; + MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy); + if (MapList == NULL) { + return EFI_NOT_FOUND; + } + + if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) { + return EFI_NOT_FOUND; + } + + if (Normal || !Consist) { + // + // need the Normal here since people can use both on command line. otherwise unused. + // + + // + // Allocate a name + // + CurrentName = NULL; + CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0); + if (CurrentName == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + // + // Chop off the other names that become "Alias(s)" + // leaving just the normal name + // + TempSpot = StrStr (CurrentName, L";"); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + } else { + CurrentName = NULL; + + // + // Skip the first name. This is the standard name. + // + TempSpot = StrStr (MapList, L";"); + if (TempSpot != NULL) { + TempSpot++; + } + + SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";"); + if (CurrentName == NULL) { + SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";"); + } + + if (CurrentName == NULL) { + SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";"); + } + + if (CurrentName == NULL) { + SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";"); + } + + if (CurrentName == NULL) { + // + // We didnt find anything, so just the first one in the list... + // + CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0); + if (CurrentName == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + TempSpot = StrStr (CurrentName, L";"); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + } else { + Alias = StrnCatGrow (&Alias, 0, MapList, 0); + if (Alias == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TempSpot = StrStr (Alias, CurrentName); + if (TempSpot != NULL) { + TempSpot2 = StrStr (TempSpot, L";"); + if (TempSpot2 != NULL) { + TempSpot2++; // Move past ";" from CurrentName + CopyMem (TempSpot, TempSpot2, StrSize (TempSpot2)); + } else { + *TempSpot = CHAR_NULL; + } + } + + if (Alias[StrLen (Alias)-1] == L';') { + Alias[StrLen (Alias)-1] = CHAR_NULL; + } + } + } + + DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE); + TempLen = StrLen (CurrentName); + if (!SFO) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_MAP_ENTRY), + gShellLevel2HiiHandle, + CurrentName, + Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""), + DevPathString + ); + if (Verbose) { + // + // also print handle, media type, removable (y/n), and current directory + // + MediaType = GetDeviceMediaType (DevPath); + if (((TypeString != NULL) && (MediaType != NULL) && (StrStr (TypeString, MediaType) != NULL)) || (TypeString == NULL)) { + Removable = IsRemoveableDevice (DevPath); + TempSpot2 = ShellGetCurrentDir (CurrentName); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_MAP_ENTRY_VERBOSE), + gShellLevel2HiiHandle, + ConvertHandleToHandleIndex (Handle), + MediaType, + Removable ? L"Yes" : L"No", + TempSpot2 + ); + } + + SHELL_FREE_NON_NULL (MediaType); + } + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_MAP_SFO_MAPPINGS), + gShellLevel2HiiHandle, + CurrentName, + DevPathString, + Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"") + ); + } + + SHELL_FREE_NON_NULL (DevPathString); + SHELL_FREE_NON_NULL (CurrentName); + SHELL_FREE_NON_NULL (Alias); + return EFI_SUCCESS; +} + +/** + Delete Specific from the list of maps for device Handle. + + @param[in] Specific The name to delete. + @param[in] Handle The device to look on. + + @retval EFI_SUCCESS The delete was successful. + @retval EFI_NOT_FOUND Name was not a map on Handle. +**/ +EFI_STATUS +PerformSingleMappingDelete ( + IN CONST CHAR16 *Specific, + IN CONST EFI_HANDLE Handle + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_DEVICE_PATH_PROTOCOL *DevPathCopy; + CONST CHAR16 *MapList; + CHAR16 *CurrentName; + + DevPath = DevicePathFromHandle (Handle); + DevPathCopy = DevPath; + MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy); + CurrentName = NULL; + + if (MapList == NULL) { + return (EFI_NOT_FOUND); + } + + // + // if there is a specific and its not on the list... + // + if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) { + return (EFI_NOT_FOUND); + } + + return (gEfiShellProtocol->SetMap (NULL, CurrentName)); +} + +CONST CHAR16 Cd[] = L"cd*"; +CONST CHAR16 Hd[] = L"hd*"; +CONST CHAR16 Fp[] = L"fp*"; +CONST CHAR16 AnyF[] = L"F*"; + +/** + Function to display mapping information to the user. + + If Specific is specified then Consist and Normal will be ignored since information will + be printed for the specific item only. + + @param[in] Verbose TRUE to display (extra) verbose information. + @param[in] Consist TRUE to display consistent mappings. + @param[in] Normal TRUE to display normal (not consist) mappings. + @param[in] TypeString Pointer to string of filter types. + @param[in] SFO TRUE to display output in Standard Output Format. + @param[in] Specific Pointer to string for specific map to display. + @param[in] Header TRUE to print the header block. + + @retval SHELL_SUCCESS The display was printed. + @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific. + +**/ +SHELL_STATUS +PerformMappingDisplay ( + IN CONST BOOLEAN Verbose, + IN CONST BOOLEAN Consist, + IN CONST BOOLEAN Normal, + IN CONST CHAR16 *TypeString, + IN CONST BOOLEAN SFO, + IN CONST CHAR16 *Specific OPTIONAL, + IN CONST BOOLEAN Header + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN BufferSize; + UINTN LoopVar; + CHAR16 *Test; + BOOLEAN Found; + + if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map"); + return (SHELL_INVALID_PARAMETER); + } + + if (TypeString != NULL) { + Test = (CHAR16 *)Cd; + if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { + Test = (CHAR16 *)Hd; + if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { + Test = (CHAR16 *)Fp; + if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString); + return (SHELL_INVALID_PARAMETER); + } + } else if (Test == NULL) { + Test = (CHAR16 *)AnyF; + } + } + } else { + Test = NULL; + } + + if (Header) { + // + // Print the header + // + if (!SFO) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map"); + } + } + + BufferSize = 0; + HandleBuffer = NULL; + + // + // Look up all SimpleFileSystems in the platform + // + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + HandleBuffer = AllocateZeroPool (BufferSize); + if (HandleBuffer == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + } + + // + // Get the map name(s) for each one. + // + for ( LoopVar = 0, Found = FALSE + ; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL + ; LoopVar++ + ) + { + Status = PerformSingleMappingDisplay ( + Verbose, + Consist, + Normal, + Test, + SFO, + Specific, + HandleBuffer[LoopVar] + ); + if (!EFI_ERROR (Status)) { + Found = TRUE; + } + } + + // + // Look up all BlockIo in the platform + // + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + SHELL_FREE_NON_NULL (HandleBuffer); + HandleBuffer = AllocateZeroPool (BufferSize); + if (HandleBuffer == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + } + + if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) { + // + // Get the map name(s) for each one. + // + for ( LoopVar = 0 + ; LoopVar < BufferSize / sizeof (EFI_HANDLE) + ; LoopVar++ + ) + { + // + // Skip any that were already done... + // + if (gBS->OpenProtocol ( + HandleBuffer[LoopVar], + &gEfiSimpleFileSystemProtocolGuid, + NULL, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ) == EFI_SUCCESS) + { + continue; + } + + Status = PerformSingleMappingDisplay ( + Verbose, + Consist, + Normal, + Test, + SFO, + Specific, + HandleBuffer[LoopVar] + ); + if (!EFI_ERROR (Status)) { + Found = TRUE; + } + } + + FreePool (HandleBuffer); + } + + if (!Found) { + if (Specific != NULL) { + ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific); + } else { + ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map"); + } + } + + return (SHELL_SUCCESS); +} + +/** + Perform a mapping display and parse for multiple types in the TypeString. + + @param[in] Verbose TRUE to use verbose output. + @param[in] Consist TRUE to display consistent names. + @param[in] Normal TRUE to display normal names. + @param[in] TypeString An optional comma-delimited list of types. + @param[in] SFO TRUE to display in SFO format. See Spec. + @param[in] Specific An optional specific map name to display alone. + + @retval SHELL_INVALID_PARAMETER A parameter was invalid. + @retval SHELL_SUCCESS The display was successful. + @sa PerformMappingDisplay +**/ +SHELL_STATUS +PerformMappingDisplay2 ( + IN CONST BOOLEAN Verbose, + IN CONST BOOLEAN Consist, + IN CONST BOOLEAN Normal, + IN CONST CHAR16 *TypeString, + IN CONST BOOLEAN SFO, + IN CONST CHAR16 *Specific OPTIONAL + ) +{ + CONST CHAR16 *TypeWalker; + SHELL_STATUS ShellStatus; + CHAR16 *Comma; + + if (TypeString == NULL) { + return (PerformMappingDisplay (Verbose, Consist, Normal, NULL, SFO, Specific, TRUE)); + } + + ShellStatus = SHELL_SUCCESS; + for (TypeWalker = TypeString; TypeWalker != NULL && *TypeWalker != CHAR_NULL;) { + Comma = StrStr (TypeWalker, L","); + if (Comma == NULL) { + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); + } else { + PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); + } + + break; + } else { + *Comma = CHAR_NULL; + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); + } else { + PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); + } + + *Comma = L','; + TypeWalker = Comma + 1; + } + } + + return (ShellStatus); +} + +/** + Delete a specific map. + + @param[in] Specific The pointer to the name of the map to delete. + + @retval EFI_INVALID_PARAMETER Specific was NULL. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_NOT_FOUND Specific could not be found. +**/ +EFI_STATUS +PerformMappingDelete ( + IN CONST CHAR16 *Specific + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN BufferSize; + UINTN LoopVar; + BOOLEAN Deleted; + + if (Specific == NULL) { + return (EFI_INVALID_PARAMETER); + } + + BufferSize = 0; + HandleBuffer = NULL; + Deleted = FALSE; + + // + // Look up all SimpleFileSystems in the platform + // + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiDevicePathProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + HandleBuffer = AllocateZeroPool (BufferSize); + if (HandleBuffer == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiDevicePathProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + } + + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (HandleBuffer); + return (Status); + } + + if (HandleBuffer != NULL) { + // + // Get the map name(s) for each one. + // + for ( LoopVar = 0 + ; LoopVar < BufferSize / sizeof (EFI_HANDLE) + ; LoopVar++ + ) + { + if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) { + Deleted = TRUE; + } + } + } + + // + // Look up all BlockIo in the platform + // + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (HandleBuffer); + HandleBuffer = AllocateZeroPool (BufferSize); + if (HandleBuffer == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &BufferSize, + HandleBuffer + ); + } + + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (HandleBuffer); + return (Status); + } + + if (HandleBuffer != NULL) { + // + // Get the map name(s) for each one. + // + for ( LoopVar = 0 + ; LoopVar < BufferSize / sizeof (EFI_HANDLE) + ; LoopVar++ + ) + { + // + // Skip any that were already done... + // + if (gBS->OpenProtocol ( + HandleBuffer[LoopVar], + &gEfiDevicePathProtocolGuid, + NULL, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ) == EFI_SUCCESS) + { + continue; + } + + if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) { + Deleted = TRUE; + } + } + } + + SHELL_FREE_NON_NULL (HandleBuffer); + if (!Deleted) { + return (EFI_NOT_FOUND); + } + + return (EFI_SUCCESS); +} + +/** + function to add a mapping from mapping. + + This function will get the device path associated with the mapping and call SetMap. + + @param[in] Map The Map to add a mapping for + @param[in] SName The name of the new mapping + + @retval SHELL_SUCCESS the mapping was added + @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved. + @return Shell version of a return value from EfiShellProtocol->SetMap + +**/ +SHELL_STATUS +AddMappingFromMapping ( + IN CONST CHAR16 *Map, + IN CONST CHAR16 *SName + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_STATUS Status; + CHAR16 *NewSName; + RETURN_STATUS StrRetStatus; + + NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName); + if (NewSName == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + if (NewSName[StrLen (NewSName)-1] != L':') { + StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":")); + if (EFI_ERROR (StrRetStatus)) { + FreePool (NewSName); + return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT))); + } + } + + if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) { + FreePool (NewSName); + return (SHELL_INVALID_PARAMETER); + } + + DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map); + if (DevPath == NULL) { + FreePool (NewSName); + return (SHELL_INVALID_PARAMETER); + } + + Status = gEfiShellProtocol->SetMap (DevPath, NewSName); + FreePool (NewSName); + if (EFI_ERROR (Status)) { + return (SHELL_DEVICE_ERROR); + } + + return (SHELL_SUCCESS); +} + +/** + function to add a mapping from an EFI_HANDLE. + + This function will get the device path associated with the Handle and call SetMap. + + @param[in] Handle The handle to add a mapping for + @param[in] SName The name of the new mapping + + @retval SHELL_SUCCESS the mapping was added + @retval SHELL_INVALID_PARAMETER SName was not valid for a map name. + @return Shell version of a return value from either + gBS->OpenProtocol or EfiShellProtocol->SetMap + +**/ +SHELL_STATUS +AddMappingFromHandle ( + IN CONST EFI_HANDLE Handle, + IN CONST CHAR16 *SName + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_STATUS Status; + CHAR16 *NewSName; + RETURN_STATUS StrRetStatus; + + NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName); + if (NewSName == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + if (NewSName[StrLen (NewSName)-1] != L':') { + StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":")); + if (EFI_ERROR (StrRetStatus)) { + FreePool (NewSName); + return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT))); + } + } + + if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) { + FreePool (NewSName); + return (SHELL_INVALID_PARAMETER); + } + + Status = gBS->OpenProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID **)&DevPath, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + FreePool (NewSName); + return (SHELL_DEVICE_ERROR); + } + + Status = gEfiShellProtocol->SetMap (DevPath, NewSName); + FreePool (NewSName); + if (EFI_ERROR (Status)) { + return (SHELL_DEVICE_ERROR); + } + + return (SHELL_SUCCESS); +} + +STATIC CONST SHELL_PARAM_ITEM MapParamList[] = { + { L"-d", TypeValue }, + { L"-r", TypeFlag }, + { L"-v", TypeFlag }, + { L"-c", TypeFlag }, + { L"-f", TypeFlag }, + { L"-u", TypeFlag }, + { L"-t", TypeValue }, + { L"-sfo", TypeValue }, + { NULL, TypeMax } +}; + +/** + The routine issues dummy read for every physical block device to cause + the BlockIo re-installed if media change happened. +**/ +VOID +ProbeForMediaChange ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *Handles; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + UINTN Index; + + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + // + // Probe for media change for every physical block io + // + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + Handles[Index], + &gEfiBlockIoProtocolGuid, + (VOID **)&BlockIo + ); + if (!EFI_ERROR (Status)) { + if (!BlockIo->Media->LogicalPartition) { + // + // Per spec: + // The function (ReadBlocks) must return EFI_NO_MEDIA or + // EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe + // for changes in media state. + // + BlockIo->ReadBlocks ( + BlockIo, + BlockIo->Media->MediaId, + 0, + 0, + NULL + ); + } + } + } +} + +/** + Function for 'map' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMap ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *SName; + CONST CHAR16 *Mapping; + EFI_HANDLE MapAsHandle; + SHELL_STATUS ShellStatus; + BOOLEAN SfoMode; + BOOLEAN ConstMode; + BOOLEAN NormlMode; + CONST CHAR16 *Param1; + CONST CHAR16 *TypeString; + UINTN TempStringLength; + + ProblemParam = NULL; + Mapping = NULL; + SName = NULL; + ShellStatus = SHELL_SUCCESS; + MapAsHandle = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + SfoMode = ShellCommandLineGetFlag (Package, L"-sfo"); + ConstMode = ShellCommandLineGetFlag (Package, L"-c"); + NormlMode = ShellCommandLineGetFlag (Package, L"-f"); + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // Deleting a map name... + // + if (ShellCommandLineGetFlag (Package, L"-d")) { + if ( ShellCommandLineGetFlag (Package, L"-r") + || ShellCommandLineGetFlag (Package, L"-v") + || ConstMode + || NormlMode + || ShellCommandLineGetFlag (Package, L"-u") + || ShellCommandLineGetFlag (Package, L"-t") + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + SName = ShellCommandLineGetValue (Package, L"-d"); + if (SName != NULL) { + Status = PerformMappingDelete (SName); + if (EFI_ERROR (Status)) { + if (Status == EFI_ACCESS_DENIED) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map"); + ShellStatus = SHELL_ACCESS_DENIED; + } else if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); + ShellStatus = SHELL_UNSUPPORTED; + } + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } else if ( ShellCommandLineGetFlag (Package, L"-r") + // || ShellCommandLineGetFlag(Package, L"-v") + || ConstMode + || NormlMode + || ShellCommandLineGetFlag (Package, L"-u") + || ShellCommandLineGetFlag (Package, L"-t") + ) + { + ProbeForMediaChange (); + if ( ShellCommandLineGetFlag (Package, L"-r")) { + // + // Do the reset + // + Status = ShellCommandCreateInitialMappingsAndPaths (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); + ShellStatus = SHELL_UNSUPPORTED; + } + } + + if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) { + // + // Do the Update + // + Status = ShellCommandUpdateMapping (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); + ShellStatus = SHELL_UNSUPPORTED; + } + } + + if (ShellStatus == SHELL_SUCCESS) { + Param1 = ShellCommandLineGetRawValue (Package, 1); + TypeString = ShellCommandLineGetValue (Package, L"-t"); + if ( !ConstMode + && !NormlMode + && (TypeString == NULL) + ) + { + // + // now do the display... + // + ShellStatus = PerformMappingDisplay ( + ShellCommandLineGetFlag (Package, L"-v"), + TRUE, + TRUE, + NULL, + SfoMode, + Param1, + TRUE + ); + } else { + // + // now do the display... + // + ShellStatus = PerformMappingDisplay2 ( + ShellCommandLineGetFlag (Package, L"-v"), + ConstMode, + NormlMode, + TypeString, + SfoMode, + Param1 + ); + } + } + } else { + // + // adding or displaying (there were no flags) + // + SName = ShellCommandLineGetRawValue (Package, 1); + Mapping = ShellCommandLineGetRawValue (Package, 2); + if ( (SName == NULL) + && (Mapping == NULL) + ) + { + // + // display only since no flags + // + ShellStatus = PerformMappingDisplay ( + ShellCommandLineGetFlag (Package, L"-v"), + TRUE, + TRUE, + NULL, + SfoMode, + NULL, + TRUE + ); + } else if ( (SName == NULL) + || (Mapping == NULL) + ) + { + // + // Display only the one specified + // + ShellStatus = PerformMappingDisplay ( + FALSE, + FALSE, + FALSE, + NULL, + SfoMode, + SName, // note the variable here... + TRUE + ); + } else { + if (ShellIsHexOrDecimalNumber (Mapping, TRUE, FALSE)) { + MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping)); + } else { + MapAsHandle = NULL; + } + + if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + TempStringLength = StrLen (SName); + if (!IsNumberLetterOnly (SName, TempStringLength-((SName[TempStringLength-1] == L':') ? 1 : 0))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName); + ShellStatus = SHELL_INVALID_PARAMETER; + } + + if (ShellStatus == SHELL_SUCCESS) { + if (MapAsHandle != NULL) { + ShellStatus = AddMappingFromHandle (MapAsHandle, SName); + } else { + ShellStatus = AddMappingFromMapping (Mapping, SName); + } + + if (ShellStatus != SHELL_SUCCESS) { + switch (ShellStatus) { + case SHELL_ACCESS_DENIED: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map"); + break; + case SHELL_INVALID_PARAMETER: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping); + break; + case SHELL_DEVICE_ERROR: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping); + break; + default: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT); + } + } else { + // + // now do the display... + // + ShellStatus = PerformMappingDisplay ( + FALSE, + FALSE, + FALSE, + NULL, + SfoMode, + SName, + TRUE + ); + } // we were successful so do an output + } + } // got a valid map target + } // got 2 variables + } // we are adding a mapping + } // got valid parameters + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/MkDir.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/MkDir.c index bdc6a0d08d..7aab9dea02 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/MkDir.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/MkDir.c @@ -1,170 +1,170 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- Function for 'mkdir' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMkDir (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- CONST CHAR16 *NewDirName;
- CHAR16 *NewDirNameCopy;
- CHAR16 *SplitName;
- CHAR16 SaveSplitChar;
- UINTN DirCreateCount;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_FILE_HANDLE FileHandle;
- SHELL_STATUS ShellStatus;
-
- ShellStatus = SHELL_SUCCESS;
- NewDirNameCopy = NULL;
- SplitName = NULL;
- SaveSplitChar = CHAR_NULL;
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mkdir", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- //
- // create a set of directories
- //
- if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
- //
- // we didnt get a single parameter
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mkdir");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- for ( DirCreateCount = 1
- ;
- ; DirCreateCount++
- )
- {
- //
- // loop through each directory specified
- //
-
- NewDirName = ShellCommandLineGetRawValue (Package, DirCreateCount);
- if (NewDirName == NULL) {
- break;
- }
-
- //
- // check if that already exists... if yes fail
- //
- FileHandle = NULL;
- Status = ShellOpenFileByName (
- NewDirName,
- &FileHandle,
- EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
- EFI_FILE_DIRECTORY
- );
- if (!EFI_ERROR (Status)) {
- ShellCloseFile (&FileHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MKDIR_ALREADY), gShellLevel2HiiHandle, NewDirName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FileHandle == NULL);
- //
- // create the nested directory from parent to child.
- // if NewDirName = test1\test2\test3, first create "test1\" directory, then "test1\test2\", finally "test1\test2\test3".
- //
- NewDirNameCopy = AllocateCopyPool (StrSize (NewDirName), NewDirName);
- NewDirNameCopy = PathCleanUpDirectories (NewDirNameCopy);
- if (NewDirNameCopy == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- break;
- }
-
- SplitName = NewDirNameCopy;
- while (SplitName != NULL) {
- SplitName = StrStr (SplitName + 1, L"\\");
- if (SplitName != NULL) {
- SaveSplitChar = *(SplitName + 1);
- *(SplitName + 1) = '\0';
- }
-
- //
- // check if current nested directory already exists... continue to create the child directory.
- //
- Status = ShellOpenFileByName (
- NewDirNameCopy,
- &FileHandle,
- EFI_FILE_MODE_READ,
- EFI_FILE_DIRECTORY
- );
- if (!EFI_ERROR (Status)) {
- ShellCloseFile (&FileHandle);
- } else {
- Status = ShellCreateDirectory (NewDirNameCopy, &FileHandle);
- if (EFI_ERROR (Status)) {
- break;
- }
-
- if (FileHandle != NULL) {
- gEfiShellProtocol->CloseFile (FileHandle);
- }
- }
-
- if (SplitName != NULL) {
- *(SplitName + 1) = SaveSplitChar;
- }
- }
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MKDIR_CREATEFAIL), gShellLevel2HiiHandle, NewDirName);
- ShellStatus = SHELL_ACCESS_DENIED;
- break;
- }
-
- SHELL_FREE_NON_NULL (NewDirNameCopy);
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + Function for 'mkdir' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMkDir ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CONST CHAR16 *NewDirName; + CHAR16 *NewDirNameCopy; + CHAR16 *SplitName; + CHAR16 SaveSplitChar; + UINTN DirCreateCount; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_FILE_HANDLE FileHandle; + SHELL_STATUS ShellStatus; + + ShellStatus = SHELL_SUCCESS; + NewDirNameCopy = NULL; + SplitName = NULL; + SaveSplitChar = CHAR_NULL; + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mkdir", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + // + // create a set of directories + // + if (ShellCommandLineGetRawValue (Package, 1) == NULL) { + // + // we didnt get a single parameter + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mkdir"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + for ( DirCreateCount = 1 + ; + ; DirCreateCount++ + ) + { + // + // loop through each directory specified + // + + NewDirName = ShellCommandLineGetRawValue (Package, DirCreateCount); + if (NewDirName == NULL) { + break; + } + + // + // check if that already exists... if yes fail + // + FileHandle = NULL; + Status = ShellOpenFileByName ( + NewDirName, + &FileHandle, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, + EFI_FILE_DIRECTORY + ); + if (!EFI_ERROR (Status)) { + ShellCloseFile (&FileHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MKDIR_ALREADY), gShellLevel2HiiHandle, NewDirName); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FileHandle == NULL); + // + // create the nested directory from parent to child. + // if NewDirName = test1\test2\test3, first create "test1\" directory, then "test1\test2\", finally "test1\test2\test3". + // + NewDirNameCopy = AllocateCopyPool (StrSize (NewDirName), NewDirName); + NewDirNameCopy = PathCleanUpDirectories (NewDirNameCopy); + if (NewDirNameCopy == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + break; + } + + SplitName = NewDirNameCopy; + while (SplitName != NULL) { + SplitName = StrStr (SplitName + 1, L"\\"); + if (SplitName != NULL) { + SaveSplitChar = *(SplitName + 1); + *(SplitName + 1) = '\0'; + } + + // + // check if current nested directory already exists... continue to create the child directory. + // + Status = ShellOpenFileByName ( + NewDirNameCopy, + &FileHandle, + EFI_FILE_MODE_READ, + EFI_FILE_DIRECTORY + ); + if (!EFI_ERROR (Status)) { + ShellCloseFile (&FileHandle); + } else { + Status = ShellCreateDirectory (NewDirNameCopy, &FileHandle); + if (EFI_ERROR (Status)) { + break; + } + + if (FileHandle != NULL) { + gEfiShellProtocol->CloseFile (FileHandle); + } + } + + if (SplitName != NULL) { + *(SplitName + 1) = SaveSplitChar; + } + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MKDIR_CREATEFAIL), gShellLevel2HiiHandle, NewDirName); + ShellStatus = SHELL_ACCESS_DENIED; + break; + } + + SHELL_FREE_NON_NULL (NewDirNameCopy); + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c index d93facc6f5..5fe9663454 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c @@ -1,891 +1,891 @@ -/** @file
- Main file for mv shell level 2 function.
-
- (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- function to determine if a move is between file systems.
-
- @param FullName [in] The name of the file to move.
- @param Cwd [in] The current working directory
- @param DestPath [in] The target location to move to
-
- @retval TRUE The move is across file system.
- @retval FALSE The move is within a file system.
-**/
-BOOLEAN
-IsBetweenFileSystem (
- IN CONST CHAR16 *FullName,
- IN CONST CHAR16 *Cwd,
- IN CONST CHAR16 *DestPath
- )
-{
- CHAR16 *Test;
- CHAR16 *Test1;
- UINTN Result;
-
- Test = StrStr (FullName, L":");
- if ((Test == NULL) && (Cwd != NULL)) {
- Test = StrStr (Cwd, L":");
- }
-
- Test1 = StrStr (DestPath, L":");
- if ((Test1 == NULL) && (Cwd != NULL)) {
- Test1 = StrStr (Cwd, L":");
- }
-
- if ((Test1 != NULL) && (Test != NULL)) {
- *Test = CHAR_NULL;
- *Test1 = CHAR_NULL;
- Result = StringNoCaseCompare (&FullName, &DestPath);
- *Test = L':';
- *Test1 = L':';
- if (Result != 0) {
- return (TRUE);
- }
- }
-
- return (FALSE);
-}
-
-/**
- function to determine if SrcPath is valid to mv.
-
- if SrcPath equal CWD then it's invalid.
- if SrcPath is the parent path of CWD then it's invalid.
- is SrcPath is NULL return FALSE.
-
- if CwdPath is NULL then ASSERT()
-
- @param SrcPath [in] The source path.
- @param CwdPath [in] The current working directory.
-
- @retval TRUE The source path is valid.
- @retval FALSE The source path is invalid.
-**/
-BOOLEAN
-IsSoucePathValid (
- IN CONST CHAR16 *SrcPath,
- IN CONST CHAR16 *CwdPath
- )
-{
- CHAR16 *SrcPathBuffer;
- CHAR16 *CwdPathBuffer;
- BOOLEAN Ret;
-
- ASSERT (CwdPath != NULL);
- if (SrcPath == NULL) {
- return FALSE;
- }
-
- Ret = TRUE;
-
- SrcPathBuffer = AllocateCopyPool (StrSize (SrcPath), SrcPath);
- if (SrcPathBuffer == NULL) {
- return FALSE;
- }
-
- CwdPathBuffer = AllocateCopyPool (StrSize (CwdPath), CwdPath);
- if (CwdPathBuffer == NULL) {
- FreePool (SrcPathBuffer);
- return FALSE;
- }
-
- gUnicodeCollation->StrUpr (gUnicodeCollation, SrcPathBuffer);
- gUnicodeCollation->StrUpr (gUnicodeCollation, CwdPathBuffer);
-
- if (SrcPathBuffer[StrLen (SrcPathBuffer) -1] == L'\\') {
- SrcPathBuffer[StrLen (SrcPathBuffer) - 1] = CHAR_NULL;
- }
-
- if (CwdPathBuffer[StrLen (CwdPathBuffer) - 1] == L'\\') {
- CwdPathBuffer[StrLen (CwdPathBuffer) - 1] = CHAR_NULL;
- }
-
- if ((StrCmp (CwdPathBuffer, SrcPathBuffer) == 0) ||
- ((StrStr (CwdPathBuffer, SrcPathBuffer) == CwdPathBuffer) &&
- (CwdPathBuffer[StrLen (SrcPathBuffer)] == L'\\'))
- )
- {
- Ret = FALSE;
- }
-
- FreePool (SrcPathBuffer);
- FreePool (CwdPathBuffer);
-
- return Ret;
-}
-
-/**
- Function to validate that moving a specific file (FileName) to a specific
- location (DestPath) is valid.
-
- This function will verify that the destination is not a subdirectory of
- FullName, that the Current working Directory is not being moved, and that
- the directory is not read only.
-
- if the move is invalid this function will report the error to StdOut.
-
- @param SourcePath [in] The name of the file to move.
- @param Cwd [in] The current working directory
- @param DestPath [in] The target location to move to
- @param Attribute [in] The Attribute of the file
- @param DestAttr [in] The Attribute of the destination
- @param FileStatus [in] The Status of the file when opened
-
- @retval TRUE The move is valid
- @retval FALSE The move is not
-**/
-BOOLEAN
-IsValidMove (
- IN CONST CHAR16 *SourcePath,
- IN CONST CHAR16 *Cwd,
- IN CONST CHAR16 *DestPath,
- IN CONST UINT64 Attribute,
- IN CONST UINT64 DestAttr,
- IN CONST EFI_STATUS FileStatus
- )
-{
- CHAR16 *DestPathCopy;
- CHAR16 *DestPathWalker;
-
- if ((Cwd != NULL) && ((Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)) {
- if (!IsSoucePathValid (SourcePath, Cwd)) {
- //
- // Invalid move
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle);
- return FALSE;
- }
- }
-
- //
- // invalid to move read only or move to a read only destination
- //
- if ( ((Attribute & EFI_FILE_READ_ONLY) != 0)
- || (FileStatus == EFI_WRITE_PROTECTED)
- || ((DestAttr & EFI_FILE_READ_ONLY) != 0)
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, SourcePath);
- return (FALSE);
- }
-
- DestPathCopy = AllocateCopyPool (StrSize (DestPath), DestPath);
- if (DestPathCopy == NULL) {
- return (FALSE);
- }
-
- for (DestPathWalker = DestPathCopy; *DestPathWalker == L'\\'; DestPathWalker++) {
- }
-
- while (DestPathWalker != NULL && DestPathWalker[StrLen (DestPathWalker)-1] == L'\\') {
- DestPathWalker[StrLen (DestPathWalker)-1] = CHAR_NULL;
- }
-
- ASSERT (DestPathWalker != NULL);
- ASSERT (SourcePath != NULL);
-
- //
- // If they're the same, or if source is "above" dest on file path tree
- //
- if ((StringNoCaseCompare (&DestPathWalker, &SourcePath) == 0) ||
- ((StrStr (DestPathWalker, SourcePath) == DestPathWalker) &&
- (DestPathWalker[StrLen (SourcePath)] == '\\')
- )
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);
- FreePool (DestPathCopy);
- return (FALSE);
- }
-
- FreePool (DestPathCopy);
-
- return (TRUE);
-}
-
-/**
- Function to take a destination path that might contain wildcards and verify
- that there is only a single possible target (IE we cant have wildcards that
- have 2 possible destination).
-
- if the result is successful the caller must free *DestPathPointer.
-
- @param[in] DestParameter The original path to the destination.
- @param[in, out] DestPathPointer A pointer to the callee allocated final path.
- @param[in] Cwd A pointer to the current working directory.
- @param[in] SingleSource TRUE to have only one source file.
- @param[in, out] DestAttr A pointer to the destination information attribute.
-
- @retval SHELL_INVALID_PARAMETER The DestParameter could not be resolved to a location.
- @retval SHELL_INVALID_PARAMETER The DestParameter could be resolved to more than 1 location.
- @retval SHELL_INVALID_PARAMETER Cwd is required and is NULL.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-GetDestinationLocation (
- IN CONST CHAR16 *DestParameter,
- IN OUT CHAR16 **DestPathPointer,
- IN CONST CHAR16 *Cwd,
- IN CONST BOOLEAN SingleSource,
- IN OUT UINT64 *DestAttr
- )
-{
- EFI_SHELL_FILE_INFO *DestList;
- EFI_SHELL_FILE_INFO *Node;
- CHAR16 *DestPath;
- UINTN NewSize;
- UINTN CurrentSize;
-
- DestList = NULL;
- DestPath = NULL;
-
- ASSERT (DestAttr != NULL);
-
- if (StrStr (DestParameter, L"\\") == DestParameter) {
- if (Cwd == NULL) {
- return SHELL_INVALID_PARAMETER;
- }
-
- DestPath = AllocateZeroPool (StrSize (Cwd));
- if (DestPath == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- StrCpyS (DestPath, StrSize (Cwd) / sizeof (CHAR16), Cwd);
- while (PathRemoveLastItem (DestPath)) {
- }
-
- //
- // Append DestParameter beyond '\' which may be present
- //
- CurrentSize = StrSize (DestPath);
- StrnCatGrow (&DestPath, &CurrentSize, &DestParameter[1], 0);
-
- *DestPathPointer = DestPath;
- return (SHELL_SUCCESS);
- }
-
- //
- // get the destination path
- //
- ShellOpenFileMetaArg ((CHAR16 *)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList);
- if ((DestList == NULL) || IsListEmpty (&DestList->Link)) {
- //
- // Not existing... must be renaming
- //
- if (StrStr (DestParameter, L":") == NULL) {
- if (Cwd == NULL) {
- ShellCloseFileMetaArg (&DestList);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);
- return (SHELL_INVALID_PARAMETER);
- }
-
- NewSize = StrSize (Cwd);
- NewSize += StrSize (DestParameter);
- DestPath = AllocateZeroPool (NewSize);
- if (DestPath == NULL) {
- ShellCloseFileMetaArg (&DestList);
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- StrCpyS (DestPath, NewSize / sizeof (CHAR16), Cwd);
- if ((DestPath[StrLen (DestPath)-1] != L'\\') && (DestParameter[0] != L'\\')) {
- StrCatS (DestPath, NewSize / sizeof (CHAR16), L"\\");
- } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (DestParameter[0] == L'\\')) {
- ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
- }
-
- StrCatS (DestPath, NewSize / sizeof (CHAR16), DestParameter);
- } else {
- ASSERT (DestPath == NULL);
- DestPath = StrnCatGrow (&DestPath, NULL, DestParameter, 0);
- if (DestPath == NULL) {
- ShellCloseFileMetaArg (&DestList);
- return (SHELL_OUT_OF_RESOURCES);
- }
- }
- } else {
- Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&DestList->Link);
- *DestAttr = Node->Info->Attribute;
- //
- // Make sure there is only 1 node in the list.
- //
- if (!IsNodeAtEnd (&DestList->Link, &Node->Link)) {
- ShellCloseFileMetaArg (&DestList);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter);
- return (SHELL_INVALID_PARAMETER);
- }
-
- //
- // If we are a directory or a single file, then one node is fine.
- //
- if ((ShellIsDirectory (Node->FullName) == EFI_SUCCESS) || SingleSource) {
- DestPath = AllocateZeroPool (StrSize (Node->FullName)+sizeof (CHAR16));
- if (DestPath == NULL) {
- ShellCloseFileMetaArg (&DestList);
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- StrCpyS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), Node->FullName);
- StrCatS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), L"\\");
- } else {
- //
- // cant move multiple files onto a single file.
- //
- ShellCloseFileMetaArg (&DestList);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter);
- return (SHELL_INVALID_PARAMETER);
- }
- }
-
- *DestPathPointer = DestPath;
- ShellCloseFileMetaArg (&DestList);
-
- return (SHELL_SUCCESS);
-}
-
-/**
- Function to do a move across file systems.
-
- @param[in] Node A pointer to the file to be removed.
- @param[in] DestPath A pointer to the destination file path.
- @param[out] Resp A pointer to response from question. Pass back on looped calling
-
- @retval SHELL_SUCCESS The source file was moved to the destination.
-**/
-EFI_STATUS
-MoveBetweenFileSystems (
- IN EFI_SHELL_FILE_INFO *Node,
- IN CONST CHAR16 *DestPath,
- OUT VOID **Resp
- )
-{
- SHELL_STATUS ShellStatus;
-
- //
- // First we copy the file
- //
- ShellStatus = CopySingleFile (Node->FullName, DestPath, Resp, TRUE, L"mv");
-
- //
- // Check our result
- //
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // The copy was successful. delete the source file.
- //
- CascadeDelete (Node, TRUE);
- Node->Handle = NULL;
- } else if (ShellStatus == SHELL_ABORTED) {
- return EFI_ABORTED;
- } else if (ShellStatus == SHELL_ACCESS_DENIED) {
- return EFI_ACCESS_DENIED;
- } else if (ShellStatus == SHELL_VOLUME_FULL) {
- return EFI_VOLUME_FULL;
- } else {
- return EFI_UNSUPPORTED;
- }
-
- return (EFI_SUCCESS);
-}
-
-/**
- Function to take the destination path and target file name to generate the full destination path.
-
- @param[in] DestPath A pointer to the destination file path string.
- @param[out] FullDestPath A pointer to the full destination path string.
- @param[in] FileName Name string of the targe file.
-
- @retval SHELL_SUCCESS the files were all moved.
- @retval SHELL_INVALID_PARAMETER a parameter was invalid
- @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
-**/
-EFI_STATUS
-CreateFullDestPath (
- IN CONST CHAR16 **DestPath,
- OUT CHAR16 **FullDestPath,
- IN CONST CHAR16 *FileName
- )
-{
- UINTN Size;
-
- if ((FullDestPath == NULL) || (FileName == NULL) || (DestPath == NULL) || (*DestPath == NULL)) {
- return (EFI_INVALID_PARAMETER);
- }
-
- Size = StrSize (*DestPath) + StrSize (FileName);
-
- *FullDestPath = AllocateZeroPool (Size);
- if (*FullDestPath == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- StrCpyS (*FullDestPath, Size / sizeof (CHAR16), *DestPath);
- if (((*FullDestPath)[StrLen (*FullDestPath)-1] != L'\\') && (FileName[0] != L'\\')) {
- StrCatS (*FullDestPath, Size / sizeof (CHAR16), L"\\");
- }
-
- StrCatS (*FullDestPath, Size / sizeof (CHAR16), FileName);
-
- return (EFI_SUCCESS);
-}
-
-/**
- Function to do a move within a file system.
-
- @param[in] Node A pointer to the file to be removed.
- @param[in] DestPath A pointer to the destination file path.
- @param[out] Resp A pointer to response from question. Pass back on looped calling.
-
- @retval SHELL_SUCCESS The source file was moved to the destination.
- @retval SHELL_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-MoveWithinFileSystems (
- IN EFI_SHELL_FILE_INFO *Node,
- IN CHAR16 *DestPath,
- OUT VOID **Resp
- )
-{
- EFI_FILE_INFO *NewFileInfo;
- CHAR16 *TempLocation;
- UINTN NewSize;
- UINTN Length;
- EFI_STATUS Status;
-
- //
- // Chop off map info from DestPath
- //
- if ((TempLocation = StrStr (DestPath, L":")) != NULL) {
- CopyMem (DestPath, TempLocation+1, StrSize (TempLocation+1));
- }
-
- //
- // construct the new file info block
- //
- NewSize = StrSize (DestPath);
- NewSize += StrSize (Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
- NewFileInfo = AllocateZeroPool (NewSize);
- if (NewFileInfo == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- CopyMem (NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO);
- if (DestPath[0] != L'\\') {
- StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), L"\\");
- StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath);
- } else {
- StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath);
- }
-
- Length = StrLen (NewFileInfo->FileName);
- if (Length > 0) {
- Length--;
- }
-
- if (NewFileInfo->FileName[Length] == L'\\') {
- if (Node->FileName[0] == L'\\') {
- //
- // Don't allow for double slashes. Eliminate one of them.
- //
- NewFileInfo->FileName[Length] = CHAR_NULL;
- }
-
- StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), Node->FileName);
- }
-
- NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize (NewFileInfo->FileName);
-
- //
- // Perform the move operation
- //
- Status = ShellSetFileInfo (Node->Handle, NewFileInfo);
-
- //
- // Free the info object we used...
- //
- FreePool (NewFileInfo);
- }
-
- return (Status);
-}
-
-/**
- function to take a list of files to move and a destination location and do
- the verification and moving of those files to that location. This function
- will report any errors to the user and continue to move the rest of the files.
-
- @param[in] FileList A LIST_ENTRY* based list of files to move
- @param[out] Resp pointer to response from question. Pass back on looped calling
- @param[in] DestParameter the originally specified destination location
-
- @retval SHELL_SUCCESS the files were all moved.
- @retval SHELL_INVALID_PARAMETER a parameter was invalid
- @retval SHELL_SECURITY_VIOLATION a security violation ocurred
- @retval SHELL_WRITE_PROTECTED the destination was write protected
- @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
-**/
-SHELL_STATUS
-ValidateAndMoveFiles (
- IN EFI_SHELL_FILE_INFO *FileList,
- OUT VOID **Resp,
- IN CONST CHAR16 *DestParameter
- )
-{
- EFI_STATUS Status;
- CHAR16 *HiiOutput;
- CHAR16 *HiiResultOk;
- CHAR16 *DestPath;
- CHAR16 *FullDestPath;
- CONST CHAR16 *Cwd;
- CHAR16 *FullCwd;
- SHELL_STATUS ShellStatus;
- EFI_SHELL_FILE_INFO *Node;
- VOID *Response;
- UINT64 Attr;
- CHAR16 *CleanFilePathStr;
-
- ASSERT (FileList != NULL);
- ASSERT (DestParameter != NULL);
-
- DestPath = NULL;
- FullDestPath = NULL;
- Cwd = ShellGetCurrentDir (NULL);
- Response = *Resp;
- Attr = 0;
- CleanFilePathStr = NULL;
- FullCwd = NULL;
-
- if (Cwd != NULL) {
- FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16));
- if (FullCwd == NULL) {
- return SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, Cwd);
- StrCatS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, L"\\");
- }
- }
-
- Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr);
- if (EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (FullCwd);
- if (Status == EFI_OUT_OF_RESOURCES) {
- return SHELL_OUT_OF_RESOURCES;
- } else {
- return SHELL_INVALID_PARAMETER;
- }
- }
-
- ASSERT (CleanFilePathStr != NULL);
-
- //
- // Get and validate the destination location
- //
- ShellStatus = GetDestinationLocation (CleanFilePathStr, &DestPath, FullCwd, (BOOLEAN)(FileList->Link.ForwardLink == FileList->Link.BackLink), &Attr);
- FreePool (CleanFilePathStr);
-
- if (ShellStatus != SHELL_SUCCESS) {
- SHELL_FREE_NON_NULL (FullCwd);
- return (ShellStatus);
- }
-
- DestPath = PathCleanUpDirectories (DestPath);
- if (DestPath == NULL) {
- FreePool (FullCwd);
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL);
- HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);
- if ((HiiOutput == NULL) || (HiiResultOk == NULL)) {
- SHELL_FREE_NON_NULL (DestPath);
- SHELL_FREE_NON_NULL (HiiOutput);
- SHELL_FREE_NON_NULL (HiiResultOk);
- SHELL_FREE_NON_NULL (FullCwd);
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- //
- // Go through the list of files and directories to move...
- //
- for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
- ; !IsNull (&FileList->Link, &Node->Link)
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
- )
- {
- if (ShellGetExecutionBreakFlag ()) {
- break;
- }
-
- //
- // These should never be NULL
- //
- ASSERT (Node->FileName != NULL);
- ASSERT (Node->FullName != NULL);
- ASSERT (Node->Info != NULL);
-
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) {
- continue;
- }
-
- SHELL_FREE_NON_NULL (FullDestPath);
- FullDestPath = NULL;
- if (ShellIsDirectory (DestPath) == EFI_SUCCESS) {
- CreateFullDestPath ((CONST CHAR16 **)&DestPath, &FullDestPath, Node->FileName);
- }
-
- //
- // Validate that the move is valid
- //
- if (!IsValidMove (Node->FullName, FullCwd, (FullDestPath != NULL) ? FullDestPath : DestPath, Node->Info->Attribute, Attr, Node->Status)) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- continue;
- }
-
- ShellPrintEx (-1, -1, HiiOutput, Node->FullName, FullDestPath != NULL ? FullDestPath : DestPath);
-
- //
- // See if destination exists
- //
- if (!EFI_ERROR (ShellFileExists ((FullDestPath != NULL) ? FullDestPath : DestPath))) {
- if (Response == NULL) {
- ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
- }
-
- if (Response == NULL) {
- return SHELL_ABORTED;
- }
-
- switch (*(SHELL_PROMPT_RESPONSE *)Response) {
- case ShellPromptResponseNo:
- FreePool (Response);
- Response = NULL;
- continue;
- case ShellPromptResponseCancel:
- *Resp = Response;
- //
- // indicate to stop everything
- //
- SHELL_FREE_NON_NULL (FullCwd);
- return (SHELL_ABORTED);
- case ShellPromptResponseAll:
- *Resp = Response;
- break;
- case ShellPromptResponseYes:
- FreePool (Response);
- Response = NULL;
- break;
- default:
- FreePool (Response);
- SHELL_FREE_NON_NULL (FullCwd);
- return SHELL_ABORTED;
- }
-
- Status = ShellDeleteFileByName (FullDestPath != NULL ? FullDestPath : DestPath);
- }
-
- if (IsBetweenFileSystem (Node->FullName, FullCwd, DestPath)) {
- while (FullDestPath == NULL && DestPath != NULL && DestPath[0] != CHAR_NULL && DestPath[StrLen (DestPath) - 1] == L'\\') {
- DestPath[StrLen (DestPath) - 1] = CHAR_NULL;
- }
-
- Status = MoveBetweenFileSystems (Node, FullDestPath != NULL ? FullDestPath : DestPath, &Response);
- } else {
- Status = MoveWithinFileSystems (Node, DestPath, &Response);
- //
- // Display error status
- //
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"mv", Status);
- }
- }
-
- //
- // Check our result
- //
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- if (Status == EFI_SECURITY_VIOLATION) {
- ShellStatus = SHELL_SECURITY_VIOLATION;
- } else if (Status == EFI_WRITE_PROTECTED) {
- ShellStatus = SHELL_WRITE_PROTECTED;
- } else if (Status == EFI_OUT_OF_RESOURCES) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else if (Status == EFI_DEVICE_ERROR) {
- ShellStatus = SHELL_DEVICE_ERROR;
- } else if (Status == EFI_ACCESS_DENIED) {
- ShellStatus = SHELL_ACCESS_DENIED;
- }
- } else {
- ShellPrintEx (-1, -1, L"%s", HiiResultOk);
- }
- } // main for loop
-
- SHELL_FREE_NON_NULL (FullDestPath);
- SHELL_FREE_NON_NULL (DestPath);
- SHELL_FREE_NON_NULL (HiiOutput);
- SHELL_FREE_NON_NULL (HiiResultOk);
- SHELL_FREE_NON_NULL (FullCwd);
- return (ShellStatus);
-}
-
-/**
- Function for 'mv' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMv (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- CHAR16 *Cwd;
- UINTN CwdSize;
- SHELL_STATUS ShellStatus;
- UINTN ParamCount;
- UINTN LoopCounter;
- EFI_SHELL_FILE_INFO *FileList;
- VOID *Response;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- ParamCount = 0;
- FileList = NULL;
- Response = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mv", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- switch (ParamCount = ShellCommandLineGetCount (Package)) {
- case 0:
- case 1:
- //
- // we have insufficient parameters
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mv");
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- case 2:
- //
- // must have valid CWD for single parameter...
- //
- if (ShellGetCurrentDir (NULL) == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"mv");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, 1));
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- //
- // ValidateAndMoveFiles will report errors to the screen itself
- //
- CwdSize = StrSize (ShellGetCurrentDir (NULL)) + sizeof (CHAR16);
- Cwd = AllocateZeroPool (CwdSize);
- if (Cwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"mv");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (Cwd, CwdSize / sizeof (CHAR16), ShellGetCurrentDir (NULL));
- StrCatS (Cwd, CwdSize / sizeof (CHAR16), L"\\");
- ShellStatus = ValidateAndMoveFiles (FileList, &Response, Cwd);
- FreePool (Cwd);
- }
- }
- }
-
- break;
- default:
- /// @todo make sure this works with error half way through and continues...
- for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount; LoopCounter++) {
- if (ShellGetExecutionBreakFlag ()) {
- break;
- }
-
- Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, LoopCounter));
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- //
- // ValidateAndMoveFiles will report errors to the screen itself
- // Only change ShellStatus if it's successful
- //
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount));
- } else {
- ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount));
- }
- }
-
- if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
- Status = ShellCloseFileMetaArg (&FileList);
- if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, 1), ShellStatus|MAX_BIT);
- }
- }
- }
-
- break;
- } // switch on parameter count
-
- if (FileList != NULL) {
- ShellCloseFileMetaArg (&FileList);
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
- }
-
- SHELL_FREE_NON_NULL (Response);
-
- if (ShellGetExecutionBreakFlag ()) {
- return (SHELL_ABORTED);
- }
-
- return (ShellStatus);
-}
+/** @file + Main file for mv shell level 2 function. + + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + function to determine if a move is between file systems. + + @param FullName [in] The name of the file to move. + @param Cwd [in] The current working directory + @param DestPath [in] The target location to move to + + @retval TRUE The move is across file system. + @retval FALSE The move is within a file system. +**/ +BOOLEAN +IsBetweenFileSystem ( + IN CONST CHAR16 *FullName, + IN CONST CHAR16 *Cwd, + IN CONST CHAR16 *DestPath + ) +{ + CHAR16 *Test; + CHAR16 *Test1; + UINTN Result; + + Test = StrStr (FullName, L":"); + if ((Test == NULL) && (Cwd != NULL)) { + Test = StrStr (Cwd, L":"); + } + + Test1 = StrStr (DestPath, L":"); + if ((Test1 == NULL) && (Cwd != NULL)) { + Test1 = StrStr (Cwd, L":"); + } + + if ((Test1 != NULL) && (Test != NULL)) { + *Test = CHAR_NULL; + *Test1 = CHAR_NULL; + Result = StringNoCaseCompare (&FullName, &DestPath); + *Test = L':'; + *Test1 = L':'; + if (Result != 0) { + return (TRUE); + } + } + + return (FALSE); +} + +/** + function to determine if SrcPath is valid to mv. + + if SrcPath equal CWD then it's invalid. + if SrcPath is the parent path of CWD then it's invalid. + is SrcPath is NULL return FALSE. + + if CwdPath is NULL then ASSERT() + + @param SrcPath [in] The source path. + @param CwdPath [in] The current working directory. + + @retval TRUE The source path is valid. + @retval FALSE The source path is invalid. +**/ +BOOLEAN +IsSoucePathValid ( + IN CONST CHAR16 *SrcPath, + IN CONST CHAR16 *CwdPath + ) +{ + CHAR16 *SrcPathBuffer; + CHAR16 *CwdPathBuffer; + BOOLEAN Ret; + + ASSERT (CwdPath != NULL); + if (SrcPath == NULL) { + return FALSE; + } + + Ret = TRUE; + + SrcPathBuffer = AllocateCopyPool (StrSize (SrcPath), SrcPath); + if (SrcPathBuffer == NULL) { + return FALSE; + } + + CwdPathBuffer = AllocateCopyPool (StrSize (CwdPath), CwdPath); + if (CwdPathBuffer == NULL) { + FreePool (SrcPathBuffer); + return FALSE; + } + + gUnicodeCollation->StrUpr (gUnicodeCollation, SrcPathBuffer); + gUnicodeCollation->StrUpr (gUnicodeCollation, CwdPathBuffer); + + if (SrcPathBuffer[StrLen (SrcPathBuffer) -1] == L'\\') { + SrcPathBuffer[StrLen (SrcPathBuffer) - 1] = CHAR_NULL; + } + + if (CwdPathBuffer[StrLen (CwdPathBuffer) - 1] == L'\\') { + CwdPathBuffer[StrLen (CwdPathBuffer) - 1] = CHAR_NULL; + } + + if ((StrCmp (CwdPathBuffer, SrcPathBuffer) == 0) || + ((StrStr (CwdPathBuffer, SrcPathBuffer) == CwdPathBuffer) && + (CwdPathBuffer[StrLen (SrcPathBuffer)] == L'\\')) + ) + { + Ret = FALSE; + } + + FreePool (SrcPathBuffer); + FreePool (CwdPathBuffer); + + return Ret; +} + +/** + Function to validate that moving a specific file (FileName) to a specific + location (DestPath) is valid. + + This function will verify that the destination is not a subdirectory of + FullName, that the Current working Directory is not being moved, and that + the directory is not read only. + + if the move is invalid this function will report the error to StdOut. + + @param SourcePath [in] The name of the file to move. + @param Cwd [in] The current working directory + @param DestPath [in] The target location to move to + @param Attribute [in] The Attribute of the file + @param DestAttr [in] The Attribute of the destination + @param FileStatus [in] The Status of the file when opened + + @retval TRUE The move is valid + @retval FALSE The move is not +**/ +BOOLEAN +IsValidMove ( + IN CONST CHAR16 *SourcePath, + IN CONST CHAR16 *Cwd, + IN CONST CHAR16 *DestPath, + IN CONST UINT64 Attribute, + IN CONST UINT64 DestAttr, + IN CONST EFI_STATUS FileStatus + ) +{ + CHAR16 *DestPathCopy; + CHAR16 *DestPathWalker; + + if ((Cwd != NULL) && ((Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)) { + if (!IsSoucePathValid (SourcePath, Cwd)) { + // + // Invalid move + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle); + return FALSE; + } + } + + // + // invalid to move read only or move to a read only destination + // + if ( ((Attribute & EFI_FILE_READ_ONLY) != 0) + || (FileStatus == EFI_WRITE_PROTECTED) + || ((DestAttr & EFI_FILE_READ_ONLY) != 0) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, SourcePath); + return (FALSE); + } + + DestPathCopy = AllocateCopyPool (StrSize (DestPath), DestPath); + if (DestPathCopy == NULL) { + return (FALSE); + } + + for (DestPathWalker = DestPathCopy; *DestPathWalker == L'\\'; DestPathWalker++) { + } + + while (DestPathWalker != NULL && DestPathWalker[StrLen (DestPathWalker)-1] == L'\\') { + DestPathWalker[StrLen (DestPathWalker)-1] = CHAR_NULL; + } + + ASSERT (DestPathWalker != NULL); + ASSERT (SourcePath != NULL); + + // + // If they're the same, or if source is "above" dest on file path tree + // + if ((StringNoCaseCompare (&DestPathWalker, &SourcePath) == 0) || + ((StrStr (DestPathWalker, SourcePath) == DestPathWalker) && + (DestPathWalker[StrLen (SourcePath)] == '\\') + ) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle); + FreePool (DestPathCopy); + return (FALSE); + } + + FreePool (DestPathCopy); + + return (TRUE); +} + +/** + Function to take a destination path that might contain wildcards and verify + that there is only a single possible target (IE we cant have wildcards that + have 2 possible destination). + + if the result is successful the caller must free *DestPathPointer. + + @param[in] DestParameter The original path to the destination. + @param[in, out] DestPathPointer A pointer to the callee allocated final path. + @param[in] Cwd A pointer to the current working directory. + @param[in] SingleSource TRUE to have only one source file. + @param[in, out] DestAttr A pointer to the destination information attribute. + + @retval SHELL_INVALID_PARAMETER The DestParameter could not be resolved to a location. + @retval SHELL_INVALID_PARAMETER The DestParameter could be resolved to more than 1 location. + @retval SHELL_INVALID_PARAMETER Cwd is required and is NULL. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +GetDestinationLocation ( + IN CONST CHAR16 *DestParameter, + IN OUT CHAR16 **DestPathPointer, + IN CONST CHAR16 *Cwd, + IN CONST BOOLEAN SingleSource, + IN OUT UINT64 *DestAttr + ) +{ + EFI_SHELL_FILE_INFO *DestList; + EFI_SHELL_FILE_INFO *Node; + CHAR16 *DestPath; + UINTN NewSize; + UINTN CurrentSize; + + DestList = NULL; + DestPath = NULL; + + ASSERT (DestAttr != NULL); + + if (StrStr (DestParameter, L"\\") == DestParameter) { + if (Cwd == NULL) { + return SHELL_INVALID_PARAMETER; + } + + DestPath = AllocateZeroPool (StrSize (Cwd)); + if (DestPath == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + StrCpyS (DestPath, StrSize (Cwd) / sizeof (CHAR16), Cwd); + while (PathRemoveLastItem (DestPath)) { + } + + // + // Append DestParameter beyond '\' which may be present + // + CurrentSize = StrSize (DestPath); + StrnCatGrow (&DestPath, &CurrentSize, &DestParameter[1], 0); + + *DestPathPointer = DestPath; + return (SHELL_SUCCESS); + } + + // + // get the destination path + // + ShellOpenFileMetaArg ((CHAR16 *)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList); + if ((DestList == NULL) || IsListEmpty (&DestList->Link)) { + // + // Not existing... must be renaming + // + if (StrStr (DestParameter, L":") == NULL) { + if (Cwd == NULL) { + ShellCloseFileMetaArg (&DestList); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); + return (SHELL_INVALID_PARAMETER); + } + + NewSize = StrSize (Cwd); + NewSize += StrSize (DestParameter); + DestPath = AllocateZeroPool (NewSize); + if (DestPath == NULL) { + ShellCloseFileMetaArg (&DestList); + return (SHELL_OUT_OF_RESOURCES); + } + + StrCpyS (DestPath, NewSize / sizeof (CHAR16), Cwd); + if ((DestPath[StrLen (DestPath)-1] != L'\\') && (DestParameter[0] != L'\\')) { + StrCatS (DestPath, NewSize / sizeof (CHAR16), L"\\"); + } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (DestParameter[0] == L'\\')) { + ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL; + } + + StrCatS (DestPath, NewSize / sizeof (CHAR16), DestParameter); + } else { + ASSERT (DestPath == NULL); + DestPath = StrnCatGrow (&DestPath, NULL, DestParameter, 0); + if (DestPath == NULL) { + ShellCloseFileMetaArg (&DestList); + return (SHELL_OUT_OF_RESOURCES); + } + } + } else { + Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&DestList->Link); + *DestAttr = Node->Info->Attribute; + // + // Make sure there is only 1 node in the list. + // + if (!IsNodeAtEnd (&DestList->Link, &Node->Link)) { + ShellCloseFileMetaArg (&DestList); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); + return (SHELL_INVALID_PARAMETER); + } + + // + // If we are a directory or a single file, then one node is fine. + // + if ((ShellIsDirectory (Node->FullName) == EFI_SUCCESS) || SingleSource) { + DestPath = AllocateZeroPool (StrSize (Node->FullName)+sizeof (CHAR16)); + if (DestPath == NULL) { + ShellCloseFileMetaArg (&DestList); + return (SHELL_OUT_OF_RESOURCES); + } + + StrCpyS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), Node->FullName); + StrCatS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), L"\\"); + } else { + // + // cant move multiple files onto a single file. + // + ShellCloseFileMetaArg (&DestList); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); + return (SHELL_INVALID_PARAMETER); + } + } + + *DestPathPointer = DestPath; + ShellCloseFileMetaArg (&DestList); + + return (SHELL_SUCCESS); +} + +/** + Function to do a move across file systems. + + @param[in] Node A pointer to the file to be removed. + @param[in] DestPath A pointer to the destination file path. + @param[out] Resp A pointer to response from question. Pass back on looped calling + + @retval SHELL_SUCCESS The source file was moved to the destination. +**/ +EFI_STATUS +MoveBetweenFileSystems ( + IN EFI_SHELL_FILE_INFO *Node, + IN CONST CHAR16 *DestPath, + OUT VOID **Resp + ) +{ + SHELL_STATUS ShellStatus; + + // + // First we copy the file + // + ShellStatus = CopySingleFile (Node->FullName, DestPath, Resp, TRUE, L"mv"); + + // + // Check our result + // + if (ShellStatus == SHELL_SUCCESS) { + // + // The copy was successful. delete the source file. + // + CascadeDelete (Node, TRUE); + Node->Handle = NULL; + } else if (ShellStatus == SHELL_ABORTED) { + return EFI_ABORTED; + } else if (ShellStatus == SHELL_ACCESS_DENIED) { + return EFI_ACCESS_DENIED; + } else if (ShellStatus == SHELL_VOLUME_FULL) { + return EFI_VOLUME_FULL; + } else { + return EFI_UNSUPPORTED; + } + + return (EFI_SUCCESS); +} + +/** + Function to take the destination path and target file name to generate the full destination path. + + @param[in] DestPath A pointer to the destination file path string. + @param[out] FullDestPath A pointer to the full destination path string. + @param[in] FileName Name string of the targe file. + + @retval SHELL_SUCCESS the files were all moved. + @retval SHELL_INVALID_PARAMETER a parameter was invalid + @retval SHELL_OUT_OF_RESOURCES a memory allocation failed +**/ +EFI_STATUS +CreateFullDestPath ( + IN CONST CHAR16 **DestPath, + OUT CHAR16 **FullDestPath, + IN CONST CHAR16 *FileName + ) +{ + UINTN Size; + + if ((FullDestPath == NULL) || (FileName == NULL) || (DestPath == NULL) || (*DestPath == NULL)) { + return (EFI_INVALID_PARAMETER); + } + + Size = StrSize (*DestPath) + StrSize (FileName); + + *FullDestPath = AllocateZeroPool (Size); + if (*FullDestPath == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + StrCpyS (*FullDestPath, Size / sizeof (CHAR16), *DestPath); + if (((*FullDestPath)[StrLen (*FullDestPath)-1] != L'\\') && (FileName[0] != L'\\')) { + StrCatS (*FullDestPath, Size / sizeof (CHAR16), L"\\"); + } + + StrCatS (*FullDestPath, Size / sizeof (CHAR16), FileName); + + return (EFI_SUCCESS); +} + +/** + Function to do a move within a file system. + + @param[in] Node A pointer to the file to be removed. + @param[in] DestPath A pointer to the destination file path. + @param[out] Resp A pointer to response from question. Pass back on looped calling. + + @retval SHELL_SUCCESS The source file was moved to the destination. + @retval SHELL_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MoveWithinFileSystems ( + IN EFI_SHELL_FILE_INFO *Node, + IN CHAR16 *DestPath, + OUT VOID **Resp + ) +{ + EFI_FILE_INFO *NewFileInfo; + CHAR16 *TempLocation; + UINTN NewSize; + UINTN Length; + EFI_STATUS Status; + + // + // Chop off map info from DestPath + // + if ((TempLocation = StrStr (DestPath, L":")) != NULL) { + CopyMem (DestPath, TempLocation+1, StrSize (TempLocation+1)); + } + + // + // construct the new file info block + // + NewSize = StrSize (DestPath); + NewSize += StrSize (Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16); + NewFileInfo = AllocateZeroPool (NewSize); + if (NewFileInfo == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle); + Status = EFI_OUT_OF_RESOURCES; + } else { + CopyMem (NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO); + if (DestPath[0] != L'\\') { + StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), L"\\"); + StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath); + } else { + StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath); + } + + Length = StrLen (NewFileInfo->FileName); + if (Length > 0) { + Length--; + } + + if (NewFileInfo->FileName[Length] == L'\\') { + if (Node->FileName[0] == L'\\') { + // + // Don't allow for double slashes. Eliminate one of them. + // + NewFileInfo->FileName[Length] = CHAR_NULL; + } + + StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), Node->FileName); + } + + NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize (NewFileInfo->FileName); + + // + // Perform the move operation + // + Status = ShellSetFileInfo (Node->Handle, NewFileInfo); + + // + // Free the info object we used... + // + FreePool (NewFileInfo); + } + + return (Status); +} + +/** + function to take a list of files to move and a destination location and do + the verification and moving of those files to that location. This function + will report any errors to the user and continue to move the rest of the files. + + @param[in] FileList A LIST_ENTRY* based list of files to move + @param[out] Resp pointer to response from question. Pass back on looped calling + @param[in] DestParameter the originally specified destination location + + @retval SHELL_SUCCESS the files were all moved. + @retval SHELL_INVALID_PARAMETER a parameter was invalid + @retval SHELL_SECURITY_VIOLATION a security violation ocurred + @retval SHELL_WRITE_PROTECTED the destination was write protected + @retval SHELL_OUT_OF_RESOURCES a memory allocation failed +**/ +SHELL_STATUS +ValidateAndMoveFiles ( + IN EFI_SHELL_FILE_INFO *FileList, + OUT VOID **Resp, + IN CONST CHAR16 *DestParameter + ) +{ + EFI_STATUS Status; + CHAR16 *HiiOutput; + CHAR16 *HiiResultOk; + CHAR16 *DestPath; + CHAR16 *FullDestPath; + CONST CHAR16 *Cwd; + CHAR16 *FullCwd; + SHELL_STATUS ShellStatus; + EFI_SHELL_FILE_INFO *Node; + VOID *Response; + UINT64 Attr; + CHAR16 *CleanFilePathStr; + + ASSERT (FileList != NULL); + ASSERT (DestParameter != NULL); + + DestPath = NULL; + FullDestPath = NULL; + Cwd = ShellGetCurrentDir (NULL); + Response = *Resp; + Attr = 0; + CleanFilePathStr = NULL; + FullCwd = NULL; + + if (Cwd != NULL) { + FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16)); + if (FullCwd == NULL) { + return SHELL_OUT_OF_RESOURCES; + } else { + StrCpyS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, Cwd); + StrCatS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, L"\\"); + } + } + + Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (FullCwd); + if (Status == EFI_OUT_OF_RESOURCES) { + return SHELL_OUT_OF_RESOURCES; + } else { + return SHELL_INVALID_PARAMETER; + } + } + + ASSERT (CleanFilePathStr != NULL); + + // + // Get and validate the destination location + // + ShellStatus = GetDestinationLocation (CleanFilePathStr, &DestPath, FullCwd, (BOOLEAN)(FileList->Link.ForwardLink == FileList->Link.BackLink), &Attr); + FreePool (CleanFilePathStr); + + if (ShellStatus != SHELL_SUCCESS) { + SHELL_FREE_NON_NULL (FullCwd); + return (ShellStatus); + } + + DestPath = PathCleanUpDirectories (DestPath); + if (DestPath == NULL) { + FreePool (FullCwd); + return (SHELL_OUT_OF_RESOURCES); + } + + HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL); + HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); + if ((HiiOutput == NULL) || (HiiResultOk == NULL)) { + SHELL_FREE_NON_NULL (DestPath); + SHELL_FREE_NON_NULL (HiiOutput); + SHELL_FREE_NON_NULL (HiiResultOk); + SHELL_FREE_NON_NULL (FullCwd); + return (SHELL_OUT_OF_RESOURCES); + } + + // + // Go through the list of files and directories to move... + // + for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link) + ; !IsNull (&FileList->Link, &Node->Link) + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link) + ) + { + if (ShellGetExecutionBreakFlag ()) { + break; + } + + // + // These should never be NULL + // + ASSERT (Node->FileName != NULL); + ASSERT (Node->FullName != NULL); + ASSERT (Node->Info != NULL); + + // + // skip the directory traversing stuff... + // + if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) { + continue; + } + + SHELL_FREE_NON_NULL (FullDestPath); + FullDestPath = NULL; + if (ShellIsDirectory (DestPath) == EFI_SUCCESS) { + CreateFullDestPath ((CONST CHAR16 **)&DestPath, &FullDestPath, Node->FileName); + } + + // + // Validate that the move is valid + // + if (!IsValidMove (Node->FullName, FullCwd, (FullDestPath != NULL) ? FullDestPath : DestPath, Node->Info->Attribute, Attr, Node->Status)) { + ShellStatus = SHELL_INVALID_PARAMETER; + continue; + } + + ShellPrintEx (-1, -1, HiiOutput, Node->FullName, FullDestPath != NULL ? FullDestPath : DestPath); + + // + // See if destination exists + // + if (!EFI_ERROR (ShellFileExists ((FullDestPath != NULL) ? FullDestPath : DestPath))) { + if (Response == NULL) { + ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); + } + + if (Response == NULL) { + return SHELL_ABORTED; + } + + switch (*(SHELL_PROMPT_RESPONSE *)Response) { + case ShellPromptResponseNo: + FreePool (Response); + Response = NULL; + continue; + case ShellPromptResponseCancel: + *Resp = Response; + // + // indicate to stop everything + // + SHELL_FREE_NON_NULL (FullCwd); + return (SHELL_ABORTED); + case ShellPromptResponseAll: + *Resp = Response; + break; + case ShellPromptResponseYes: + FreePool (Response); + Response = NULL; + break; + default: + FreePool (Response); + SHELL_FREE_NON_NULL (FullCwd); + return SHELL_ABORTED; + } + + Status = ShellDeleteFileByName (FullDestPath != NULL ? FullDestPath : DestPath); + } + + if (IsBetweenFileSystem (Node->FullName, FullCwd, DestPath)) { + while (FullDestPath == NULL && DestPath != NULL && DestPath[0] != CHAR_NULL && DestPath[StrLen (DestPath) - 1] == L'\\') { + DestPath[StrLen (DestPath) - 1] = CHAR_NULL; + } + + Status = MoveBetweenFileSystems (Node, FullDestPath != NULL ? FullDestPath : DestPath, &Response); + } else { + Status = MoveWithinFileSystems (Node, DestPath, &Response); + // + // Display error status + // + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"mv", Status); + } + } + + // + // Check our result + // + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_INVALID_PARAMETER; + if (Status == EFI_SECURITY_VIOLATION) { + ShellStatus = SHELL_SECURITY_VIOLATION; + } else if (Status == EFI_WRITE_PROTECTED) { + ShellStatus = SHELL_WRITE_PROTECTED; + } else if (Status == EFI_OUT_OF_RESOURCES) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + } else if (Status == EFI_DEVICE_ERROR) { + ShellStatus = SHELL_DEVICE_ERROR; + } else if (Status == EFI_ACCESS_DENIED) { + ShellStatus = SHELL_ACCESS_DENIED; + } + } else { + ShellPrintEx (-1, -1, L"%s", HiiResultOk); + } + } // main for loop + + SHELL_FREE_NON_NULL (FullDestPath); + SHELL_FREE_NON_NULL (DestPath); + SHELL_FREE_NON_NULL (HiiOutput); + SHELL_FREE_NON_NULL (HiiResultOk); + SHELL_FREE_NON_NULL (FullCwd); + return (ShellStatus); +} + +/** + Function for 'mv' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMv ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CHAR16 *Cwd; + UINTN CwdSize; + SHELL_STATUS ShellStatus; + UINTN ParamCount; + UINTN LoopCounter; + EFI_SHELL_FILE_INFO *FileList; + VOID *Response; + + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + ParamCount = 0; + FileList = NULL; + Response = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mv", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + switch (ParamCount = ShellCommandLineGetCount (Package)) { + case 0: + case 1: + // + // we have insufficient parameters + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mv"); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + case 2: + // + // must have valid CWD for single parameter... + // + if (ShellGetCurrentDir (NULL) == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"mv"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, 1)); + ShellStatus = SHELL_NOT_FOUND; + } else { + // + // ValidateAndMoveFiles will report errors to the screen itself + // + CwdSize = StrSize (ShellGetCurrentDir (NULL)) + sizeof (CHAR16); + Cwd = AllocateZeroPool (CwdSize); + if (Cwd == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"mv"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + } else { + StrCpyS (Cwd, CwdSize / sizeof (CHAR16), ShellGetCurrentDir (NULL)); + StrCatS (Cwd, CwdSize / sizeof (CHAR16), L"\\"); + ShellStatus = ValidateAndMoveFiles (FileList, &Response, Cwd); + FreePool (Cwd); + } + } + } + + break; + default: + /// @todo make sure this works with error half way through and continues... + for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount; LoopCounter++) { + if (ShellGetExecutionBreakFlag ()) { + break; + } + + Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, LoopCounter)); + ShellStatus = SHELL_NOT_FOUND; + } else { + // + // ValidateAndMoveFiles will report errors to the screen itself + // Only change ShellStatus if it's successful + // + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount)); + } else { + ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount)); + } + } + + if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) { + Status = ShellCloseFileMetaArg (&FileList); + if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) { + ShellStatus = SHELL_ACCESS_DENIED; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, 1), ShellStatus|MAX_BIT); + } + } + } + + break; + } // switch on parameter count + + if (FileList != NULL) { + ShellCloseFileMetaArg (&FileList); + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + } + + SHELL_FREE_NON_NULL (Response); + + if (ShellGetExecutionBreakFlag ()) { + return (SHELL_ABORTED); + } + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c index 955e082a93..b7eda08d1b 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c @@ -1,328 +1,328 @@ -/** @file
- Main file for Parse shell level 2 function.
-
- (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- Check if data is coming from StdIn output.
-
- @param[in] None
-
- @retval TRUE StdIn stream data available to parse
- @retval FALSE StdIn stream data is not available to parse.
-**/
-BOOLEAN
-IsStdInDataAvailable (
- VOID
- )
-{
- SHELL_FILE_HANDLE FileHandle;
- EFI_STATUS Status;
- CHAR16 CharBuffer;
- UINTN CharSize;
- UINT64 OriginalFilePosition;
-
- Status = EFI_SUCCESS;
- FileHandle = NULL;
- OriginalFilePosition = 0;
-
- if (ShellOpenFileByName (L">i", &FileHandle, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) {
- CharSize = sizeof (CHAR16);
- gEfiShellProtocol->GetFilePosition (FileHandle, &OriginalFilePosition);
- Status = gEfiShellProtocol->ReadFile (FileHandle, &CharSize, &CharBuffer);
- if (EFI_ERROR (Status) || (CharSize != sizeof (CHAR16))) {
- return FALSE;
- }
-
- gEfiShellProtocol->SetFilePosition (FileHandle, OriginalFilePosition);
- }
-
- if (FileHandle == NULL) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-/**
- Handle stings for SFO Output with escape character ^ in a string
- 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^").
- 2. The ^ character may be inserted using ^^.
-
- @param[in] String The Unicode NULL-terminated string.
-
- @retval NewString The new string handled for SFO.
-**/
-EFI_STRING
-HandleStringWithEscapeCharForParse (
- IN CHAR16 *String
- )
-{
- EFI_STRING NewStr;
- EFI_STRING StrWalker;
- EFI_STRING ReturnStr;
-
- if (String == NULL) {
- return NULL;
- }
-
- //
- // start to parse the input string.
- //
- NewStr = AllocateZeroPool (StrSize (String));
- if (NewStr == NULL) {
- return NULL;
- }
-
- ReturnStr = NewStr;
- StrWalker = String;
- while (*StrWalker != CHAR_NULL) {
- if ((*StrWalker == L'^') && ((*(StrWalker + 1) == L'^') || (*(StrWalker + 1) == L'"'))) {
- *NewStr = *(StrWalker + 1);
- StrWalker++;
- } else {
- *NewStr = *StrWalker;
- }
-
- StrWalker++;
- NewStr++;
- }
-
- return ReturnStr;
-}
-
-/**
- Do the actual parsing of the file. the file should be SFO output from a
- shell command or a similar format.
-
- @param[in] FileName The filename to open.
- @param[in] TableName The name of the table to find.
- @param[in] ColumnIndex The column number to get.
- @param[in] TableNameInstance Which instance of the table to get (row).
- @param[in] ShellCommandInstance Which instance of the command to get.
- @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not
-
- @retval SHELL_NOT_FOUND The requested instance was not found.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-PerformParsing (
- IN CONST CHAR16 *FileName,
- IN CONST CHAR16 *TableName,
- IN CONST UINTN ColumnIndex,
- IN CONST UINTN TableNameInstance,
- IN CONST UINTN ShellCommandInstance,
- IN BOOLEAN StreamingUnicode
- )
-{
- SHELL_FILE_HANDLE FileHandle;
- EFI_STATUS Status;
- BOOLEAN Ascii;
- UINTN LoopVariable;
- UINTN ColumnLoop;
- CHAR16 *TempLine;
- CHAR16 *ColumnPointer;
- SHELL_STATUS ShellStatus;
- CHAR16 *TempSpot;
- CHAR16 *SfoString;
-
- ASSERT (FileName != NULL);
- ASSERT (TableName != NULL);
-
- ShellStatus = SHELL_SUCCESS;
-
- Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"parse", FileName);
- ShellStatus = SHELL_NOT_FOUND;
- } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_FILE), gShellLevel2HiiHandle, L"parse", FileName);
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- for (LoopVariable = 0; LoopVariable < ShellCommandInstance && !ShellFileHandleEof (FileHandle);) {
- TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);
-
- if ((TempLine == NULL) || ((*TempLine == CHAR_NULL) && StreamingUnicode)) {
- break;
- }
-
- //
- // Search for "ShellCommand," in the file to start the SFO table
- // for a given ShellCommand. The UEFI Shell spec does not specify
- // a space after the comma.
- //
- if (StrStr (TempLine, L"ShellCommand,") == TempLine) {
- LoopVariable++;
- }
-
- SHELL_FREE_NON_NULL (TempLine);
- }
-
- if (LoopVariable == ShellCommandInstance) {
- LoopVariable = 0;
- while (1) {
- TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);
- if ( (TempLine == NULL)
- || (*TempLine == CHAR_NULL)
- || (StrStr (TempLine, L"ShellCommand,") == TempLine))
- {
- SHELL_FREE_NON_NULL (TempLine);
- break;
- }
-
- if (StrStr (TempLine, TableName) == TempLine) {
- LoopVariable++;
- if ( (LoopVariable == TableNameInstance)
- || (TableNameInstance == (UINTN)-1))
- {
- for (ColumnLoop = 1, ColumnPointer = TempLine; ColumnLoop < ColumnIndex && ColumnPointer != NULL && *ColumnPointer != CHAR_NULL; ColumnLoop++) {
- ColumnPointer = StrStr (ColumnPointer, L",\"");
- if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL)) {
- ColumnPointer++;
- }
- }
-
- if (ColumnLoop == ColumnIndex) {
- if (ColumnPointer == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- TempSpot = StrStr (ColumnPointer, L",\"");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
-
- while (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L' ') {
- ColumnPointer++;
- }
-
- if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[0] == L'\"')) {
- ColumnPointer++;
- }
-
- if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[StrLen (ColumnPointer) - 1] == L'\"')) {
- ColumnPointer[StrLen (ColumnPointer) - 1] = CHAR_NULL;
- }
-
- SfoString = HandleStringWithEscapeCharForParse (ColumnPointer);
- if (SfoString != NULL) {
- ShellPrintEx (-1, -1, L"%s\r\n", SfoString);
- SHELL_FREE_NON_NULL (SfoString);
- }
- }
- }
- }
- }
-
- SHELL_FREE_NON_NULL (TempLine);
- }
- }
- }
-
- return (ShellStatus);
-}
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-i", TypeValue },
- { L"-s", TypeValue },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'parse' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunParse (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- CONST CHAR16 *FileName;
- CONST CHAR16 *TableName;
- CONST CHAR16 *ColumnString;
- SHELL_STATUS ShellStatus;
- UINTN ShellCommandInstance;
- UINTN TableNameInstance;
- BOOLEAN StreamingUnicode;
-
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
- StreamingUnicode = FALSE;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParseEx (ParamList, &Package, &ProblemParam, TRUE, FALSE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"parse", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- StreamingUnicode = IsStdInDataAvailable ();
- if ((!StreamingUnicode && (ShellCommandLineGetCount (Package) < 4)) ||
- (ShellCommandLineGetCount (Package) < 3))
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"parse");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if ((StreamingUnicode && (ShellCommandLineGetCount (Package) > 3)) ||
- (ShellCommandLineGetCount (Package) > 4))
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"parse");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- if (StreamingUnicode) {
- FileName = L">i";
- TableName = ShellCommandLineGetRawValue (Package, 1);
- ColumnString = ShellCommandLineGetRawValue (Package, 2);
- } else {
- FileName = ShellCommandLineGetRawValue (Package, 1);
- TableName = ShellCommandLineGetRawValue (Package, 2);
- ColumnString = ShellCommandLineGetRawValue (Package, 3);
- }
-
- if (ShellCommandLineGetValue (Package, L"-i") == NULL) {
- TableNameInstance = (UINTN)-1;
- } else {
- TableNameInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-i"));
- }
-
- if (ShellCommandLineGetValue (Package, L"-s") == NULL) {
- ShellCommandInstance = 1;
- } else {
- ShellCommandInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-s"));
- }
-
- ShellStatus = PerformParsing (FileName, TableName, ShellStrToUintn (ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode);
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for Parse shell level 2 function. + + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + Check if data is coming from StdIn output. + + @param[in] None + + @retval TRUE StdIn stream data available to parse + @retval FALSE StdIn stream data is not available to parse. +**/ +BOOLEAN +IsStdInDataAvailable ( + VOID + ) +{ + SHELL_FILE_HANDLE FileHandle; + EFI_STATUS Status; + CHAR16 CharBuffer; + UINTN CharSize; + UINT64 OriginalFilePosition; + + Status = EFI_SUCCESS; + FileHandle = NULL; + OriginalFilePosition = 0; + + if (ShellOpenFileByName (L">i", &FileHandle, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) { + CharSize = sizeof (CHAR16); + gEfiShellProtocol->GetFilePosition (FileHandle, &OriginalFilePosition); + Status = gEfiShellProtocol->ReadFile (FileHandle, &CharSize, &CharBuffer); + if (EFI_ERROR (Status) || (CharSize != sizeof (CHAR16))) { + return FALSE; + } + + gEfiShellProtocol->SetFilePosition (FileHandle, OriginalFilePosition); + } + + if (FileHandle == NULL) { + return FALSE; + } else { + return TRUE; + } +} + +/** + Handle stings for SFO Output with escape character ^ in a string + 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^"). + 2. The ^ character may be inserted using ^^. + + @param[in] String The Unicode NULL-terminated string. + + @retval NewString The new string handled for SFO. +**/ +EFI_STRING +HandleStringWithEscapeCharForParse ( + IN CHAR16 *String + ) +{ + EFI_STRING NewStr; + EFI_STRING StrWalker; + EFI_STRING ReturnStr; + + if (String == NULL) { + return NULL; + } + + // + // start to parse the input string. + // + NewStr = AllocateZeroPool (StrSize (String)); + if (NewStr == NULL) { + return NULL; + } + + ReturnStr = NewStr; + StrWalker = String; + while (*StrWalker != CHAR_NULL) { + if ((*StrWalker == L'^') && ((*(StrWalker + 1) == L'^') || (*(StrWalker + 1) == L'"'))) { + *NewStr = *(StrWalker + 1); + StrWalker++; + } else { + *NewStr = *StrWalker; + } + + StrWalker++; + NewStr++; + } + + return ReturnStr; +} + +/** + Do the actual parsing of the file. the file should be SFO output from a + shell command or a similar format. + + @param[in] FileName The filename to open. + @param[in] TableName The name of the table to find. + @param[in] ColumnIndex The column number to get. + @param[in] TableNameInstance Which instance of the table to get (row). + @param[in] ShellCommandInstance Which instance of the command to get. + @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not + + @retval SHELL_NOT_FOUND The requested instance was not found. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +PerformParsing ( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *TableName, + IN CONST UINTN ColumnIndex, + IN CONST UINTN TableNameInstance, + IN CONST UINTN ShellCommandInstance, + IN BOOLEAN StreamingUnicode + ) +{ + SHELL_FILE_HANDLE FileHandle; + EFI_STATUS Status; + BOOLEAN Ascii; + UINTN LoopVariable; + UINTN ColumnLoop; + CHAR16 *TempLine; + CHAR16 *ColumnPointer; + SHELL_STATUS ShellStatus; + CHAR16 *TempSpot; + CHAR16 *SfoString; + + ASSERT (FileName != NULL); + ASSERT (TableName != NULL); + + ShellStatus = SHELL_SUCCESS; + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"parse", FileName); + ShellStatus = SHELL_NOT_FOUND; + } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_FILE), gShellLevel2HiiHandle, L"parse", FileName); + ShellStatus = SHELL_NOT_FOUND; + } else { + for (LoopVariable = 0; LoopVariable < ShellCommandInstance && !ShellFileHandleEof (FileHandle);) { + TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii); + + if ((TempLine == NULL) || ((*TempLine == CHAR_NULL) && StreamingUnicode)) { + break; + } + + // + // Search for "ShellCommand," in the file to start the SFO table + // for a given ShellCommand. The UEFI Shell spec does not specify + // a space after the comma. + // + if (StrStr (TempLine, L"ShellCommand,") == TempLine) { + LoopVariable++; + } + + SHELL_FREE_NON_NULL (TempLine); + } + + if (LoopVariable == ShellCommandInstance) { + LoopVariable = 0; + while (1) { + TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii); + if ( (TempLine == NULL) + || (*TempLine == CHAR_NULL) + || (StrStr (TempLine, L"ShellCommand,") == TempLine)) + { + SHELL_FREE_NON_NULL (TempLine); + break; + } + + if (StrStr (TempLine, TableName) == TempLine) { + LoopVariable++; + if ( (LoopVariable == TableNameInstance) + || (TableNameInstance == (UINTN)-1)) + { + for (ColumnLoop = 1, ColumnPointer = TempLine; ColumnLoop < ColumnIndex && ColumnPointer != NULL && *ColumnPointer != CHAR_NULL; ColumnLoop++) { + ColumnPointer = StrStr (ColumnPointer, L",\""); + if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL)) { + ColumnPointer++; + } + } + + if (ColumnLoop == ColumnIndex) { + if (ColumnPointer == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + TempSpot = StrStr (ColumnPointer, L",\""); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + + while (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L' ') { + ColumnPointer++; + } + + if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[0] == L'\"')) { + ColumnPointer++; + } + + if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[StrLen (ColumnPointer) - 1] == L'\"')) { + ColumnPointer[StrLen (ColumnPointer) - 1] = CHAR_NULL; + } + + SfoString = HandleStringWithEscapeCharForParse (ColumnPointer); + if (SfoString != NULL) { + ShellPrintEx (-1, -1, L"%s\r\n", SfoString); + SHELL_FREE_NON_NULL (SfoString); + } + } + } + } + } + + SHELL_FREE_NON_NULL (TempLine); + } + } + } + + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-i", TypeValue }, + { L"-s", TypeValue }, + { NULL, TypeMax } +}; + +/** + Function for 'parse' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunParse ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *FileName; + CONST CHAR16 *TableName; + CONST CHAR16 *ColumnString; + SHELL_STATUS ShellStatus; + UINTN ShellCommandInstance; + UINTN TableNameInstance; + BOOLEAN StreamingUnicode; + + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + StreamingUnicode = FALSE; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParseEx (ParamList, &Package, &ProblemParam, TRUE, FALSE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"parse", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + StreamingUnicode = IsStdInDataAvailable (); + if ((!StreamingUnicode && (ShellCommandLineGetCount (Package) < 4)) || + (ShellCommandLineGetCount (Package) < 3)) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"parse"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((StreamingUnicode && (ShellCommandLineGetCount (Package) > 3)) || + (ShellCommandLineGetCount (Package) > 4)) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"parse"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (StreamingUnicode) { + FileName = L">i"; + TableName = ShellCommandLineGetRawValue (Package, 1); + ColumnString = ShellCommandLineGetRawValue (Package, 2); + } else { + FileName = ShellCommandLineGetRawValue (Package, 1); + TableName = ShellCommandLineGetRawValue (Package, 2); + ColumnString = ShellCommandLineGetRawValue (Package, 3); + } + + if (ShellCommandLineGetValue (Package, L"-i") == NULL) { + TableNameInstance = (UINTN)-1; + } else { + TableNameInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-i")); + } + + if (ShellCommandLineGetValue (Package, L"-s") == NULL) { + ShellCommandInstance = 1; + } else { + ShellCommandInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-s")); + } + + ShellStatus = PerformParsing (FileName, TableName, ShellStrToUintn (ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode); + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c index 361c47e430..0b7ec3529e 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c @@ -1,178 +1,178 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-STATIC CONST SHELL_PARAM_ITEM ResetParamList[] = {
- { L"-w", TypeValue },
- { L"-s", TypeValue },
- { L"-c", TypeValue },
- { L"-fwui", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'reset' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunReset (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CONST CHAR16 *String;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINT64 OsIndications;
- UINT32 Attr;
- UINTN DataSize;
-
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ResetParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"reset", ProblemParam);
- FreePool (ProblemParam);
- return (SHELL_INVALID_PARAMETER);
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 1) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- if (ShellCommandLineGetFlag (Package, L"-fwui")) {
- DataSize = sizeof (OsIndications);
- Status = gRT->GetVariable (
- EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
- &gEfiGlobalVariableGuid,
- &Attr,
- &DataSize,
- &OsIndications
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_UNSUPPORTED;
- goto Error;
- }
-
- if ((OsIndications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0) {
- DataSize = sizeof (OsIndications);
- Status = gRT->GetVariable (
- EFI_OS_INDICATIONS_VARIABLE_NAME,
- &gEfiGlobalVariableGuid,
- &Attr,
- &DataSize,
- &OsIndications
- );
-
- if (EFI_ERROR (Status)) {
- OsIndications = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
- } else {
- OsIndications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
- }
-
- Status = gRT->SetVariable (
- EFI_OS_INDICATIONS_VARIABLE_NAME,
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (OsIndications),
- &OsIndications
- );
- }
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_UNSUPPORTED;
- goto Error;
- }
- }
-
- //
- // check for warm reset flag, then shutdown reset flag, then cold (default) reset flag
- //
- if (ShellCommandLineGetFlag (Package, L"-w")) {
- if (ShellCommandLineGetFlag (Package, L"-s") || ShellCommandLineGetFlag (Package, L"-c")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- String = ShellCommandLineGetValue (Package, L"-w");
- if (String != NULL) {
- gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, StrSize (String), (VOID *)String);
- } else {
- gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
- }
- }
- } else if (ShellCommandLineGetFlag (Package, L"-s")) {
- if (ShellCommandLineGetFlag (Package, L"-c")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- String = ShellCommandLineGetValue (Package, L"-s");
- DEBUG_CODE (
- ShellPrintEx (-1, -1, L"Reset with %s (%d bytes)", String, String != NULL ? StrSize (String) : 0);
- );
- if (String != NULL) {
- gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, StrSize (String), (VOID *)String);
- } else {
- gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
- }
- }
- } else {
- //
- // this is default so dont worry about flag...
- //
- String = ShellCommandLineGetValue (Package, L"-c");
- if (String != NULL) {
- gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, StrSize (String), (VOID *)String);
- } else {
- gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
- }
- }
- }
- }
-
- //
- // we should never get here... so the free and return are for formality more than use
- // as the ResetSystem function should not return...
- //
-
-Error:
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- //
- // return the status
- //
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +STATIC CONST SHELL_PARAM_ITEM ResetParamList[] = { + { L"-w", TypeValue }, + { L"-s", TypeValue }, + { L"-c", TypeValue }, + { L"-fwui", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'reset' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunReset ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CONST CHAR16 *String; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINT64 OsIndications; + UINT32 Attr; + UINTN DataSize; + + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (ResetParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"reset", ProblemParam); + FreePool (ProblemParam); + return (SHELL_INVALID_PARAMETER); + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 1) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (ShellCommandLineGetFlag (Package, L"-fwui")) { + DataSize = sizeof (OsIndications); + Status = gRT->GetVariable ( + EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, + &gEfiGlobalVariableGuid, + &Attr, + &DataSize, + &OsIndications + ); + + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_UNSUPPORTED; + goto Error; + } + + if ((OsIndications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0) { + DataSize = sizeof (OsIndications); + Status = gRT->GetVariable ( + EFI_OS_INDICATIONS_VARIABLE_NAME, + &gEfiGlobalVariableGuid, + &Attr, + &DataSize, + &OsIndications + ); + + if (EFI_ERROR (Status)) { + OsIndications = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; + } else { + OsIndications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; + } + + Status = gRT->SetVariable ( + EFI_OS_INDICATIONS_VARIABLE_NAME, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (OsIndications), + &OsIndications + ); + } + + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_UNSUPPORTED; + goto Error; + } + } + + // + // check for warm reset flag, then shutdown reset flag, then cold (default) reset flag + // + if (ShellCommandLineGetFlag (Package, L"-w")) { + if (ShellCommandLineGetFlag (Package, L"-s") || ShellCommandLineGetFlag (Package, L"-c")) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + String = ShellCommandLineGetValue (Package, L"-w"); + if (String != NULL) { + gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, StrSize (String), (VOID *)String); + } else { + gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); + } + } + } else if (ShellCommandLineGetFlag (Package, L"-s")) { + if (ShellCommandLineGetFlag (Package, L"-c")) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"reset"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + String = ShellCommandLineGetValue (Package, L"-s"); + DEBUG_CODE ( + ShellPrintEx (-1, -1, L"Reset with %s (%d bytes)", String, String != NULL ? StrSize (String) : 0); + ); + if (String != NULL) { + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, StrSize (String), (VOID *)String); + } else { + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + } + } else { + // + // this is default so dont worry about flag... + // + String = ShellCommandLineGetValue (Package, L"-c"); + if (String != NULL) { + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, StrSize (String), (VOID *)String); + } else { + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } + } + } + } + + // + // we should never get here... so the free and return are for formality more than use + // as the ResetSystem function should not return... + // + +Error: + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + // + // return the status + // + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c index 2354cd0620..439a514182 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c @@ -1,394 +1,394 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-q", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Determine if a directory has no files in it.
-
- @param[in] FileHandle The EFI_HANDLE to the directory.
-
- @retval TRUE The directory has no files (or directories).
- @retval FALSE The directory has at least 1 file or directory in it.
-**/
-BOOLEAN
-IsDirectoryEmpty (
- IN SHELL_FILE_HANDLE FileHandle
- )
-{
- EFI_STATUS Status;
- EFI_FILE_INFO *FileInfo;
- BOOLEAN NoFile;
- BOOLEAN RetVal;
-
- RetVal = TRUE;
- NoFile = FALSE;
- FileInfo = NULL;
-
- for (Status = FileHandleFindFirstFile (FileHandle, &FileInfo)
- ; !NoFile && !EFI_ERROR (Status)
- ; FileHandleFindNextFile (FileHandle, FileInfo, &NoFile)
- )
- {
- if ( (StrStr (FileInfo->FileName, L".") != FileInfo->FileName)
- && (StrStr (FileInfo->FileName, L"..") != FileInfo->FileName))
- {
- RetVal = FALSE;
- }
- }
-
- return (RetVal);
-}
-
-/**
- Delete a node and all nodes under it (including sub directories).
-
- @param[in] Node The node to start deleting with.
- @param[in] Quiet TRUE to print no messages.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_ACCESS_DENIED A file was read only.
- @retval SHELL_ABORTED The abort message was received.
- @retval SHELL_DEVICE_ERROR A device error occurred reading this Node.
-**/
-SHELL_STATUS
-CascadeDelete (
- IN EFI_SHELL_FILE_INFO *Node,
- IN CONST BOOLEAN Quiet
- )
-{
- SHELL_STATUS ShellStatus;
- EFI_SHELL_FILE_INFO *List;
- EFI_SHELL_FILE_INFO *Node2;
- EFI_STATUS Status;
- SHELL_PROMPT_RESPONSE *Resp;
- CHAR16 *TempName;
- UINTN NewSize;
-
- Resp = NULL;
- ShellStatus = SHELL_SUCCESS;
- List = NULL;
- Status = EFI_SUCCESS;
-
- if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, L"rm", Node->FullName);
- return (SHELL_ACCESS_DENIED);
- }
-
- if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
- if (!IsDirectoryEmpty (Node->Handle)) {
- if (!Quiet) {
- Status = ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName);
- Status = ShellPromptForResponse (ShellPromptResponseTypeYesNo, NULL, (VOID **)&Resp);
- ASSERT (Resp != NULL);
- if (EFI_ERROR (Status) || (*Resp != ShellPromptResponseYes)) {
- SHELL_FREE_NON_NULL (Resp);
- return (SHELL_ABORTED);
- }
-
- SHELL_FREE_NON_NULL (Resp);
- }
-
- //
- // empty out the directory
- //
- Status = gEfiShellProtocol->FindFilesInDir (Node->Handle, &List);
- if (EFI_ERROR (Status)) {
- if (List != NULL) {
- gEfiShellProtocol->FreeFileList (&List);
- }
-
- return (SHELL_DEVICE_ERROR);
- }
-
- for (Node2 = (EFI_SHELL_FILE_INFO *)GetFirstNode (&List->Link)
- ; !IsNull (&List->Link, &Node2->Link)
- ; Node2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&List->Link, &Node2->Link)
- )
- {
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (Node2->FileName, L".") == 0) || (StrCmp (Node2->FileName, L"..") == 0)) {
- continue;
- }
-
- Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
- if (EFI_ERROR (Node2->Status) && (StrStr (Node2->FileName, L":") == NULL)) {
- //
- // Update the node filename to have full path with file system identifier
- //
- NewSize = StrSize (Node->FullName) + StrSize (Node2->FullName);
- TempName = AllocateZeroPool (NewSize);
- if (TempName == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (TempName, NewSize/sizeof (CHAR16), Node->FullName);
- TempName[StrStr (TempName, L":")+1-TempName] = CHAR_NULL;
- StrCatS (TempName, NewSize/sizeof (CHAR16), Node2->FullName);
- FreePool ((VOID *)Node2->FullName);
- Node2->FullName = TempName;
-
- //
- // Now try again to open the file
- //
- Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE);
- }
- }
-
- if (!EFI_ERROR (Node2->Status)) {
- ShellStatus = CascadeDelete (Node2, Quiet);
- } else if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000));
- }
-
- if (ShellStatus != SHELL_SUCCESS) {
- if (List != NULL) {
- gEfiShellProtocol->FreeFileList (&List);
- }
-
- return (ShellStatus);
- }
- }
-
- if (List != NULL) {
- gEfiShellProtocol->FreeFileList (&List);
- }
- }
- }
-
- if (!((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0))) {
- //
- // now delete the current node...
- //
- if (!Quiet) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName);
- }
-
- Status = gEfiShellProtocol->DeleteFile (Node->Handle);
- Node->Handle = NULL;
- }
-
- //
- // We cant allow for the warning here! (Dont use EFI_ERROR Macro).
- //
- if (Status != EFI_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status);
- return (SHELL_ACCESS_DENIED);
- } else {
- if (!Quiet) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle);
- }
-
- return (SHELL_SUCCESS);
- }
-}
-
-/**
- Determines if a Node is a valid delete target. Will prevent deleting the root directory.
-
- @param[in] List RESERVED. Not used.
- @param[in] Node The node to analyze.
- @param[in] Package RESERVED. Not used.
-**/
-BOOLEAN
-IsValidDeleteTarget (
- IN CONST EFI_SHELL_FILE_INFO *List,
- IN CONST EFI_SHELL_FILE_INFO *Node,
- IN CONST LIST_ENTRY *Package
- )
-{
- CONST CHAR16 *TempLocation;
- BOOLEAN RetVal;
- CHAR16 *SearchString;
- CHAR16 *Pattern;
- UINTN Size;
-
- if ((Node == NULL) || (Node->FullName == NULL)) {
- return (FALSE);
- }
-
- TempLocation = StrStr (Node->FullName, L":");
- if (StrLen (TempLocation) <= 2) {
- //
- // Deleting the root directory is invalid.
- //
- return (FALSE);
- }
-
- TempLocation = ShellGetCurrentDir (NULL);
- if (TempLocation == NULL) {
- //
- // No working directory is specified so whatever is left is ok.
- //
- return (TRUE);
- }
-
- Pattern = NULL;
- SearchString = NULL;
- Size = 0;
- Pattern = StrnCatGrow (&Pattern, &Size, TempLocation, 0);
- Pattern = StrnCatGrow (&Pattern, &Size, L"\\", 0);
- Size = 0;
- SearchString = StrnCatGrow (&SearchString, &Size, Node->FullName, 0);
- if (!EFI_ERROR (ShellIsDirectory (SearchString))) {
- SearchString = StrnCatGrow (&SearchString, &Size, L"\\", 0);
- SearchString = StrnCatGrow (&SearchString, &Size, L"*", 0);
- }
-
- if ((Pattern == NULL) || (SearchString == NULL)) {
- RetVal = FALSE;
- } else {
- RetVal = TRUE;
- if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, Pattern, SearchString)) {
- RetVal = FALSE;
- }
- }
-
- SHELL_FREE_NON_NULL (Pattern);
- SHELL_FREE_NON_NULL (SearchString);
-
- return (RetVal);
-}
-
-/**
- Function for 'rm' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunRm (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- CONST CHAR16 *Param;
- SHELL_STATUS ShellStatus;
- UINTN ParamCount;
- EFI_SHELL_FILE_INFO *FileList;
- EFI_SHELL_FILE_INFO *Node;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- ParamCount = 0;
- FileList = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"rm", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
- //
- // we insufficient parameters
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"rm");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // get a list with each file specified by parameters
- // if parameter is a directory then add all the files below it to the list
- //
- for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)
- ; Param != NULL
- ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)
- )
- {
- Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"rm", (CHAR16 *)Param);
- ShellStatus = SHELL_NOT_FOUND;
- break;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // loop through the list and make sure we are not aborting...
- //
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
- ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
- )
- {
- //
- // skip the directory traversing stuff...
- //
- if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) {
- continue;
- }
-
- //
- // do the deleting of nodes
- //
- if (EFI_ERROR (Node->Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR2), gShellLevel2HiiHandle, Node->Status);
- ShellStatus = SHELL_ACCESS_DENIED;
- break;
- }
-
- if (!IsValidDeleteTarget (FileList, Node, Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR3), gShellLevel2HiiHandle, Node->FullName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- break;
- }
-
- ShellStatus = CascadeDelete (Node, ShellCommandLineGetFlag (Package, L"-q"));
- }
- }
-
- //
- // Free the fileList
- //
- if (FileList != NULL) {
- Status = ShellCloseFileMetaArg (&FileList);
- }
-
- FileList = NULL;
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
- }
-
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-q", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Determine if a directory has no files in it. + + @param[in] FileHandle The EFI_HANDLE to the directory. + + @retval TRUE The directory has no files (or directories). + @retval FALSE The directory has at least 1 file or directory in it. +**/ +BOOLEAN +IsDirectoryEmpty ( + IN SHELL_FILE_HANDLE FileHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *FileInfo; + BOOLEAN NoFile; + BOOLEAN RetVal; + + RetVal = TRUE; + NoFile = FALSE; + FileInfo = NULL; + + for (Status = FileHandleFindFirstFile (FileHandle, &FileInfo) + ; !NoFile && !EFI_ERROR (Status) + ; FileHandleFindNextFile (FileHandle, FileInfo, &NoFile) + ) + { + if ( (StrStr (FileInfo->FileName, L".") != FileInfo->FileName) + && (StrStr (FileInfo->FileName, L"..") != FileInfo->FileName)) + { + RetVal = FALSE; + } + } + + return (RetVal); +} + +/** + Delete a node and all nodes under it (including sub directories). + + @param[in] Node The node to start deleting with. + @param[in] Quiet TRUE to print no messages. + + @retval SHELL_SUCCESS The operation was successful. + @retval SHELL_ACCESS_DENIED A file was read only. + @retval SHELL_ABORTED The abort message was received. + @retval SHELL_DEVICE_ERROR A device error occurred reading this Node. +**/ +SHELL_STATUS +CascadeDelete ( + IN EFI_SHELL_FILE_INFO *Node, + IN CONST BOOLEAN Quiet + ) +{ + SHELL_STATUS ShellStatus; + EFI_SHELL_FILE_INFO *List; + EFI_SHELL_FILE_INFO *Node2; + EFI_STATUS Status; + SHELL_PROMPT_RESPONSE *Resp; + CHAR16 *TempName; + UINTN NewSize; + + Resp = NULL; + ShellStatus = SHELL_SUCCESS; + List = NULL; + Status = EFI_SUCCESS; + + if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, L"rm", Node->FullName); + return (SHELL_ACCESS_DENIED); + } + + if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { + if (!IsDirectoryEmpty (Node->Handle)) { + if (!Quiet) { + Status = ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName); + Status = ShellPromptForResponse (ShellPromptResponseTypeYesNo, NULL, (VOID **)&Resp); + ASSERT (Resp != NULL); + if (EFI_ERROR (Status) || (*Resp != ShellPromptResponseYes)) { + SHELL_FREE_NON_NULL (Resp); + return (SHELL_ABORTED); + } + + SHELL_FREE_NON_NULL (Resp); + } + + // + // empty out the directory + // + Status = gEfiShellProtocol->FindFilesInDir (Node->Handle, &List); + if (EFI_ERROR (Status)) { + if (List != NULL) { + gEfiShellProtocol->FreeFileList (&List); + } + + return (SHELL_DEVICE_ERROR); + } + + for (Node2 = (EFI_SHELL_FILE_INFO *)GetFirstNode (&List->Link) + ; !IsNull (&List->Link, &Node2->Link) + ; Node2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&List->Link, &Node2->Link) + ) + { + // + // skip the directory traversing stuff... + // + if ((StrCmp (Node2->FileName, L".") == 0) || (StrCmp (Node2->FileName, L"..") == 0)) { + continue; + } + + Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); + if (EFI_ERROR (Node2->Status) && (StrStr (Node2->FileName, L":") == NULL)) { + // + // Update the node filename to have full path with file system identifier + // + NewSize = StrSize (Node->FullName) + StrSize (Node2->FullName); + TempName = AllocateZeroPool (NewSize); + if (TempName == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + } else { + StrCpyS (TempName, NewSize/sizeof (CHAR16), Node->FullName); + TempName[StrStr (TempName, L":")+1-TempName] = CHAR_NULL; + StrCatS (TempName, NewSize/sizeof (CHAR16), Node2->FullName); + FreePool ((VOID *)Node2->FullName); + Node2->FullName = TempName; + + // + // Now try again to open the file + // + Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); + } + } + + if (!EFI_ERROR (Node2->Status)) { + ShellStatus = CascadeDelete (Node2, Quiet); + } else if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000)); + } + + if (ShellStatus != SHELL_SUCCESS) { + if (List != NULL) { + gEfiShellProtocol->FreeFileList (&List); + } + + return (ShellStatus); + } + } + + if (List != NULL) { + gEfiShellProtocol->FreeFileList (&List); + } + } + } + + if (!((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0))) { + // + // now delete the current node... + // + if (!Quiet) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName); + } + + Status = gEfiShellProtocol->DeleteFile (Node->Handle); + Node->Handle = NULL; + } + + // + // We cant allow for the warning here! (Dont use EFI_ERROR Macro). + // + if (Status != EFI_SUCCESS) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status); + return (SHELL_ACCESS_DENIED); + } else { + if (!Quiet) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle); + } + + return (SHELL_SUCCESS); + } +} + +/** + Determines if a Node is a valid delete target. Will prevent deleting the root directory. + + @param[in] List RESERVED. Not used. + @param[in] Node The node to analyze. + @param[in] Package RESERVED. Not used. +**/ +BOOLEAN +IsValidDeleteTarget ( + IN CONST EFI_SHELL_FILE_INFO *List, + IN CONST EFI_SHELL_FILE_INFO *Node, + IN CONST LIST_ENTRY *Package + ) +{ + CONST CHAR16 *TempLocation; + BOOLEAN RetVal; + CHAR16 *SearchString; + CHAR16 *Pattern; + UINTN Size; + + if ((Node == NULL) || (Node->FullName == NULL)) { + return (FALSE); + } + + TempLocation = StrStr (Node->FullName, L":"); + if (StrLen (TempLocation) <= 2) { + // + // Deleting the root directory is invalid. + // + return (FALSE); + } + + TempLocation = ShellGetCurrentDir (NULL); + if (TempLocation == NULL) { + // + // No working directory is specified so whatever is left is ok. + // + return (TRUE); + } + + Pattern = NULL; + SearchString = NULL; + Size = 0; + Pattern = StrnCatGrow (&Pattern, &Size, TempLocation, 0); + Pattern = StrnCatGrow (&Pattern, &Size, L"\\", 0); + Size = 0; + SearchString = StrnCatGrow (&SearchString, &Size, Node->FullName, 0); + if (!EFI_ERROR (ShellIsDirectory (SearchString))) { + SearchString = StrnCatGrow (&SearchString, &Size, L"\\", 0); + SearchString = StrnCatGrow (&SearchString, &Size, L"*", 0); + } + + if ((Pattern == NULL) || (SearchString == NULL)) { + RetVal = FALSE; + } else { + RetVal = TRUE; + if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, Pattern, SearchString)) { + RetVal = FALSE; + } + } + + SHELL_FREE_NON_NULL (Pattern); + SHELL_FREE_NON_NULL (SearchString); + + return (RetVal); +} + +/** + Function for 'rm' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunRm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *Param; + SHELL_STATUS ShellStatus; + UINTN ParamCount; + EFI_SHELL_FILE_INFO *FileList; + EFI_SHELL_FILE_INFO *Node; + + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + ParamCount = 0; + FileList = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"rm", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + if (ShellCommandLineGetRawValue (Package, 1) == NULL) { + // + // we insufficient parameters + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"rm"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // get a list with each file specified by parameters + // if parameter is a directory then add all the files below it to the list + // + for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount) + ; Param != NULL + ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount) + ) + { + Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"rm", (CHAR16 *)Param); + ShellStatus = SHELL_NOT_FOUND; + break; + } + } + + if (ShellStatus == SHELL_SUCCESS) { + // + // loop through the list and make sure we are not aborting... + // + for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link) + ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag () + ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link) + ) + { + // + // skip the directory traversing stuff... + // + if ((StrCmp (Node->FileName, L".") == 0) || (StrCmp (Node->FileName, L"..") == 0)) { + continue; + } + + // + // do the deleting of nodes + // + if (EFI_ERROR (Node->Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR2), gShellLevel2HiiHandle, Node->Status); + ShellStatus = SHELL_ACCESS_DENIED; + break; + } + + if (!IsValidDeleteTarget (FileList, Node, Package)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR3), gShellLevel2HiiHandle, Node->FullName); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } + + ShellStatus = CascadeDelete (Node, ShellCommandLineGetFlag (Package, L"-q")); + } + } + + // + // Free the fileList + // + if (FileList != NULL) { + Status = ShellCloseFileMetaArg (&FileList); + } + + FileList = NULL; + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + } + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Set.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Set.c index 79596373d6..5b59df4c8e 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Set.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Set.c @@ -1,168 +1,168 @@ -/** @file
- Main file for attrib shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- Print out each environment variable registered with the Shell 2.0 GUID.
-
- If you spawn a pre 2.0 shell from the Shell 2.0 the environment variable may not carry through.
-
- @retval STATUS_SUCCESS the printout was successful
- @return any return code from GetNextVariableName except EFI_NOT_FOUND
-**/
-SHELL_STATUS
-PrintAllShellEnvVars (
- VOID
- )
-{
- CONST CHAR16 *Value;
- CONST CHAR16 *ConstEnvNameList;
-
- ConstEnvNameList = gEfiShellProtocol->GetEnv (NULL);
- if (ConstEnvNameList == NULL) {
- return (SHELL_SUCCESS);
- }
-
- while (*ConstEnvNameList != CHAR_NULL) {
- Value = gEfiShellProtocol->GetEnv (ConstEnvNameList);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_DISP), gShellLevel2HiiHandle, ConstEnvNameList, Value);
- ConstEnvNameList += StrLen (ConstEnvNameList)+1;
- }
-
- return (SHELL_SUCCESS);
-}
-
-STATIC CONST SHELL_PARAM_ITEM SetParamList[] = {
- { L"-d", TypeValue },
- { L"-v", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'set' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunSet (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CONST CHAR16 *KeyName;
- CONST CHAR16 *Value;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Make sure globals are good...
- //
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (SetParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"set", ProblemParam);
- FreePool (ProblemParam);
- return (SHELL_INVALID_PARAMETER);
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"set");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if ((ShellCommandLineGetRawValue (Package, 1) != NULL) && ShellCommandLineGetFlag (Package, L"-d")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"set");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetFlag (Package, L"-d")) {
- //
- // delete a environment variable
- //
- KeyName = ShellCommandLineGetValue (Package, L"-d");
- if (KeyName == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"set", L"-d");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellSetEnvironmentVariable (KeyName, L"", ShellCommandLineGetFlag (Package, L"-v"));
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_ND), gShellLevel2HiiHandle, L"set", KeyName);
- ShellStatus = SHELL_DEVICE_ERROR;
- }
- }
- } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
- //
- // print out all current environment variables
- //
- return (PrintAllShellEnvVars ());
- } else {
- //
- // we are either printing one or assigning one
- //
- KeyName = ShellCommandLineGetRawValue (Package, 1);
- Value = ShellCommandLineGetRawValue (Package, 2);
- if ((KeyName != NULL) && (Value != NULL)) {
- //
- // assigning one
- //
- Status = ShellSetEnvironmentVariable (KeyName, Value, ShellCommandLineGetFlag (Package, L"-v"));
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_ERROR_SET), gShellLevel2HiiHandle, L"set", KeyName);
- ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
- }
- } else {
- if (KeyName != NULL) {
- //
- // print out value for this one only.
- //
- Value = ShellGetEnvironmentVariable (KeyName);
- if (Value == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_NF), gShellLevel2HiiHandle, L"set", KeyName);
- ShellStatus = SHELL_SUCCESS;
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_DISP), gShellLevel2HiiHandle, KeyName, Value);
- ShellStatus = SHELL_SUCCESS;
- }
- } else {
- ASSERT (FALSE);
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for attrib shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + Print out each environment variable registered with the Shell 2.0 GUID. + + If you spawn a pre 2.0 shell from the Shell 2.0 the environment variable may not carry through. + + @retval STATUS_SUCCESS the printout was successful + @return any return code from GetNextVariableName except EFI_NOT_FOUND +**/ +SHELL_STATUS +PrintAllShellEnvVars ( + VOID + ) +{ + CONST CHAR16 *Value; + CONST CHAR16 *ConstEnvNameList; + + ConstEnvNameList = gEfiShellProtocol->GetEnv (NULL); + if (ConstEnvNameList == NULL) { + return (SHELL_SUCCESS); + } + + while (*ConstEnvNameList != CHAR_NULL) { + Value = gEfiShellProtocol->GetEnv (ConstEnvNameList); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_DISP), gShellLevel2HiiHandle, ConstEnvNameList, Value); + ConstEnvNameList += StrLen (ConstEnvNameList)+1; + } + + return (SHELL_SUCCESS); +} + +STATIC CONST SHELL_PARAM_ITEM SetParamList[] = { + { L"-d", TypeValue }, + { L"-v", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'set' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSet ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CONST CHAR16 *KeyName; + CONST CHAR16 *Value; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // Make sure globals are good... + // + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (SetParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"set", ProblemParam); + FreePool (ProblemParam); + return (SHELL_INVALID_PARAMETER); + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"set"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((ShellCommandLineGetRawValue (Package, 1) != NULL) && ShellCommandLineGetFlag (Package, L"-d")) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"set"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag (Package, L"-d")) { + // + // delete a environment variable + // + KeyName = ShellCommandLineGetValue (Package, L"-d"); + if (KeyName == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"set", L"-d"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellSetEnvironmentVariable (KeyName, L"", ShellCommandLineGetFlag (Package, L"-v")); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_ND), gShellLevel2HiiHandle, L"set", KeyName); + ShellStatus = SHELL_DEVICE_ERROR; + } + } + } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) { + // + // print out all current environment variables + // + return (PrintAllShellEnvVars ()); + } else { + // + // we are either printing one or assigning one + // + KeyName = ShellCommandLineGetRawValue (Package, 1); + Value = ShellCommandLineGetRawValue (Package, 2); + if ((KeyName != NULL) && (Value != NULL)) { + // + // assigning one + // + Status = ShellSetEnvironmentVariable (KeyName, Value, ShellCommandLineGetFlag (Package, L"-v")); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_ERROR_SET), gShellLevel2HiiHandle, L"set", KeyName); + ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT)); + } + } else { + if (KeyName != NULL) { + // + // print out value for this one only. + // + Value = ShellGetEnvironmentVariable (KeyName); + if (Value == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_NF), gShellLevel2HiiHandle, L"set", KeyName); + ShellStatus = SHELL_SUCCESS; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SET_DISP), gShellLevel2HiiHandle, KeyName, Value); + ShellStatus = SHELL_SUCCESS; + } + } else { + ASSERT (FALSE); + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c index f01f4e450b..70593ff3b2 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c @@ -1,1006 +1,1006 @@ -/** @file
- Main file for time, timezone, and date shell level 2 and shell level 3 functions.
-
- (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-
-/**
- Determine if String is a valid representation for a time or date.
-
- @param[in] String The pointer to the string to test.
- @param[in] Char The delimeter character.
- @param[in] Min The minimum value allowed.
- @param[in] Max The maximum value allowed.
- @param[in] MinusOk Whether negative numbers are permitted.
-
- @retval TRUE String is a valid representation.
- @retval FALSE String is invalid.
-**/
-BOOLEAN
-InternalIsTimeLikeString (
- IN CONST CHAR16 *String,
- IN CONST CHAR16 Char,
- IN CONST UINTN Min,
- IN CONST UINTN Max,
- IN CONST BOOLEAN MinusOk
- )
-{
- UINTN Count;
-
- Count = 0;
-
- if (MinusOk) {
- //
- // A single minus is ok.
- //
- if (*String == L'-') {
- String++;
- }
- }
-
- //
- // the first char must be numeric.
- //
- if (!ShellIsDecimalDigitCharacter (*String)) {
- return (FALSE);
- }
-
- //
- // loop through the characters and use the lib function
- //
- for ( ; String != NULL && *String != CHAR_NULL; String++) {
- if (*String == Char) {
- Count++;
- if (Count > Max) {
- return (FALSE);
- }
-
- continue;
- }
-
- if (!ShellIsDecimalDigitCharacter (*String)) {
- return (FALSE);
- }
- }
-
- if (Count < Min) {
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-/**
- Verify that the DateString is valid and if so set that as the current
- date.
-
- @param[in] DateString The pointer to a string representation of the date.
-
- @retval SHELL_INVALID_PARAMETER DateString was NULL.
- @retval SHELL_INVALID_PARAMETER DateString was mis-formatted.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-CheckAndSetDate (
- IN CONST CHAR16 *DateString
- )
-{
- EFI_TIME TheTime;
- EFI_STATUS Status;
- CHAR16 *DateStringCopy;
- CHAR16 *Walker;
- CHAR16 *Walker1;
-
- if (!InternalIsTimeLikeString (DateString, L'/', 2, 2, FALSE)) {
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- DateStringCopy = NULL;
- DateStringCopy = StrnCatGrow (&DateStringCopy, NULL, DateString, 0);
- if (DateStringCopy == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- Walker = DateStringCopy;
-
- TheTime.Month = 0xFF;
- TheTime.Day = 0xFF;
- TheTime.Year = 0xFFFF;
-
- Walker1 = StrStr (Walker, L"/");
- if ((Walker1 != NULL) && (*Walker1 == L'/')) {
- *Walker1 = CHAR_NULL;
- }
-
- TheTime.Month = (UINT8)ShellStrToUintn (Walker);
- if (Walker1 != NULL) {
- Walker = Walker1 + 1;
- }
-
- Walker1 = Walker != NULL ? StrStr (Walker, L"/") : NULL;
- if ((Walker1 != NULL) && (*Walker1 == L'/')) {
- *Walker1 = CHAR_NULL;
- }
-
- if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) {
- TheTime.Day = (UINT8)ShellStrToUintn (Walker);
- if (Walker1 != NULL) {
- Walker = Walker1 + 1;
- }
-
- Walker1 = Walker != NULL ? StrStr (Walker, L"/") : NULL;
- if ((Walker1 != NULL) && (*Walker1 == L'/')) {
- *Walker1 = CHAR_NULL;
- }
-
- if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) {
- TheTime.Year = (UINT16)ShellStrToUintn (Walker);
- }
- }
-
- if (TheTime.Year < 100) {
- if (TheTime.Year >= 98) {
- TheTime.Year = (UINT16)(1900 + TheTime.Year);
- } else {
- TheTime.Year = (UINT16)(2000 + TheTime.Year);
- }
- }
-
- Status = gRT->SetTime (&TheTime);
-
- if (!EFI_ERROR (Status)) {
- return (SHELL_SUCCESS);
- }
-
- return (SHELL_INVALID_PARAMETER);
-}
-
-/**
- Function for 'date' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunDate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- EFI_TIME TheTime;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- CONST CHAR16 *Param1;
-
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"date", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // If there are 0 value parameters, then print the current date
- // else If there are any value paramerers, then print error
- //
- if (ShellCommandLineGetRawValue (Package, 1) == NULL) {
- //
- // get the current date
- //
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- //
- // ShellPrintEx the date in SFO or regular format
- //
- if (ShellCommandLineGetFlag (Package, L"-sfo")) {
- //
- // Match UEFI Shell spec:
- // ShellCommand,"date"
- // Date,"DD","MM","YYYY"
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"date");
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Day, TheTime.Month, TheTime.Year);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);
- }
- } else {
- if (PcdGet8 (PcdShellSupportLevel) == 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // perform level 3 operation here.
- //
- Param1 = ShellCommandLineGetRawValue (Package, 1);
- if (Param1 == NULL) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ShellStatus = CheckAndSetDate (Param1);
- }
-
- if (ShellStatus != SHELL_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"date", Param1);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- //
- // return the status
- //
- return (ShellStatus);
-}
-
-//
-// Note "-tz" is invalid for this (non-interactive) version of 'time'.
-//
-STATIC CONST SHELL_PARAM_ITEM TimeParamList2[] = {
- { L"-d", TypeValue },
- { NULL, TypeMax }
-};
-
-STATIC CONST SHELL_PARAM_ITEM TimeParamList3[] = {
- { L"-d", TypeValue },
- { L"-tz", TypeValue },
- { NULL, TypeMax }
-};
-
-/**
- Verify that the TimeString is valid and if so set that as the current
- time.
-
- @param[in] TimeString The pointer to a string representation of the time.
- @param[in] Tz The value to set for TimeZone.
- @param[in] Daylight The value to set for Daylight.
-
- @retval SHELL_INVALID_PARAMETER TimeString was NULL.
- @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-CheckAndSetTime (
- IN CONST CHAR16 *TimeString,
- IN CONST INT16 Tz,
- IN CONST UINT8 Daylight
- )
-{
- EFI_TIME TheTime;
- EFI_STATUS Status;
- CHAR16 *TimeStringCopy;
- CHAR16 *Walker1;
- CHAR16 *Walker2;
-
- if ((TimeString != NULL) && !InternalIsTimeLikeString (TimeString, L':', 1, 2, FALSE)) {
- return (SHELL_INVALID_PARAMETER);
- }
-
- if ((Daylight != 0xFF) && ((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) {
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- if (TimeString != NULL) {
- TimeStringCopy = NULL;
- TimeStringCopy = StrnCatGrow (&TimeStringCopy, NULL, TimeString, 0);
- Walker1 = TimeStringCopy;
- TheTime.Hour = 0xFF;
- TheTime.Minute = 0xFF;
-
- Walker2 = Walker1 != NULL ? StrStr (Walker1, L":") : NULL;
- if ((Walker2 != NULL) && (*Walker2 == L':')) {
- *Walker2 = CHAR_NULL;
- }
-
- TheTime.Hour = (UINT8)ShellStrToUintn (Walker1);
- if (Walker2 != NULL) {
- Walker1 = Walker2 + 1;
- }
-
- Walker2 = Walker1 != NULL ? StrStr (Walker1, L":") : NULL;
- if ((Walker2 != NULL) && (*Walker2 == L':')) {
- *Walker2 = CHAR_NULL;
- TheTime.Second = (UINT8)0;
- } else if (Walker2 == NULL) {
- TheTime.Second = (UINT8)0;
- }
-
- if ((Walker1 != NULL) && (Walker1[0] != CHAR_NULL)) {
- TheTime.Minute = (UINT8)ShellStrToUintn (Walker1);
- if (Walker2 != NULL) {
- Walker1 = Walker2 + 1;
- if ((Walker1 != NULL) && (Walker1[0] != CHAR_NULL)) {
- TheTime.Second = (UINT8)ShellStrToUintn (Walker1);
- }
- }
- }
-
- SHELL_FREE_NON_NULL (TimeStringCopy);
- }
-
- if ((Tz >= -1440) && (Tz <= 1440)) {
- //
- // EFI_TIME TimeZone is stored to meet the following calculation (see UEFI Spec):
- // Localtime = UTC - TimeZone
- // This means the sign must be changed for the user provided Tz.
- // EX: User wants to set TimeZone to Pacific Standard Time, so runs
- // time -tz -480 # set to UTC-08:00
- // To meet the calculation, the sign must be changed.
- //
- TheTime.TimeZone = -Tz;
- } else if (Tz == EFI_UNSPECIFIED_TIMEZONE) {
- TheTime.TimeZone = Tz;
- }
-
- if (Daylight != 0xFF) {
- TheTime.Daylight = Daylight;
- }
-
- Status = gRT->SetTime (&TheTime);
-
- if (!EFI_ERROR (Status)) {
- return (SHELL_SUCCESS);
- }
-
- return (SHELL_INVALID_PARAMETER);
-}
-
-/**
- Function for 'time' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunTime (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- EFI_TIME TheTime;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- INT16 Tz;
- UINT8 Daylight;
- CONST CHAR16 *TempLocation;
- UINTN TzMinutes;
-
- //
- // Initialize variables
- //
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- if (PcdGet8 (PcdShellSupportLevel) == 2) {
- Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);
- } else {
- ASSERT (PcdGet8 (PcdShellSupportLevel) == 3);
- Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);
- }
-
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"time", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // If there are no parameters, then print the current time
- //
- if ( (ShellCommandLineGetRawValue (Package, 1) == NULL)
- && !ShellCommandLineGetFlag (Package, L"-d")
- && !ShellCommandLineGetFlag (Package, L"-tz"))
- {
- //
- // ShellPrintEx the current time
- //
- if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
- TzMinutes = 0;
- } else {
- TzMinutes = (ABS (TheTime.TimeZone)) % 60;
- }
-
- if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIME_FORMAT),
- gShellLevel2HiiHandle,
- TheTime.Hour,
- TheTime.Minute,
- TheTime.Second,
- (TheTime.TimeZone > 0 ? L"-" : L"+"),
- ((ABS (TheTime.TimeZone)) / 60),
- TzMinutes
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIME_FORMAT_LOCAL),
- gShellLevel2HiiHandle,
- TheTime.Hour,
- TheTime.Minute,
- TheTime.Second
- );
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);
- } else if (ShellCommandLineGetFlag (Package, L"-d") && (ShellCommandLineGetValue (Package, L"-d") == NULL)) {
- if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIME_FORMAT_LOCAL),
- gShellLevel2HiiHandle,
- TheTime.Hour,
- TheTime.Minute,
- TheTime.Second
- );
- } else {
- TzMinutes = (ABS (TheTime.TimeZone)) % 60;
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIME_FORMAT),
- gShellLevel2HiiHandle,
- TheTime.Hour,
- TheTime.Minute,
- TheTime.Second,
- (TheTime.TimeZone > 0 ? L"-" : L"+"),
- ((ABS (TheTime.TimeZone)) / 60),
- TzMinutes
- );
- }
-
- switch (TheTime.Daylight) {
- case 0:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);
- break;
- case EFI_TIME_ADJUST_DAYLIGHT:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);
- break;
- case EFI_TIME_IN_DAYLIGHT:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);
- break;
- case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);
- break;
- default:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);
- }
- } else {
- if (PcdGet8 (PcdShellSupportLevel) == 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // perform level 3 operation here.
- //
- if ((TempLocation = ShellCommandLineGetValue (Package, L"-tz")) != NULL) {
- if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempLocation, L"_local") == 0) {
- Tz = EFI_UNSPECIFIED_TIMEZONE;
- } else if (TempLocation[0] == L'-') {
- Tz = (INT16)ShellStrToUintn (++TempLocation);
- //
- // When the argument of "time [-tz tz]" is not numeric, ShellStrToUintn() returns "-1".
- // Here we can detect the argument error by checking the return of ShellStrToUintn().
- //
- if (Tz == -1) {
- Tz = 1441; // make it to be out of bounds value
- } else {
- Tz *= (-1); // sign convert
- }
- } else {
- if (TempLocation[0] == L'+') {
- Tz = (INT16)ShellStrToUintn (++TempLocation);
- } else {
- Tz = (INT16)ShellStrToUintn (TempLocation);
- }
-
- //
- // Detect the return of ShellStrToUintn() to make sure the argument is valid.
- //
- if (Tz == -1) {
- Tz = 1441; // make it to be out of bounds value
- }
- }
-
- if (!((Tz >= -1440) && (Tz <= 1440)) && (Tz != EFI_UNSPECIFIED_TIMEZONE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-tz");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- } else {
- //
- // intentionally out of bounds value will prevent changing it...
- //
- Tz = 1441;
- }
-
- TempLocation = ShellCommandLineGetValue (Package, L"-d");
- if (TempLocation != NULL) {
- Daylight = (UINT8)ShellStrToUintn (TempLocation);
- //
- // The argument of "time [-d dl]" is unsigned, if the first character is '-',
- // the argument is incorrect. That's because ShellStrToUintn() will skip past
- // any '-' sign and convert what's next, forgetting the sign is here.
- //
- if (TempLocation[0] == '-') {
- Daylight = 0xff; // make it invalid = will not use
- }
-
- if ((Daylight != 0) && (Daylight != 1) && (Daylight != 3)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-d");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- } else {
- //
- // invalid = will not use
- //
- Daylight = 0xFF;
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = CheckAndSetTime (ShellCommandLineGetRawValue (Package, 1), Tz, Daylight);
- if (ShellStatus != SHELL_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"time", ShellCommandLineGetRawValue (Package, 1));
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- //
- // return the status
- //
- return (ShellStatus);
-}
-
-typedef struct {
- INT16 TimeZone;
- EFI_STRING_ID StringId;
-} TIME_ZONE_ITEM;
-
-STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList2[] = {
- { L"-l", TypeFlag },
- { L"-f", TypeFlag },
- { NULL, TypeMax }
-};
-STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = {
- { L"-l", TypeFlag },
- { L"-f", TypeFlag },
- { L"-s", TypeTimeValue },
- { NULL, TypeMax }
-};
-
-STATIC CONST TIME_ZONE_ITEM TimeZoneList[] = {
- { 720, STRING_TOKEN (STR_TIMEZONE_M12) },
- { 660, STRING_TOKEN (STR_TIMEZONE_M11) },
- { 600, STRING_TOKEN (STR_TIMEZONE_M10) },
- { 540, STRING_TOKEN (STR_TIMEZONE_M9) },
- { 480, STRING_TOKEN (STR_TIMEZONE_M8) },
- { 420, STRING_TOKEN (STR_TIMEZONE_M7) },
- { 360, STRING_TOKEN (STR_TIMEZONE_M6) },
- { 300, STRING_TOKEN (STR_TIMEZONE_M5) },
- { 270, STRING_TOKEN (STR_TIMEZONE_M430) },
- { 240, STRING_TOKEN (STR_TIMEZONE_M4) },
- { 210, STRING_TOKEN (STR_TIMEZONE_M330) },
- { 180, STRING_TOKEN (STR_TIMEZONE_M3) },
- { 120, STRING_TOKEN (STR_TIMEZONE_M2) },
- { 60, STRING_TOKEN (STR_TIMEZONE_M1) },
- { 0, STRING_TOKEN (STR_TIMEZONE_0) },
- { -60, STRING_TOKEN (STR_TIMEZONE_P1) },
- { -120, STRING_TOKEN (STR_TIMEZONE_P2) },
- { -180, STRING_TOKEN (STR_TIMEZONE_P3) },
- { -210, STRING_TOKEN (STR_TIMEZONE_P330) },
- { -240, STRING_TOKEN (STR_TIMEZONE_P4) },
- { -270, STRING_TOKEN (STR_TIMEZONE_P430) },
- { -300, STRING_TOKEN (STR_TIMEZONE_P5) },
- { -330, STRING_TOKEN (STR_TIMEZONE_P530) },
- { -345, STRING_TOKEN (STR_TIMEZONE_P545) },
- { -360, STRING_TOKEN (STR_TIMEZONE_P6) },
- { -390, STRING_TOKEN (STR_TIMEZONE_P630) },
- { -420, STRING_TOKEN (STR_TIMEZONE_P7) },
- { -480, STRING_TOKEN (STR_TIMEZONE_P8) },
- { -540, STRING_TOKEN (STR_TIMEZONE_P9) },
- { -570, STRING_TOKEN (STR_TIMEZONE_P930) },
- { -600, STRING_TOKEN (STR_TIMEZONE_P10) },
- { -660, STRING_TOKEN (STR_TIMEZONE_P11) },
- { -720, STRING_TOKEN (STR_TIMEZONE_P12) },
- { -780, STRING_TOKEN (STR_TIMEZONE_P13) },
- { -840, STRING_TOKEN (STR_TIMEZONE_P14) },
- { EFI_UNSPECIFIED_TIMEZONE, STRING_TOKEN (STR_TIMEZONE_LOCAL) }
-};
-
-/**
- Verify that the TimeZoneString is valid and if so set that as the current
- timezone.
-
- @param[in] TimeZoneString The pointer to a string representation of the timezone.
-
- @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL.
- @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted.
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-CheckAndSetTimeZone (
- IN CONST CHAR16 *TimeZoneString
- )
-{
- EFI_TIME TheTime;
- EFI_STATUS Status;
- CHAR16 *TimeZoneCopy;
- CHAR16 *Walker;
- CHAR16 *Walker2;
- UINTN LoopVar;
-
- if (TimeZoneString == NULL) {
- return (SHELL_INVALID_PARAMETER);
- }
-
- if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TimeZoneString, L"_local") == 0) {
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
- Status = gRT->SetTime (&TheTime);
- if (!EFI_ERROR (Status)) {
- return (SHELL_SUCCESS);
- }
-
- return (SHELL_INVALID_PARAMETER);
- }
-
- if ((TimeZoneString != NULL) && !InternalIsTimeLikeString (TimeZoneString, L':', 1, 1, TRUE)) {
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- TimeZoneCopy = NULL;
- TimeZoneCopy = StrnCatGrow (&TimeZoneCopy, NULL, TimeZoneString, 0);
- if (TimeZoneCopy == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- Walker = TimeZoneCopy;
- Walker2 = StrStr (Walker, L":");
- if ((Walker2 != NULL) && (*Walker2 == L':')) {
- *Walker2 = CHAR_NULL;
- }
-
- if (*Walker == L'-') {
- TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);
- } else {
- TheTime.TimeZone = (INT16)((INT16)(ShellStrToUintn (Walker)) * -60);
- }
-
- if (Walker2 != NULL) {
- Walker = Walker2 + 1;
- }
-
- if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) {
- if (TheTime.TimeZone < 0) {
- TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));
- } else {
- TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));
- }
- }
-
- Status = EFI_INVALID_PARAMETER;
-
- for ( LoopVar = 0
- ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0])
- ; LoopVar++
- )
- {
- if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
- Status = gRT->SetTime (&TheTime);
- break;
- }
- }
-
- FreePool (TimeZoneCopy);
-
- if (!EFI_ERROR (Status)) {
- return (SHELL_SUCCESS);
- }
-
- return (SHELL_INVALID_PARAMETER);
-}
-
-/**
- Function for 'timezone' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunTimeZone (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- //
- // non interactive
- //
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINT8 LoopVar;
- EFI_TIME TheTime;
- BOOLEAN Found;
- UINTN TzMinutes;
-
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- if (PcdGet8 (PcdShellSupportLevel) == 2) {
- Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, TRUE);
- } else {
- ASSERT (PcdGet8 (PcdShellSupportLevel) == 3);
- Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, TRUE, TRUE);
- }
-
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"timezone", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetCount (Package) > 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"timezone");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- } else if (ShellCommandLineGetFlag (Package, L"-s")) {
- if ((ShellCommandLineGetFlag (Package, L"-l")) || (ShellCommandLineGetFlag (Package, L"-f"))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", L"-l or -f");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (PcdGet8 (PcdShellSupportLevel) == 3);
- if (ShellCommandLineGetValue (Package, L"-s") == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"timezone", L"-s");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // Set the time zone
- //
- ShellStatus = CheckAndSetTimeZone (ShellCommandLineGetValue (Package, L"-s"));
- if (ShellStatus != SHELL_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", ShellCommandLineGetValue (Package, L"-s"));
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- }
- } else if (ShellCommandLineGetFlag (Package, L"-l")) {
- //
- // Print a list of all time zones
- //
- for ( LoopVar = 0
- ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0])
- ; LoopVar++
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
- }
- } else {
- //
- // Get Current Time Zone Info
- //
- Status = gRT->GetTime (&TheTime, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status);
- return (SHELL_DEVICE_ERROR);
- }
-
- if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
- Found = FALSE;
- for ( LoopVar = 0
- ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0])
- ; LoopVar++
- )
- {
- if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
- if (ShellCommandLineGetFlag (Package, L"-f")) {
- //
- // Print all info about current time zone
- //
- ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
- } else {
- //
- // Print basic info only
- //
- TzMinutes = (ABS (TheTime.TimeZone)) % 60;
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIMEZONE_SIMPLE),
- gShellLevel2HiiHandle,
- (TheTime.TimeZone > 0 ? L"-" : L"+"),
- (ABS (TheTime.TimeZone)) / 60,
- TzMinutes
- );
- }
-
- Found = TRUE;
- break;
- }
- }
-
- if (!Found) {
- //
- // Print basic info only
- //
- TzMinutes = (ABS (TheTime.TimeZone)) % 60;
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TIMEZONE_SIMPLE),
- gShellLevel2HiiHandle,
- (TheTime.TimeZone > 0 ? L"-" : L"+"),
- (ABS (TheTime.TimeZone)) / 60,
- TzMinutes
- );
-
- if (ShellCommandLineGetFlag (Package, L"-f")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_NI), gShellLevel2HiiHandle);
- }
- }
- } else {
- //
- // TimeZone was EFI_UNSPECIFIED_TIMEZONE (local) from GetTime()
- //
- if (ShellCommandLineGetFlag (Package, L"-f")) {
- for ( LoopVar = 0
- ; LoopVar < ARRAY_SIZE (TimeZoneList)
- ; LoopVar++
- )
- {
- if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
- //
- // Print all info about current time zone
- //
- ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
- break;
- }
- }
- } else {
- //
- // Print basic info only
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_SIMPLE_LOCAL), gShellLevel2HiiHandle);
- }
- }
- }
- }
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for time, timezone, and date shell level 2 and shell level 3 functions. + + (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" + +/** + Determine if String is a valid representation for a time or date. + + @param[in] String The pointer to the string to test. + @param[in] Char The delimeter character. + @param[in] Min The minimum value allowed. + @param[in] Max The maximum value allowed. + @param[in] MinusOk Whether negative numbers are permitted. + + @retval TRUE String is a valid representation. + @retval FALSE String is invalid. +**/ +BOOLEAN +InternalIsTimeLikeString ( + IN CONST CHAR16 *String, + IN CONST CHAR16 Char, + IN CONST UINTN Min, + IN CONST UINTN Max, + IN CONST BOOLEAN MinusOk + ) +{ + UINTN Count; + + Count = 0; + + if (MinusOk) { + // + // A single minus is ok. + // + if (*String == L'-') { + String++; + } + } + + // + // the first char must be numeric. + // + if (!ShellIsDecimalDigitCharacter (*String)) { + return (FALSE); + } + + // + // loop through the characters and use the lib function + // + for ( ; String != NULL && *String != CHAR_NULL; String++) { + if (*String == Char) { + Count++; + if (Count > Max) { + return (FALSE); + } + + continue; + } + + if (!ShellIsDecimalDigitCharacter (*String)) { + return (FALSE); + } + } + + if (Count < Min) { + return (FALSE); + } + + return (TRUE); +} + +/** + Verify that the DateString is valid and if so set that as the current + date. + + @param[in] DateString The pointer to a string representation of the date. + + @retval SHELL_INVALID_PARAMETER DateString was NULL. + @retval SHELL_INVALID_PARAMETER DateString was mis-formatted. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +CheckAndSetDate ( + IN CONST CHAR16 *DateString + ) +{ + EFI_TIME TheTime; + EFI_STATUS Status; + CHAR16 *DateStringCopy; + CHAR16 *Walker; + CHAR16 *Walker1; + + if (!InternalIsTimeLikeString (DateString, L'/', 2, 2, FALSE)) { + return (SHELL_INVALID_PARAMETER); + } + + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + DateStringCopy = NULL; + DateStringCopy = StrnCatGrow (&DateStringCopy, NULL, DateString, 0); + if (DateStringCopy == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + Walker = DateStringCopy; + + TheTime.Month = 0xFF; + TheTime.Day = 0xFF; + TheTime.Year = 0xFFFF; + + Walker1 = StrStr (Walker, L"/"); + if ((Walker1 != NULL) && (*Walker1 == L'/')) { + *Walker1 = CHAR_NULL; + } + + TheTime.Month = (UINT8)ShellStrToUintn (Walker); + if (Walker1 != NULL) { + Walker = Walker1 + 1; + } + + Walker1 = Walker != NULL ? StrStr (Walker, L"/") : NULL; + if ((Walker1 != NULL) && (*Walker1 == L'/')) { + *Walker1 = CHAR_NULL; + } + + if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) { + TheTime.Day = (UINT8)ShellStrToUintn (Walker); + if (Walker1 != NULL) { + Walker = Walker1 + 1; + } + + Walker1 = Walker != NULL ? StrStr (Walker, L"/") : NULL; + if ((Walker1 != NULL) && (*Walker1 == L'/')) { + *Walker1 = CHAR_NULL; + } + + if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) { + TheTime.Year = (UINT16)ShellStrToUintn (Walker); + } + } + + if (TheTime.Year < 100) { + if (TheTime.Year >= 98) { + TheTime.Year = (UINT16)(1900 + TheTime.Year); + } else { + TheTime.Year = (UINT16)(2000 + TheTime.Year); + } + } + + Status = gRT->SetTime (&TheTime); + + if (!EFI_ERROR (Status)) { + return (SHELL_SUCCESS); + } + + return (SHELL_INVALID_PARAMETER); +} + +/** + Function for 'date' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDate ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + EFI_TIME TheTime; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Param1; + + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"date", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // If there are 0 value parameters, then print the current date + // else If there are any value paramerers, then print error + // + if (ShellCommandLineGetRawValue (Package, 1) == NULL) { + // + // get the current date + // + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"date", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + // + // ShellPrintEx the date in SFO or regular format + // + if (ShellCommandLineGetFlag (Package, L"-sfo")) { + // + // Match UEFI Shell spec: + // ShellCommand,"date" + // Date,"DD","MM","YYYY" + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"date"); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Day, TheTime.Month, TheTime.Year); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year); + } + } else { + if (PcdGet8 (PcdShellSupportLevel) == 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"date"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // perform level 3 operation here. + // + Param1 = ShellCommandLineGetRawValue (Package, 1); + if (Param1 == NULL) { + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ShellStatus = CheckAndSetDate (Param1); + } + + if (ShellStatus != SHELL_SUCCESS) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"date", Param1); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + // + // return the status + // + return (ShellStatus); +} + +// +// Note "-tz" is invalid for this (non-interactive) version of 'time'. +// +STATIC CONST SHELL_PARAM_ITEM TimeParamList2[] = { + { L"-d", TypeValue }, + { NULL, TypeMax } +}; + +STATIC CONST SHELL_PARAM_ITEM TimeParamList3[] = { + { L"-d", TypeValue }, + { L"-tz", TypeValue }, + { NULL, TypeMax } +}; + +/** + Verify that the TimeString is valid and if so set that as the current + time. + + @param[in] TimeString The pointer to a string representation of the time. + @param[in] Tz The value to set for TimeZone. + @param[in] Daylight The value to set for Daylight. + + @retval SHELL_INVALID_PARAMETER TimeString was NULL. + @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +CheckAndSetTime ( + IN CONST CHAR16 *TimeString, + IN CONST INT16 Tz, + IN CONST UINT8 Daylight + ) +{ + EFI_TIME TheTime; + EFI_STATUS Status; + CHAR16 *TimeStringCopy; + CHAR16 *Walker1; + CHAR16 *Walker2; + + if ((TimeString != NULL) && !InternalIsTimeLikeString (TimeString, L':', 1, 2, FALSE)) { + return (SHELL_INVALID_PARAMETER); + } + + if ((Daylight != 0xFF) && ((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) { + return (SHELL_INVALID_PARAMETER); + } + + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + if (TimeString != NULL) { + TimeStringCopy = NULL; + TimeStringCopy = StrnCatGrow (&TimeStringCopy, NULL, TimeString, 0); + Walker1 = TimeStringCopy; + TheTime.Hour = 0xFF; + TheTime.Minute = 0xFF; + + Walker2 = Walker1 != NULL ? StrStr (Walker1, L":") : NULL; + if ((Walker2 != NULL) && (*Walker2 == L':')) { + *Walker2 = CHAR_NULL; + } + + TheTime.Hour = (UINT8)ShellStrToUintn (Walker1); + if (Walker2 != NULL) { + Walker1 = Walker2 + 1; + } + + Walker2 = Walker1 != NULL ? StrStr (Walker1, L":") : NULL; + if ((Walker2 != NULL) && (*Walker2 == L':')) { + *Walker2 = CHAR_NULL; + TheTime.Second = (UINT8)0; + } else if (Walker2 == NULL) { + TheTime.Second = (UINT8)0; + } + + if ((Walker1 != NULL) && (Walker1[0] != CHAR_NULL)) { + TheTime.Minute = (UINT8)ShellStrToUintn (Walker1); + if (Walker2 != NULL) { + Walker1 = Walker2 + 1; + if ((Walker1 != NULL) && (Walker1[0] != CHAR_NULL)) { + TheTime.Second = (UINT8)ShellStrToUintn (Walker1); + } + } + } + + SHELL_FREE_NON_NULL (TimeStringCopy); + } + + if ((Tz >= -1440) && (Tz <= 1440)) { + // + // EFI_TIME TimeZone is stored to meet the following calculation (see UEFI Spec): + // Localtime = UTC - TimeZone + // This means the sign must be changed for the user provided Tz. + // EX: User wants to set TimeZone to Pacific Standard Time, so runs + // time -tz -480 # set to UTC-08:00 + // To meet the calculation, the sign must be changed. + // + TheTime.TimeZone = -Tz; + } else if (Tz == EFI_UNSPECIFIED_TIMEZONE) { + TheTime.TimeZone = Tz; + } + + if (Daylight != 0xFF) { + TheTime.Daylight = Daylight; + } + + Status = gRT->SetTime (&TheTime); + + if (!EFI_ERROR (Status)) { + return (SHELL_SUCCESS); + } + + return (SHELL_INVALID_PARAMETER); +} + +/** + Function for 'time' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunTime ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + EFI_TIME TheTime; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + INT16 Tz; + UINT8 Daylight; + CONST CHAR16 *TempLocation; + UINTN TzMinutes; + + // + // Initialize variables + // + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + if (PcdGet8 (PcdShellSupportLevel) == 2) { + Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE); + } else { + ASSERT (PcdGet8 (PcdShellSupportLevel) == 3); + Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE); + } + + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"time", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // If there are no parameters, then print the current time + // + if ( (ShellCommandLineGetRawValue (Package, 1) == NULL) + && !ShellCommandLineGetFlag (Package, L"-d") + && !ShellCommandLineGetFlag (Package, L"-tz")) + { + // + // ShellPrintEx the current time + // + if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { + TzMinutes = 0; + } else { + TzMinutes = (ABS (TheTime.TimeZone)) % 60; + } + + if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second, + (TheTime.TimeZone > 0 ? L"-" : L"+"), + ((ABS (TheTime.TimeZone)) / 60), + TzMinutes + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT_LOCAL), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second + ); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle); + } else if (ShellCommandLineGetFlag (Package, L"-d") && (ShellCommandLineGetValue (Package, L"-d") == NULL)) { + if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT_LOCAL), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second + ); + } else { + TzMinutes = (ABS (TheTime.TimeZone)) % 60; + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIME_FORMAT), + gShellLevel2HiiHandle, + TheTime.Hour, + TheTime.Minute, + TheTime.Second, + (TheTime.TimeZone > 0 ? L"-" : L"+"), + ((ABS (TheTime.TimeZone)) / 60), + TzMinutes + ); + } + + switch (TheTime.Daylight) { + case 0: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle); + break; + case EFI_TIME_ADJUST_DAYLIGHT: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle); + break; + case EFI_TIME_IN_DAYLIGHT: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle); + break; + case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle); + break; + default: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight); + } + } else { + if (PcdGet8 (PcdShellSupportLevel) == 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // perform level 3 operation here. + // + if ((TempLocation = ShellCommandLineGetValue (Package, L"-tz")) != NULL) { + if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempLocation, L"_local") == 0) { + Tz = EFI_UNSPECIFIED_TIMEZONE; + } else if (TempLocation[0] == L'-') { + Tz = (INT16)ShellStrToUintn (++TempLocation); + // + // When the argument of "time [-tz tz]" is not numeric, ShellStrToUintn() returns "-1". + // Here we can detect the argument error by checking the return of ShellStrToUintn(). + // + if (Tz == -1) { + Tz = 1441; // make it to be out of bounds value + } else { + Tz *= (-1); // sign convert + } + } else { + if (TempLocation[0] == L'+') { + Tz = (INT16)ShellStrToUintn (++TempLocation); + } else { + Tz = (INT16)ShellStrToUintn (TempLocation); + } + + // + // Detect the return of ShellStrToUintn() to make sure the argument is valid. + // + if (Tz == -1) { + Tz = 1441; // make it to be out of bounds value + } + } + + if (!((Tz >= -1440) && (Tz <= 1440)) && (Tz != EFI_UNSPECIFIED_TIMEZONE)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-tz"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } else { + // + // intentionally out of bounds value will prevent changing it... + // + Tz = 1441; + } + + TempLocation = ShellCommandLineGetValue (Package, L"-d"); + if (TempLocation != NULL) { + Daylight = (UINT8)ShellStrToUintn (TempLocation); + // + // The argument of "time [-d dl]" is unsigned, if the first character is '-', + // the argument is incorrect. That's because ShellStrToUintn() will skip past + // any '-' sign and convert what's next, forgetting the sign is here. + // + if (TempLocation[0] == '-') { + Daylight = 0xff; // make it invalid = will not use + } + + if ((Daylight != 0) && (Daylight != 1) && (Daylight != 3)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-d"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } else { + // + // invalid = will not use + // + Daylight = 0xFF; + } + + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = CheckAndSetTime (ShellCommandLineGetRawValue (Package, 1), Tz, Daylight); + if (ShellStatus != SHELL_SUCCESS) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"time", ShellCommandLineGetRawValue (Package, 1)); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + // + // return the status + // + return (ShellStatus); +} + +typedef struct { + INT16 TimeZone; + EFI_STRING_ID StringId; +} TIME_ZONE_ITEM; + +STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList2[] = { + { L"-l", TypeFlag }, + { L"-f", TypeFlag }, + { NULL, TypeMax } +}; +STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = { + { L"-l", TypeFlag }, + { L"-f", TypeFlag }, + { L"-s", TypeTimeValue }, + { NULL, TypeMax } +}; + +STATIC CONST TIME_ZONE_ITEM TimeZoneList[] = { + { 720, STRING_TOKEN (STR_TIMEZONE_M12) }, + { 660, STRING_TOKEN (STR_TIMEZONE_M11) }, + { 600, STRING_TOKEN (STR_TIMEZONE_M10) }, + { 540, STRING_TOKEN (STR_TIMEZONE_M9) }, + { 480, STRING_TOKEN (STR_TIMEZONE_M8) }, + { 420, STRING_TOKEN (STR_TIMEZONE_M7) }, + { 360, STRING_TOKEN (STR_TIMEZONE_M6) }, + { 300, STRING_TOKEN (STR_TIMEZONE_M5) }, + { 270, STRING_TOKEN (STR_TIMEZONE_M430) }, + { 240, STRING_TOKEN (STR_TIMEZONE_M4) }, + { 210, STRING_TOKEN (STR_TIMEZONE_M330) }, + { 180, STRING_TOKEN (STR_TIMEZONE_M3) }, + { 120, STRING_TOKEN (STR_TIMEZONE_M2) }, + { 60, STRING_TOKEN (STR_TIMEZONE_M1) }, + { 0, STRING_TOKEN (STR_TIMEZONE_0) }, + { -60, STRING_TOKEN (STR_TIMEZONE_P1) }, + { -120, STRING_TOKEN (STR_TIMEZONE_P2) }, + { -180, STRING_TOKEN (STR_TIMEZONE_P3) }, + { -210, STRING_TOKEN (STR_TIMEZONE_P330) }, + { -240, STRING_TOKEN (STR_TIMEZONE_P4) }, + { -270, STRING_TOKEN (STR_TIMEZONE_P430) }, + { -300, STRING_TOKEN (STR_TIMEZONE_P5) }, + { -330, STRING_TOKEN (STR_TIMEZONE_P530) }, + { -345, STRING_TOKEN (STR_TIMEZONE_P545) }, + { -360, STRING_TOKEN (STR_TIMEZONE_P6) }, + { -390, STRING_TOKEN (STR_TIMEZONE_P630) }, + { -420, STRING_TOKEN (STR_TIMEZONE_P7) }, + { -480, STRING_TOKEN (STR_TIMEZONE_P8) }, + { -540, STRING_TOKEN (STR_TIMEZONE_P9) }, + { -570, STRING_TOKEN (STR_TIMEZONE_P930) }, + { -600, STRING_TOKEN (STR_TIMEZONE_P10) }, + { -660, STRING_TOKEN (STR_TIMEZONE_P11) }, + { -720, STRING_TOKEN (STR_TIMEZONE_P12) }, + { -780, STRING_TOKEN (STR_TIMEZONE_P13) }, + { -840, STRING_TOKEN (STR_TIMEZONE_P14) }, + { EFI_UNSPECIFIED_TIMEZONE, STRING_TOKEN (STR_TIMEZONE_LOCAL) } +}; + +/** + Verify that the TimeZoneString is valid and if so set that as the current + timezone. + + @param[in] TimeZoneString The pointer to a string representation of the timezone. + + @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL. + @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +CheckAndSetTimeZone ( + IN CONST CHAR16 *TimeZoneString + ) +{ + EFI_TIME TheTime; + EFI_STATUS Status; + CHAR16 *TimeZoneCopy; + CHAR16 *Walker; + CHAR16 *Walker2; + UINTN LoopVar; + + if (TimeZoneString == NULL) { + return (SHELL_INVALID_PARAMETER); + } + + if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TimeZoneString, L"_local") == 0) { + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; + Status = gRT->SetTime (&TheTime); + if (!EFI_ERROR (Status)) { + return (SHELL_SUCCESS); + } + + return (SHELL_INVALID_PARAMETER); + } + + if ((TimeZoneString != NULL) && !InternalIsTimeLikeString (TimeZoneString, L':', 1, 1, TRUE)) { + return (SHELL_INVALID_PARAMETER); + } + + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + TimeZoneCopy = NULL; + TimeZoneCopy = StrnCatGrow (&TimeZoneCopy, NULL, TimeZoneString, 0); + if (TimeZoneCopy == NULL) { + return (SHELL_OUT_OF_RESOURCES); + } + + Walker = TimeZoneCopy; + Walker2 = StrStr (Walker, L":"); + if ((Walker2 != NULL) && (*Walker2 == L':')) { + *Walker2 = CHAR_NULL; + } + + if (*Walker == L'-') { + TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60); + } else { + TheTime.TimeZone = (INT16)((INT16)(ShellStrToUintn (Walker)) * -60); + } + + if (Walker2 != NULL) { + Walker = Walker2 + 1; + } + + if ((Walker != NULL) && (Walker[0] != CHAR_NULL)) { + if (TheTime.TimeZone < 0) { + TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker)); + } else { + TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker)); + } + } + + Status = EFI_INVALID_PARAMETER; + + for ( LoopVar = 0 + ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0]) + ; LoopVar++ + ) + { + if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { + Status = gRT->SetTime (&TheTime); + break; + } + } + + FreePool (TimeZoneCopy); + + if (!EFI_ERROR (Status)) { + return (SHELL_SUCCESS); + } + + return (SHELL_INVALID_PARAMETER); +} + +/** + Function for 'timezone' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunTimeZone ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // non interactive + // + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINT8 LoopVar; + EFI_TIME TheTime; + BOOLEAN Found; + UINTN TzMinutes; + + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + if (PcdGet8 (PcdShellSupportLevel) == 2) { + Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, TRUE); + } else { + ASSERT (PcdGet8 (PcdShellSupportLevel) == 3); + Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, TRUE, TRUE); + } + + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"timezone", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetCount (Package) > 1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"timezone"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } else if (ShellCommandLineGetFlag (Package, L"-s")) { + if ((ShellCommandLineGetFlag (Package, L"-l")) || (ShellCommandLineGetFlag (Package, L"-f"))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", L"-l or -f"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (PcdGet8 (PcdShellSupportLevel) == 3); + if (ShellCommandLineGetValue (Package, L"-s") == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"timezone", L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // Set the time zone + // + ShellStatus = CheckAndSetTimeZone (ShellCommandLineGetValue (Package, L"-s")); + if (ShellStatus != SHELL_SUCCESS) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"timezone", ShellCommandLineGetValue (Package, L"-s")); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } + } else if (ShellCommandLineGetFlag (Package, L"-l")) { + // + // Print a list of all time zones + // + for ( LoopVar = 0 + ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0]) + ; LoopVar++ + ) + { + ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle); + } + } else { + // + // Get Current Time Zone Info + // + Status = gRT->GetTime (&TheTime, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status); + return (SHELL_DEVICE_ERROR); + } + + if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + Found = FALSE; + for ( LoopVar = 0 + ; LoopVar < sizeof (TimeZoneList) / sizeof (TimeZoneList[0]) + ; LoopVar++ + ) + { + if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { + if (ShellCommandLineGetFlag (Package, L"-f")) { + // + // Print all info about current time zone + // + ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle); + } else { + // + // Print basic info only + // + TzMinutes = (ABS (TheTime.TimeZone)) % 60; + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIMEZONE_SIMPLE), + gShellLevel2HiiHandle, + (TheTime.TimeZone > 0 ? L"-" : L"+"), + (ABS (TheTime.TimeZone)) / 60, + TzMinutes + ); + } + + Found = TRUE; + break; + } + } + + if (!Found) { + // + // Print basic info only + // + TzMinutes = (ABS (TheTime.TimeZone)) % 60; + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TIMEZONE_SIMPLE), + gShellLevel2HiiHandle, + (TheTime.TimeZone > 0 ? L"-" : L"+"), + (ABS (TheTime.TimeZone)) / 60, + TzMinutes + ); + + if (ShellCommandLineGetFlag (Package, L"-f")) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_NI), gShellLevel2HiiHandle); + } + } + } else { + // + // TimeZone was EFI_UNSPECIFIED_TIMEZONE (local) from GetTime() + // + if (ShellCommandLineGetFlag (Package, L"-f")) { + for ( LoopVar = 0 + ; LoopVar < ARRAY_SIZE (TimeZoneList) + ; LoopVar++ + ) + { + if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { + // + // Print all info about current time zone + // + ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle); + break; + } + } + } else { + // + // Print basic info only + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TIMEZONE_SIMPLE_LOCAL), gShellLevel2HiiHandle); + } + } + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c index ae643996aa..5bfa809667 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c @@ -1,345 +1,345 @@ -/** @file
- Main file for NULL named library for level 2 shell command functions.
-
- these functions are:
- attrib,
- cd,
- cp,
- date*,
- time*,
- load,
- ls,
- map,
- mkdir,
- mv,
- parse,
- rm,
- reset,
- set,
- timezone*,
- vol
-
- * functions are non-interactive only
-
- Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "UefiShellLevel2CommandsLib.h"
-
-CONST CHAR16 mFileName[] = L"ShellCommands";
-EFI_HII_HANDLE gShellLevel2HiiHandle = NULL;
-
-/**
- Get the filename to get help text from if not using HII.
-
- @retval The filename.
-**/
-CONST CHAR16 *
-EFIAPI
-ShellCommandGetManFileNameLevel2 (
- VOID
- )
-{
- return (mFileName);
-}
-
-/**
- Constructor for the Shell Level 2 Commands library.
-
- Install the handlers for level 2 UEFI Shell 2.0 commands.
-
- @param ImageHandle the image handle of the process
- @param SystemTable the EFI System Table pointer
-
- @retval EFI_SUCCESS the shell command handlers were installed successfully
- @retval EFI_UNSUPPORTED the shell level required was not found.
-**/
-EFI_STATUS
-EFIAPI
-ShellLevel2CommandsLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- //
- // if shell level is less than 2 do nothing
- //
- if (PcdGet8 (PcdShellSupportLevel) < 2) {
- return (EFI_SUCCESS);
- }
-
- gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL);
- if (gShellLevel2HiiHandle == NULL) {
- return (EFI_DEVICE_ERROR);
- }
-
- //
- // install our shell command handlers that are always installed
- //
- ShellCommandRegisterCommandName (L"attrib", ShellCommandRunAttrib, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_ATTRIB));
- ShellCommandRegisterCommandName (L"cd", ShellCommandRunCd, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CD));
- ShellCommandRegisterCommandName (L"cp", ShellCommandRunCp, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CP));
- ShellCommandRegisterCommandName (L"load", ShellCommandRunLoad, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LOAD));
- ShellCommandRegisterCommandName (L"map", ShellCommandRunMap, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MAP));
- ShellCommandRegisterCommandName (L"mkdir", ShellCommandRunMkDir, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MKDIR));
- ShellCommandRegisterCommandName (L"mv", ShellCommandRunMv, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MV));
- ShellCommandRegisterCommandName (L"parse", ShellCommandRunParse, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_PARSE));
- ShellCommandRegisterCommandName (L"reset", ShellCommandRunReset, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RESET));
- ShellCommandRegisterCommandName (L"set", ShellCommandRunSet, ShellCommandGetManFileNameLevel2, 2, L"", FALSE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_SET));
- ShellCommandRegisterCommandName (L"ls", ShellCommandRunLs, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LS));
- ShellCommandRegisterCommandName (L"rm", ShellCommandRunRm, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RM));
- ShellCommandRegisterCommandName (L"vol", ShellCommandRunVol, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_VOL));
-
- //
- // support for permanent (built in) aliases
- //
- ShellCommandRegisterAlias (L"rm", L"del");
- ShellCommandRegisterAlias (L"ls", L"dir");
- ShellCommandRegisterAlias (L"cp", L"copy");
- ShellCommandRegisterAlias (L"mkdir", L"md");
- ShellCommandRegisterAlias (L"cd ..", L"cd..");
- ShellCommandRegisterAlias (L"cd \\", L"cd\\");
- ShellCommandRegisterAlias (L"mv", L"ren");
- ShellCommandRegisterAlias (L"mv", L"move");
- ShellCommandRegisterAlias (L"map", L"mount");
- //
- // These are installed in level 2 or 3...
- //
- if ((PcdGet8 (PcdShellSupportLevel) == 2) || (PcdGet8 (PcdShellSupportLevel) == 3)) {
- ShellCommandRegisterCommandName (L"date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE));
- ShellCommandRegisterCommandName (L"time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME));
- ShellCommandRegisterCommandName (L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE));
- } else {
- DEBUG_CODE_BEGIN ();
- //
- // we want to be able to test these so install them under a different name in debug mode...
- //
- ShellCommandRegisterCommandName (L"l2date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE));
- ShellCommandRegisterCommandName (L"l2time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME));
- ShellCommandRegisterCommandName (L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE));
- DEBUG_CODE_END ();
- }
-
- return (EFI_SUCCESS);
-}
-
-/**
- Destructor for the library. free any resources.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Always returned.
-**/
-EFI_STATUS
-EFIAPI
-ShellLevel2CommandsLibDestructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- if (gShellLevel2HiiHandle != NULL) {
- HiiRemovePackages (gShellLevel2HiiHandle);
- }
-
- return (EFI_SUCCESS);
-}
-
-/**
- returns a fully qualified directory (contains a map drive at the beginning)
- path from a unknown directory path.
-
- If Path is already fully qualified this will return a duplicate otherwise this
- will use get the current directory and use that to build the fully qualified
- version.
-
- if the return value is not NULL it must be caller freed.
-
- @param[in] Path The unknown Path Value
-
- @retval NULL A memory allocation failed
- @retval NULL A fully qualified path could not be discovered.
- @retval other An allocated pointer to a fully qualified path.
-**/
-CHAR16 *
-GetFullyQualifiedPath (
- IN CONST CHAR16 *Path
- )
-{
- CHAR16 *PathToReturn;
- UINTN Size;
- CONST CHAR16 *CurDir;
-
- PathToReturn = NULL;
- Size = 0;
-
- ASSERT ((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
- //
- // convert a local path to an absolute path
- //
- if (StrStr (Path, L":") == NULL) {
- CurDir = gEfiShellProtocol->GetCurDir (NULL);
- StrnCatGrow (&PathToReturn, &Size, CurDir, 0);
- StrnCatGrow (&PathToReturn, &Size, L"\\", 0);
- if (*Path == L'\\') {
- Path++;
- }
- }
-
- StrnCatGrow (&PathToReturn, &Size, Path, 0);
-
- PathCleanUpDirectories (PathToReturn);
-
- if (PathToReturn == NULL) {
- return NULL;
- }
-
- while (PathToReturn[StrLen (PathToReturn)-1] == L'*') {
- PathToReturn[StrLen (PathToReturn)-1] = CHAR_NULL;
- }
-
- return (PathToReturn);
-}
-
-/**
- Function to verify all intermediate directories in the path.
-
- @param[in] Path The pointer to the path to fix.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-VerifyIntermediateDirectories (
- IN CONST CHAR16 *Path
- )
-{
- EFI_STATUS Status;
- CHAR16 *PathCopy;
- CHAR16 *TempSpot;
- SHELL_FILE_HANDLE FileHandle;
-
- ASSERT (Path != NULL);
-
- Status = EFI_SUCCESS;
- PathCopy = NULL;
- PathCopy = StrnCatGrow (&PathCopy, NULL, Path, 0);
- FileHandle = NULL;
-
- if (PathCopy == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- for (TempSpot = &PathCopy[StrLen (PathCopy)-1]; *TempSpot != CHAR_NULL && *TempSpot != L'\\'; TempSpot = &PathCopy[StrLen (PathCopy)-1]) {
- *TempSpot = CHAR_NULL;
- }
-
- if (*TempSpot == L'\\') {
- *TempSpot = CHAR_NULL;
- }
-
- if ((PathCopy != NULL) && (*PathCopy != CHAR_NULL)) {
- Status = VerifyIntermediateDirectories (PathCopy);
-
- if (PathCopy[StrLen (PathCopy)-1] != L':') {
- if (!EFI_ERROR (Status)) {
- Status = ShellOpenFileByName (PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0);
- if (FileHandle != NULL) {
- ShellCloseFile (&FileHandle);
- }
- }
- }
- }
-
- SHELL_FREE_NON_NULL (PathCopy);
-
- return (Status);
-}
-
-/**
- String comparison without regard to case for a limited number of characters.
-
- @param[in] Source The first item to compare.
- @param[in] Target The second item to compare.
- @param[in] Count How many characters to compare.
-
- @retval 0 Source and Target are identical strings without regard to case.
- @retval !=0 Source is not identical to Target.
-
-**/
-INTN
-StrniCmp (
- IN CONST CHAR16 *Source,
- IN CONST CHAR16 *Target,
- IN CONST UINTN Count
- )
-{
- CHAR16 *SourceCopy;
- CHAR16 *TargetCopy;
- UINTN SourceLength;
- UINTN TargetLength;
- INTN Result;
-
- if (Count == 0) {
- return 0;
- }
-
- SourceLength = StrLen (Source);
- TargetLength = StrLen (Target);
- SourceLength = MIN (SourceLength, Count);
- TargetLength = MIN (TargetLength, Count);
- SourceCopy = AllocateCopyPool ((SourceLength + 1) * sizeof (CHAR16), Source);
- if (SourceCopy == NULL) {
- return -1;
- }
-
- TargetCopy = AllocateCopyPool ((TargetLength + 1) * sizeof (CHAR16), Target);
- if (TargetCopy == NULL) {
- FreePool (SourceCopy);
- return -1;
- }
-
- SourceCopy[SourceLength] = L'\0';
- TargetCopy[TargetLength] = L'\0';
- Result = gUnicodeCollation->StriColl (gUnicodeCollation, SourceCopy, TargetCopy);
- FreePool (SourceCopy);
- FreePool (TargetCopy);
- return Result;
-}
-
-/**
- Cleans off all the quotes in the string.
-
- @param[in] OriginalString pointer to the string to be cleaned.
- @param[out] CleanString The new string with all quotes removed.
- Memory allocated in the function and free
- by caller.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-ShellLevel2StripQuotes (
- IN CONST CHAR16 *OriginalString,
- OUT CHAR16 **CleanString
- )
-{
- CHAR16 *Walker;
-
- if ((OriginalString == NULL) || (CleanString == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString);
- if (*CleanString == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
- if (*Walker == L'\"') {
- CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
- }
- }
-
- return EFI_SUCCESS;
-}
+/** @file + Main file for NULL named library for level 2 shell command functions. + + these functions are: + attrib, + cd, + cp, + date*, + time*, + load, + ls, + map, + mkdir, + mv, + parse, + rm, + reset, + set, + timezone*, + vol + + * functions are non-interactive only + + Copyright (c) 2014 Hewlett-Packard Development Company, L.P. + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "UefiShellLevel2CommandsLib.h" + +CONST CHAR16 mFileName[] = L"ShellCommands"; +EFI_HII_HANDLE gShellLevel2HiiHandle = NULL; + +/** + Get the filename to get help text from if not using HII. + + @retval The filename. +**/ +CONST CHAR16 * +EFIAPI +ShellCommandGetManFileNameLevel2 ( + VOID + ) +{ + return (mFileName); +} + +/** + Constructor for the Shell Level 2 Commands library. + + Install the handlers for level 2 UEFI Shell 2.0 commands. + + @param ImageHandle the image handle of the process + @param SystemTable the EFI System Table pointer + + @retval EFI_SUCCESS the shell command handlers were installed successfully + @retval EFI_UNSUPPORTED the shell level required was not found. +**/ +EFI_STATUS +EFIAPI +ShellLevel2CommandsLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // if shell level is less than 2 do nothing + // + if (PcdGet8 (PcdShellSupportLevel) < 2) { + return (EFI_SUCCESS); + } + + gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL); + if (gShellLevel2HiiHandle == NULL) { + return (EFI_DEVICE_ERROR); + } + + // + // install our shell command handlers that are always installed + // + ShellCommandRegisterCommandName (L"attrib", ShellCommandRunAttrib, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_ATTRIB)); + ShellCommandRegisterCommandName (L"cd", ShellCommandRunCd, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CD)); + ShellCommandRegisterCommandName (L"cp", ShellCommandRunCp, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CP)); + ShellCommandRegisterCommandName (L"load", ShellCommandRunLoad, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LOAD)); + ShellCommandRegisterCommandName (L"map", ShellCommandRunMap, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MAP)); + ShellCommandRegisterCommandName (L"mkdir", ShellCommandRunMkDir, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MKDIR)); + ShellCommandRegisterCommandName (L"mv", ShellCommandRunMv, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MV)); + ShellCommandRegisterCommandName (L"parse", ShellCommandRunParse, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_PARSE)); + ShellCommandRegisterCommandName (L"reset", ShellCommandRunReset, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RESET)); + ShellCommandRegisterCommandName (L"set", ShellCommandRunSet, ShellCommandGetManFileNameLevel2, 2, L"", FALSE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_SET)); + ShellCommandRegisterCommandName (L"ls", ShellCommandRunLs, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LS)); + ShellCommandRegisterCommandName (L"rm", ShellCommandRunRm, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RM)); + ShellCommandRegisterCommandName (L"vol", ShellCommandRunVol, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_VOL)); + + // + // support for permanent (built in) aliases + // + ShellCommandRegisterAlias (L"rm", L"del"); + ShellCommandRegisterAlias (L"ls", L"dir"); + ShellCommandRegisterAlias (L"cp", L"copy"); + ShellCommandRegisterAlias (L"mkdir", L"md"); + ShellCommandRegisterAlias (L"cd ..", L"cd.."); + ShellCommandRegisterAlias (L"cd \\", L"cd\\"); + ShellCommandRegisterAlias (L"mv", L"ren"); + ShellCommandRegisterAlias (L"mv", L"move"); + ShellCommandRegisterAlias (L"map", L"mount"); + // + // These are installed in level 2 or 3... + // + if ((PcdGet8 (PcdShellSupportLevel) == 2) || (PcdGet8 (PcdShellSupportLevel) == 3)) { + ShellCommandRegisterCommandName (L"date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE)); + ShellCommandRegisterCommandName (L"time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME)); + ShellCommandRegisterCommandName (L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE)); + } else { + DEBUG_CODE_BEGIN (); + // + // we want to be able to test these so install them under a different name in debug mode... + // + ShellCommandRegisterCommandName (L"l2date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE)); + ShellCommandRegisterCommandName (L"l2time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME)); + ShellCommandRegisterCommandName (L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE)); + DEBUG_CODE_END (); + } + + return (EFI_SUCCESS); +} + +/** + Destructor for the library. free any resources. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Always returned. +**/ +EFI_STATUS +EFIAPI +ShellLevel2CommandsLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (gShellLevel2HiiHandle != NULL) { + HiiRemovePackages (gShellLevel2HiiHandle); + } + + return (EFI_SUCCESS); +} + +/** + returns a fully qualified directory (contains a map drive at the beginning) + path from a unknown directory path. + + If Path is already fully qualified this will return a duplicate otherwise this + will use get the current directory and use that to build the fully qualified + version. + + if the return value is not NULL it must be caller freed. + + @param[in] Path The unknown Path Value + + @retval NULL A memory allocation failed + @retval NULL A fully qualified path could not be discovered. + @retval other An allocated pointer to a fully qualified path. +**/ +CHAR16 * +GetFullyQualifiedPath ( + IN CONST CHAR16 *Path + ) +{ + CHAR16 *PathToReturn; + UINTN Size; + CONST CHAR16 *CurDir; + + PathToReturn = NULL; + Size = 0; + + ASSERT ((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL)); + // + // convert a local path to an absolute path + // + if (StrStr (Path, L":") == NULL) { + CurDir = gEfiShellProtocol->GetCurDir (NULL); + StrnCatGrow (&PathToReturn, &Size, CurDir, 0); + StrnCatGrow (&PathToReturn, &Size, L"\\", 0); + if (*Path == L'\\') { + Path++; + } + } + + StrnCatGrow (&PathToReturn, &Size, Path, 0); + + PathCleanUpDirectories (PathToReturn); + + if (PathToReturn == NULL) { + return NULL; + } + + while (PathToReturn[StrLen (PathToReturn)-1] == L'*') { + PathToReturn[StrLen (PathToReturn)-1] = CHAR_NULL; + } + + return (PathToReturn); +} + +/** + Function to verify all intermediate directories in the path. + + @param[in] Path The pointer to the path to fix. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +VerifyIntermediateDirectories ( + IN CONST CHAR16 *Path + ) +{ + EFI_STATUS Status; + CHAR16 *PathCopy; + CHAR16 *TempSpot; + SHELL_FILE_HANDLE FileHandle; + + ASSERT (Path != NULL); + + Status = EFI_SUCCESS; + PathCopy = NULL; + PathCopy = StrnCatGrow (&PathCopy, NULL, Path, 0); + FileHandle = NULL; + + if (PathCopy == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + for (TempSpot = &PathCopy[StrLen (PathCopy)-1]; *TempSpot != CHAR_NULL && *TempSpot != L'\\'; TempSpot = &PathCopy[StrLen (PathCopy)-1]) { + *TempSpot = CHAR_NULL; + } + + if (*TempSpot == L'\\') { + *TempSpot = CHAR_NULL; + } + + if ((PathCopy != NULL) && (*PathCopy != CHAR_NULL)) { + Status = VerifyIntermediateDirectories (PathCopy); + + if (PathCopy[StrLen (PathCopy)-1] != L':') { + if (!EFI_ERROR (Status)) { + Status = ShellOpenFileByName (PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0); + if (FileHandle != NULL) { + ShellCloseFile (&FileHandle); + } + } + } + } + + SHELL_FREE_NON_NULL (PathCopy); + + return (Status); +} + +/** + String comparison without regard to case for a limited number of characters. + + @param[in] Source The first item to compare. + @param[in] Target The second item to compare. + @param[in] Count How many characters to compare. + + @retval 0 Source and Target are identical strings without regard to case. + @retval !=0 Source is not identical to Target. + +**/ +INTN +StrniCmp ( + IN CONST CHAR16 *Source, + IN CONST CHAR16 *Target, + IN CONST UINTN Count + ) +{ + CHAR16 *SourceCopy; + CHAR16 *TargetCopy; + UINTN SourceLength; + UINTN TargetLength; + INTN Result; + + if (Count == 0) { + return 0; + } + + SourceLength = StrLen (Source); + TargetLength = StrLen (Target); + SourceLength = MIN (SourceLength, Count); + TargetLength = MIN (TargetLength, Count); + SourceCopy = AllocateCopyPool ((SourceLength + 1) * sizeof (CHAR16), Source); + if (SourceCopy == NULL) { + return -1; + } + + TargetCopy = AllocateCopyPool ((TargetLength + 1) * sizeof (CHAR16), Target); + if (TargetCopy == NULL) { + FreePool (SourceCopy); + return -1; + } + + SourceCopy[SourceLength] = L'\0'; + TargetCopy[TargetLength] = L'\0'; + Result = gUnicodeCollation->StriColl (gUnicodeCollation, SourceCopy, TargetCopy); + FreePool (SourceCopy); + FreePool (TargetCopy); + return Result; +} + +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ShellLevel2StripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ) +{ + CHAR16 *Walker; + + if ((OriginalString == NULL) || (CleanString == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString); + if (*CleanString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL; Walker++) { + if (*Walker == L'\"') { + CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0])); + } + } + + return EFI_SUCCESS; +} diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h index 814044d095..a917b24df0 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h @@ -1,362 +1,362 @@ -/** @file
- Main file for NULL named library for level 2 shell command functions.
-
- these functions are:
- attrib, cd, cp, date*, time*, rm, reset,
- load, ls, map, mkdir, mv, parse, set, timezone*
-
-
- * functions are non-interactive only
-
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _UEFI_SHELL_LEVEL2_COMMANDS_LIB_H_
-#define _UEFI_SHELL_LEVEL2_COMMANDS_LIB_H_
-
-#include <Uefi.h>
-
-#include <Guid/GlobalVariable.h>
-#include <Guid/ShellLibHiiGuid.h>
-
-#include <Protocol/Shell.h>
-#include <Protocol/ShellParameters.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/UnicodeCollation.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PcdLib.h>
-#include <Library/ShellCommandLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/HiiLib.h>
-#include <Library/SortLib.h>
-#include <Library/FileHandleLib.h>
-
-extern CONST CHAR16 mFileName[];
-extern EFI_HII_HANDLE gShellLevel2HiiHandle;
-
-/**
- Function for 'attrib' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunAttrib (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'date' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunDate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'time' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunTime (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'load' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunLoad (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'ls' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunLs (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'map' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMap (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'reset' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunReset (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'timezone' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunTimeZone (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'set' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunSet (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'mkdir' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMkDir (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'cd' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunCd (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'cp' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunCp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'parse' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunParse (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'rm' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunRm (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'mv' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunMv (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- returns a fully qualified directory (contains a map drive at the beginning)
- path from a unknown directory path.
-
- If Path is already fully qualified this will return a duplicate otherwise this
- will use get the current directory and use that to build the fully qualified
- version.
-
- if the return value is not NULL it must be caller freed.
-
- @param[in] Path The unknown Path Value
-
- @retval NULL A memory allocation failed
- @retval NULL a fully qualified path could not be discovered.
- @retval other pointer to a fully qualified path.
-**/
-CHAR16 *
-GetFullyQualifiedPath (
- IN CONST CHAR16 *Path
- );
-
-/**
- Function to verify all intermediate directories in the path.
-
- @param[in] Path The pointer to the path to fix.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-VerifyIntermediateDirectories (
- IN CONST CHAR16 *Path
- );
-
-/**
- String comparison without regard to case for a limited number of characters.
-
- @param[in] Source The first item to compare.
- @param[in] Target The second item to compare.
- @param[in] Count How many characters to compare.
-
- @retval 0 Source and Target are identical strings without regard to case.
- @retval !=0 Source is not identical to Target.
-
-**/
-INTN
-StrniCmp (
- IN CONST CHAR16 *Source,
- IN CONST CHAR16 *Target,
- IN CONST UINTN Count
- );
-
-/**
- Cleans off all the quotes in the string.
-
- @param[in] OriginalString pointer to the string to be cleaned.
- @param[out] CleanString The new string with all quotes removed.
- Memory allocated in the function and free
- by caller.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-ShellLevel2StripQuotes (
- IN CONST CHAR16 *OriginalString,
- OUT CHAR16 **CleanString
- );
-
-/**
- Function for 'Vol' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunVol (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function to Copy one file to another location
-
- If the destination exists the user will be prompted and the result put into *resp
-
- @param[in] Source pointer to source file name
- @param[in] Dest pointer to destination file name
- @param[out] Resp pointer to response from question. Pass back on looped calling
- @param[in] SilentMode whether to run in quiet mode or not
- @param[in] CmdName Source command name requesting single file copy
-
- @retval SHELL_SUCCESS The source file was copied to the destination
-**/
-SHELL_STATUS
-CopySingleFile (
- IN CONST CHAR16 *Source,
- IN CONST CHAR16 *Dest,
- OUT VOID **Resp,
- IN BOOLEAN SilentMode,
- IN CONST CHAR16 *CmdName
- );
-
-/**
- Delete a node and all nodes under it (including sub directories).
-
- @param[in] Node The node to start deleting with.
- @param[in] Quiet TRUE to print no messages.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_ACCESS_DENIED A file was read only.
- @retval SHELL_ABORTED The abort message was received.
- @retval SHELL_DEVICE_ERROR A device error occurred reading this Node.
-**/
-SHELL_STATUS
-CascadeDelete (
- IN EFI_SHELL_FILE_INFO *Node,
- IN CONST BOOLEAN Quiet
- );
-
-#endif
+/** @file + Main file for NULL named library for level 2 shell command functions. + + these functions are: + attrib, cd, cp, date*, time*, rm, reset, + load, ls, map, mkdir, mv, parse, set, timezone* + + + * functions are non-interactive only + + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _UEFI_SHELL_LEVEL2_COMMANDS_LIB_H_ +#define _UEFI_SHELL_LEVEL2_COMMANDS_LIB_H_ + +#include <Uefi.h> + +#include <Guid/GlobalVariable.h> +#include <Guid/ShellLibHiiGuid.h> + +#include <Protocol/Shell.h> +#include <Protocol/ShellParameters.h> +#include <Protocol/DevicePath.h> +#include <Protocol/LoadedImage.h> +#include <Protocol/UnicodeCollation.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/HiiLib.h> +#include <Library/SortLib.h> +#include <Library/FileHandleLib.h> + +extern CONST CHAR16 mFileName[]; +extern EFI_HII_HANDLE gShellLevel2HiiHandle; + +/** + Function for 'attrib' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunAttrib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'date' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDate ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'time' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunTime ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'load' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLoad ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'ls' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLs ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'map' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMap ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'reset' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunReset ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'timezone' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunTimeZone ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'set' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSet ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'mkdir' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMkDir ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'cd' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunCd ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'cp' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunCp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'parse' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunParse ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'rm' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunRm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'mv' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMv ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + returns a fully qualified directory (contains a map drive at the beginning) + path from a unknown directory path. + + If Path is already fully qualified this will return a duplicate otherwise this + will use get the current directory and use that to build the fully qualified + version. + + if the return value is not NULL it must be caller freed. + + @param[in] Path The unknown Path Value + + @retval NULL A memory allocation failed + @retval NULL a fully qualified path could not be discovered. + @retval other pointer to a fully qualified path. +**/ +CHAR16 * +GetFullyQualifiedPath ( + IN CONST CHAR16 *Path + ); + +/** + Function to verify all intermediate directories in the path. + + @param[in] Path The pointer to the path to fix. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +VerifyIntermediateDirectories ( + IN CONST CHAR16 *Path + ); + +/** + String comparison without regard to case for a limited number of characters. + + @param[in] Source The first item to compare. + @param[in] Target The second item to compare. + @param[in] Count How many characters to compare. + + @retval 0 Source and Target are identical strings without regard to case. + @retval !=0 Source is not identical to Target. + +**/ +INTN +StrniCmp ( + IN CONST CHAR16 *Source, + IN CONST CHAR16 *Target, + IN CONST UINTN Count + ); + +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ShellLevel2StripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ); + +/** + Function for 'Vol' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunVol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function to Copy one file to another location + + If the destination exists the user will be prompted and the result put into *resp + + @param[in] Source pointer to source file name + @param[in] Dest pointer to destination file name + @param[out] Resp pointer to response from question. Pass back on looped calling + @param[in] SilentMode whether to run in quiet mode or not + @param[in] CmdName Source command name requesting single file copy + + @retval SHELL_SUCCESS The source file was copied to the destination +**/ +SHELL_STATUS +CopySingleFile ( + IN CONST CHAR16 *Source, + IN CONST CHAR16 *Dest, + OUT VOID **Resp, + IN BOOLEAN SilentMode, + IN CONST CHAR16 *CmdName + ); + +/** + Delete a node and all nodes under it (including sub directories). + + @param[in] Node The node to start deleting with. + @param[in] Quiet TRUE to print no messages. + + @retval SHELL_SUCCESS The operation was successful. + @retval SHELL_ACCESS_DENIED A file was read only. + @retval SHELL_ABORTED The abort message was received. + @retval SHELL_DEVICE_ERROR A device error occurred reading this Node. +**/ +SHELL_STATUS +CascadeDelete ( + IN EFI_SHELL_FILE_INFO *Node, + IN CONST BOOLEAN Quiet + ); + +#endif diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf index 3b83742236..d481df56db 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf @@ -1,79 +1,79 @@ -## @file
-# Provides shell level 2 functions
-#
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = UefiShellLevel2CommandsLib
- FILE_GUID = CBF3931C-A2DF-40e5-B77E-CCA9555E9755
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
- CONSTRUCTOR = ShellLevel2CommandsLibConstructor
- DESTRUCTOR = ShellLevel2CommandsLibDestructor
-
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources.common]
- UefiShellLevel2CommandsLib.c
- UefiShellLevel2CommandsLib.h
- UefiShellLevel2CommandsLib.uni
- TimeDate.c
- Load.c
- Ls.c
- Map.c
- Reset.c
- Set.c
- MkDir.c
- Cd.c
- Cp.c
- Parse.c
- Rm.c
- Mv.c
- Attrib.c
- Vol.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellCommandLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- PcdLib
- HiiLib
- HandleParsingLib
- DevicePathLib
-
-[Protocols]
- gEfiUnicodeCollation2ProtocolGuid ## CONSUMES
- gEfiShellProtocolGuid ## CONSUMES
- gEfiShellParametersProtocolGuid ## CONSUMES
- gEfiDevicePathProtocolGuid ## CONSUMES
- gEfiLoadedImageProtocolGuid ## CONSUMES
- gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
-
-[Pcd.common]
- gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel ## CONSUMES
- gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize ## CONSUMES
-
-[Guids]
- gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## GUID
- gEfiFileInfoGuid ## UNDEFINED
- gShellLevel2HiiGuid ## SOMETIMES_CONSUMES ## HII
+## @file +# Provides shell level 2 functions +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = UefiShellLevel2CommandsLib + FILE_GUID = CBF3931C-A2DF-40e5-B77E-CCA9555E9755 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = ShellLevel2CommandsLibConstructor + DESTRUCTOR = ShellLevel2CommandsLibDestructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources.common] + UefiShellLevel2CommandsLib.c + UefiShellLevel2CommandsLib.h + UefiShellLevel2CommandsLib.uni + TimeDate.c + Load.c + Ls.c + Map.c + Reset.c + Set.c + MkDir.c + Cd.c + Cp.c + Parse.c + Rm.c + Mv.c + Attrib.c + Vol.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellCommandLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + PcdLib + HiiLib + HandleParsingLib + DevicePathLib + +[Protocols] + gEfiUnicodeCollation2ProtocolGuid ## CONSUMES + gEfiShellProtocolGuid ## CONSUMES + gEfiShellParametersProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## CONSUMES + gEfiLoadedImageProtocolGuid ## CONSUMES + gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd.common] + gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel ## CONSUMES + gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize ## CONSUMES + +[Guids] + gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## GUID + gEfiFileInfoGuid ## UNDEFINED + gShellLevel2HiiGuid ## SOMETIMES_CONSUMES ## HII diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni index 0a0cd3090e..18f691ac7b 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni @@ -1,1078 +1,1078 @@ -// /**
-//
-// (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
-// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Module Name:
-//
-// UefiShellLevel2CommandsLib.uni
-//
-// Abstract:
-//
-// String definitions for UEFI Shell 2.0 level 2 commands
-//
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-#string STR_GEN_NO_MEM #language en-US "%H%s%N: Memory is not available.\r\n"
-#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n"
-#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments.\r\n"
-#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n"
-#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
-#string STR_GEN_PROBLEM_VAL #language en-US "%H%s%N: Bad value - '%H%s%N' for flag - '%H%s%N'\r\n"
-#string STR_GEN_ATTRIBUTE #language en-US "%H%s%N: Invalid argument - '%H-a%s%N'\r\n"
-#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
-#string STR_GEN_ERR_AD #language en-US "%H%s%N: Access denied.\r\n"
-#string STR_GEN_ERR_FILE #language en-US "%H%s%N: File '%H%s%N' error - %r\r\n"
-#string STR_GEN_ERR_UK #language en-US "%H%s%N: Status: %r\r\n"
-#string STR_GEN_PARAM_CON #language en-US "%H%s%N: Parameters conflict.\r\n"
-#string STR_GEN_PARAM_CONFLICT #language en-US "%H%s%N: Flags conflict with - '%H%s%N' and '%H%s%N'\r\n"
-#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
-#string STR_GEN_FILE_CLOSE_FAIL #language en-US "%H%s%N: Cannot close file - '%H%s%N'\r\n"
-#string STR_GEN_FILE_AD #language en-US "%H%s%N: File access error - '%H%s%N'\r\n"
-#string STR_GEN_FILE_NF #language en-US "%H%s%N: File not found - '%H%s%N'\r\n"
-#string STR_GEN_CRLF #language en-US "\r\n"
-#string STR_GEN_NO_CWD #language en-US "%H%s%N: Current directory not specified.\r\n"
-#string STR_GEN_NO_FILES #language en-US "%H%s%N: No matching files were found.\r\n"
-#string STR_GEN_DIR_NF #language en-US "%H%s%N: Directory not found - '%H%s%N'\r\n"
-#string STR_GEN_RES_OK #language en-US "- [ok]\r\n"
-#string STR_GEN_NOT_DIR #language en-US "%H%s%N: '%H%s%N' is not a directory.\r\n"
-#string STR_GEN_NOT_FILE #language en-US "%H%s%N: '%H%s%N' is not a file.\r\n"
-#string STR_GEN_SFO_HEADER #language en-US "ShellCommand,"%s"\r\n"
-#string STR_GEN_MARG_ERROR #language en-US "%H%s%N: The destination '%H%s%N' is ambiguous.\r\n"
-#string STR_GEN_FILE_ERROR #language en-US "%H%s%N: The destination is an existing file '%H%s%N'.\r\n"
-#string STR_GEN_UEFI_FUNC_ERROR #language en-US "%H%s%N: UEFI function '%H%s%N' returned an incorrect value for: %s (%x).\r\n"
-#string STR_GEN_UEFI_FUNC_WARN #language en-US "%H%s%N: UEFI function '%H%s%N' returned: %r\r\n"
-#string STR_GEN_DEST_EXIST_OVR #language en-US "Destination file already exists. Overwrite? %BY%Nes, %BN%No, %BA%Nll, %BC%Nancel "
-#string STR_GEN_CPY_FAIL #language en-US "%H%s%N: Copy failure: insufficient capacity on destination media.\r\n"
-#string STR_GEN_CPY_READ_ERROR #language en-US "%H%s%N: reading '%B%s%N': IO Error \r\n"
-#string STR_GEN_CPY_WRITE_ERROR #language en-US "%H%s%N: writing '%B%s%N': IO Error \r\n"
-#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
-
-#string STR_SET_DISP #language en-US "%V%8s %N= %H%s%N\r\n"
-#string STR_SET_NF #language en-US "%H%s%N: Environment Variable '%H%s%N' not defined.\r\n"
-#string STR_SET_ND #language en-US "%H%s%N: Environment Variable '%H%s%N' could not be deleted.\r\n"
-#string STR_SET_ERROR_SET #language en-US "%H%s%N: Unable to set %H%s%N\r\n"
-
-#string STR_CD_PRINT #language en-US "%s\r\n"
-#string STR_CD_NF #language en-US "%H%s%N: No mapping found.\r\n"
-
-#string STR_MAP_NF #language en-US "%H%s%N: Cannot find mapped device - '%H%s%N'\r\n"
-#string STR_MAP_NOF #language en-US "%H%s%N: No mappable target found - '%H%s%N'\r\n"
-#string STR_MAP_SFO_MAPPINGS #language en-US "Mappings,"%s","%s","%s"\r\n"
-#string STR_MAP_HEADER #language en-US "%EMapping table%N\r\n"
-#string STR_MAP_ENTRY #language en-US "%E%10s%N %HAlias(s):%N%s\r\n %s\r\n"
-#string STR_MAP_ENTRY_VERBOSE #language en-US " Handle: [%H%02x%N]\r\n"
- " Media Type: %s\r\n"
- " Removable: %s\r\n"
- " Current Dir: %s\r\n"
-
-#string STR_ATTRIB_OUTPUT_LINE #language en-US "Attrib: %1c%1c%1c%1c%1c %s\r\n"
-
-#string STR_MAP_MEDIA_FLOPPY #language en-US "Floppy"
-#string STR_MAP_MEDIA_UNKNOWN #language en-US "Unknown"
-#string STR_MAP_MEDIA_HARDDISK #language en-US "HardDisk"
-#string STR_MAP_MEDIA_CDROM #language en-US "CD-Rom"
-
-#string STR_MKDIR_ALREADY #language en-US "Directory '%B%s%N' already exists.\r\n"
-#string STR_MKDIR_CREATEFAIL #language en-US "Directory '%B%s%N' unable to create.\r\n"
-
-#string STR_DATE_FORMAT #language en-US "%02d/%02d/%04d\r\n"
-#string STR_DATE_SFO_FORMAT #language en-US "Date,"%02d","%02d","%04d"\r\n"
-
-#string STR_TIME_FORMAT #language en-US "%02d:%02d:%02d (UTC%1s%02d:%02d)"
-#string STR_TIME_FORMAT_LOCAL #language en-US "%02d:%02d:%02d (LOCAL)"
-#string STR_TIME_DST0 #language en-US " DST: Not Affected\r\n"
-#string STR_TIME_DST1 #language en-US " DST: Affected\r\n"
-#string STR_TIME_DST2 #language en-US " DST: Adjusted\r\n"
-#string STR_TIME_DST3 #language en-US " DST: Affected and Adjusted\r\n"
-
-#string STR_TIMEZONE_M12 #language en-US "UTC-12:00, International Date Line West\r\n"
-#string STR_TIMEZONE_M11 #language en-US "UTC-11:00, Midway Island, Samoa\r\n"
-#string STR_TIMEZONE_M10 #language en-US "UTC-10:00, Hawaii\r\n"
-#string STR_TIMEZONE_M9 #language en-US "UTC-09:00, Alaska\r\n"
-#string STR_TIMEZONE_M8 #language en-US "UTC-08:00, Pacific Time(US & Canada), Tijuana, Portland\r\n"
-#string STR_TIMEZONE_M7 #language en-US "UTC-07:00, Arizona, Chihuahua, La Paz, Mazatlan, Mountain Time (US & Canada)\r\n"
-#string STR_TIMEZONE_M6 #language en-US "UTC-06:00, Central America, Central Time(US & Canada)\r\n"
-#string STR_TIMEZONE_M5 #language en-US "UTC-05:00, Bogota, Lima, Quito, Eastern Time(US & Canada)\r\n"
-#string STR_TIMEZONE_M430 #language en-US "UTC-04:30, Caracas\r\n"
-#string STR_TIMEZONE_M4 #language en-US "UTC-04:00, Atlantic Time(Canada), Caracas, Santiago, Georgetown\r\n"
-#string STR_TIMEZONE_M330 #language en-US "UTC-03:30, Newfoundland\r\n"
-#string STR_TIMEZONE_M3 #language en-US "UTC-03:00, Brasilia, Buenos Aires, Greenland\r\n"
-#string STR_TIMEZONE_M2 #language en-US "UTC-02:00, Mid-Atlantic\r\n"
-#string STR_TIMEZONE_M1 #language en-US "UTC-01:00, Azores, Cape Verde Is.\r\n"
-#string STR_TIMEZONE_0 #language en-US "UTC , Greenwich Mean Time, Casablanca, Monrovia, Dublin, London\r\n"
-#string STR_TIMEZONE_P1 #language en-US "UTC+01:00, Amsterdam, Berlin, Bern, Rome, Paris, West Central Africa\r\n"
-#string STR_TIMEZONE_P2 #language en-US "UTC+02:00, Athens, Bucharest, Cairo, Jerusalem\r\n"
-#string STR_TIMEZONE_P3 #language en-US "UTC+03:00, Baghdad, Kuwait, Riyadh, Moscow, Nairobi, Istanbul\r\n"
-#string STR_TIMEZONE_P330 #language en-US "UTC+03:30, Tehran\r\n"
-#string STR_TIMEZONE_P4 #language en-US "UTC+04:00, Abu Dhabi, Muscat, Baku, Tbilisi, Yerevan\r\n"
-#string STR_TIMEZONE_P430 #language en-US "UTC+04:30, Kabul\r\n"
-#string STR_TIMEZONE_P5 #language en-US "UTC+05:00, Ekaterinburg, Islamabad, Karachi, Tashkent\r\n"
-#string STR_TIMEZONE_P530 #language en-US "UTC+05:30, Chennai, Kolkata, Mumbai, New Delhi\r\n"
-#string STR_TIMEZONE_P545 #language en-US "UTC+05:45, Kathmandu\r\n"
-#string STR_TIMEZONE_P6 #language en-US "UTC+06:00, Almaty, Astana, Dhaka, Sri Jayawardenepura\r\n"
-#string STR_TIMEZONE_P630 #language en-US "UTC+06:30, Rangoon\r\n"
-#string STR_TIMEZONE_P7 #language en-US "UTC+07:00, Bangkok, Hanio, Jakarta, Krasnoyarsk, Novosibirsk\r\n"
-#string STR_TIMEZONE_P8 #language en-US "UTC+08:00, Beijing, Chongqing, Hong Kong, Urumqi, Taipei, Perth\r\n"
-#string STR_TIMEZONE_P9 #language en-US "UTC+09:00, Osaka, Sapporo, Tokyo, Seoul, Yakutsk\r\n"
-#string STR_TIMEZONE_P930 #language en-US "UTC+09:30, Adelaide, Darwin\r\n"
-#string STR_TIMEZONE_P10 #language en-US "UTC+10:00, Canberra, Melbourne, Sydney, Guam, Hobart, Vladivostok\r\n"
-#string STR_TIMEZONE_P11 #language en-US "UTC+11:00, Magadan, Solomon Is., New Caledonia\r\n"
-#string STR_TIMEZONE_P12 #language en-US "UTC+12:00, Auckland, Wellington, Fiji, Kamchatka, Marshall Is.\r\n"
-#string STR_TIMEZONE_P13 #language en-US "UTC+13:00, Nuku'alofa\r\n"
-#string STR_TIMEZONE_P14 #language en-US "UTC+14:00, Line Islands\r\n"
-#string STR_TIMEZONE_LOCAL #language en-US "LOCAL , Local Time\r\n"
-#string STR_TIMEZONE_SIMPLE #language en-US "UTC%1s%02d:%02d\r\n"
-#string STR_TIMEZONE_SIMPLE_LOCAL #language en-US "LOCAL\r\n"
-#string STR_TIMEZONE_NI #language en-US "No additional information known."
-
-#string STR_LOAD_NOT_IMAGE #language en-US "Image '%s' is not an image.\r\n"
-#string STR_LOAD_NOT_DRIVER #language en-US "Image '%s' is not a driver.\r\n"
-#string STR_LOAD_LOADED #language en-US "Image '%s' loaded at %p - %r\r\n"
-#string STR_LOAD_ERROR #language en-US "Image '%s' error in StartImage: %r\r\n"
-
-#string STR_LS_LINE_START_ALL #language en-US "%t %5s %1c % ,L11d "
-#string STR_LS_LINE_END_FILE #language en-US "%s\r\n"
-#string STR_LS_LINE_END_EXE #language en-US "%V%s%N\r\n"
-#string STR_LS_LINE_END_DIR #language en-US "%B%s%N\r\n"
-#string STR_LS_FOOTER_LINE #language en-US "% ,L11d File(s) % ,L11d bytes\r\n% ,L11d Dir(s)\r\n"
-#string STR_LS_HEADER_LINE1 #language en-US "Directory of: %H%s%N\r\n"
-#string STR_LS_FILE_NOT_FOUND #language en-US "%H%s%N: File Not Found - '%H%s%N'\r\n"
-#string STR_LS_SFO_VOLINFO #language en-US "VolumeInfo,"%s","%Ld","%5s","%Ld","%Ld"\r\n"
-#string STR_LS_SFO_FILEINFO #language en-US "FileInfo,"%s","%Ld","%Ld","%s%s%s%s%s","%02d:%02d:%02d","%02d.%02d.%04d","%02d:%02d:%02d","%02d.%02d.%04d","%02d:%02d:%02d","%02d.%02d.%04d"\r\n"
-
-#string STR_VOL_VOLINFO #language en-US "Volume %s (%s)\r\n"
- "%Ld bytes total disk space\r\n"
- "%Ld bytes available on disk\r\n"
- "%d bytes in each allocation unit\r\n"
-
-#string STR_RM_LOG_DELETE_CONF #language en-US "Remove Subtree '%B%s%N' [y/n]?"
-#string STR_RM_LOG_DELETE #language en-US "Deleting '%B%s%N'\r\n"
-#string STR_RM_LOG_DELETE_ERR #language en-US "Delete error: %r\r\n"
-#string STR_RM_LOG_DELETE_ERR2 #language en-US "Delete error. Couldn't open file: %r\r\n"
-#string STR_RM_LOG_DELETE_ERR3 #language en-US "Delete error. Invalid target '%B%s%N'\r\n"
-#string STR_RM_LOG_DELETE_COMP #language en-US "Delete successful.\r\n"
-#string STR_RM_LOG_DETELE_RO #language en-US "%H%s%N: '%H%s%N' is read-only\r\n"
-
-#string STR_MV_OUTPUT #language en-US "Moving %s -> %s\r\n"
-#string STR_MV_INV_SUB #language en-US "Cannot move a directory into itself or its subdirectory.\r\n"
-#string STR_MV_INV_RO #language en-US "Cannot move to or from a read-only file or directory '%B%s%N'\r\n"
-#string STR_MV_INV_CWD #language en-US "Cannot move current working directory or its subdirectory.\r\n"
-
-#string STR_CP_OUTPUT #language en-US "Copying %s -> %s\r\n"
-#string STR_CP_ERROR #language en-US "%H%s%N: Could not copy - '%H%s%N'\r\n"
-#string STR_CP_DIR_REQ #language en-US "%H%s%N: Copying a directory requires -r.\r\n"
-#string STR_CP_DIR_WNF #language en-US "%H%s%N: The specified path does not exist - '%H%s%N'\r\n"
-#string STR_CP_SD_SAME #language en-US "%H%s%N: The source and destination are the same.\r\n"
-#string STR_CP_SD_PARENT #language en-US "%H%s%N: The destination is a parent of the source.\r\n"
-#string STR_CP_DEST_ERROR #language en-US "%H%s%N: The destination is read-only.\r\n"
-#string STR_CP_DEST_OPEN_FAIL #language en-US "%H%s%N: The destination file '%B%s%N' failed to open with create.\r\n"
-#string STR_CP_DEST_DIR_FAIL #language en-US "%H%s%N: The destination directory '%B%s%N' could not be created.\r\n"
-#string STR_CP_SRC_OPEN_FAIL #language en-US "%H%s%N: The source file '%B%s%N' failed to open with read.\r\n"
-
-#string STR_GET_HELP_ATTRIB #language en-US ""
-".TH attrib 0 "Displays or modifies the attributes of files or directories."\r\n"
-".SH NAME\r\n"
-"Displays or modifies the attributes of files or directories.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"ATTRIB [+a|-a] [+s|-s] [+h|-h] [+r|-r] [file...] [directory...]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" +a|-a - Sets or clears the 'archive' attribute.\r\n"
-" +s|-s - Sets or clears the 'system' attribute.\r\n"
-" +h|-h - Sets or clears the 'hidden' attribute.\r\n"
-" +r|-r - Sets or clears the 'read-only' attribute.\r\n"
-" file - Specifies the file name (wild cards are permitted).\r\n"
-" directory - Specifies the directory name (wildcards are permitted).\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. Four attribute types are supported in the UEFI file system:\r\n"
-" - Archive [A]\r\n"
-" - System [S]\r\n"
-" - Hidden [H]\r\n"
-" - Read only [R]\r\n"
-" 2. If a file (in general meaning) is a directory, then it is also shown\r\n"
-" to have the attribute [D].\r\n"
-" 3. If any file in the file list that is specified \r\n"
-" does not exist, attrib will continue processing the remaining files\r\n"
-" while reporting the error.\r\n"
-" 4. If no attributes parameters are specified, the current attributes of\r\n"
-" the specified files or directories are displayed.\r\n"
-" 5. If no files or directories are specified, the command applies to\r\n"
-" all files and sub-directories within the current directory.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display the attributes of a directory:\r\n"
-" fs0:\> attrib fs0:\ \r\n"
-" \r\n"
-" * To display the attributes of all files and sub-directories in the current\r\n"
-" directory:\r\n"
-" fs0:\> attrib *\r\n"
-" \r\n"
-" * To add the system attribute to all files with extension '.efi':\r\n"
-" fs0:\> attrib +s *.efi\r\n"
-" \r\n"
-" * To remove the read-only attribute from all files with extension '.inf':\r\n"
-" fs0:\> attrib -r *.inf\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_NOT_FOUND The requested file was not found.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_WRITE_PROTECTED The media that the action was to take place on is\r\n"
-" write-protected.\r\n"
-
-#string STR_GET_HELP_CD #language en-US ""
-".TH cd 0 "Displays or changes the current directory."\r\n"
-".SH NAME\r\n"
-"Displays or changes the current directory.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"CD [path]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" path - Specifies the relative or absolute directory path.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command changes the current working directory that is used by the\r\n"
-" UEFI Shell environment. If a file system mapping is specified, then the\r\n"
-" current working directory is changed for that device. Otherwise, the\r\n"
-" current working directory is changed for the current device.\r\n"
-" 2. If path is not present, then the current working directory (including\r\n"
-" file system mapping) is displayed to standard out.\r\n"
-" 3. The table below describes the conventions that are used to refer to the\r\n"
-" directory, its parent, and the root directory in the UEFI Shell\r\n"
-" environment.\r\n"
-" Convention Description\r\n"
-" '.' Refers to the current directory.\r\n"
-" '..' Refers to the directory's parent.\r\n"
-" '\\\' Refers to the root of the current file system.\r\n"
-" 4. The current working directory is maintained in the environment\r\n"
-" variable %cwd%.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To change the current file system to the mapped fs0 file system:\r\n"
-" Shell> fs0:\r\n"
-" \r\n"
-" * To change the current directory to subdirectory 'efi':\r\n"
-" fs0:\> cd efi\r\n"
-" \r\n"
-" * To change the current directory to the parent directory (fs0:\):\r\n"
-" fs0:\efi\> cd ..\r\n"
-" \r\n"
-" * To change the current directory to 'fs0:\efi\Tools':\r\n"
-" fs0:\> cd efi\Tools\r\n"
-" \r\n"
-" * To change the current directory to the root of the current fs (fs0):\r\n"
-" fs0:\efi\Tools\> cd \ \r\n"
-" \r\n"
-" * To move between volumes and maintain the current path, and then copy\r\n"
-" all of files in fs0:\efi\Tools into the fs1:\Tmp directory:\r\n"
-" fs0:\> cd \efi\Tools\r\n"
-" fs0:\efi\Tools\> fs1:\r\n"
-" fs1:\> cd Tmp\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-
-#string STR_GET_HELP_CP #language en-US ""
-".TH cp 0 "Copies files or directories."\r\n"
-".SH NAME\r\n"
-"Copies one or more files or directories to another location.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"CP [-r] [-q] src [src...] [dst]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -r - Makes a recursive copy.\r\n"
-" -q - Makes a quiet copy (without a prompt).\r\n"
-" src - Specifies a source file/directory name (wildcards are permitted).\r\n"
-" dst - Specifies a destination file/directory name (wildcards are not permitted). \r\n"
-" If more than one directory is specified, the last directory is\r\n"
-" assumed to be the destination.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. '-r' must be specified if src is a directory. If '-r' is specified,\r\n"
-" the source directory is recursively copied to the destination.\r\n"
-" 'src' itself is copied.\r\n"
-" 2. If a destination is not specified, the current working directory is\r\n"
-" assumed to be the destination.\r\n"
-" 3. 'CP -r src1 src2 dst' copies all files and subdirectories in 'src1' and\r\n"
-" 'src2' to the destination 'dst'. 'src1' and 'src2' themselves are also\r\n"
-" copied. The 'dst' parameter is interpreted as a directory.\r\n"
-" 4. Copying a directory or file to itself is not allowed.\r\n"
-" 5. If an error occurs, this command exits immediately and the remaining files or\r\n"
-" directories are not copied.\r\n"
-" 6. When 'cp' is executed with a script file, it always performs quiet\r\n"
-" copying, regardless of whether the '-q' option is specified.\r\n"
-" 7. If you are copying multiple files, the destination must be an existing\r\n"
-" directory.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display the contents of the current directory:\r\n"
-" fs0:\> ls\r\n"
-" \r\n"
-" * To copy a file in the same directory and change the file name:\r\n"
-" fs0:\> cp temp.txt readme.txt\r\n"
-" \r\n"
-" * To copy multiple files to another directory:\r\n"
-" fs0:\> cp temp.txt isaBus.efi \Test\r\n"
-" \r\n"
-" * To copy multiple directories recursively to another directory:\r\n"
-" fs0:\> cp -r test1 test2 boot \Test\r\n"
-" \r\n"
-" * To see the results of the above operations:\r\n"
-" fs0:\> ls \Test\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly \r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_OUT_OF_RESOURCES There was insufficient space to save the \r\n"
-" requested file at the destination.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security \r\n"
-" violation.\r\n"
-" SHELL_WRITE_PROTECTED An attempt was made to create a file on media that\r\n"
-" was write-protected.\r\n"
-
-#string STR_GET_HELP_MAP #language en-US ""
-".TH map 0 "Displays or defines file system mappings"\r\n"
-".SH NAME\r\n"
-"Displays or defines file system mappings.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"MAP [-d <sname>]\r\n"
-"MAP [[-r][-v][-c][-f][-u][-t <type[,type...]>][sname]]\r\n"
-"MAP [sname handle | mapping]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -d - Deletes a file system mapping.\r\n"
-" -r - Resets file system mappings to default values.\r\n"
-" -u - Adds file system mappings for newly-installed devices and\r\n"
-" removes mappings for uninstalled devices. This does not change\r\n"
-" the mappings of existing devices and preserves user-defined mappings.\r\n"
-" -v - Displays verbose information about all file system mappings.\r\n"
-" -c - Displays the consistent mappings.\r\n"
-" -f - Displays the normal mappings (not the consistent mappings).\r\n"
-" -t - Displays the device mappings, filtered according to the device type.\r\n"
-" Supported types are:\r\n"
-" fp - Floppy\r\n"
-" hd - Hard Disk\r\n"
-" cd - CD-ROM\r\n"
-" Types can be combined by putting a comma between two types. Spaces\r\n"
-" are not allowed between types.\r\n"
-" -sfo - Displays information in Standard-Format Output.\r\n"
-" sname - Specifies a mapping name.\r\n"
-" handle - Specifies the number of a handle. Use the same value that is\r\n"
-" displayed by the 'dh' command.\r\n"
-" mapping - Specifies a new mapping name to assign to a device.\r\n"
-" This value must end with a ':'.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command creates a mapping between a user-defined name and a device.\r\n"
-" The most common use of this command is to create a mapped name for\r\n"
-" devices that support a file system protocol. After these mappings are\r\n"
-" created, the names can be used with all the file manipulation commands.\r\n"
-" 2. The UEFI Shell environment creates default mappings for all of the\r\n"
-" devices that support a recognized file system.\r\n"
-" 3. This command can be used to create additional mappings, or \r\n"
-" when used with the -d option, to delete an existing mapping. If it is\r\n"
-" used without any parameters, all of the current mappings are listed.\r\n"
-" If the -v option is used, the mappings are shown with additional\r\n"
-" information about each device.\r\n"
-" 4. The -r option is used to reset all the default mappings in a system,\r\n"
-" which is useful if the system configuration has changed since the\r\n"
-" last boot.\r\n"
-" 5. The -u option adds mappings for newly-installed devices and removes\r\n"
-" mappings for uninstalled devices without changing the mappings of\r\n"
-" existing devices. User-defined mappings are also preserved. A mapping\r\n"
-" history is saved, which preserves the original mapping name for\r\n"
-" a device with a specific device path. The current directory is also\r\n"
-" preserved if the current device is not changed.\r\n"
-" 6. Each device in the system has a consistent mapping. If the hardware\r\n"
-" configuration has not changed, the device's consistent mappings do not\r\n"
-" change. If two or more machines have the same hardware configurations,\r\n"
-" the device's consistent mapping remains the same. Use the -c option to\r\n"
-" list all the consistent mappings in the system.\r\n"
-" 7. The mapping value must consist of digits and characters. Other\r\n"
-" characters are illegal.\r\n"
-" 8. This command support wildcards. You can use the wildcards to delete\r\n"
-" or show the mapping. However, when you assign the mapping, wildcards\r\n"
-" are forbidden.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display verbose mapping table information:\r\n"
-" Shell> map -v\r\n"
-" \r\n"
-" * To assign a different name to fs0:\r\n"
-" Shell> map floppy fs0:\r\n"
-" \r\n"
-" * To operate with the mapped name:\r\n"
-" Shell> floppy:\r\n"
-" \r\n"
-" * To delete a mapped name:\r\n"
-" Shell> map -d floppy:\r\n"
-" \r\n"
-" * To display all the mapped names starting with 'f': \r\n"
-" Shell> map f* \r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-
-#string STR_GET_HELP_MKDIR #language en-US ""
-".TH mkdir 0 "Creates directories."\r\n"
-".SH NAME\r\n"
-"Creates one or more new directories.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"MKDIR dir [dir...]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" dir - Specifies the name of a directory or directories to create.\r\n"
-" (Wildcards are not allowed)\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. Mkdir can create one or more new directories.\r\n"
-" 2. If dir includes nested directories, then parent directories will be\r\n"
-" created before child directories.\r\n"
-" 3. If the directory already exists, mkdir will exit with an error.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To create a new directory:\r\n"
-" fs0:\> mkdir rafter\r\n"
-" \r\n"
-" * To create multiple directories:\r\n"
-" fs0:\> mkdir temp1 temp2\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly \r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_OUT_OF_RESOURCES There was insufficient space on the destination \r\n"
-" to create the requested directory.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security \r\n"
-" violation.\r\n"
-" SHELL_WRITE_PROTECTED An attempt was made to create a directory when the\r\n"
-" target media was write-protected.\r\n"
-
-#string STR_GET_HELP_MV #language en-US ""
-".TH mv 0 "Moves files."\r\n"
-".SH NAME\r\n"
-"Moves one or more files to a destination within or between file systems.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"MV src [src...] [dst]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" src - Specifies a source file/directory name (wildcards are permitted).\r\n"
-" dst - Specifies a destination file/directory name (wildcards are permitted).\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command moves one or more files to a destination within or between\r\n"
-" file systems.\r\n"
-" 2. If the destination is an existing directory, the sources are moved\r\n"
-" into that directory. You cannot move the sources to a non-existing\r\n"
-" directory.\r\n"
-" 3. If a destination is not specified, the current directory is assumed to be\r\n"
-" the destination. If there is more than one argument on the command line,\r\n"
-" the last one is assumed to be the destination.\r\n"
-" 4. Attempting to move a read-only file/directory results in an error.\r\n"
-" Moving a directory that contains read-only files is allowed.\r\n"
-" 5. You cannot move a directory into itself or its subdirectories.\r\n"
-" 6. You cannot move a directory if the current working directory is itself or\r\n"
-" its subdirectories.\r\n"
-" 7. If an error occurs, the remaining files or directories are still be\r\n"
-" moved.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To rename a file:\r\n"
-" fs0:\> mv IsaBus.efi Bus.efi\r\n"
-" \r\n"
-" * To move a directory to the current directory:\r\n"
-" fs0:\> mkdir Test1\Temp\r\n"
-" fs0:\> mv Test1\Temp\r\n"
-" \r\n"
-" * To rename a directory:\r\n"
-" fs0:\> mv efi efi1.1\r\n"
-" \r\n"
-" * To move multiple directories at a time:\r\n"
-" fs0:\> mv Test1 Test2 Test\r\n"
-" \r\n"
-" * To attempt moving a read-only directory, which results in a failure:\r\n"
-" fs0:\Test> attrib +r Temp1\r\n"
-" DA R fs0:\Test\Temp1\r\n"
-" fs0:\Test> mv Temp1 Temp2\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_NOT_FOUND The source file was not able to be found.\r\n"
-" SHELL_OUT_OF_RESOURCES There was insufficient free space to move the\r\n"
-" requested file to its destination.\r\n"
-" SHELL_WRITE_PROTECTED An attempt was made to create a file on media that\r\n"
-" was write-protected.\r\n"
-
-#string STR_GET_HELP_PARSE #language en-US ""
-".TH parse 0 "Parses standard format output files."\r\n"
-".SH NAME\r\n"
-"Retrieves a value from a standard format output file.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"PARSE filename tablename column [-i <Instance>] [-s <Instance>]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" filename - Specifies a source file name.\r\n"
-" tablename - Specifies the name of the table to be parsed.\r\n"
-" column - Specifies the one-based column index to use to determine which value\r\n"
-" from a particular record to parse.\r\n"
-" -i <Instance> - Specifies an instance number to use to start parsing the ShellCommand table,\r\n"
-" and then the specified tablename. If not specified, all instances are returned.\r\n"
-" -s <Instance> - Specifies an instance number to use to start parsing the ShellCommand\r\n"
-" table. If not present, then 1 is assumed.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command enables you to parse data from a file that has been output\r\n"
-" using the -sfo parameter.\r\n"
-" 2. Since the standard formatted output has a well known means of parsing,\r\n"
-" this command is intended to provide an easy way of enabling\r\n"
-" scripts to consume retrieved data from such constructed output files, and\r\n"
-" use it in the logic of scripts written for the UEFI shell.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * The following data is contained in a temporary file (temp.txt):\r\n"
-" ShellCommand,"ls"\r\n"
-" VolumeInfo,"MikesVolume","400000000","FALSE","32000000","16000000"\r\n"
-" FileInfo,"FS0:\efi\\boot\winloader.efi","45670","45900","arsh","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n"
-" FileInfo,"FS0:\efi\\boot\mikesfile.txt","1250","1280","a","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n"
-" FileInfo,"FS0:\efi\\boot\\readme.txt","795","900","a","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n"
-" \r\n"
-" * To display VolumeInfo column 2 in temp.txt:\r\n"
-" fs0:\> parse temp.txt VolumeInfo 2\r\n"
-" MikesVolume\r\n"
-" \r\n"
-" * To display FileInfo column 3 in temp.txt, starting with instance 3:\r\n"
-" fs0:\> parse temp.txt FileInfo 3 -i 3\r\n"
-" 795\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_NOT_FOUND The source file was not able to be found.\r\n"
-
-#string STR_GET_HELP_RESET #language en-US ""
-".TH reset 0 "Reset the system."\r\n"
-".SH NAME\r\n"
-"Resets the system.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"RESET [-w [string]]\r\n"
-"RESET [-s [string]]\r\n"
-"RESET [-c [string]]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -s - Performs a shutdown.\r\n"
-" -w - Performs a warm boot.\r\n"
-" -c - Performs a cold boot.\r\n"
-" string - Describes a reason for the reset.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command resets the system.\r\n"
-" 2. The default is to perform a cold reset unless the -w parameter is\r\n"
-" specified.\r\n"
-" 3. If a reset string is specified, it is passed into the Reset() \r\n"
-" function, and the system records the reason for the system reset.\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_INVALID_PARAMETER One of the passed in parameters was incorrectly \r\n"
-" formatted or its value was out of bounds.\r\n"
-
-#string STR_GET_HELP_RM #language en-US ""
-".TH rm 0 "Deletes one or more files or directories."\r\n"
-".SH NAME\r\n"
-"Deletes one or more files or directories.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"RM [-q] file/directory [file/directory ...]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -q - Specifies quiet mode. Does not prompt for a confirmation.\r\n"
-" file - Specifies a file name (wildcards are permitted).\r\n"
-" directory - Specifies a directory name (wildcards are permitted).\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command deletes one or more files or directories.\r\n"
-" 2. If the target is a directory, it deletes the directory, including all\r\n"
-" its subdirectories.\r\n"
-" 3. Redirecting a file whose parent directory (or the file\r\n"
-" itself) is being deleted is not allowed.\r\n"
-" 4. Removing a read-only file/directory results in a failure.\r\n"
-" 5. Removing a directory containing read-only file(s) results in\r\n"
-" a failure. If an error occurs, the command exits immediately and stops\r\n"
-" removing files/directories.\r\n"
-" 6. You cannot remove a directory when the current directory is itself or its\r\n"
-" subdirectory. If a file contains wildcards, you are not prompted for\r\n"
-" confirmation.\r\n"
-" 7. The root directory cannot be removed.\r\n"
-" 8. The current directory or its ancestor directories cannot be removed.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To remove multiple directories at a time:\r\n"
-" fs0:\> rm Test\Temp1 Temp2\r\n"
-" \r\n"
-" * To remove multiple directories with wildcards:\r\n"
-" fs0:\> rm Test\Temp*\r\n"
-" \r\n"
-" * To attempt removing a directory that contains a read-only file,\r\n"
-" which results in a failure:\r\n"
-" fs0:\> attrib +r Test\Temp1\readme.txt\r\n"
-" A R fs0:\Test\Temp1\readme.txt\r\n"
-" fs0:\> rm Test\Temp1\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_NOT_FOUND The source file was not able to be found.\r\n"
-" SHELL_WRITE_PROTECTED The target was write protected.\r\n"
-
-#string STR_GET_HELP_SET #language en-US ""
-".TH set 0 "Displays or modifies UEFI Shell environment variables."\r\n"
-".SH NAME\r\n"
-"Displays or modifies UEFI Shell environment variables.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"SET [-v] [sname [value]]\r\n"
-"SET [-d <sname>]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -d - Deletes the environment variable.\r\n"
-" -v - Displays or modifies a volatile variable.\r\n"
-" sname - Specifies an environment variable name.\r\n"
-" value - Specifies an environment variable value.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command is used to maintain the UEFI Shell environment variables.\r\n"
-" This command can do the following:\r\n"
-" - Display environment variables.\r\n"
-" - Create new environment variables.\r\n"
-" - Change the value of existing environment variables.\r\n"
-" - Delete environment variables.\r\n"
-" 2. This command sets an environment variable to a specified \r\n"
-" value. You can use it to create a new environment\r\n"
-" variable or to modify an existing environment variable.\r\n"
-" 3. If used without any parameters, all the environment variables\r\n"
-" are displayed.\r\n"
-" 4. If used with the -d option, the environment variable that\r\n"
-" is specified by sname is deleted.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To add an environment variable:\r\n"
-" Shell> set DiagnosticPath fs0:\efi\diag;fs1:\efi\diag\r\n"
-" \r\n"
-" * To display environment variables:\r\n"
-" Shell> set\r\n"
-" \r\n"
-" * To delete an environment variable:\r\n"
-" Shell> set -d diagnosticpath\r\n"
-" \r\n"
-" * To change an environment variable:\r\n"
-" fs0:\> set src efi\r\n"
-" fs0:\> set src efi1.1\r\n"
-" \r\n"
-" * To append an environment variable:\r\n"
-" Shell> set path %path%;fs0:\efi\Tools;fs0:\efi\boot;fs0:\\r\n"
-" \r\n"
-" * To set a volatile variable that will disappear at the next boot:\r\n"
-" Shell> set -v EFI_SOURCE c:\project\EFI1.1\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_OUT_OF_RESOURCES A request to set a variable in a non-volatile \r\n"
-" fashion could not be completed. The resulting \r\n"
-" non-volatile request has been converted into a \r\n"
-" volatile request.\r\n"
-
-#string STR_GET_HELP_DATE #language en-US ""
-".TH date 0 "Displays and sets the current date for the system."\r\n"
-".SH NAME\r\n"
-"Displays and sets the current date for the system.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"DATE [mm/dd/[yy]yy][-sfo]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -sfo - Displays information in Standard-Format Output.\r\n"
-" mm - Specifies the month of the date to be set. (1-12)\r\n"
-" dd - Specifies the day of the date to be set (1-31)\r\n"
-" yy/yyyy - Specifies the year of the date to be set. If only two digits,\r\n"
-" then enter 9x = 199x. Otherwise enter 20xx.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command displays and/or sets the current date for the system.\r\n"
-" If no parameters are used, it shows the current date. If a valid month,\r\n"
-" day, and year are specified, the system's date is updated.\r\n"
-" The following rules apply:\r\n"
-" - Except for numeric characters and /, all other characters in the\r\n"
-" argument are invalid.\r\n"
-" - The Shell reports an error if the number is in the wrong\r\n"
-" month/date/year range.\r\n"
-" - A space before or after the numeric character is not allowed. Inserting\r\n"
-" a space into the number is invalid.\r\n"
-" - Repeated zeros are allowed before the number. For example:\r\n"
-" Shell > date 0000008/000004/000097\r\n"
-" Shell > date\r\n"
-" 08/04/2097\r\n"
-" Shell >\r\n"
-" - The year range must be greater than or equal to 1998.\r\n"
-" - Two numeric characters indicate the year. Numbers below 98 are\r\n"
-" regarded as 20xx, and numbers equal to or above 98 are regarded as\r\n"
-" 19xx. 00 means 2000. For example:\r\n"
-" Shell > date 8/4/97\r\n"
-" Shell > date\r\n"
-" 08/04/2097\r\n"
-" Shell >\r\n"
-" Shell > date 8/4/98\r\n"
-" Shell > date\r\n"
-" 08/04/1998\r\n"
-" Shell >\r\n"
-" 2. The range of valid years is from 1998-2099.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display the current date in the system:\r\n"
-" fs0:\> date\r\n"
-" \r\n"
-" * To set the date with long year format:\r\n"
-" fs0:\> date 01/01/2050\r\n"
-" \r\n"
-" * To set the date with short year format:\r\n"
-" fs0:\> date 06/18/01\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_DEVICE_ERROR There was a hardware error preventing the\r\n"
-" completion of this command.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-
-#string STR_GET_HELP_TIME #language en-US ""
-".TH time 0 "Displays or sets the time for the system."\r\n"
-".SH NAME\r\n"
-"Displays or sets the current time for the system.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"TIME [hh:mm[:ss]] [-tz tz] [-d dl]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -d - Sets or displays a daylight savings time value.\r\n"
-" -tz - Specifies a time zone adjustment, measured in minutes offset from UTC. Valid values\r\n"
-" are between -1440 and 1440 or 2047. If not present or set to 2047,\r\n"
-" time is interpreted as local time.\r\n"
-" hh - Specifies a new hour (0-23) (required).\r\n"
-" mm - Specifies a new minute (0-59) (required).\r\n"
-" ss - Specifies a new second (0-59). If not specified, zero is used.\r\n"
-" dl - Specifies a daylight saving time value to set.\r\n"
-" 0 : Time is not affected.\r\n"
-" 1 : Time is affected, and has not been adjusted for daylight\r\n"
-" savings.\r\n"
-" 3 : Time is affected, and has been adjusted for daylight savings.\r\n"
-" All other values are invalid. If no value follows -d, the\r\n"
-" current daylight savings time is displayed.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command displays or sets the current time for the system.\r\n"
-" If no parameters are used, it shows the current time. If valid hours, \r\n"
-" minutes, and seconds are provided, the system time is\r\n"
-" updated. Note the following rules:\r\n"
-" - Except for numeric characters and the : character, all other\r\n"
-" characters in the argument are invalid.\r\n"
-" - The Shell reports an error if the number is in the wrong \r\n"
-" hour/minute/second range.\r\n"
-" - Spaces before or after the numeric character and spaces inserted into\r\n"
-" the number are not allowed.\r\n"
-" - Repeated zeros are allowed before the number. For example:\r\n"
-" Shell> time 00000017:000004:0000\r\n"
-" Shell> time\r\n"
-" 17:04:00 (UTC+08:00)\r\n"
-" 2. The seconds parameter is optional. If none is specified, it is\r\n"
-" set to zero.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display current system time:\r\n"
-" fs0:\> time\r\n"
-" \r\n"
-" * To set the system time:\r\n"
-" fs0:\> time 9:51:30\r\n"
-" \r\n"
-" * To display the system time, including daylight savings time:\r\n"
-" fs0:\> time -d\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_DEVICE_ERROR There was a hardware error preventing the\r\n"
-" completion of this command\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-
-#string STR_GET_HELP_TIMEZONE #language en-US ""
-".TH timezone 0 "Displays or sets time zone information."\r\n"
-".SH NAME\r\n"
-"Displays or sets time zone information.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"TIMEZONE [-s hh:mm | -l] [-b] [-f]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -s - Sets the time zone associated with hh:mm offset from UTC.\r\n"
-" -l - Displays a list of all time zones.\r\n"
-" -b - Displays one screen at a time.\r\n"
-" -f - Displays full information for the specified time zone.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command displays and sets the current time zone for the system.\r\n"
-" 2. If no parameters are used, it shows the current time zone.\r\n"
-" 3. If a valid hh:mm parameter is provided, the time zone\r\n"
-" information is updated.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display all available time zones:\r\n"
-" Shell> timezone -l\r\n"
-" \r\n"
-" * To set the time zone:\r\n"
-" Shell> timezone -s -7:00\r\n"
-" \r\n"
-" * To display detailed information for the current time zone:\r\n"
-" Shell> timezone -f\r\n"
-
-#string STR_GET_HELP_LS #language en-US ""
-".TH ls 0 "Lists the contents of a directory or file information."\r\n"
-".SH NAME\r\n"
-"Lists the contents of a directory or file information.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"LS [-r] [-a[attrib]][-sfo][file]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -r - Displays recursively (including subdirectories).\r\n"
-" -a - Displays files with a specified attribute. If \r\n"
-" attribute is not specified, all files are listed. If -a is not\r\n"
-" specified, all non-system and non-hidden files are listed.\r\n"
-" -sfo - Displays information in Standard-Format Output.\r\n"
-" attrib - Specifies a file attribute list value:\r\n"
-" a - Archive\r\n"
-" s - System\r\n"
-" h - Hidden\r\n"
-" r - Read-only\r\n"
-" d - Directory\r\n"
-" file - Specifies a name of a file or directory (wildcards are permitted).\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command lists directory contents or file information. If no file\r\n"
-" name or directory name is specified, the current working directory\r\n"
-" is assumed.\r\n"
-" 2. The contents of a directory are listed if all of the following are true:\r\n"
-" - If option -r is not specified.\r\n"
-" - If no wildcard characters are specified in the file parameter.\r\n"
-" - If the file specified represents an existing directory.\r\n"
-" 3. In all other cases, the command functions as follows:\r\n"
-" - All files/directories that match the specified name are displayed.\r\n"
-" - The -r flag determines whether a recursive search is performed.\r\n"
-" - The option flag -a[attrib] only displays those\r\n"
-" files with the attributes that are specified.\r\n"
-" - If more than one attribute is specified, only the files that have all\r\n"
-" those attributes are listed.\r\n"
-" - If -a is followed by nothing, then all files/directories are\r\n"
-" displayed, regardless of their attributes.\r\n"
-" - If -a itself is not specified, then all files except system and\r\n"
-" hidden files are displayed.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To hide files by adding the hidden or system attribute to them:\r\n"
-" fs0:\> attrib +s +h *.efi\r\n"
-" \r\n"
-" * To display all, except the files/directories with 'h' or 's' attribute:\r\n"
-" fs0:\> ls\r\n"
-" \r\n"
-" * To display files with all attributes in the current directory:\r\n"
-" fs0:\> ls -a\r\n"
-" \r\n"
-" * To display files with read-only attributes in the current directory:\r\n"
-" fs0:\> ls -ar\r\n"
-" \r\n"
-" * To display the files with attribute of 's':\r\n"
-" fs0:\> ls -as isabus.efi\r\n"
-" \r\n"
-" * To display all in fs0:\efi directory recursively:\r\n"
-" fs0:\> ls -r -a efi\r\n"
-" \r\n"
-" * To display files with a specified type in the current directory: \r\n"
-" recursively:\r\n"
-" fs0:\> ls -r -a *.efi -b\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_NOT_FOUND The requested file or directory was not found.\r\n"
-
-#string STR_GET_HELP_LOAD #language en-US ""
-".TH load 0 "Loads a UEFI driver into memory."\r\n"
-".SH NAME\r\n"
-"Loads a UEFI driver into memory.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"LOAD [-nc] file [file...]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -nc - Loads the driver, but does not connect the driver.\r\n"
-" File - Specifies a file that contains the image of the UEFI driver (wildcards are\r\n"
-" permitted).\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command loads a driver into memory. It can load multiple files at\r\n"
-" one time. The file name supports wildcards.\r\n"
-" 2. If the -nc flag is not specified, this command attempts to connect the\r\n"
-" driver to a proper device. It might also cause previously loaded drivers\r\n"
-" to be connected to their corresponding devices.\r\n"
-" 3. Use the 'UNLOAD' command to unload a driver.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To load a driver:\r\n"
-" fs0:\> load Isabus.efi\r\n"
-" \r\n"
-" * To load multiple drivers:\r\n"
-" fs0:\> load Isabus.efi IsaSerial.efi\r\n"
-" \r\n"
-" * To load multiple drivers using file name wildcards:\r\n"
-" fs0:\> load Isa*.efi\r\n"
-" \r\n"
-" * To load a driver without connecting it to a device:\r\n"
-" fs0:\> load -nc IsaBus.efi\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_NOT_FOUND The requested file was not found.\r\n"
-
-#string STR_GET_HELP_VOL #language en-US ""
-".TH vol 0 "Displays or modifies information about a disk volume."\r\n"
-".SH NAME\r\n"
-"Displays or modifies information about a disk volume.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"VOL [fs] [-n <VolumeLabel>]\r\n"
-"VOL [fs] [-d]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -n - Displays or modifies a new volume label.\r\n"
-" -d - Displays or modifies an empty volume label.\r\n"
-" fs - Specifies the name of the file system.\r\n"
-" VolumeLabel - Specifies a volume label.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. The following characters cannot be used in a volume label:\r\n"
-" % ^ * + = [ ] | : ; \" < > ? / . \r\n"
-" 2. No spaces are allowed in a volume label.\r\n"
-" 3. This command displays the volume information for the specified file\r\n"
-" system. If fs is not specified, the current file system is used.\r\n"
-" 4. If -n is specified, the volume label for fs is set to\r\n"
-" VolumeLabel.\r\n"
-" 5. The maximum length for volume label is 11 characters.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display the volume of the current file system:\r\n"
-" fs0:\> vol\r\n"
-" \r\n"
-" * To change the label of fs0:\r\n"
-" Shell> vol fs0 -n help_test\r\n"
-" \r\n"
-" * To delete the volume label of fs0:\r\n"
-" fs0:\> vol fs0 -d\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_NOT_FOUND The target file-system was not found.\r\n"
+// /** +// +// (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> +// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// UefiShellLevel2CommandsLib.uni +// +// Abstract: +// +// String definitions for UEFI Shell 2.0 level 2 commands +// +// +// **/ + +/=# + +#langdef en-US "english" + +#string STR_GEN_NO_MEM #language en-US "%H%s%N: Memory is not available.\r\n" +#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n" +#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments.\r\n" +#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n" +#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n" +#string STR_GEN_PROBLEM_VAL #language en-US "%H%s%N: Bad value - '%H%s%N' for flag - '%H%s%N'\r\n" +#string STR_GEN_ATTRIBUTE #language en-US "%H%s%N: Invalid argument - '%H-a%s%N'\r\n" +#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n" +#string STR_GEN_ERR_AD #language en-US "%H%s%N: Access denied.\r\n" +#string STR_GEN_ERR_FILE #language en-US "%H%s%N: File '%H%s%N' error - %r\r\n" +#string STR_GEN_ERR_UK #language en-US "%H%s%N: Status: %r\r\n" +#string STR_GEN_PARAM_CON #language en-US "%H%s%N: Parameters conflict.\r\n" +#string STR_GEN_PARAM_CONFLICT #language en-US "%H%s%N: Flags conflict with - '%H%s%N' and '%H%s%N'\r\n" +#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n" +#string STR_GEN_FILE_CLOSE_FAIL #language en-US "%H%s%N: Cannot close file - '%H%s%N'\r\n" +#string STR_GEN_FILE_AD #language en-US "%H%s%N: File access error - '%H%s%N'\r\n" +#string STR_GEN_FILE_NF #language en-US "%H%s%N: File not found - '%H%s%N'\r\n" +#string STR_GEN_CRLF #language en-US "\r\n" +#string STR_GEN_NO_CWD #language en-US "%H%s%N: Current directory not specified.\r\n" +#string STR_GEN_NO_FILES #language en-US "%H%s%N: No matching files were found.\r\n" +#string STR_GEN_DIR_NF #language en-US "%H%s%N: Directory not found - '%H%s%N'\r\n" +#string STR_GEN_RES_OK #language en-US "- [ok]\r\n" +#string STR_GEN_NOT_DIR #language en-US "%H%s%N: '%H%s%N' is not a directory.\r\n" +#string STR_GEN_NOT_FILE #language en-US "%H%s%N: '%H%s%N' is not a file.\r\n" +#string STR_GEN_SFO_HEADER #language en-US "ShellCommand,"%s"\r\n" +#string STR_GEN_MARG_ERROR #language en-US "%H%s%N: The destination '%H%s%N' is ambiguous.\r\n" +#string STR_GEN_FILE_ERROR #language en-US "%H%s%N: The destination is an existing file '%H%s%N'.\r\n" +#string STR_GEN_UEFI_FUNC_ERROR #language en-US "%H%s%N: UEFI function '%H%s%N' returned an incorrect value for: %s (%x).\r\n" +#string STR_GEN_UEFI_FUNC_WARN #language en-US "%H%s%N: UEFI function '%H%s%N' returned: %r\r\n" +#string STR_GEN_DEST_EXIST_OVR #language en-US "Destination file already exists. Overwrite? %BY%Nes, %BN%No, %BA%Nll, %BC%Nancel " +#string STR_GEN_CPY_FAIL #language en-US "%H%s%N: Copy failure: insufficient capacity on destination media.\r\n" +#string STR_GEN_CPY_READ_ERROR #language en-US "%H%s%N: reading '%B%s%N': IO Error \r\n" +#string STR_GEN_CPY_WRITE_ERROR #language en-US "%H%s%N: writing '%B%s%N': IO Error \r\n" +#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n" + +#string STR_SET_DISP #language en-US "%V%8s %N= %H%s%N\r\n" +#string STR_SET_NF #language en-US "%H%s%N: Environment Variable '%H%s%N' not defined.\r\n" +#string STR_SET_ND #language en-US "%H%s%N: Environment Variable '%H%s%N' could not be deleted.\r\n" +#string STR_SET_ERROR_SET #language en-US "%H%s%N: Unable to set %H%s%N\r\n" + +#string STR_CD_PRINT #language en-US "%s\r\n" +#string STR_CD_NF #language en-US "%H%s%N: No mapping found.\r\n" + +#string STR_MAP_NF #language en-US "%H%s%N: Cannot find mapped device - '%H%s%N'\r\n" +#string STR_MAP_NOF #language en-US "%H%s%N: No mappable target found - '%H%s%N'\r\n" +#string STR_MAP_SFO_MAPPINGS #language en-US "Mappings,"%s","%s","%s"\r\n" +#string STR_MAP_HEADER #language en-US "%EMapping table%N\r\n" +#string STR_MAP_ENTRY #language en-US "%E%10s%N %HAlias(s):%N%s\r\n %s\r\n" +#string STR_MAP_ENTRY_VERBOSE #language en-US " Handle: [%H%02x%N]\r\n" + " Media Type: %s\r\n" + " Removable: %s\r\n" + " Current Dir: %s\r\n" + +#string STR_ATTRIB_OUTPUT_LINE #language en-US "Attrib: %1c%1c%1c%1c%1c %s\r\n" + +#string STR_MAP_MEDIA_FLOPPY #language en-US "Floppy" +#string STR_MAP_MEDIA_UNKNOWN #language en-US "Unknown" +#string STR_MAP_MEDIA_HARDDISK #language en-US "HardDisk" +#string STR_MAP_MEDIA_CDROM #language en-US "CD-Rom" + +#string STR_MKDIR_ALREADY #language en-US "Directory '%B%s%N' already exists.\r\n" +#string STR_MKDIR_CREATEFAIL #language en-US "Directory '%B%s%N' unable to create.\r\n" + +#string STR_DATE_FORMAT #language en-US "%02d/%02d/%04d\r\n" +#string STR_DATE_SFO_FORMAT #language en-US "Date,"%02d","%02d","%04d"\r\n" + +#string STR_TIME_FORMAT #language en-US "%02d:%02d:%02d (UTC%1s%02d:%02d)" +#string STR_TIME_FORMAT_LOCAL #language en-US "%02d:%02d:%02d (LOCAL)" +#string STR_TIME_DST0 #language en-US " DST: Not Affected\r\n" +#string STR_TIME_DST1 #language en-US " DST: Affected\r\n" +#string STR_TIME_DST2 #language en-US " DST: Adjusted\r\n" +#string STR_TIME_DST3 #language en-US " DST: Affected and Adjusted\r\n" + +#string STR_TIMEZONE_M12 #language en-US "UTC-12:00, International Date Line West\r\n" +#string STR_TIMEZONE_M11 #language en-US "UTC-11:00, Midway Island, Samoa\r\n" +#string STR_TIMEZONE_M10 #language en-US "UTC-10:00, Hawaii\r\n" +#string STR_TIMEZONE_M9 #language en-US "UTC-09:00, Alaska\r\n" +#string STR_TIMEZONE_M8 #language en-US "UTC-08:00, Pacific Time(US & Canada), Tijuana, Portland\r\n" +#string STR_TIMEZONE_M7 #language en-US "UTC-07:00, Arizona, Chihuahua, La Paz, Mazatlan, Mountain Time (US & Canada)\r\n" +#string STR_TIMEZONE_M6 #language en-US "UTC-06:00, Central America, Central Time(US & Canada)\r\n" +#string STR_TIMEZONE_M5 #language en-US "UTC-05:00, Bogota, Lima, Quito, Eastern Time(US & Canada)\r\n" +#string STR_TIMEZONE_M430 #language en-US "UTC-04:30, Caracas\r\n" +#string STR_TIMEZONE_M4 #language en-US "UTC-04:00, Atlantic Time(Canada), Caracas, Santiago, Georgetown\r\n" +#string STR_TIMEZONE_M330 #language en-US "UTC-03:30, Newfoundland\r\n" +#string STR_TIMEZONE_M3 #language en-US "UTC-03:00, Brasilia, Buenos Aires, Greenland\r\n" +#string STR_TIMEZONE_M2 #language en-US "UTC-02:00, Mid-Atlantic\r\n" +#string STR_TIMEZONE_M1 #language en-US "UTC-01:00, Azores, Cape Verde Is.\r\n" +#string STR_TIMEZONE_0 #language en-US "UTC , Greenwich Mean Time, Casablanca, Monrovia, Dublin, London\r\n" +#string STR_TIMEZONE_P1 #language en-US "UTC+01:00, Amsterdam, Berlin, Bern, Rome, Paris, West Central Africa\r\n" +#string STR_TIMEZONE_P2 #language en-US "UTC+02:00, Athens, Bucharest, Cairo, Jerusalem\r\n" +#string STR_TIMEZONE_P3 #language en-US "UTC+03:00, Baghdad, Kuwait, Riyadh, Moscow, Nairobi, Istanbul\r\n" +#string STR_TIMEZONE_P330 #language en-US "UTC+03:30, Tehran\r\n" +#string STR_TIMEZONE_P4 #language en-US "UTC+04:00, Abu Dhabi, Muscat, Baku, Tbilisi, Yerevan\r\n" +#string STR_TIMEZONE_P430 #language en-US "UTC+04:30, Kabul\r\n" +#string STR_TIMEZONE_P5 #language en-US "UTC+05:00, Ekaterinburg, Islamabad, Karachi, Tashkent\r\n" +#string STR_TIMEZONE_P530 #language en-US "UTC+05:30, Chennai, Kolkata, Mumbai, New Delhi\r\n" +#string STR_TIMEZONE_P545 #language en-US "UTC+05:45, Kathmandu\r\n" +#string STR_TIMEZONE_P6 #language en-US "UTC+06:00, Almaty, Astana, Dhaka, Sri Jayawardenepura\r\n" +#string STR_TIMEZONE_P630 #language en-US "UTC+06:30, Rangoon\r\n" +#string STR_TIMEZONE_P7 #language en-US "UTC+07:00, Bangkok, Hanio, Jakarta, Krasnoyarsk, Novosibirsk\r\n" +#string STR_TIMEZONE_P8 #language en-US "UTC+08:00, Beijing, Chongqing, Hong Kong, Urumqi, Taipei, Perth\r\n" +#string STR_TIMEZONE_P9 #language en-US "UTC+09:00, Osaka, Sapporo, Tokyo, Seoul, Yakutsk\r\n" +#string STR_TIMEZONE_P930 #language en-US "UTC+09:30, Adelaide, Darwin\r\n" +#string STR_TIMEZONE_P10 #language en-US "UTC+10:00, Canberra, Melbourne, Sydney, Guam, Hobart, Vladivostok\r\n" +#string STR_TIMEZONE_P11 #language en-US "UTC+11:00, Magadan, Solomon Is., New Caledonia\r\n" +#string STR_TIMEZONE_P12 #language en-US "UTC+12:00, Auckland, Wellington, Fiji, Kamchatka, Marshall Is.\r\n" +#string STR_TIMEZONE_P13 #language en-US "UTC+13:00, Nuku'alofa\r\n" +#string STR_TIMEZONE_P14 #language en-US "UTC+14:00, Line Islands\r\n" +#string STR_TIMEZONE_LOCAL #language en-US "LOCAL , Local Time\r\n" +#string STR_TIMEZONE_SIMPLE #language en-US "UTC%1s%02d:%02d\r\n" +#string STR_TIMEZONE_SIMPLE_LOCAL #language en-US "LOCAL\r\n" +#string STR_TIMEZONE_NI #language en-US "No additional information known." + +#string STR_LOAD_NOT_IMAGE #language en-US "Image '%s' is not an image.\r\n" +#string STR_LOAD_NOT_DRIVER #language en-US "Image '%s' is not a driver.\r\n" +#string STR_LOAD_LOADED #language en-US "Image '%s' loaded at %p - %r\r\n" +#string STR_LOAD_ERROR #language en-US "Image '%s' error in StartImage: %r\r\n" + +#string STR_LS_LINE_START_ALL #language en-US "%t %5s %1c % ,L11d " +#string STR_LS_LINE_END_FILE #language en-US "%s\r\n" +#string STR_LS_LINE_END_EXE #language en-US "%V%s%N\r\n" +#string STR_LS_LINE_END_DIR #language en-US "%B%s%N\r\n" +#string STR_LS_FOOTER_LINE #language en-US "% ,L11d File(s) % ,L11d bytes\r\n% ,L11d Dir(s)\r\n" +#string STR_LS_HEADER_LINE1 #language en-US "Directory of: %H%s%N\r\n" +#string STR_LS_FILE_NOT_FOUND #language en-US "%H%s%N: File Not Found - '%H%s%N'\r\n" +#string STR_LS_SFO_VOLINFO #language en-US "VolumeInfo,"%s","%Ld","%5s","%Ld","%Ld"\r\n" +#string STR_LS_SFO_FILEINFO #language en-US "FileInfo,"%s","%Ld","%Ld","%s%s%s%s%s","%02d:%02d:%02d","%02d.%02d.%04d","%02d:%02d:%02d","%02d.%02d.%04d","%02d:%02d:%02d","%02d.%02d.%04d"\r\n" + +#string STR_VOL_VOLINFO #language en-US "Volume %s (%s)\r\n" + "%Ld bytes total disk space\r\n" + "%Ld bytes available on disk\r\n" + "%d bytes in each allocation unit\r\n" + +#string STR_RM_LOG_DELETE_CONF #language en-US "Remove Subtree '%B%s%N' [y/n]?" +#string STR_RM_LOG_DELETE #language en-US "Deleting '%B%s%N'\r\n" +#string STR_RM_LOG_DELETE_ERR #language en-US "Delete error: %r\r\n" +#string STR_RM_LOG_DELETE_ERR2 #language en-US "Delete error. Couldn't open file: %r\r\n" +#string STR_RM_LOG_DELETE_ERR3 #language en-US "Delete error. Invalid target '%B%s%N'\r\n" +#string STR_RM_LOG_DELETE_COMP #language en-US "Delete successful.\r\n" +#string STR_RM_LOG_DETELE_RO #language en-US "%H%s%N: '%H%s%N' is read-only\r\n" + +#string STR_MV_OUTPUT #language en-US "Moving %s -> %s\r\n" +#string STR_MV_INV_SUB #language en-US "Cannot move a directory into itself or its subdirectory.\r\n" +#string STR_MV_INV_RO #language en-US "Cannot move to or from a read-only file or directory '%B%s%N'\r\n" +#string STR_MV_INV_CWD #language en-US "Cannot move current working directory or its subdirectory.\r\n" + +#string STR_CP_OUTPUT #language en-US "Copying %s -> %s\r\n" +#string STR_CP_ERROR #language en-US "%H%s%N: Could not copy - '%H%s%N'\r\n" +#string STR_CP_DIR_REQ #language en-US "%H%s%N: Copying a directory requires -r.\r\n" +#string STR_CP_DIR_WNF #language en-US "%H%s%N: The specified path does not exist - '%H%s%N'\r\n" +#string STR_CP_SD_SAME #language en-US "%H%s%N: The source and destination are the same.\r\n" +#string STR_CP_SD_PARENT #language en-US "%H%s%N: The destination is a parent of the source.\r\n" +#string STR_CP_DEST_ERROR #language en-US "%H%s%N: The destination is read-only.\r\n" +#string STR_CP_DEST_OPEN_FAIL #language en-US "%H%s%N: The destination file '%B%s%N' failed to open with create.\r\n" +#string STR_CP_DEST_DIR_FAIL #language en-US "%H%s%N: The destination directory '%B%s%N' could not be created.\r\n" +#string STR_CP_SRC_OPEN_FAIL #language en-US "%H%s%N: The source file '%B%s%N' failed to open with read.\r\n" + +#string STR_GET_HELP_ATTRIB #language en-US "" +".TH attrib 0 "Displays or modifies the attributes of files or directories."\r\n" +".SH NAME\r\n" +"Displays or modifies the attributes of files or directories.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"ATTRIB [+a|-a] [+s|-s] [+h|-h] [+r|-r] [file...] [directory...]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" +a|-a - Sets or clears the 'archive' attribute.\r\n" +" +s|-s - Sets or clears the 'system' attribute.\r\n" +" +h|-h - Sets or clears the 'hidden' attribute.\r\n" +" +r|-r - Sets or clears the 'read-only' attribute.\r\n" +" file - Specifies the file name (wild cards are permitted).\r\n" +" directory - Specifies the directory name (wildcards are permitted).\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. Four attribute types are supported in the UEFI file system:\r\n" +" - Archive [A]\r\n" +" - System [S]\r\n" +" - Hidden [H]\r\n" +" - Read only [R]\r\n" +" 2. If a file (in general meaning) is a directory, then it is also shown\r\n" +" to have the attribute [D].\r\n" +" 3. If any file in the file list that is specified \r\n" +" does not exist, attrib will continue processing the remaining files\r\n" +" while reporting the error.\r\n" +" 4. If no attributes parameters are specified, the current attributes of\r\n" +" the specified files or directories are displayed.\r\n" +" 5. If no files or directories are specified, the command applies to\r\n" +" all files and sub-directories within the current directory.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display the attributes of a directory:\r\n" +" fs0:\> attrib fs0:\ \r\n" +" \r\n" +" * To display the attributes of all files and sub-directories in the current\r\n" +" directory:\r\n" +" fs0:\> attrib *\r\n" +" \r\n" +" * To add the system attribute to all files with extension '.efi':\r\n" +" fs0:\> attrib +s *.efi\r\n" +" \r\n" +" * To remove the read-only attribute from all files with extension '.inf':\r\n" +" fs0:\> attrib -r *.inf\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_NOT_FOUND The requested file was not found.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_WRITE_PROTECTED The media that the action was to take place on is\r\n" +" write-protected.\r\n" + +#string STR_GET_HELP_CD #language en-US "" +".TH cd 0 "Displays or changes the current directory."\r\n" +".SH NAME\r\n" +"Displays or changes the current directory.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"CD [path]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" path - Specifies the relative or absolute directory path.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command changes the current working directory that is used by the\r\n" +" UEFI Shell environment. If a file system mapping is specified, then the\r\n" +" current working directory is changed for that device. Otherwise, the\r\n" +" current working directory is changed for the current device.\r\n" +" 2. If path is not present, then the current working directory (including\r\n" +" file system mapping) is displayed to standard out.\r\n" +" 3. The table below describes the conventions that are used to refer to the\r\n" +" directory, its parent, and the root directory in the UEFI Shell\r\n" +" environment.\r\n" +" Convention Description\r\n" +" '.' Refers to the current directory.\r\n" +" '..' Refers to the directory's parent.\r\n" +" '\\\' Refers to the root of the current file system.\r\n" +" 4. The current working directory is maintained in the environment\r\n" +" variable %cwd%.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To change the current file system to the mapped fs0 file system:\r\n" +" Shell> fs0:\r\n" +" \r\n" +" * To change the current directory to subdirectory 'efi':\r\n" +" fs0:\> cd efi\r\n" +" \r\n" +" * To change the current directory to the parent directory (fs0:\):\r\n" +" fs0:\efi\> cd ..\r\n" +" \r\n" +" * To change the current directory to 'fs0:\efi\Tools':\r\n" +" fs0:\> cd efi\Tools\r\n" +" \r\n" +" * To change the current directory to the root of the current fs (fs0):\r\n" +" fs0:\efi\Tools\> cd \ \r\n" +" \r\n" +" * To move between volumes and maintain the current path, and then copy\r\n" +" all of files in fs0:\efi\Tools into the fs1:\Tmp directory:\r\n" +" fs0:\> cd \efi\Tools\r\n" +" fs0:\efi\Tools\> fs1:\r\n" +" fs1:\> cd Tmp\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" + +#string STR_GET_HELP_CP #language en-US "" +".TH cp 0 "Copies files or directories."\r\n" +".SH NAME\r\n" +"Copies one or more files or directories to another location.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"CP [-r] [-q] src [src...] [dst]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -r - Makes a recursive copy.\r\n" +" -q - Makes a quiet copy (without a prompt).\r\n" +" src - Specifies a source file/directory name (wildcards are permitted).\r\n" +" dst - Specifies a destination file/directory name (wildcards are not permitted). \r\n" +" If more than one directory is specified, the last directory is\r\n" +" assumed to be the destination.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. '-r' must be specified if src is a directory. If '-r' is specified,\r\n" +" the source directory is recursively copied to the destination.\r\n" +" 'src' itself is copied.\r\n" +" 2. If a destination is not specified, the current working directory is\r\n" +" assumed to be the destination.\r\n" +" 3. 'CP -r src1 src2 dst' copies all files and subdirectories in 'src1' and\r\n" +" 'src2' to the destination 'dst'. 'src1' and 'src2' themselves are also\r\n" +" copied. The 'dst' parameter is interpreted as a directory.\r\n" +" 4. Copying a directory or file to itself is not allowed.\r\n" +" 5. If an error occurs, this command exits immediately and the remaining files or\r\n" +" directories are not copied.\r\n" +" 6. When 'cp' is executed with a script file, it always performs quiet\r\n" +" copying, regardless of whether the '-q' option is specified.\r\n" +" 7. If you are copying multiple files, the destination must be an existing\r\n" +" directory.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display the contents of the current directory:\r\n" +" fs0:\> ls\r\n" +" \r\n" +" * To copy a file in the same directory and change the file name:\r\n" +" fs0:\> cp temp.txt readme.txt\r\n" +" \r\n" +" * To copy multiple files to another directory:\r\n" +" fs0:\> cp temp.txt isaBus.efi \Test\r\n" +" \r\n" +" * To copy multiple directories recursively to another directory:\r\n" +" fs0:\> cp -r test1 test2 boot \Test\r\n" +" \r\n" +" * To see the results of the above operations:\r\n" +" fs0:\> ls \Test\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly \r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_OUT_OF_RESOURCES There was insufficient space to save the \r\n" +" requested file at the destination.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security \r\n" +" violation.\r\n" +" SHELL_WRITE_PROTECTED An attempt was made to create a file on media that\r\n" +" was write-protected.\r\n" + +#string STR_GET_HELP_MAP #language en-US "" +".TH map 0 "Displays or defines file system mappings"\r\n" +".SH NAME\r\n" +"Displays or defines file system mappings.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"MAP [-d <sname>]\r\n" +"MAP [[-r][-v][-c][-f][-u][-t <type[,type...]>][sname]]\r\n" +"MAP [sname handle | mapping]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -d - Deletes a file system mapping.\r\n" +" -r - Resets file system mappings to default values.\r\n" +" -u - Adds file system mappings for newly-installed devices and\r\n" +" removes mappings for uninstalled devices. This does not change\r\n" +" the mappings of existing devices and preserves user-defined mappings.\r\n" +" -v - Displays verbose information about all file system mappings.\r\n" +" -c - Displays the consistent mappings.\r\n" +" -f - Displays the normal mappings (not the consistent mappings).\r\n" +" -t - Displays the device mappings, filtered according to the device type.\r\n" +" Supported types are:\r\n" +" fp - Floppy\r\n" +" hd - Hard Disk\r\n" +" cd - CD-ROM\r\n" +" Types can be combined by putting a comma between two types. Spaces\r\n" +" are not allowed between types.\r\n" +" -sfo - Displays information in Standard-Format Output.\r\n" +" sname - Specifies a mapping name.\r\n" +" handle - Specifies the number of a handle. Use the same value that is\r\n" +" displayed by the 'dh' command.\r\n" +" mapping - Specifies a new mapping name to assign to a device.\r\n" +" This value must end with a ':'.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command creates a mapping between a user-defined name and a device.\r\n" +" The most common use of this command is to create a mapped name for\r\n" +" devices that support a file system protocol. After these mappings are\r\n" +" created, the names can be used with all the file manipulation commands.\r\n" +" 2. The UEFI Shell environment creates default mappings for all of the\r\n" +" devices that support a recognized file system.\r\n" +" 3. This command can be used to create additional mappings, or \r\n" +" when used with the -d option, to delete an existing mapping. If it is\r\n" +" used without any parameters, all of the current mappings are listed.\r\n" +" If the -v option is used, the mappings are shown with additional\r\n" +" information about each device.\r\n" +" 4. The -r option is used to reset all the default mappings in a system,\r\n" +" which is useful if the system configuration has changed since the\r\n" +" last boot.\r\n" +" 5. The -u option adds mappings for newly-installed devices and removes\r\n" +" mappings for uninstalled devices without changing the mappings of\r\n" +" existing devices. User-defined mappings are also preserved. A mapping\r\n" +" history is saved, which preserves the original mapping name for\r\n" +" a device with a specific device path. The current directory is also\r\n" +" preserved if the current device is not changed.\r\n" +" 6. Each device in the system has a consistent mapping. If the hardware\r\n" +" configuration has not changed, the device's consistent mappings do not\r\n" +" change. If two or more machines have the same hardware configurations,\r\n" +" the device's consistent mapping remains the same. Use the -c option to\r\n" +" list all the consistent mappings in the system.\r\n" +" 7. The mapping value must consist of digits and characters. Other\r\n" +" characters are illegal.\r\n" +" 8. This command support wildcards. You can use the wildcards to delete\r\n" +" or show the mapping. However, when you assign the mapping, wildcards\r\n" +" are forbidden.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display verbose mapping table information:\r\n" +" Shell> map -v\r\n" +" \r\n" +" * To assign a different name to fs0:\r\n" +" Shell> map floppy fs0:\r\n" +" \r\n" +" * To operate with the mapped name:\r\n" +" Shell> floppy:\r\n" +" \r\n" +" * To delete a mapped name:\r\n" +" Shell> map -d floppy:\r\n" +" \r\n" +" * To display all the mapped names starting with 'f': \r\n" +" Shell> map f* \r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" + +#string STR_GET_HELP_MKDIR #language en-US "" +".TH mkdir 0 "Creates directories."\r\n" +".SH NAME\r\n" +"Creates one or more new directories.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"MKDIR dir [dir...]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" dir - Specifies the name of a directory or directories to create.\r\n" +" (Wildcards are not allowed)\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. Mkdir can create one or more new directories.\r\n" +" 2. If dir includes nested directories, then parent directories will be\r\n" +" created before child directories.\r\n" +" 3. If the directory already exists, mkdir will exit with an error.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To create a new directory:\r\n" +" fs0:\> mkdir rafter\r\n" +" \r\n" +" * To create multiple directories:\r\n" +" fs0:\> mkdir temp1 temp2\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly \r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_OUT_OF_RESOURCES There was insufficient space on the destination \r\n" +" to create the requested directory.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security \r\n" +" violation.\r\n" +" SHELL_WRITE_PROTECTED An attempt was made to create a directory when the\r\n" +" target media was write-protected.\r\n" + +#string STR_GET_HELP_MV #language en-US "" +".TH mv 0 "Moves files."\r\n" +".SH NAME\r\n" +"Moves one or more files to a destination within or between file systems.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"MV src [src...] [dst]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" src - Specifies a source file/directory name (wildcards are permitted).\r\n" +" dst - Specifies a destination file/directory name (wildcards are permitted).\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command moves one or more files to a destination within or between\r\n" +" file systems.\r\n" +" 2. If the destination is an existing directory, the sources are moved\r\n" +" into that directory. You cannot move the sources to a non-existing\r\n" +" directory.\r\n" +" 3. If a destination is not specified, the current directory is assumed to be\r\n" +" the destination. If there is more than one argument on the command line,\r\n" +" the last one is assumed to be the destination.\r\n" +" 4. Attempting to move a read-only file/directory results in an error.\r\n" +" Moving a directory that contains read-only files is allowed.\r\n" +" 5. You cannot move a directory into itself or its subdirectories.\r\n" +" 6. You cannot move a directory if the current working directory is itself or\r\n" +" its subdirectories.\r\n" +" 7. If an error occurs, the remaining files or directories are still be\r\n" +" moved.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To rename a file:\r\n" +" fs0:\> mv IsaBus.efi Bus.efi\r\n" +" \r\n" +" * To move a directory to the current directory:\r\n" +" fs0:\> mkdir Test1\Temp\r\n" +" fs0:\> mv Test1\Temp\r\n" +" \r\n" +" * To rename a directory:\r\n" +" fs0:\> mv efi efi1.1\r\n" +" \r\n" +" * To move multiple directories at a time:\r\n" +" fs0:\> mv Test1 Test2 Test\r\n" +" \r\n" +" * To attempt moving a read-only directory, which results in a failure:\r\n" +" fs0:\Test> attrib +r Temp1\r\n" +" DA R fs0:\Test\Temp1\r\n" +" fs0:\Test> mv Temp1 Temp2\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_NOT_FOUND The source file was not able to be found.\r\n" +" SHELL_OUT_OF_RESOURCES There was insufficient free space to move the\r\n" +" requested file to its destination.\r\n" +" SHELL_WRITE_PROTECTED An attempt was made to create a file on media that\r\n" +" was write-protected.\r\n" + +#string STR_GET_HELP_PARSE #language en-US "" +".TH parse 0 "Parses standard format output files."\r\n" +".SH NAME\r\n" +"Retrieves a value from a standard format output file.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"PARSE filename tablename column [-i <Instance>] [-s <Instance>]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" filename - Specifies a source file name.\r\n" +" tablename - Specifies the name of the table to be parsed.\r\n" +" column - Specifies the one-based column index to use to determine which value\r\n" +" from a particular record to parse.\r\n" +" -i <Instance> - Specifies an instance number to use to start parsing the ShellCommand table,\r\n" +" and then the specified tablename. If not specified, all instances are returned.\r\n" +" -s <Instance> - Specifies an instance number to use to start parsing the ShellCommand\r\n" +" table. If not present, then 1 is assumed.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command enables you to parse data from a file that has been output\r\n" +" using the -sfo parameter.\r\n" +" 2. Since the standard formatted output has a well known means of parsing,\r\n" +" this command is intended to provide an easy way of enabling\r\n" +" scripts to consume retrieved data from such constructed output files, and\r\n" +" use it in the logic of scripts written for the UEFI shell.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * The following data is contained in a temporary file (temp.txt):\r\n" +" ShellCommand,"ls"\r\n" +" VolumeInfo,"MikesVolume","400000000","FALSE","32000000","16000000"\r\n" +" FileInfo,"FS0:\efi\\boot\winloader.efi","45670","45900","arsh","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n" +" FileInfo,"FS0:\efi\\boot\mikesfile.txt","1250","1280","a","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n" +" FileInfo,"FS0:\efi\\boot\\readme.txt","795","900","a","08:30:12","01.08.2013","00:00:00","01.08.2013","08:30:12","01.08.2013"\r\n" +" \r\n" +" * To display VolumeInfo column 2 in temp.txt:\r\n" +" fs0:\> parse temp.txt VolumeInfo 2\r\n" +" MikesVolume\r\n" +" \r\n" +" * To display FileInfo column 3 in temp.txt, starting with instance 3:\r\n" +" fs0:\> parse temp.txt FileInfo 3 -i 3\r\n" +" 795\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_NOT_FOUND The source file was not able to be found.\r\n" + +#string STR_GET_HELP_RESET #language en-US "" +".TH reset 0 "Reset the system."\r\n" +".SH NAME\r\n" +"Resets the system.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"RESET [-w [string]]\r\n" +"RESET [-s [string]]\r\n" +"RESET [-c [string]]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -s - Performs a shutdown.\r\n" +" -w - Performs a warm boot.\r\n" +" -c - Performs a cold boot.\r\n" +" string - Describes a reason for the reset.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command resets the system.\r\n" +" 2. The default is to perform a cold reset unless the -w parameter is\r\n" +" specified.\r\n" +" 3. If a reset string is specified, it is passed into the Reset() \r\n" +" function, and the system records the reason for the system reset.\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_INVALID_PARAMETER One of the passed in parameters was incorrectly \r\n" +" formatted or its value was out of bounds.\r\n" + +#string STR_GET_HELP_RM #language en-US "" +".TH rm 0 "Deletes one or more files or directories."\r\n" +".SH NAME\r\n" +"Deletes one or more files or directories.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"RM [-q] file/directory [file/directory ...]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -q - Specifies quiet mode. Does not prompt for a confirmation.\r\n" +" file - Specifies a file name (wildcards are permitted).\r\n" +" directory - Specifies a directory name (wildcards are permitted).\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command deletes one or more files or directories.\r\n" +" 2. If the target is a directory, it deletes the directory, including all\r\n" +" its subdirectories.\r\n" +" 3. Redirecting a file whose parent directory (or the file\r\n" +" itself) is being deleted is not allowed.\r\n" +" 4. Removing a read-only file/directory results in a failure.\r\n" +" 5. Removing a directory containing read-only file(s) results in\r\n" +" a failure. If an error occurs, the command exits immediately and stops\r\n" +" removing files/directories.\r\n" +" 6. You cannot remove a directory when the current directory is itself or its\r\n" +" subdirectory. If a file contains wildcards, you are not prompted for\r\n" +" confirmation.\r\n" +" 7. The root directory cannot be removed.\r\n" +" 8. The current directory or its ancestor directories cannot be removed.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To remove multiple directories at a time:\r\n" +" fs0:\> rm Test\Temp1 Temp2\r\n" +" \r\n" +" * To remove multiple directories with wildcards:\r\n" +" fs0:\> rm Test\Temp*\r\n" +" \r\n" +" * To attempt removing a directory that contains a read-only file,\r\n" +" which results in a failure:\r\n" +" fs0:\> attrib +r Test\Temp1\readme.txt\r\n" +" A R fs0:\Test\Temp1\readme.txt\r\n" +" fs0:\> rm Test\Temp1\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_NOT_FOUND The source file was not able to be found.\r\n" +" SHELL_WRITE_PROTECTED The target was write protected.\r\n" + +#string STR_GET_HELP_SET #language en-US "" +".TH set 0 "Displays or modifies UEFI Shell environment variables."\r\n" +".SH NAME\r\n" +"Displays or modifies UEFI Shell environment variables.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"SET [-v] [sname [value]]\r\n" +"SET [-d <sname>]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -d - Deletes the environment variable.\r\n" +" -v - Displays or modifies a volatile variable.\r\n" +" sname - Specifies an environment variable name.\r\n" +" value - Specifies an environment variable value.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command is used to maintain the UEFI Shell environment variables.\r\n" +" This command can do the following:\r\n" +" - Display environment variables.\r\n" +" - Create new environment variables.\r\n" +" - Change the value of existing environment variables.\r\n" +" - Delete environment variables.\r\n" +" 2. This command sets an environment variable to a specified \r\n" +" value. You can use it to create a new environment\r\n" +" variable or to modify an existing environment variable.\r\n" +" 3. If used without any parameters, all the environment variables\r\n" +" are displayed.\r\n" +" 4. If used with the -d option, the environment variable that\r\n" +" is specified by sname is deleted.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To add an environment variable:\r\n" +" Shell> set DiagnosticPath fs0:\efi\diag;fs1:\efi\diag\r\n" +" \r\n" +" * To display environment variables:\r\n" +" Shell> set\r\n" +" \r\n" +" * To delete an environment variable:\r\n" +" Shell> set -d diagnosticpath\r\n" +" \r\n" +" * To change an environment variable:\r\n" +" fs0:\> set src efi\r\n" +" fs0:\> set src efi1.1\r\n" +" \r\n" +" * To append an environment variable:\r\n" +" Shell> set path %path%;fs0:\efi\Tools;fs0:\efi\boot;fs0:\\r\n" +" \r\n" +" * To set a volatile variable that will disappear at the next boot:\r\n" +" Shell> set -v EFI_SOURCE c:\project\EFI1.1\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_OUT_OF_RESOURCES A request to set a variable in a non-volatile \r\n" +" fashion could not be completed. The resulting \r\n" +" non-volatile request has been converted into a \r\n" +" volatile request.\r\n" + +#string STR_GET_HELP_DATE #language en-US "" +".TH date 0 "Displays and sets the current date for the system."\r\n" +".SH NAME\r\n" +"Displays and sets the current date for the system.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"DATE [mm/dd/[yy]yy][-sfo]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -sfo - Displays information in Standard-Format Output.\r\n" +" mm - Specifies the month of the date to be set. (1-12)\r\n" +" dd - Specifies the day of the date to be set (1-31)\r\n" +" yy/yyyy - Specifies the year of the date to be set. If only two digits,\r\n" +" then enter 9x = 199x. Otherwise enter 20xx.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command displays and/or sets the current date for the system.\r\n" +" If no parameters are used, it shows the current date. If a valid month,\r\n" +" day, and year are specified, the system's date is updated.\r\n" +" The following rules apply:\r\n" +" - Except for numeric characters and /, all other characters in the\r\n" +" argument are invalid.\r\n" +" - The Shell reports an error if the number is in the wrong\r\n" +" month/date/year range.\r\n" +" - A space before or after the numeric character is not allowed. Inserting\r\n" +" a space into the number is invalid.\r\n" +" - Repeated zeros are allowed before the number. For example:\r\n" +" Shell > date 0000008/000004/000097\r\n" +" Shell > date\r\n" +" 08/04/2097\r\n" +" Shell >\r\n" +" - The year range must be greater than or equal to 1998.\r\n" +" - Two numeric characters indicate the year. Numbers below 98 are\r\n" +" regarded as 20xx, and numbers equal to or above 98 are regarded as\r\n" +" 19xx. 00 means 2000. For example:\r\n" +" Shell > date 8/4/97\r\n" +" Shell > date\r\n" +" 08/04/2097\r\n" +" Shell >\r\n" +" Shell > date 8/4/98\r\n" +" Shell > date\r\n" +" 08/04/1998\r\n" +" Shell >\r\n" +" 2. The range of valid years is from 1998-2099.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display the current date in the system:\r\n" +" fs0:\> date\r\n" +" \r\n" +" * To set the date with long year format:\r\n" +" fs0:\> date 01/01/2050\r\n" +" \r\n" +" * To set the date with short year format:\r\n" +" fs0:\> date 06/18/01\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_DEVICE_ERROR There was a hardware error preventing the\r\n" +" completion of this command.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" + +#string STR_GET_HELP_TIME #language en-US "" +".TH time 0 "Displays or sets the time for the system."\r\n" +".SH NAME\r\n" +"Displays or sets the current time for the system.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"TIME [hh:mm[:ss]] [-tz tz] [-d dl]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -d - Sets or displays a daylight savings time value.\r\n" +" -tz - Specifies a time zone adjustment, measured in minutes offset from UTC. Valid values\r\n" +" are between -1440 and 1440 or 2047. If not present or set to 2047,\r\n" +" time is interpreted as local time.\r\n" +" hh - Specifies a new hour (0-23) (required).\r\n" +" mm - Specifies a new minute (0-59) (required).\r\n" +" ss - Specifies a new second (0-59). If not specified, zero is used.\r\n" +" dl - Specifies a daylight saving time value to set.\r\n" +" 0 : Time is not affected.\r\n" +" 1 : Time is affected, and has not been adjusted for daylight\r\n" +" savings.\r\n" +" 3 : Time is affected, and has been adjusted for daylight savings.\r\n" +" All other values are invalid. If no value follows -d, the\r\n" +" current daylight savings time is displayed.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command displays or sets the current time for the system.\r\n" +" If no parameters are used, it shows the current time. If valid hours, \r\n" +" minutes, and seconds are provided, the system time is\r\n" +" updated. Note the following rules:\r\n" +" - Except for numeric characters and the : character, all other\r\n" +" characters in the argument are invalid.\r\n" +" - The Shell reports an error if the number is in the wrong \r\n" +" hour/minute/second range.\r\n" +" - Spaces before or after the numeric character and spaces inserted into\r\n" +" the number are not allowed.\r\n" +" - Repeated zeros are allowed before the number. For example:\r\n" +" Shell> time 00000017:000004:0000\r\n" +" Shell> time\r\n" +" 17:04:00 (UTC+08:00)\r\n" +" 2. The seconds parameter is optional. If none is specified, it is\r\n" +" set to zero.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display current system time:\r\n" +" fs0:\> time\r\n" +" \r\n" +" * To set the system time:\r\n" +" fs0:\> time 9:51:30\r\n" +" \r\n" +" * To display the system time, including daylight savings time:\r\n" +" fs0:\> time -d\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_DEVICE_ERROR There was a hardware error preventing the\r\n" +" completion of this command\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" + +#string STR_GET_HELP_TIMEZONE #language en-US "" +".TH timezone 0 "Displays or sets time zone information."\r\n" +".SH NAME\r\n" +"Displays or sets time zone information.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"TIMEZONE [-s hh:mm | -l] [-b] [-f]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -s - Sets the time zone associated with hh:mm offset from UTC.\r\n" +" -l - Displays a list of all time zones.\r\n" +" -b - Displays one screen at a time.\r\n" +" -f - Displays full information for the specified time zone.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command displays and sets the current time zone for the system.\r\n" +" 2. If no parameters are used, it shows the current time zone.\r\n" +" 3. If a valid hh:mm parameter is provided, the time zone\r\n" +" information is updated.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display all available time zones:\r\n" +" Shell> timezone -l\r\n" +" \r\n" +" * To set the time zone:\r\n" +" Shell> timezone -s -7:00\r\n" +" \r\n" +" * To display detailed information for the current time zone:\r\n" +" Shell> timezone -f\r\n" + +#string STR_GET_HELP_LS #language en-US "" +".TH ls 0 "Lists the contents of a directory or file information."\r\n" +".SH NAME\r\n" +"Lists the contents of a directory or file information.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"LS [-r] [-a[attrib]][-sfo][file]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -r - Displays recursively (including subdirectories).\r\n" +" -a - Displays files with a specified attribute. If \r\n" +" attribute is not specified, all files are listed. If -a is not\r\n" +" specified, all non-system and non-hidden files are listed.\r\n" +" -sfo - Displays information in Standard-Format Output.\r\n" +" attrib - Specifies a file attribute list value:\r\n" +" a - Archive\r\n" +" s - System\r\n" +" h - Hidden\r\n" +" r - Read-only\r\n" +" d - Directory\r\n" +" file - Specifies a name of a file or directory (wildcards are permitted).\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command lists directory contents or file information. If no file\r\n" +" name or directory name is specified, the current working directory\r\n" +" is assumed.\r\n" +" 2. The contents of a directory are listed if all of the following are true:\r\n" +" - If option -r is not specified.\r\n" +" - If no wildcard characters are specified in the file parameter.\r\n" +" - If the file specified represents an existing directory.\r\n" +" 3. In all other cases, the command functions as follows:\r\n" +" - All files/directories that match the specified name are displayed.\r\n" +" - The -r flag determines whether a recursive search is performed.\r\n" +" - The option flag -a[attrib] only displays those\r\n" +" files with the attributes that are specified.\r\n" +" - If more than one attribute is specified, only the files that have all\r\n" +" those attributes are listed.\r\n" +" - If -a is followed by nothing, then all files/directories are\r\n" +" displayed, regardless of their attributes.\r\n" +" - If -a itself is not specified, then all files except system and\r\n" +" hidden files are displayed.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To hide files by adding the hidden or system attribute to them:\r\n" +" fs0:\> attrib +s +h *.efi\r\n" +" \r\n" +" * To display all, except the files/directories with 'h' or 's' attribute:\r\n" +" fs0:\> ls\r\n" +" \r\n" +" * To display files with all attributes in the current directory:\r\n" +" fs0:\> ls -a\r\n" +" \r\n" +" * To display files with read-only attributes in the current directory:\r\n" +" fs0:\> ls -ar\r\n" +" \r\n" +" * To display the files with attribute of 's':\r\n" +" fs0:\> ls -as isabus.efi\r\n" +" \r\n" +" * To display all in fs0:\efi directory recursively:\r\n" +" fs0:\> ls -r -a efi\r\n" +" \r\n" +" * To display files with a specified type in the current directory: \r\n" +" recursively:\r\n" +" fs0:\> ls -r -a *.efi -b\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_NOT_FOUND The requested file or directory was not found.\r\n" + +#string STR_GET_HELP_LOAD #language en-US "" +".TH load 0 "Loads a UEFI driver into memory."\r\n" +".SH NAME\r\n" +"Loads a UEFI driver into memory.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"LOAD [-nc] file [file...]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -nc - Loads the driver, but does not connect the driver.\r\n" +" File - Specifies a file that contains the image of the UEFI driver (wildcards are\r\n" +" permitted).\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. This command loads a driver into memory. It can load multiple files at\r\n" +" one time. The file name supports wildcards.\r\n" +" 2. If the -nc flag is not specified, this command attempts to connect the\r\n" +" driver to a proper device. It might also cause previously loaded drivers\r\n" +" to be connected to their corresponding devices.\r\n" +" 3. Use the 'UNLOAD' command to unload a driver.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To load a driver:\r\n" +" fs0:\> load Isabus.efi\r\n" +" \r\n" +" * To load multiple drivers:\r\n" +" fs0:\> load Isabus.efi IsaSerial.efi\r\n" +" \r\n" +" * To load multiple drivers using file name wildcards:\r\n" +" fs0:\> load Isa*.efi\r\n" +" \r\n" +" * To load a driver without connecting it to a device:\r\n" +" fs0:\> load -nc IsaBus.efi\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_NOT_FOUND The requested file was not found.\r\n" + +#string STR_GET_HELP_VOL #language en-US "" +".TH vol 0 "Displays or modifies information about a disk volume."\r\n" +".SH NAME\r\n" +"Displays or modifies information about a disk volume.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"VOL [fs] [-n <VolumeLabel>]\r\n" +"VOL [fs] [-d]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -n - Displays or modifies a new volume label.\r\n" +" -d - Displays or modifies an empty volume label.\r\n" +" fs - Specifies the name of the file system.\r\n" +" VolumeLabel - Specifies a volume label.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. The following characters cannot be used in a volume label:\r\n" +" % ^ * + = [ ] | : ; \" < > ? / . \r\n" +" 2. No spaces are allowed in a volume label.\r\n" +" 3. This command displays the volume information for the specified file\r\n" +" system. If fs is not specified, the current file system is used.\r\n" +" 4. If -n is specified, the volume label for fs is set to\r\n" +" VolumeLabel.\r\n" +" 5. The maximum length for volume label is 11 characters.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To display the volume of the current file system:\r\n" +" fs0:\> vol\r\n" +" \r\n" +" * To change the label of fs0:\r\n" +" Shell> vol fs0 -n help_test\r\n" +" \r\n" +" * To delete the volume label of fs0:\r\n" +" fs0:\> vol fs0 -d\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n" +" violation.\r\n" +" SHELL_NOT_FOUND The target file-system was not found.\r\n" diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c index c4accca6cd..f18fdbe3e6 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c @@ -1,320 +1,320 @@ -/** @file
- Main file for vol shell level 2 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellLevel2CommandsLib.h"
-#include <Guid/FileSystemInfo.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-
-/**
- Print the info or change the volume info.
-
- @param[in] Path String with starting path.
- @param[in] Delete TRUE to delete the volume label. FALSE otherwise.
- @param[in] Name New name to set to the volume label.
-
- @retval SHELL_SUCCESS The operation was successful.
-**/
-SHELL_STATUS
-HandleVol (
- IN CONST CHAR16 *Path,
- IN CONST BOOLEAN Delete,
- IN CONST CHAR16 *Name OPTIONAL
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- EFI_FILE_SYSTEM_INFO *SysInfo;
- UINTN SysInfoSize;
- SHELL_FILE_HANDLE ShellFileHandle;
- EFI_FILE_PROTOCOL *EfiFpHandle;
- UINTN Size1;
- UINTN Size2;
-
- ShellStatus = SHELL_SUCCESS;
-
- if (
- (Name != NULL) && (
- (StrStr (Name, L"%") != NULL) ||
- (StrStr (Name, L"^") != NULL) ||
- (StrStr (Name, L"*") != NULL) ||
- (StrStr (Name, L"+") != NULL) ||
- (StrStr (Name, L"=") != NULL) ||
- (StrStr (Name, L"[") != NULL) ||
- (StrStr (Name, L"]") != NULL) ||
- (StrStr (Name, L"|") != NULL) ||
- (StrStr (Name, L":") != NULL) ||
- (StrStr (Name, L";") != NULL) ||
- (StrStr (Name, L"\"") != NULL) ||
- (StrStr (Name, L"<") != NULL) ||
- (StrStr (Name, L">") != NULL) ||
- (StrStr (Name, L"?") != NULL) ||
- (StrStr (Name, L"/") != NULL) ||
- (StrStr (Name, L" ") != NULL))
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"vol", Name);
- return (SHELL_INVALID_PARAMETER);
- }
-
- Status = gEfiShellProtocol->OpenFileByName (
- Path,
- &ShellFileHandle,
- Name != NULL ? EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE : EFI_FILE_MODE_READ
- );
-
- if (EFI_ERROR (Status) || (ShellFileHandle == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"vol", Path);
- return (SHELL_ACCESS_DENIED);
- }
-
- //
- // Get the Volume Info from ShellFileHandle
- //
- SysInfo = NULL;
- SysInfoSize = 0;
- EfiFpHandle = ConvertShellHandleToEfiFileProtocol (ShellFileHandle);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- SysInfo = AllocateZeroPool (SysInfoSize);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
- }
-
- ASSERT (SysInfo != NULL);
-
- if (Delete) {
- *((CHAR16 *)SysInfo->VolumeLabel) = CHAR_NULL;
- SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SysInfo->VolumeLabel);
- Status = EfiFpHandle->SetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- (UINTN)SysInfo->Size,
- SysInfo
- );
- } else if (Name != NULL) {
- Size1 = StrSize (Name);
- Size2 = StrSize (SysInfo->VolumeLabel);
- if (Size1 > Size2) {
- SysInfo = ReallocatePool ((UINTN)SysInfo->Size, (UINTN)SysInfo->Size + Size1 - Size2, SysInfo);
- if (SysInfo == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"vol");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- }
- }
-
- if (SysInfo != NULL) {
- StrCpyS (
- (CHAR16 *)SysInfo->VolumeLabel,
- (Size1 > Size2 ? Size1/sizeof (CHAR16) : Size2/sizeof (CHAR16)),
- Name
- );
- SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + Size1;
- Status = EfiFpHandle->SetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- (UINTN)SysInfo->Size,
- SysInfo
- );
- }
- }
-
- FreePool (SysInfo);
-
- if (Delete || (Name != NULL)) {
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"vol", Path);
- ShellStatus = SHELL_ACCESS_DENIED;
- }
- }
-
- SysInfoSize = 0;
- SysInfo = NULL;
-
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- SysInfo = AllocateZeroPool (SysInfoSize);
- Status = EfiFpHandle->GetInfo (
- EfiFpHandle,
- &gEfiFileSystemInfoGuid,
- &SysInfoSize,
- SysInfo
- );
- }
-
- gEfiShellProtocol->CloseFile (ShellFileHandle);
-
- ASSERT (SysInfo != NULL);
-
- if (SysInfo != NULL) {
- //
- // print VolumeInfo table
- //
- ShellPrintHiiEx (
- 0,
- gST->ConOut->Mode->CursorRow,
- NULL,
- STRING_TOKEN (STR_VOL_VOLINFO),
- gShellLevel2HiiHandle,
- SysInfo->VolumeLabel,
- SysInfo->ReadOnly ? L"r" : L"rw",
- SysInfo->VolumeSize,
- SysInfo->FreeSpace,
- SysInfo->BlockSize
- );
- SHELL_FREE_NON_NULL (SysInfo);
- }
-
- return (ShellStatus);
-}
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-d", TypeFlag },
- { L"-n", TypeValue },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'Vol' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunVol (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- CONST CHAR16 *PathName;
- CONST CHAR16 *CurDir;
- BOOLEAN DeleteMode;
- CHAR16 *FullPath;
- CHAR16 *TempSpot;
- UINTN Length;
- CONST CHAR16 *NewName;
-
- Length = 0;
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- PathName = NULL;
- CurDir = NULL;
- FullPath = NULL;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Fix local copies of the protocol pointers
- //
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"vol", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // check for "-?"
- //
- if (ShellCommandLineGetFlag (Package, L"-?")) {
- ASSERT (FALSE);
- }
-
- if (ShellCommandLineGetCount (Package) > 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"vol");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- PathName = ShellCommandLineGetRawValue (Package, 1);
- if (PathName == NULL) {
- CurDir = gEfiShellProtocol->GetCurDir (NULL);
- if (CurDir == NULL) {
- ShellStatus = SHELL_NOT_FOUND;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"vol");
- } else {
- PathName = CurDir;
- }
- }
-
- if (PathName != NULL) {
- TempSpot = StrStr (PathName, L":");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
-
- TempSpot = StrStr (PathName, L"\\");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
-
- StrnCatGrow (&FullPath, &Length, PathName, 0);
- StrnCatGrow (&FullPath, &Length, L":\\", 0);
- DeleteMode = ShellCommandLineGetFlag (Package, L"-d");
- NewName = ShellCommandLineGetValue (Package, L"-n");
- if (DeleteMode && ShellCommandLineGetFlag (Package, L"-n")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellLevel2HiiHandle, L"vol", L"-d", L"-n");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetFlag (Package, L"-n") && (NewName == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"vol", L"-n");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if ((NewName != NULL) && (StrLen (NewName) > 11)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"vol", NewName, L"-n");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = HandleVol (
- FullPath,
- DeleteMode,
- NewName
- );
- }
- }
- }
- }
-
- SHELL_FREE_NON_NULL (FullPath);
-
- //
- // free the command line package
- //
- ShellCommandLineFreeVarList (Package);
-
- return (ShellStatus);
-}
+/** @file + Main file for vol shell level 2 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellLevel2CommandsLib.h" +#include <Guid/FileSystemInfo.h> +#include <Guid/FileSystemVolumeLabelInfo.h> + +/** + Print the info or change the volume info. + + @param[in] Path String with starting path. + @param[in] Delete TRUE to delete the volume label. FALSE otherwise. + @param[in] Name New name to set to the volume label. + + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +HandleVol ( + IN CONST CHAR16 *Path, + IN CONST BOOLEAN Delete, + IN CONST CHAR16 *Name OPTIONAL + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + EFI_FILE_SYSTEM_INFO *SysInfo; + UINTN SysInfoSize; + SHELL_FILE_HANDLE ShellFileHandle; + EFI_FILE_PROTOCOL *EfiFpHandle; + UINTN Size1; + UINTN Size2; + + ShellStatus = SHELL_SUCCESS; + + if ( + (Name != NULL) && ( + (StrStr (Name, L"%") != NULL) || + (StrStr (Name, L"^") != NULL) || + (StrStr (Name, L"*") != NULL) || + (StrStr (Name, L"+") != NULL) || + (StrStr (Name, L"=") != NULL) || + (StrStr (Name, L"[") != NULL) || + (StrStr (Name, L"]") != NULL) || + (StrStr (Name, L"|") != NULL) || + (StrStr (Name, L":") != NULL) || + (StrStr (Name, L";") != NULL) || + (StrStr (Name, L"\"") != NULL) || + (StrStr (Name, L"<") != NULL) || + (StrStr (Name, L">") != NULL) || + (StrStr (Name, L"?") != NULL) || + (StrStr (Name, L"/") != NULL) || + (StrStr (Name, L" ") != NULL)) + ) + { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"vol", Name); + return (SHELL_INVALID_PARAMETER); + } + + Status = gEfiShellProtocol->OpenFileByName ( + Path, + &ShellFileHandle, + Name != NULL ? EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE : EFI_FILE_MODE_READ + ); + + if (EFI_ERROR (Status) || (ShellFileHandle == NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"vol", Path); + return (SHELL_ACCESS_DENIED); + } + + // + // Get the Volume Info from ShellFileHandle + // + SysInfo = NULL; + SysInfoSize = 0; + EfiFpHandle = ConvertShellHandleToEfiFileProtocol (ShellFileHandle); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + SysInfo = AllocateZeroPool (SysInfoSize); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + } + + ASSERT (SysInfo != NULL); + + if (Delete) { + *((CHAR16 *)SysInfo->VolumeLabel) = CHAR_NULL; + SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SysInfo->VolumeLabel); + Status = EfiFpHandle->SetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + (UINTN)SysInfo->Size, + SysInfo + ); + } else if (Name != NULL) { + Size1 = StrSize (Name); + Size2 = StrSize (SysInfo->VolumeLabel); + if (Size1 > Size2) { + SysInfo = ReallocatePool ((UINTN)SysInfo->Size, (UINTN)SysInfo->Size + Size1 - Size2, SysInfo); + if (SysInfo == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"vol"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + } + } + + if (SysInfo != NULL) { + StrCpyS ( + (CHAR16 *)SysInfo->VolumeLabel, + (Size1 > Size2 ? Size1/sizeof (CHAR16) : Size2/sizeof (CHAR16)), + Name + ); + SysInfo->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + Size1; + Status = EfiFpHandle->SetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + (UINTN)SysInfo->Size, + SysInfo + ); + } + } + + FreePool (SysInfo); + + if (Delete || (Name != NULL)) { + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"vol", Path); + ShellStatus = SHELL_ACCESS_DENIED; + } + } + + SysInfoSize = 0; + SysInfo = NULL; + + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + SysInfo = AllocateZeroPool (SysInfoSize); + Status = EfiFpHandle->GetInfo ( + EfiFpHandle, + &gEfiFileSystemInfoGuid, + &SysInfoSize, + SysInfo + ); + } + + gEfiShellProtocol->CloseFile (ShellFileHandle); + + ASSERT (SysInfo != NULL); + + if (SysInfo != NULL) { + // + // print VolumeInfo table + // + ShellPrintHiiEx ( + 0, + gST->ConOut->Mode->CursorRow, + NULL, + STRING_TOKEN (STR_VOL_VOLINFO), + gShellLevel2HiiHandle, + SysInfo->VolumeLabel, + SysInfo->ReadOnly ? L"r" : L"rw", + SysInfo->VolumeSize, + SysInfo->FreeSpace, + SysInfo->BlockSize + ); + SHELL_FREE_NON_NULL (SysInfo); + } + + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-d", TypeFlag }, + { L"-n", TypeValue }, + { NULL, TypeMax } +}; + +/** + Function for 'Vol' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunVol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *PathName; + CONST CHAR16 *CurDir; + BOOLEAN DeleteMode; + CHAR16 *FullPath; + CHAR16 *TempSpot; + UINTN Length; + CONST CHAR16 *NewName; + + Length = 0; + ProblemParam = NULL; + ShellStatus = SHELL_SUCCESS; + PathName = NULL; + CurDir = NULL; + FullPath = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // Fix local copies of the protocol pointers + // + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"vol", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // check for "-?" + // + if (ShellCommandLineGetFlag (Package, L"-?")) { + ASSERT (FALSE); + } + + if (ShellCommandLineGetCount (Package) > 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"vol"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + PathName = ShellCommandLineGetRawValue (Package, 1); + if (PathName == NULL) { + CurDir = gEfiShellProtocol->GetCurDir (NULL); + if (CurDir == NULL) { + ShellStatus = SHELL_NOT_FOUND; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"vol"); + } else { + PathName = CurDir; + } + } + + if (PathName != NULL) { + TempSpot = StrStr (PathName, L":"); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + + TempSpot = StrStr (PathName, L"\\"); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + + StrnCatGrow (&FullPath, &Length, PathName, 0); + StrnCatGrow (&FullPath, &Length, L":\\", 0); + DeleteMode = ShellCommandLineGetFlag (Package, L"-d"); + NewName = ShellCommandLineGetValue (Package, L"-n"); + if (DeleteMode && ShellCommandLineGetFlag (Package, L"-n")) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellLevel2HiiHandle, L"vol", L"-d", L"-n"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag (Package, L"-n") && (NewName == NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"vol", L"-n"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((NewName != NULL) && (StrLen (NewName) > 11)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"vol", NewName, L"-n"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = HandleVol ( + FullPath, + DeleteMode, + NewName + ); + } + } + } + } + + SHELL_FREE_NON_NULL (FullPath); + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} |
