* [PATCH 0/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
@ 2016-12-21 8:54 Ruiyu Ni
2016-12-21 8:55 ` [PATCH 1/2] MdePkg/BaseLib: Fix PathCleanUpDirectories to correctly handle "\.\" Ruiyu Ni
2016-12-21 8:55 ` [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
0 siblings, 2 replies; 6+ messages in thread
From: Ruiyu Ni @ 2016-12-21 8:54 UTC (permalink / raw)
To: edk2-devel
When "fs0:dir"(drive letter without slash) is used as destination
of "cd", "cd" tries to change to "dir" in root directory of "fs0:".
It's incorrect. The correct behavior is to change to "dir" in
current directory of "fs0:"
Ruiyu Ni (2):
MdePkg/BaseLib: Fix PathCleanUpDirectories to correctly handle "\.\"
ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
MdePkg/Library/BaseLib/FilePaths.c | 60 ++--
ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c | 415 +++++++++++++----------
2 files changed, 265 insertions(+), 210 deletions(-)
--
2.9.0.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] MdePkg/BaseLib: Fix PathCleanUpDirectories to correctly handle "\.\"
2016-12-21 8:54 [PATCH 0/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
@ 2016-12-21 8:55 ` Ruiyu Ni
2016-12-21 8:55 ` [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
1 sibling, 0 replies; 6+ messages in thread
From: Ruiyu Ni @ 2016-12-21 8:55 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Jaben Carsey
The old code incorrectly cleans path like "fs0:\abc\.\.." to
"fs0:\abc", instead of "fs0:\"
The patch fixes this bug.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jaben Carsey <jaben.carsey@intel.com>
---
MdePkg/Library/BaseLib/FilePaths.c | 60 ++++++++++++++++----------------------
1 file changed, 25 insertions(+), 35 deletions(-)
diff --git a/MdePkg/Library/BaseLib/FilePaths.c b/MdePkg/Library/BaseLib/FilePaths.c
index 29a84ea..203045c 100644
--- a/MdePkg/Library/BaseLib/FilePaths.c
+++ b/MdePkg/Library/BaseLib/FilePaths.c
@@ -68,61 +68,51 @@ CHAR16*
EFIAPI
PathCleanUpDirectories(
IN CHAR16 *Path
- )
+)
{
CHAR16 *TempString;
- UINTN TempSize;
- if (Path==NULL) {
- return(NULL);
+ if (Path == NULL) {
+ return NULL;
}
+
//
- // Fix up the '/' vs '\'
+ // Replace the '/' with '\'
//
- for (TempString = Path ; TempString != NULL && *TempString != CHAR_NULL ; TempString++) {
+ for (TempString = Path; *TempString != CHAR_NULL; TempString++) {
if (*TempString == L'/') {
*TempString = L'\\';
}
}
+
//
- // Fix up the ..
+ // Remove all the "\.". E.g.: fs0:\abc\.\def\.
//
- while ((TempString = StrStr(Path, L"\\..\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 4;
- PathRemoveLastItem(Path);
- TempSize = StrSize(TempString);
- CopyMem(Path+StrLen(Path), TempString, TempSize);
+ while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
+ CopyMem (TempString, TempString + 2, StrSize (TempString + 2));
}
- if ((TempString = StrStr(Path, L"\\..")) != NULL && *(TempString + 3) == CHAR_NULL) {
- *TempString = CHAR_NULL;
- if (!PathRemoveLastItem(Path)) {
- *TempString = L'\\';
- }
+ if (StrCmp (Path + StrLen (Path) - 2, L"\\.") == 0) {
+ Path[StrLen (Path) - 1] = CHAR_NULL;
}
+
//
- // Fix up the .
+ // Remove all the "\..". E.g.: fs0:\abc\..\def\..
//
- while ((TempString = StrStr(Path, L"\\.\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 2;
- TempSize = StrSize(TempString);
- CopyMem(Path+StrLen(Path), TempString, TempSize);
- }
- if ((TempString = StrStr(Path, L"\\.")) != NULL && *(TempString + 2) == CHAR_NULL) {
+ while (((TempString = StrStr(Path, L"\\..")) != NULL) &&
+ ((*(TempString + 3) == L'\\') || (*(TempString + 3) == CHAR_NULL))
+ ) {
*(TempString + 1) = CHAR_NULL;
+ PathRemoveLastItem(Path);
+ CopyMem (Path + StrLen (Path), TempString + 3, StrSize (TempString + 3));
}
- while ((TempString = StrStr(Path, L"\\\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 1;
- TempSize = StrSize(TempString);
- CopyMem(Path+StrLen(Path), TempString, TempSize);
- }
- if ((TempString = StrStr(Path, L"\\\\")) != NULL && *(TempString + 1) == CHAR_NULL) {
- *(TempString) = CHAR_NULL;
+ //
+ // Replace the "\\" with "\"
+ //
+ while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
+ CopyMem (TempString, TempString + 1, StrSize (TempString + 1));
}
- return (Path);
+ return Path;
}
--
2.9.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
2016-12-21 8:54 [PATCH 0/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
2016-12-21 8:55 ` [PATCH 1/2] MdePkg/BaseLib: Fix PathCleanUpDirectories to correctly handle "\.\" Ruiyu Ni
@ 2016-12-21 8:55 ` Ruiyu Ni
2016-12-21 16:23 ` Carsey, Jaben
1 sibling, 1 reply; 6+ messages in thread
From: Ruiyu Ni @ 2016-12-21 8:55 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Jaben Carsey
When "fs0:dir"(drive letter without slash) is used as destination
of "cd", "cd" tries to change to "dir" in root directory of "fs0:".
It's incorrect. The correct behavior is to change to "dir" in
current directory of "fs0:"
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Cc: Jaben Carsey <jaben.carsey@intel.com>
---
ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c | 415 +++++++++++++----------
1 file changed, 240 insertions(+), 175 deletions(-)
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
index 0967bc7..0b4becf 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
@@ -17,6 +17,156 @@
#include "UefiShellLevel2CommandsLib.h"
/**
+ Function will replace drive identifier with CWD.
+
+ If FullPath begining with ':' is invalid path, then ASSERT.
+ If FullPath not include dirve 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 - FullPath) != (UINTN)(Splitter2 - Cwd)) {
+ return FALSE;
+ } else {
+ if (StrniCmp(FullPath, Cwd, (UINTN)(Splitter1 - FullPath)) == NULL) {
+ 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).
@@ -31,23 +181,26 @@ ShellCommandRunCd (
{
EFI_STATUS Status;
LIST_ENTRY *Package;
- CONST CHAR16 *Directory;
- CHAR16 *Cwd;
+ CONST CHAR16 *Cwd;
CHAR16 *Path;
CHAR16 *Drive;
- UINTN CwdSize;
- UINTN DriveSize;
CHAR16 *ProblemParam;
SHELL_STATUS ShellStatus;
- SHELL_FILE_HANDLE Handle;
CONST CHAR16 *Param1;
CHAR16 *Param1Copy;
- CHAR16* Walker;
+ CHAR16 *Walker;
+ CHAR16 *Splitter;
+ CHAR16 *TempBuffer;
+ UINTN TotalSize;
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
- Drive = NULL;
- DriveSize = 0;
+ ProblemParam = NULL;
+ ShellStatus = SHELL_SUCCESS;
+ Cwd = NULL;
+ Path = NULL;
+ Drive = NULL;
+ Splitter = NULL;
+ TempBuffer = NULL;
+ TotalSize = 0;
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
@@ -87,194 +240,106 @@ ShellCommandRunCd (
// else If there are 2 value parameters, then print the error message
// else If there is 1 value paramerer , then change the directory
//
- Param1 = ShellCommandLineGetRawValue(Package, 1);
- if (Param1 == NULL) {
- //
- // display the current directory
- //
- Directory = ShellGetCurrentDir(NULL);
- if (Directory != NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT), gShellLevel2HiiHandle, Directory);
- } else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- }
+ Cwd = ShellGetCurrentDir (NULL);
+ if (Cwd == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
+ ShellStatus = SHELL_NOT_FOUND;
} 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]));
+ 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) {
- Param1Copy = PathCleanUpDirectories(Param1Copy);
- }
- if (Param1Copy != NULL) {
- if (StrCmp(Param1Copy, L".") == 0) {
- //
- // nothing to do... change to current directory
- //
- } else if (StrCmp(Param1Copy, L"..") == 0) {
+
+ if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) {
+ Status = ReplaceDriveWithCwd (&Param1Copy,Cwd);
+ if (!EFI_ERROR(Status)) {
+ Param1Copy = PathCleanUpDirectories(Param1Copy);
+ }
+ } else {
//
- // Change up one directory...
+ // Can't use cd command to change filesystem.
//
- Directory = ShellGetCurrentDir(NULL);
- if (Directory == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- CwdSize = StrSize(Directory) + sizeof(CHAR16);
- Cwd = AllocateZeroPool(CwdSize);
- if (Cwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
- StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
- Drive = GetFullyQualifiedPath (Cwd);
- PathRemoveLastItem (Drive);
- FreePool (Cwd);
- }
- }
- if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
+ 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'\\') {
//
- // change directory on current drive letter
+ // Absolute Path on current drive letter.
//
- Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
+ 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 (StrCmp(Param1Copy, L"\\") == 0) {
- //
- // Move to root of current drive
- //
- Directory = ShellGetCurrentDir(NULL);
- if (Directory == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
} else {
- CwdSize = StrSize(Directory) + sizeof(CHAR16);
- Cwd = AllocateZeroPool(CwdSize);
- if (Cwd == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
- StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
- Drive = GetFullyQualifiedPath (Cwd);
- while (PathRemoveLastItem (Drive)) {
- //
- // Check if Drive contains 'fsx:\' only or still points to a sub-directory.
- // Don't remove trailing '\' from Drive if it points to the root directory.
- //
- Path = StrStr (Drive, L":\\");
- if ((Path != NULL) && (*(Path + 2) == CHAR_NULL)) {
- break;
- }
+ 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 = PathCleanUpDirectories (TempBuffer);
}
- FreePool (Cwd);
}
}
- if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
- //
- // change directory on current drive letter
- //
- Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
- } else if (StrStr(Param1Copy, L":") == NULL) {
- //
- // change directory without a drive identifier
- //
- if (ShellGetCurrentDir(NULL) == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");
+ }
+
+ if (!EFI_ERROR(Status)) {
+ 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 {
- ASSERT((Drive == NULL && DriveSize == 0) || (Drive != NULL));
- Drive = StrnCatGrow(&Drive, &DriveSize, ShellGetCurrentDir(NULL), 0);
- Drive = StrnCatGrow(&Drive, &DriveSize, L"\\", 0);
- if (*Param1Copy == L'\\') {
- while (PathRemoveLastItem(Drive)) ;
- Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy+1, 0);
- } else {
- Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy, 0);
- }
- //
- // Verify that this is a valid directory
- //
- Status = gEfiShellProtocol->OpenFileByName(Drive, &Handle, EFI_FILE_MODE_READ);
+ Status = gEfiShellProtocol->SetCurDir(Drive, Path + 1);
if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Drive);
- ShellStatus = SHELL_NOT_FOUND;
- } else if (EFI_ERROR(FileHandleIsDirectory(Handle))) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Drive);
- ShellStatus = SHELL_NOT_FOUND;
- }
- if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
- //
- // change directory on current drive letter
- //
- Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
- if (Handle != NULL) {
- gEfiShellProtocol->CloseFile(Handle);
- DEBUG_CODE(Handle = NULL;);
- }
- }
- } else {
- //
- // change directory with a drive letter
- //
- Drive = AllocateCopyPool(StrSize(Param1Copy), Param1Copy);
- if (Drive == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- Path = StrStr(Drive, L":");
- ASSERT(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 if (*(Path+1) == CHAR_NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy);
ShellStatus = SHELL_NOT_FOUND;
} else {
- *(Path+1) = CHAR_NULL;
- if (Path == Drive + StrLen(Drive)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- Status = gEfiShellProtocol->SetCurDir(Drive, Path+2);
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT), gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
- }
- }
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");
- Status = SHELL_NOT_FOUND;
- } else if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy);
- Status = SHELL_NOT_FOUND;
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT), gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
}
}
}
+
+ if (Drive != NULL) {
+ FreePool (Drive);
+ }
+
+ if (Path != NULL) {
+ FreePool (Path);
+ }
+
+ FreePool(Param1Copy);
}
- FreePool(Param1Copy);
}
}
- if (Drive != NULL) {
- FreePool(Drive);
- }
//
// free the command line package
//
--
2.9.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
2016-12-21 8:55 ` [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
@ 2016-12-21 16:23 ` Carsey, Jaben
2016-12-23 5:43 ` Ni, Ruiyu
0 siblings, 1 reply; 6+ messages in thread
From: Carsey, Jaben @ 2016-12-21 16:23 UTC (permalink / raw)
To: Ni, Ruiyu, edk2-devel@lists.01.org; +Cc: Chen, Chen A, Carsey, Jaben
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, December 21, 2016 12:55 AM
> To: edk2-devel@lists.01.org
> Cc: Chen, Chen A <chen.a.chen@intel.com>; Carsey, Jaben
> <jaben.carsey@intel.com>
> Subject: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after
> ':')
> Importance: High
>
> When "fs0:dir"(drive letter without slash) is used as destination
> of "cd", "cd" tries to change to "dir" in root directory of "fs0:".
> It's incorrect. The correct behavior is to change to "dir" in
> current directory of "fs0:"
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
> Cc: Jaben Carsey <jaben.carsey@intel.com>
> ---
> ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c | 415 +++++++++++++--
> --------
> 1 file changed, 240 insertions(+), 175 deletions(-)
>
> diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> index 0967bc7..0b4becf 100644
> --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> @@ -17,6 +17,156 @@
> #include "UefiShellLevel2CommandsLib.h"
>
> /**
> + Function will replace drive identifier with CWD.
> +
> + If FullPath begining with ':' is invalid path, then ASSERT.
Is there any way for the user from the shell prompt to hit the ASSERT? Is there a good reason to use ASSERT and not just return an error (NULL for example)?
> + If FullPath not include dirve 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 - FullPath) != (UINTN)(Splitter2 - Cwd)) {
> + return FALSE;
> + } else {
> + if (StrniCmp(FullPath, Cwd, (UINTN)(Splitter1 - FullPath)) == NULL) {
> + 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).
> @@ -31,23 +181,26 @@ ShellCommandRunCd (
> {
> EFI_STATUS Status;
> LIST_ENTRY *Package;
> - CONST CHAR16 *Directory;
> - CHAR16 *Cwd;
> + CONST CHAR16 *Cwd;
> CHAR16 *Path;
> CHAR16 *Drive;
> - UINTN CwdSize;
> - UINTN DriveSize;
> CHAR16 *ProblemParam;
> SHELL_STATUS ShellStatus;
> - SHELL_FILE_HANDLE Handle;
> CONST CHAR16 *Param1;
> CHAR16 *Param1Copy;
> - CHAR16* Walker;
> + CHAR16 *Walker;
> + CHAR16 *Splitter;
> + CHAR16 *TempBuffer;
> + UINTN TotalSize;
>
> - ProblemParam = NULL;
> - ShellStatus = SHELL_SUCCESS;
> - Drive = NULL;
> - DriveSize = 0;
> + ProblemParam = NULL;
> + ShellStatus = SHELL_SUCCESS;
> + Cwd = NULL;
> + Path = NULL;
> + Drive = NULL;
> + Splitter = NULL;
> + TempBuffer = NULL;
> + TotalSize = 0;
>
> Status = CommandInit();
> ASSERT_EFI_ERROR(Status);
> @@ -87,194 +240,106 @@ ShellCommandRunCd (
> // else If there are 2 value parameters, then print the error message
> // else If there is 1 value paramerer , then change the directory
> //
> - Param1 = ShellCommandLineGetRawValue(Package, 1);
> - if (Param1 == NULL) {
> - //
> - // display the current directory
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory != NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, Directory);
> - } else {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> + Cwd = ShellGetCurrentDir (NULL);
> + if (Cwd == NULL) {
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + ShellStatus = SHELL_NOT_FOUND;
> } 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]));
> + 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) {
> - Param1Copy = PathCleanUpDirectories(Param1Copy);
> - }
> - if (Param1Copy != NULL) {
> - if (StrCmp(Param1Copy, L".") == 0) {
> - //
> - // nothing to do... change to current directory
> - //
> - } else if (StrCmp(Param1Copy, L"..") == 0) {
> +
> + if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) {
> + Status = ReplaceDriveWithCwd (&Param1Copy,Cwd);
> + if (!EFI_ERROR(Status)) {
> + Param1Copy = PathCleanUpDirectories(Param1Copy);
> + }
> + } else {
> //
> - // Change up one directory...
> + // Can't use cd command to change filesystem.
> //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - PathRemoveLastItem (Drive);
> - FreePool (Cwd);
> - }
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> + 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'\\') {
> //
> - // change directory on current drive letter
> + // Absolute Path on current drive letter.
> //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> + 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 (StrCmp(Param1Copy, L"\\") == 0) {
> - //
> - // Move to root of current drive
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - while (PathRemoveLastItem (Drive)) {
> - //
> - // Check if Drive contains 'fsx:\' only or still points to a sub-directory.
> - // Don't remove trailing '\' from Drive if it points to the root
> directory.
> - //
> - Path = StrStr (Drive, L":\\");
> - if ((Path != NULL) && (*(Path + 2) == CHAR_NULL)) {
> - break;
> - }
> + 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 = PathCleanUpDirectories (TempBuffer);
> }
> - FreePool (Cwd);
> }
> }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - } else if (StrStr(Param1Copy, L":") == NULL) {
> - //
> - // change directory without a drive identifier
> - //
> - if (ShellGetCurrentDir(NULL) == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + }
> +
> + if (!EFI_ERROR(Status)) {
> + 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 {
> - ASSERT((Drive == NULL && DriveSize == 0) || (Drive != NULL));
> - Drive = StrnCatGrow(&Drive, &DriveSize, ShellGetCurrentDir(NULL),
> 0);
> - Drive = StrnCatGrow(&Drive, &DriveSize, L"\\", 0);
> - if (*Param1Copy == L'\\') {
> - while (PathRemoveLastItem(Drive)) ;
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy+1, 0);
> - } else {
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy, 0);
> - }
> - //
> - // Verify that this is a valid directory
> - //
> - Status = gEfiShellProtocol->OpenFileByName(Drive, &Handle,
> EFI_FILE_MODE_READ);
> + Status = gEfiShellProtocol->SetCurDir(Drive, Path + 1);
> if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(FileHandleIsDirectory(Handle))) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - if (Handle != NULL) {
> - gEfiShellProtocol->CloseFile(Handle);
> - DEBUG_CODE(Handle = NULL;);
> - }
> - }
> - } else {
> - //
> - // change directory with a drive letter
> - //
> - Drive = AllocateCopyPool(StrSize(Param1Copy), Param1Copy);
> - if (Drive == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - Path = StrStr(Drive, L":");
> - ASSERT(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 if (*(Path+1) == CHAR_NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> ShellStatus = SHELL_NOT_FOUND;
> } else {
> - *(Path+1) = CHAR_NULL;
> - if (Path == Drive + StrLen(Drive)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - Status = gEfiShellProtocol->SetCurDir(Drive, Path+2);
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> - }
> - }
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - Status = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> - Status = SHELL_NOT_FOUND;
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> }
> }
> }
> +
> + if (Drive != NULL) {
> + FreePool (Drive);
> + }
> +
> + if (Path != NULL) {
> + FreePool (Path);
> + }
> +
> + FreePool(Param1Copy);
> }
> - FreePool(Param1Copy);
> }
> }
>
> - if (Drive != NULL) {
> - FreePool(Drive);
> - }
> //
> // free the command line package
> //
> --
> 2.9.0.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
2016-12-21 16:23 ` Carsey, Jaben
@ 2016-12-23 5:43 ` Ni, Ruiyu
2016-12-27 23:01 ` Carsey, Jaben
0 siblings, 1 reply; 6+ messages in thread
From: Ni, Ruiyu @ 2016-12-23 5:43 UTC (permalink / raw)
To: Carsey, Jaben, edk2-devel@lists.01.org; +Cc: Carsey, Jaben, Chen, Chen A
Jaben,
The assertion is to check caller instead of check user's input.
It's to make sure future modification won't break the parameter assumption of this function.
It's like the below assertion in StrCpy:
ASSERT (Destination != NULL);
ASSERT (((UINTN) Destination & BIT0) == 0);
Regards,
Ray
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Carsey, Jaben
Sent: Thursday, December 22, 2016 12:23 AM
To: Ni, Ruiyu <ruiyu.ni@intel.com>; edk2-devel@lists.01.org
Cc: Carsey, Jaben <jaben.carsey@intel.com>; Chen, Chen A <chen.a.chen@intel.com>
Subject: Re: [edk2] [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, December 21, 2016 12:55 AM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>; Carsey, Jaben
> <jaben.carsey@intel.com<mailto:jaben.carsey@intel.com>>
> Subject: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after
> ':')
> Importance: High
>
> When "fs0:dir"(drive letter without slash) is used as destination
> of "cd", "cd" tries to change to "dir" in root directory of "fs0:".
> It's incorrect. The correct behavior is to change to "dir" in
> current directory of "fs0:"
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> Cc: Jaben Carsey <jaben.carsey@intel.com<mailto:jaben.carsey@intel.com>>
> ---
> ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c | 415 +++++++++++++--
> --------
> 1 file changed, 240 insertions(+), 175 deletions(-)
>
> diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> index 0967bc7..0b4becf 100644
> --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> @@ -17,6 +17,156 @@
> #include "UefiShellLevel2CommandsLib.h"
>
> /**
> + Function will replace drive identifier with CWD.
> +
> + If FullPath begining with ':' is invalid path, then ASSERT.
Is there any way for the user from the shell prompt to hit the ASSERT? Is there a good reason to use ASSERT and not just return an error (NULL for example)?
> + If FullPath not include dirve 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 - FullPath) != (UINTN)(Splitter2 - Cwd)) {
> + return FALSE;
> + } else {
> + if (StrniCmp(FullPath, Cwd, (UINTN)(Splitter1 - FullPath)) == NULL) {
> + 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).
> @@ -31,23 +181,26 @@ ShellCommandRunCd (
> {
> EFI_STATUS Status;
> LIST_ENTRY *Package;
> - CONST CHAR16 *Directory;
> - CHAR16 *Cwd;
> + CONST CHAR16 *Cwd;
> CHAR16 *Path;
> CHAR16 *Drive;
> - UINTN CwdSize;
> - UINTN DriveSize;
> CHAR16 *ProblemParam;
> SHELL_STATUS ShellStatus;
> - SHELL_FILE_HANDLE Handle;
> CONST CHAR16 *Param1;
> CHAR16 *Param1Copy;
> - CHAR16* Walker;
> + CHAR16 *Walker;
> + CHAR16 *Splitter;
> + CHAR16 *TempBuffer;
> + UINTN TotalSize;
>
> - ProblemParam = NULL;
> - ShellStatus = SHELL_SUCCESS;
> - Drive = NULL;
> - DriveSize = 0;
> + ProblemParam = NULL;
> + ShellStatus = SHELL_SUCCESS;
> + Cwd = NULL;
> + Path = NULL;
> + Drive = NULL;
> + Splitter = NULL;
> + TempBuffer = NULL;
> + TotalSize = 0;
>
> Status = CommandInit();
> ASSERT_EFI_ERROR(Status);
> @@ -87,194 +240,106 @@ ShellCommandRunCd (
> // else If there are 2 value parameters, then print the error message
> // else If there is 1 value paramerer , then change the directory
> //
> - Param1 = ShellCommandLineGetRawValue(Package, 1);
> - if (Param1 == NULL) {
> - //
> - // display the current directory
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory != NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, Directory);
> - } else {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> + Cwd = ShellGetCurrentDir (NULL);
> + if (Cwd == NULL) {
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + ShellStatus = SHELL_NOT_FOUND;
> } 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]));
> + 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) {
> - Param1Copy = PathCleanUpDirectories(Param1Copy);
> - }
> - if (Param1Copy != NULL) {
> - if (StrCmp(Param1Copy, L".") == 0) {
> - //
> - // nothing to do... change to current directory
> - //
> - } else if (StrCmp(Param1Copy, L"..") == 0) {
> +
> + if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) {
> + Status = ReplaceDriveWithCwd (&Param1Copy,Cwd);
> + if (!EFI_ERROR(Status)) {
> + Param1Copy = PathCleanUpDirectories(Param1Copy);
> + }
> + } else {
> //
> - // Change up one directory...
> + // Can't use cd command to change filesystem.
> //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - PathRemoveLastItem (Drive);
> - FreePool (Cwd);
> - }
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> + 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'\\') {
> //
> - // change directory on current drive letter
> + // Absolute Path on current drive letter.
> //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> + 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 (StrCmp(Param1Copy, L"\\") == 0) {
> - //
> - // Move to root of current drive
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - while (PathRemoveLastItem (Drive)) {
> - //
> - // Check if Drive contains 'fsx:\' only or still points to a sub-directory.
> - // Don't remove trailing '\' from Drive if it points to the root
> directory.
> - //
> - Path = StrStr (Drive, L":\\");
> - if ((Path != NULL) && (*(Path + 2) == CHAR_NULL)) {
> - break;
> - }
> + 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 = PathCleanUpDirectories (TempBuffer);
> }
> - FreePool (Cwd);
> }
> }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - } else if (StrStr(Param1Copy, L":") == NULL) {
> - //
> - // change directory without a drive identifier
> - //
> - if (ShellGetCurrentDir(NULL) == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + }
> +
> + if (!EFI_ERROR(Status)) {
> + 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 {
> - ASSERT((Drive == NULL && DriveSize == 0) || (Drive != NULL));
> - Drive = StrnCatGrow(&Drive, &DriveSize, ShellGetCurrentDir(NULL),
> 0);
> - Drive = StrnCatGrow(&Drive, &DriveSize, L"\\", 0);
> - if (*Param1Copy == L'\\') {
> - while (PathRemoveLastItem(Drive)) ;
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy+1, 0);
> - } else {
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy, 0);
> - }
> - //
> - // Verify that this is a valid directory
> - //
> - Status = gEfiShellProtocol->OpenFileByName(Drive, &Handle,
> EFI_FILE_MODE_READ);
> + Status = gEfiShellProtocol->SetCurDir(Drive, Path + 1);
> if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(FileHandleIsDirectory(Handle))) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - if (Handle != NULL) {
> - gEfiShellProtocol->CloseFile(Handle);
> - DEBUG_CODE(Handle = NULL;);
> - }
> - }
> - } else {
> - //
> - // change directory with a drive letter
> - //
> - Drive = AllocateCopyPool(StrSize(Param1Copy), Param1Copy);
> - if (Drive == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - Path = StrStr(Drive, L":");
> - ASSERT(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 if (*(Path+1) == CHAR_NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> ShellStatus = SHELL_NOT_FOUND;
> } else {
> - *(Path+1) = CHAR_NULL;
> - if (Path == Drive + StrLen(Drive)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - Status = gEfiShellProtocol->SetCurDir(Drive, Path+2);
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> - }
> - }
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - Status = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> - Status = SHELL_NOT_FOUND;
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> }
> }
> }
> +
> + if (Drive != NULL) {
> + FreePool (Drive);
> + }
> +
> + if (Path != NULL) {
> + FreePool (Path);
> + }
> +
> + FreePool(Param1Copy);
> }
> - FreePool(Param1Copy);
> }
> }
>
> - if (Drive != NULL) {
> - FreePool(Drive);
> - }
> //
> // free the command line package
> //
> --
> 2.9.0.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
2016-12-23 5:43 ` Ni, Ruiyu
@ 2016-12-27 23:01 ` Carsey, Jaben
0 siblings, 0 replies; 6+ messages in thread
From: Carsey, Jaben @ 2016-12-27 23:01 UTC (permalink / raw)
To: Ni, Ruiyu, edk2-devel@lists.01.org; +Cc: Chen, Chen A, Carsey, Jaben
Right. The question is can the user from the shell prompt trigger the assert. I didn't see clear protection from the users input to the function's assert.
-Jaben
From: Ni, Ruiyu
Sent: Thursday, December 22, 2016 9:43 PM
To: Carsey, Jaben <jaben.carsey@intel.com>; edk2-devel@lists.01.org
Cc: Carsey, Jaben <jaben.carsey@intel.com>; Chen, Chen A <chen.a.chen@intel.com>
Subject: RE: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
Importance: High
Jaben,
The assertion is to check caller instead of check user's input.
It's to make sure future modification won't break the parameter assumption of this function.
It's like the below assertion in StrCpy:
ASSERT (Destination != NULL);
ASSERT (((UINTN) Destination & BIT0) == 0);
Regards,
Ray
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Carsey, Jaben
Sent: Thursday, December 22, 2016 12:23 AM
To: Ni, Ruiyu <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
Cc: Carsey, Jaben <jaben.carsey@intel.com<mailto:jaben.carsey@intel.com>>; Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
Subject: Re: [edk2] [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':')
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, December 21, 2016 12:55 AM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>; Carsey, Jaben
> <jaben.carsey@intel.com<mailto:jaben.carsey@intel.com>>
> Subject: [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after
> ':')
> Importance: High
>
> When "fs0:dir"(drive letter without slash) is used as destination
> of "cd", "cd" tries to change to "dir" in root directory of "fs0:".
> It's incorrect. The correct behavior is to change to "dir" in
> current directory of "fs0:"
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> Cc: Jaben Carsey <jaben.carsey@intel.com<mailto:jaben.carsey@intel.com>>
> ---
> ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c | 415 +++++++++++++--
> --------
> 1 file changed, 240 insertions(+), 175 deletions(-)
>
> diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> index 0967bc7..0b4becf 100644
> --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
> @@ -17,6 +17,156 @@
> #include "UefiShellLevel2CommandsLib.h"
>
> /**
> + Function will replace drive identifier with CWD.
> +
> + If FullPath begining with ':' is invalid path, then ASSERT.
Is there any way for the user from the shell prompt to hit the ASSERT? Is there a good reason to use ASSERT and not just return an error (NULL for example)?
> + If FullPath not include dirve 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 - FullPath) != (UINTN)(Splitter2 - Cwd)) {
> + return FALSE;
> + } else {
> + if (StrniCmp(FullPath, Cwd, (UINTN)(Splitter1 - FullPath)) == NULL) {
> + 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).
> @@ -31,23 +181,26 @@ ShellCommandRunCd (
> {
> EFI_STATUS Status;
> LIST_ENTRY *Package;
> - CONST CHAR16 *Directory;
> - CHAR16 *Cwd;
> + CONST CHAR16 *Cwd;
> CHAR16 *Path;
> CHAR16 *Drive;
> - UINTN CwdSize;
> - UINTN DriveSize;
> CHAR16 *ProblemParam;
> SHELL_STATUS ShellStatus;
> - SHELL_FILE_HANDLE Handle;
> CONST CHAR16 *Param1;
> CHAR16 *Param1Copy;
> - CHAR16* Walker;
> + CHAR16 *Walker;
> + CHAR16 *Splitter;
> + CHAR16 *TempBuffer;
> + UINTN TotalSize;
>
> - ProblemParam = NULL;
> - ShellStatus = SHELL_SUCCESS;
> - Drive = NULL;
> - DriveSize = 0;
> + ProblemParam = NULL;
> + ShellStatus = SHELL_SUCCESS;
> + Cwd = NULL;
> + Path = NULL;
> + Drive = NULL;
> + Splitter = NULL;
> + TempBuffer = NULL;
> + TotalSize = 0;
>
> Status = CommandInit();
> ASSERT_EFI_ERROR(Status);
> @@ -87,194 +240,106 @@ ShellCommandRunCd (
> // else If there are 2 value parameters, then print the error message
> // else If there is 1 value paramerer , then change the directory
> //
> - Param1 = ShellCommandLineGetRawValue(Package, 1);
> - if (Param1 == NULL) {
> - //
> - // display the current directory
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory != NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, Directory);
> - } else {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> + Cwd = ShellGetCurrentDir (NULL);
> + if (Cwd == NULL) {
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + ShellStatus = SHELL_NOT_FOUND;
> } 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]));
> + 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) {
> - Param1Copy = PathCleanUpDirectories(Param1Copy);
> - }
> - if (Param1Copy != NULL) {
> - if (StrCmp(Param1Copy, L".") == 0) {
> - //
> - // nothing to do... change to current directory
> - //
> - } else if (StrCmp(Param1Copy, L"..") == 0) {
> +
> + if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) {
> + Status = ReplaceDriveWithCwd (&Param1Copy,Cwd);
> + if (!EFI_ERROR(Status)) {
> + Param1Copy = PathCleanUpDirectories(Param1Copy);
> + }
> + } else {
> //
> - // Change up one directory...
> + // Can't use cd command to change filesystem.
> //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - PathRemoveLastItem (Drive);
> - FreePool (Cwd);
> - }
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> + 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'\\') {
> //
> - // change directory on current drive letter
> + // Absolute Path on current drive letter.
> //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> + 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 (StrCmp(Param1Copy, L"\\") == 0) {
> - //
> - // Move to root of current drive
> - //
> - Directory = ShellGetCurrentDir(NULL);
> - if (Directory == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> } else {
> - CwdSize = StrSize(Directory) + sizeof(CHAR16);
> - Cwd = AllocateZeroPool(CwdSize);
> - if (Cwd == NULL) {
> - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - StrCpyS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, Directory);
> - StrCatS (Cwd, StrSize (Directory) / sizeof (CHAR16) + 1, L"\\");
> - Drive = GetFullyQualifiedPath (Cwd);
> - while (PathRemoveLastItem (Drive)) {
> - //
> - // Check if Drive contains 'fsx:\' only or still points to a sub-directory.
> - // Don't remove trailing '\' from Drive if it points to the root
> directory.
> - //
> - Path = StrStr (Drive, L":\\");
> - if ((Path != NULL) && (*(Path + 2) == CHAR_NULL)) {
> - break;
> - }
> + 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 = PathCleanUpDirectories (TempBuffer);
> }
> - FreePool (Cwd);
> }
> }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - } else if (StrStr(Param1Copy, L":") == NULL) {
> - //
> - // change directory without a drive identifier
> - //
> - if (ShellGetCurrentDir(NULL) == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD),
> gShellLevel2HiiHandle, L"cd");
> + }
> +
> + if (!EFI_ERROR(Status)) {
> + 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 {
> - ASSERT((Drive == NULL && DriveSize == 0) || (Drive != NULL));
> - Drive = StrnCatGrow(&Drive, &DriveSize, ShellGetCurrentDir(NULL),
> 0);
> - Drive = StrnCatGrow(&Drive, &DriveSize, L"\\", 0);
> - if (*Param1Copy == L'\\') {
> - while (PathRemoveLastItem(Drive)) ;
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy+1, 0);
> - } else {
> - Drive = StrnCatGrow(&Drive, &DriveSize, Param1Copy, 0);
> - }
> - //
> - // Verify that this is a valid directory
> - //
> - Status = gEfiShellProtocol->OpenFileByName(Drive, &Handle,
> EFI_FILE_MODE_READ);
> + Status = gEfiShellProtocol->SetCurDir(Drive, Path + 1);
> if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(FileHandleIsDirectory(Handle))) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR),
> gShellLevel2HiiHandle, L"cd", Drive);
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - if (ShellStatus == SHELL_SUCCESS && Drive != NULL) {
> - //
> - // change directory on current drive letter
> - //
> - Status = gEfiShellProtocol->SetCurDir(NULL, Drive);
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - }
> - }
> - if (Handle != NULL) {
> - gEfiShellProtocol->CloseFile(Handle);
> - DEBUG_CODE(Handle = NULL;);
> - }
> - }
> - } else {
> - //
> - // change directory with a drive letter
> - //
> - Drive = AllocateCopyPool(StrSize(Param1Copy), Param1Copy);
> - if (Drive == NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_OUT_OF_RESOURCES;
> - } else {
> - Path = StrStr(Drive, L":");
> - ASSERT(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 if (*(Path+1) == CHAR_NULL) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> ShellStatus = SHELL_NOT_FOUND;
> } else {
> - *(Path+1) = CHAR_NULL;
> - if (Path == Drive + StrLen(Drive)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - ShellStatus = SHELL_NOT_FOUND;
> - } else {
> - Status = gEfiShellProtocol->SetCurDir(Drive, Path+2);
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> - }
> - }
> - if (Status == EFI_NOT_FOUND) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CD_NF),
> gShellLevel2HiiHandle, L"cd");
> - Status = SHELL_NOT_FOUND;
> - } else if (EFI_ERROR(Status)) {
> - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF),
> gShellLevel2HiiHandle, L"cd", Param1Copy);
> - Status = SHELL_NOT_FOUND;
> + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT),
> gShellLevel2HiiHandle, ShellGetCurrentDir(Drive));
> }
> }
> }
> +
> + if (Drive != NULL) {
> + FreePool (Drive);
> + }
> +
> + if (Path != NULL) {
> + FreePool (Path);
> + }
> +
> + FreePool(Param1Copy);
> }
> - FreePool(Param1Copy);
> }
> }
>
> - if (Drive != NULL) {
> - FreePool(Drive);
> - }
> //
> // free the command line package
> //
> --
> 2.9.0.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-12-27 23:01 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-21 8:54 [PATCH 0/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
2016-12-21 8:55 ` [PATCH 1/2] MdePkg/BaseLib: Fix PathCleanUpDirectories to correctly handle "\.\" Ruiyu Ni
2016-12-21 8:55 ` [PATCH 2/2] ShellPkg/cd: Fix "cd" to support "fs0:dir" (no slash after ':') Ruiyu Ni
2016-12-21 16:23 ` Carsey, Jaben
2016-12-23 5:43 ` Ni, Ruiyu
2016-12-27 23:01 ` Carsey, Jaben
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox