summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellLevel2CommandsLib
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /ShellPkg/Library/UefiShellLevel2CommandsLib
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'ShellPkg/Library/UefiShellLevel2CommandsLib')
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Attrib.c570
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c690
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c1598
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c578
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c1880
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c2742
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/MkDir.c340
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c1782
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c656
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c356
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c788
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Set.c336
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c2012
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c690
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h724
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf158
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni2156
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Vol.c640
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);
+}