manipulation, and initialization of EFI_SHELL_PROTOCOL.\r
\r
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
Copyright (c) 2009 - 2016, 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
@retval FALSE gEfiBlockIoProtocolGuid was not found.\r
**/\r
BOOLEAN\r
-EFIAPI\r
InternalShellProtocolIsBlockIoPresent(\r
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
)\r
@retval FALSE gEfiSimpleFileSystemProtocolGuid was not found.\r
**/\r
BOOLEAN\r
-EFIAPI\r
InternalShellProtocolIsSimpleFileSystemPresent(\r
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
)\r
@sa OpenProtocol\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalShellProtocolDebugPrintMessage (\r
IN CONST CHAR16 *Mapping,\r
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));\r
\r
AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath);\r
- ASSERT (AlignedNode != NULL);\r
+ if (AlignedNode == NULL) {\r
+ FreePool (PathForReturn);\r
+ return NULL;\r
+ }\r
\r
// File Path Device Path Nodes 'can optionally add a "\" separator to\r
// the beginning and/or the end of the Path Name string.'\r
@retval other an error ocurred.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalOpenFileDevicePath(\r
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
OUT SHELL_FILE_HANDLE *FileHandle,\r
{\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
EFI_STATUS Status;\r
+ BOOLEAN Volatile;\r
\r
//\r
// Is this for an environment variable\r
// do we start with >v\r
//\r
if (StrStr(FileName, L">v") == FileName) {\r
- if (!IsVolatileEnv(FileName+2)) {\r
+ Status = IsVolatileEnv (FileName + 2, &Volatile);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (!Volatile) {\r
return (EFI_INVALID_PARAMETER);\r
}\r
*FileHandle = CreateFileInterfaceEnv(FileName+2);\r
@retval EFI_ACCESS_DENIED Guid already is assigned a name.\r
**/\r
EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
EfiShellRegisterGuidName(\r
IN CONST EFI_GUID *Guid,\r
IN CONST CHAR16 *GuidName\r
{\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
EFI_STATUS Status;\r
+ BOOLEAN Volatile;\r
\r
*FileHandle = NULL;\r
\r
}\r
\r
//\r
- // Is this for NUL file\r
+ // Is this for NUL / NULL file\r
//\r
- if (StrCmp(FileName, L"NUL") == 0) {\r
+ if ((gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)FileName, L"NUL") == 0) ||\r
+ (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)FileName, L"NULL") == 0)) {\r
*FileHandle = &FileInterfaceNulFile;\r
return (EFI_SUCCESS);\r
}\r
// do we start with >v\r
//\r
if (StrStr(FileName, L">v") == FileName) {\r
- if (!IsVolatileEnv(FileName+2) &&\r
+ Status = IsVolatileEnv (FileName + 2, &Volatile);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (!Volatile &&\r
((OpenMode & EFI_FILE_MODE_WRITE) != 0)) {\r
return (EFI_INVALID_PARAMETER);\r
}\r
@retval EFI_UNSUPPORTED Nested shell invocations are not allowed.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalShellExecuteDevicePath(\r
IN CONST EFI_HANDLE *ParentImageHandle,\r
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
}\r
\r
InitializeListHead(&OrigEnvs);\r
+ ZeroMem(&ShellParamsProtocol, sizeof(EFI_SHELL_PARAMETERS_PROTOCOL));\r
\r
NewHandle = NULL;\r
\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
\r
if (!EFI_ERROR(Status)) {\r
+ //\r
+ // If the image is not an app abort it.\r
+ //\r
+ if (LoadedImage->ImageCodeType != EfiLoaderCode){\r
+ ShellPrintHiiEx(\r
+ -1, \r
+ -1, \r
+ NULL,\r
+ STRING_TOKEN (STR_SHELL_IMAGE_NOT_APP),\r
+ ShellInfoObject.HiiHandle\r
+ );\r
+ goto UnloadImage;\r
+ }\r
+\r
ASSERT(LoadedImage->LoadOptionsSize == 0);\r
if (NewCmdLine != NULL) {\r
LoadedImage->LoadOptionsSize = (UINT32)StrSize(NewCmdLine);\r
@retval EFI_UNSUPPORTED Nested shell invocations are not allowed.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalShellExecute(\r
IN CONST CHAR16 *CommandLine OPTIONAL,\r
IN CONST CHAR16 **Environment OPTIONAL,\r
**/\r
STATIC\r
BOOLEAN\r
-EFIAPI\r
NestingEnabled(\r
)\r
{\r
@param FileListNode pointer to the list node to free\r
**/\r
VOID\r
-EFIAPI\r
InternalFreeShellFileInfoNode(\r
IN EFI_SHELL_FILE_INFO *FileListNode\r
)\r
@return != NULL a pointer to the new node\r
**/\r
EFI_SHELL_FILE_INFO*\r
-EFIAPI\r
InternalDuplicateShellFileInfo(\r
IN EFI_SHELL_FILE_INFO *Node,\r
IN BOOLEAN Save\r
@return a pointer to the newly allocated structure.\r
**/\r
EFI_SHELL_FILE_INFO *\r
-EFIAPI\r
CreateAndPopulateShellFileInfo(\r
IN CONST CHAR16 *BasePath,\r
IN CONST EFI_STATUS Status,\r
; !EFI_ERROR(Status) && !NoFile\r
; Status = FileHandleFindNextFile(FileDirHandle, FileInfo, &NoFile)\r
){\r
+ if (ShellFileList == NULL) {\r
+ ShellFileList = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
+ if (ShellFileList == NULL) {\r
+ SHELL_FREE_NON_NULL (BasePath);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ InitializeListHead(&ShellFileList->Link);\r
+ }\r
//\r
// allocate a new EFI_SHELL_FILE_INFO and populate it...\r
//\r
FileInfo->FileName,\r
NULL, // no handle since not open\r
FileInfo);\r
-\r
- if (ShellFileList == NULL) {\r
- ShellFileList = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
- ASSERT(ShellFileList != NULL);\r
- InitializeListHead(&ShellFileList->Link);\r
+ if (ShellFileListItem == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ //\r
+ // Free resources outside the loop.\r
+ //\r
+ break;\r
}\r
InsertTailList(&ShellFileList->Link, &ShellFileListItem->Link);\r
}\r
@retval EFI_NOT_FOUND GuidName is not a known GUID Name.\r
**/\r
EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
EfiShellGetGuidFromName(\r
IN CONST CHAR16 *GuidName,\r
OUT EFI_GUID *Guid\r
Status = GetGuidFromStringName(GuidName, NULL, &NewGuid);\r
\r
if (!EFI_ERROR(Status)) {\r
- CopyGuid(NewGuid, Guid);\r
+ CopyGuid(Guid, NewGuid);\r
}\r
\r
return (Status);\r
@retval EFI_NOT_FOUND Guid is not assigned a name.\r
**/\r
EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
EfiShellGetGuidName(\r
IN CONST EFI_GUID *Guid,\r
OUT CONST CHAR16 **GuidName\r
@retval EFI_OUT_OF_RESOURCES\r
**/\r
EFI_STATUS\r
-EFIAPI\r
UpdateFileName(\r
IN CONST CHAR16 *BasePath,\r
IN OUT CHAR16 **Path\r
@retval EFI_OUT_OF_RESOURCES a memory allocation failed\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ShellSearchHandle(\r
IN CONST CHAR16 *FilePattern,\r
IN EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation,\r
; NextFilePatternStart++);\r
\r
CurrentFilePattern = AllocateZeroPool((NextFilePatternStart-FilePattern+1)*sizeof(CHAR16));\r
- ASSERT(CurrentFilePattern != NULL);\r
+ if (CurrentFilePattern == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
StrnCpyS(CurrentFilePattern, NextFilePatternStart-FilePattern+1, FilePattern, NextFilePatternStart-FilePattern);\r
\r
if (CurrentFilePattern[0] == CHAR_NULL\r
){\r
if (UnicodeCollation->MetaiMatch(UnicodeCollation, (CHAR16*)ShellInfoNode->FileName, CurrentFilePattern)){\r
if (ShellInfoNode->FullName != NULL && StrStr(ShellInfoNode->FullName, L":") == NULL) {\r
- Size = StrSize(ShellInfoNode->FullName);\r
- Size += StrSize(MapName) + sizeof(CHAR16);\r
+ Size = StrSize (ShellInfoNode->FullName) + StrSize (MapName);\r
NewFullName = AllocateZeroPool(Size);\r
if (NewFullName == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
} else {\r
- StrCpyS(NewFullName, Size/sizeof(CHAR16), MapName);\r
- StrCatS(NewFullName, Size/sizeof(CHAR16), ShellInfoNode->FullName+1);\r
- FreePool((VOID*)ShellInfoNode->FullName);\r
+ StrCpyS(NewFullName, Size / sizeof(CHAR16), MapName);\r
+ StrCatS(NewFullName, Size / sizeof(CHAR16), ShellInfoNode->FullName);\r
+ FreePool ((VOID *) ShellInfoNode->FullName);\r
ShellInfoNode->FullName = NewFullName;\r
}\r
}\r
// copy the information we need into a new Node\r
//\r
NewShellNode = InternalDuplicateShellFileInfo(ShellInfoNode, FALSE);\r
- ASSERT(NewShellNode != NULL);\r
if (NewShellNode == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
}\r
}\r
}\r
\r
+ if (*FileList == NULL || (*FileList != NULL && IsListEmpty(&(*FileList)->Link))) {\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+\r
FreePool(CurrentFilePattern);\r
return (Status);\r
}\r
\r
PatternCopy = PathCleanUpDirectories(PatternCopy);\r
\r
- Count = StrStr(PatternCopy, L":") - PatternCopy;\r
- Count += 2;\r
+ Count = StrStr(PatternCopy, L":") - PatternCopy + 1;\r
+ ASSERT (Count <= StrLen (PatternCopy));\r
\r
ASSERT(MapName == NULL);\r
MapName = StrnCatGrow(&MapName, NULL, PatternCopy, Count);\r
pointer does not need to be freed by the caller.\r
**/\r
CONST CHAR16 *\r
-EFIAPI \r
+EFIAPI\r
EfiShellGetEnvEx(\r
IN CONST CHAR16 *Name,\r
OUT UINT32 *Attributes OPTIONAL\r
@retval EFI_SUCCESS The environment variable was successfully updated.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalEfiShellSetEnv(\r
IN CONST CHAR16 *Name,\r
IN CONST CHAR16 *Value,\r
)\r
{\r
EFI_STATUS Status;\r
- UINT32 Atts;\r
\r
- Atts = 0x0;\r
- \r
if (Value == NULL || StrLen(Value) == 0) {\r
Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Name);\r
if (!EFI_ERROR(Status)) {\r
ShellRemvoeEnvVarFromList(Name);\r
}\r
- return Status;\r
} else {\r
SHELL_DELETE_ENVIRONMENT_VARIABLE(Name);\r
- if (Volatile) {\r
- Status = SHELL_SET_ENVIRONMENT_VARIABLE_V(Name, StrSize(Value), Value);\r
- if (!EFI_ERROR(Status)) {\r
- Atts &= ~EFI_VARIABLE_NON_VOLATILE;\r
- Atts |= EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
- ShellAddEnvVarToList(Name, Value, StrSize(Value), Atts);\r
+ Status = ShellAddEnvVarToList(\r
+ Name, Value, StrSize(Value),\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE)\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = Volatile\r
+ ? SHELL_SET_ENVIRONMENT_VARIABLE_V(Name, StrSize(Value), Value)\r
+ : SHELL_SET_ENVIRONMENT_VARIABLE_NV(Name, StrSize(Value), Value);\r
+ if (EFI_ERROR (Status)) {\r
+ ShellRemvoeEnvVarFromList(Name);\r
}\r
- return Status;\r
- } else {\r
- Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Name, StrSize(Value), Value);\r
- if (!EFI_ERROR(Status)) {\r
- Atts |= EFI_VARIABLE_NON_VOLATILE;\r
- Atts |= EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
- ShellAddEnvVarToList(Name, Value, StrSize(Value), Atts);\r
- } \r
- return Status;\r
}\r
}\r
+ return Status;\r
}\r
\r
/**\r
&& (Command[StrLen(Command)-4] == L'.')\r
) {\r
FixCommand = AllocateZeroPool(StrSize(Command) - 4 * sizeof (CHAR16));\r
- ASSERT(FixCommand != NULL);\r
+ if (FixCommand == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
StrnCpyS( FixCommand, \r
(StrSize(Command) - 4 * sizeof (CHAR16))/sizeof(CHAR16), \r
@return !NULL a list of all alias'\r
**/\r
CHAR16 *\r
-EFIAPI\r
InternalEfiShellGetListAlias(\r
)\r
{\r
// Convert to lowercase to make aliases case-insensitive\r
if (Alias != NULL) {\r
AliasLower = AllocateCopyPool (StrSize (Alias), Alias);\r
- ASSERT (AliasLower != NULL);\r
+ if (AliasLower == NULL) {\r
+ return NULL;\r
+ }\r
ToLower (AliasLower);\r
\r
if (Volatile == NULL) {\r
@retval EFI_NOT_FOUND the Alias intended to be deleted was not found\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalSetAlias(\r
IN CONST CHAR16 *Command,\r
IN CONST CHAR16 *Alias,\r
// Convert to lowercase to make aliases case-insensitive\r
if (Alias != NULL) {\r
AliasLower = AllocateCopyPool (StrSize (Alias), Alias);\r
- ASSERT (AliasLower != NULL);\r
+ if (AliasLower == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
ToLower (AliasLower);\r
} else {\r
AliasLower = NULL;\r
@return An error from LocateHandle, CreateEvent, or other core function.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
CreatePopulateInstallShellProtocol (\r
IN OUT EFI_SHELL_PROTOCOL **NewShell\r
)\r
EFI_HANDLE *Buffer;\r
UINTN HandleCounter;\r
SHELL_PROTOCOL_HANDLE_LIST *OldProtocolNode;\r
+ EFI_SHELL_PROTOCOL *OldShell;\r
\r
if (NewShell == NULL) {\r
return (EFI_INVALID_PARAMETER);\r
// now overwrite each of them, but save the info to restore when we end.\r
//\r
for (HandleCounter = 0 ; HandleCounter < (BufferSize/sizeof(EFI_HANDLE)) ; HandleCounter++) {\r
- OldProtocolNode = AllocateZeroPool(sizeof(SHELL_PROTOCOL_HANDLE_LIST));\r
- ASSERT(OldProtocolNode != NULL);\r
Status = gBS->OpenProtocol(Buffer[HandleCounter],\r
&gEfiShellProtocolGuid,\r
- (VOID **) &(OldProtocolNode->Interface),\r
+ (VOID **) &OldShell,\r
gImageHandle,\r
NULL,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
if (!EFI_ERROR(Status)) {\r
+ OldProtocolNode = AllocateZeroPool(sizeof(SHELL_PROTOCOL_HANDLE_LIST));\r
+ if (OldProtocolNode == NULL) {\r
+ if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {\r
+ CleanUpShellProtocol (&mShellProtocol);\r
+ }\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
//\r
// reinstall over the old one...\r
//\r
- OldProtocolNode->Handle = Buffer[HandleCounter];\r
+ OldProtocolNode->Handle = Buffer[HandleCounter];\r
+ OldProtocolNode->Interface = OldShell;\r
Status = gBS->ReinstallProtocolInterface(\r
OldProtocolNode->Handle,\r
&gEfiShellProtocolGuid,\r
@retval EFI_SUCCESS The operation was successful.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
CleanUpShellProtocol (\r
IN OUT EFI_SHELL_PROTOCOL *NewShell\r
)\r
{\r
- EFI_STATUS Status;\r
SHELL_PROTOCOL_HANDLE_LIST *Node2;\r
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
\r
//\r
// if we need to restore old protocols...\r
//\r
if (!IsListEmpty(&ShellInfoObject.OldShellList.Link)) {\r
- for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode(&ShellInfoObject.OldShellList.Link)\r
+ for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *) GetFirstNode (&ShellInfoObject.OldShellList.Link)\r
; !IsListEmpty (&ShellInfoObject.OldShellList.Link)\r
- ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode(&ShellInfoObject.OldShellList.Link)\r
- ){\r
- RemoveEntryList(&Node2->Link);\r
- Status = gBS->ReinstallProtocolInterface(Node2->Handle,\r
- &gEfiShellProtocolGuid,\r
- NewShell,\r
- Node2->Interface);\r
- FreePool(Node2);\r
+ ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *) GetFirstNode (&ShellInfoObject.OldShellList.Link)\r
+ ) {\r
+ RemoveEntryList (&Node2->Link);\r
+ gBS->ReinstallProtocolInterface (Node2->Handle, &gEfiShellProtocolGuid, NewShell, Node2->Interface);\r
+ FreePool (Node2);\r
}\r
} else {\r
//\r
// no need to restore\r
//\r
- Status = gBS->UninstallProtocolInterface(gImageHandle,\r
- &gEfiShellProtocolGuid,\r
- NewShell);\r
+ gBS->UninstallProtocolInterface (gImageHandle, &gEfiShellProtocolGuid, NewShell);\r
}\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Cleanup the shell environment.\r
+\r
+ @param[in, out] NewShell The pointer to the new shell protocol structure.\r
+\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+CleanUpShellEnvironment (\r
+ IN OUT EFI_SHELL_PROTOCOL *NewShell\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
+ \r
+ CleanUpShellProtocol (NewShell);\r
+\r
Status = gBS->CloseEvent(NewShell->ExecutionBreak);\r
NewShell->ExecutionBreak = NULL;\r
\r
@retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InernalEfiShellStartMonitor(\r
VOID\r
)\r