/** @file\r
Provides interface to shell functionality for shell commands and applications.\r
\r
+ Copyright 2016 Dell Inc.\r
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
EFI_STATUS Status;\r
EFI_FILE_INFO *FileInfo;\r
CHAR16 *FileNameCopy;\r
+ EFI_STATUS Status2;\r
\r
//\r
// ASSERT if FileName is NULL\r
}\r
PathCleanUpDirectories (FileNameCopy);\r
if (PathRemoveLastItem (FileNameCopy)) {\r
- ShellCreateDirectory (FileNameCopy, FileHandle);\r
- ShellCloseFile (FileHandle);\r
+ if (!EFI_ERROR(ShellCreateDirectory (FileNameCopy, FileHandle))) {\r
+ ShellCloseFile (FileHandle);\r
+ }\r
}\r
SHELL_FREE_NON_NULL (FileNameCopy);\r
}\r
FileInfo = FileFunctionMap.GetFileInfo(*FileHandle);\r
ASSERT(FileInfo != NULL);\r
FileInfo->Attribute = Attributes;\r
- Status = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
+ Status2 = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
FreePool(FileInfo);\r
+ if (EFI_ERROR (Status2)) {\r
+ gEfiShellProtocol->CloseFile(*FileHandle);\r
+ }\r
+ Status = Status2;\r
}\r
return (Status);\r
}\r
name. If the DeviceName is not NULL, it returns the current directory name\r
on specified drive.\r
\r
+ Note that the current directory string should exclude the tailing backslash character.\r
+\r
@param DeviceName the name of the drive to get directory on\r
\r
@retval NULL the directory does not exist\r
\r
Path = ShellGetEnvironmentVariable(L"cwd");\r
if (Path != NULL) {\r
- Size = StrSize(Path);\r
+ Size = StrSize(Path) + sizeof(CHAR16);\r
Size += StrSize(FileName);\r
TestPath = AllocateZeroPool(Size);\r
if (TestPath == NULL) {\r
return (NULL);\r
}\r
- StrnCpy(TestPath, Path, Size/sizeof(CHAR16) - 1);\r
- StrnCat(TestPath, FileName, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+ StrCpyS(TestPath, Size/sizeof(CHAR16), Path);\r
+ StrCatS(TestPath, Size/sizeof(CHAR16), L"\\");\r
+ StrCatS(TestPath, Size/sizeof(CHAR16), FileName);\r
Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);\r
if (!EFI_ERROR(Status)){\r
if (FileHandleIsDirectory(Handle) != EFI_SUCCESS) {\r
*TempChar = CHAR_NULL;\r
}\r
if (TestPath[StrLen(TestPath)-1] != L'\\') {\r
- StrnCat(TestPath, L"\\", Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+ StrCatS(TestPath, Size/sizeof(CHAR16), L"\\");\r
}\r
if (FileName[0] == L'\\') {\r
FileName++;\r
}\r
- StrnCat(TestPath, FileName, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+ StrCatS(TestPath, Size/sizeof(CHAR16), FileName);\r
if (StrStr(Walker, L";") != NULL) {\r
Walker = StrStr(Walker, L";") + 1;\r
} else {\r
return (NULL);\r
}\r
for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16*)FileExtension; TempChar2 != NULL ; ExtensionWalker = TempChar2 + 1){\r
- StrnCpy(TestPath, FileName, Size/sizeof(CHAR16) - 1);\r
+ StrCpyS(TestPath, Size/sizeof(CHAR16), FileName);\r
if (ExtensionWalker != NULL) {\r
- StrnCat(TestPath, ExtensionWalker, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+ StrCatS(TestPath, Size/sizeof(CHAR16), ExtensionWalker);\r
}\r
TempChar = StrStr(TestPath, L";");\r
if (TempChar != NULL) {\r
ASSERT(GetItemValue == 0);\r
break;\r
}\r
- } else if (GetItemValue != 0 && CurrentItemPackage != NULL && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers, (CONST BOOLEAN)(CurrentItemPackage->Type == TypeTimeValue))) {\r
+ } else if (GetItemValue != 0 && CurrentItemPackage != NULL && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers, (BOOLEAN)(CurrentItemPackage->Type == TypeTimeValue))) {\r
//\r
// get the item VALUE for a previous flag\r
//\r
- if (StrStr(Argv[LoopCounter], L" ") == NULL) {\r
- CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
- CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
- ASSERT(CurrentItemPackage->Value != NULL);\r
- if (ValueSize == 0) {\r
- StrnCpy(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1);\r
- } else {\r
- StrnCat(CurrentItemPackage->Value, L" ", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- }\r
- ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+ CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+ CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
+ ASSERT(CurrentItemPackage->Value != NULL);\r
+ if (ValueSize == 0) {\r
+ StrCpyS( CurrentItemPackage->Value, \r
+ CurrentValueSize/sizeof(CHAR16), \r
+ Argv[LoopCounter]\r
+ );\r
} else {\r
- //\r
- // the parameter has spaces. must be quoted.\r
- //\r
- CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16) + sizeof(CHAR16) + sizeof(CHAR16);\r
- CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
- ASSERT(CurrentItemPackage->Value != NULL);\r
- if (ValueSize == 0) {\r
- StrnCpy(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1);\r
- StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- } else {\r
- StrnCat(CurrentItemPackage->Value, L" ", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
- }\r
- ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+ StrCatS( CurrentItemPackage->Value, \r
+ CurrentValueSize/sizeof(CHAR16), \r
+ L" "\r
+ );\r
+ StrCatS( CurrentItemPackage->Value, \r
+ CurrentValueSize/sizeof(CHAR16), \r
+ Argv[LoopCounter]\r
+ );\r
}\r
+ ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+ \r
GetItemValue--;\r
if (GetItemValue == 0) {\r
InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
}\r
\r
/**\r
- Determins if a parameter is duplicated.\r
+ Determines if a parameter is duplicated.\r
\r
If Param is not NULL then it will point to a callee allocated string buffer\r
with the parameter value if a duplicate is found.\r
FreePool(Replace);\r
return (EFI_BUFFER_TOO_SMALL);\r
}\r
- StrnCat(NewString, Replace, NewSize/sizeof(CHAR16) - 1 - StrLen(NewString));\r
+ StrCatS(NewString, NewSize/sizeof(CHAR16), Replace);\r
} else {\r
Size = StrSize(NewString);\r
if (Size + sizeof(CHAR16) > NewSize) {\r
FreePool(Replace);\r
return (EFI_BUFFER_TOO_SMALL);\r
}\r
- StrnCat(NewString, SourceString, 1);\r
+ StrnCatS(NewString, NewSize/sizeof(CHAR16), SourceString, 1);\r
SourceString++;\r
}\r
}\r
*CurrentSize = NewSize;\r
}\r
} else {\r
- *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));\r
+ NewSize = (Count+1)*sizeof(CHAR16);\r
+ *Destination = AllocateZeroPool(NewSize);\r
}\r
\r
//\r
if (*Destination == NULL) {\r
return (NULL);\r
}\r
- return StrnCat(*Destination, Source, Count);\r
+ \r
+ StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);\r
+ return *Destination;\r
}\r
\r
/**\r
/**\r
Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
\r
- This function returns a value of type UINTN by interpreting the contents\r
+ This function returns a value of type UINT64 by interpreting the contents\r
of the Unicode string specified by String as a hexadecimal number.\r
The format of the input Unicode string String is:\r
\r
Result = 0;\r
\r
//\r
- // Skip spaces if requested\r
+ // there is a space where there should't be\r
//\r
- while (StopAtSpace && *String == L' ') {\r
- String++;\r
+ if (*String == L' ') {\r
+ return (EFI_INVALID_PARAMETER);\r
}\r
\r
while (ShellIsHexaDecimalDigitCharacter (*String)) {\r
//\r
// If the Hex Number represented by String overflows according\r
- // to the range defined by UINTN, then ASSERT().\r
+ // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
//\r
if (!(Result <= (RShiftU64((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {\r
// if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {\r
Result = 0;\r
\r
//\r
- // Skip spaces if requested\r
+ // Stop upon space if requested \r
+ // (if the whole value was 0)\r
//\r
- while (StopAtSpace && *String == L' ') {\r
- String++;\r
+ if (StopAtSpace && *String == L' ') {\r
+ *Value = Result;\r
+ return (EFI_SUCCESS);\r
}\r
+\r
while (ShellIsDecimalDigitCharacter (*String)) {\r
//\r
// If the number represented by String overflows according\r
- // to the range defined by UINT64, then ASSERT().\r
+ // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
//\r
\r
if (!(Result <= (DivU64x32((((UINT64) ~0) - (*String - L'0')),10)))) {\r
If the position upon start is 0, then the Ascii Boolean will be set. This should be\r
maintained and not changed for all operations with the same file.\r
\r
+ NOTE: LINES THAT ARE RETURNED BY THIS FUNCTION ARE UCS2, EVEN IF THE FILE BEING READ\r
+ IS IN ASCII FORMAT.\r
+\r
@param[in] Handle SHELL_FILE_HANDLE to read from.\r
- @param[in, out] Buffer The pointer to buffer to read into.\r
- @param[in, out] Size The pointer to number of bytes in Buffer.\r
+ @param[in, out] Buffer The pointer to buffer to read into. If this function\r
+ returns EFI_SUCCESS, then on output Buffer will\r
+ contain a UCS2 string, even if the file being\r
+ read is ASCII.\r
+ @param[in, out] Size On input, pointer to number of bytes in Buffer.\r
+ On output, unchanged unless Buffer is too small\r
+ to contain the next line of the file. In that\r
+ case Size is set to the number of bytes needed\r
+ to hold the next line of the file (as a UCS2\r
+ string, even if it is an ASCII file).\r
@param[in] Truncate If the buffer is large enough, this has no effect.\r
If the buffer is is too small and Truncate is TRUE,\r
the line will be truncated.\r
\r
@retval EFI_SUCCESS The operation was successful. The line is stored in\r
Buffer.\r
+ @retval EFI_END_OF_FILE There are no more lines in the file.\r
@retval EFI_INVALID_PARAMETER Handle was NULL.\r
@retval EFI_INVALID_PARAMETER Size was NULL.\r
@retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.\r
}\r
}\r
\r
+ if (*Ascii) {\r
+ CharSize = sizeof(CHAR8);\r
+ } else {\r
+ CharSize = sizeof(CHAR16);\r
+ }\r
for (CountSoFar = 0;;CountSoFar++){\r
CharBuffer = 0;\r
- if (*Ascii) {\r
- CharSize = sizeof(CHAR8);\r
- } else {\r
- CharSize = sizeof(CHAR16);\r
- }\r
Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
if ( EFI_ERROR(Status)\r
|| CharSize == 0\r
|| (CharBuffer == L'\n' && !(*Ascii))\r
|| (CharBuffer == '\n' && *Ascii)\r
){\r
+ if (CharSize == 0) {\r
+ Status = EFI_END_OF_FILE;\r
+ }\r
break;\r
}\r
//\r