summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Library/UefiShellLib/UefiShellLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellLib/UefiShellLib.c')
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.c117
1 files changed, 116 insertions, 1 deletions
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index f04adbb63f..580a1ee612 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -2,7 +2,7 @@
Provides interface to shell functionality for shell commands and applications.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
- Copyright 2016 Dell Inc.
+ Copyright 2016-2018 Dell Technologies.<BR>
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -37,6 +37,121 @@ FILE_HANDLE_FUNCTION_MAP FileFunctionMap;
EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollationProtocol;
/**
+ Return a clean, fully-qualified version of an input path. If the return value
+ is non-NULL the caller must free the memory when it is no longer needed.
+
+ If asserts are disabled, and if the input parameter is NULL, NULL is returned.
+
+ If there is not enough memory available to create the fully-qualified path or
+ a copy of the input path, NULL is returned.
+
+ If there is no working directory, a clean copy of Path is returned.
+
+ Otherwise, the current file system or working directory (as appropriate) is
+ prepended to Path and the resulting path is cleaned and returned.
+
+ NOTE: If the input path is an empty string, then the current working directory
+ (if it exists) is returned. In other words, an empty input path is treated
+ exactly the same as ".".
+
+ @param[in] Path A pointer to some file or directory path.
+
+ @retval NULL The input path is NULL or out of memory.
+
+ @retval non-NULL A pointer to a clean, fully-qualified version of Path.
+ If there is no working directory, then a pointer to a
+ clean, but not necessarily fully-qualified version of
+ Path. The caller must free this memory when it is no
+ longer needed.
+**/
+CHAR16*
+EFIAPI
+FullyQualifyPath(
+ IN CONST CHAR16 *Path
+ )
+{
+ CONST CHAR16 *WorkingPath;
+ CONST CHAR16 *InputPath;
+ CHAR16 *InputFileSystem;
+ UINTN FileSystemCharCount;
+ CHAR16 *FullyQualifiedPath;
+ UINTN Size;
+
+ FullyQualifiedPath = NULL;
+
+ ASSERT(Path != NULL);
+ //
+ // Handle erroneous input when asserts are disabled.
+ //
+ if (Path == NULL) {
+ return NULL;
+ }
+ //
+ // In paths that contain ":", like fs0:dir/file.ext and fs2:\fqpath\file.ext,
+ // we have to consider the file system part separately from the "path" part.
+ // If there is a file system in the path, we have to get the current working
+ // directory for that file system. Then we need to use the part of the path
+ // following the ":". If a path does not contain ":", we use it as given.
+ //
+ InputPath = StrStr(Path, L":");
+ if (InputPath != NULL) {
+ InputPath++;
+ FileSystemCharCount = ((UINTN)InputPath - (UINTN)Path + sizeof(CHAR16)) / sizeof(CHAR16);
+ InputFileSystem = AllocateCopyPool(FileSystemCharCount * sizeof(CHAR16), Path);
+ if (InputFileSystem != NULL) {
+ InputFileSystem[FileSystemCharCount - 1] = CHAR_NULL;
+ }
+ WorkingPath = ShellGetCurrentDir(InputFileSystem);
+ SHELL_FREE_NON_NULL(InputFileSystem);
+ } else {
+ InputPath = Path;
+ WorkingPath = ShellGetEnvironmentVariable(L"cwd");
+ }
+
+ if (WorkingPath == NULL) {
+ //
+ // With no working directory, all we can do is copy and clean the input path.
+ //
+ FullyQualifiedPath = AllocateCopyPool(StrSize(Path), Path);
+ } else {
+ //
+ // Allocate space for both strings plus one more character.
+ //
+ Size = StrSize(WorkingPath) + StrSize(InputPath);
+ FullyQualifiedPath = AllocateZeroPool(Size);
+ if (FullyQualifiedPath == NULL) {
+ //
+ // Try to copy and clean just the input. No harm if not enough memory.
+ //
+ FullyQualifiedPath = AllocateCopyPool(StrSize(Path), Path);
+ } else {
+ if (*InputPath == L'\\' || *InputPath == L'/') {
+ //
+ // Absolute path: start with the current working directory, then
+ // truncate the new path after the file system part.
+ //
+ StrCpyS(FullyQualifiedPath, Size/sizeof(CHAR16), WorkingPath);
+ *(StrStr(FullyQualifiedPath, L":") + 1) = CHAR_NULL;
+ } else {
+ //
+ // Relative path: start with the working directory and append "\".
+ //
+ StrCpyS(FullyQualifiedPath, Size/sizeof(CHAR16), WorkingPath);
+ StrCatS(FullyQualifiedPath, Size/sizeof(CHAR16), L"\\");
+ }
+ //
+ // Now append the absolute or relative path.
+ //
+ StrCatS(FullyQualifiedPath, Size/sizeof(CHAR16), InputPath);
+ }
+ }
+
+ PathCleanUpDirectories(FullyQualifiedPath);
+
+ return FullyQualifiedPath;
+}
+
+/**
Check if a Unicode character is a hexadecimal character.
This internal function checks if a Unicode character is a