]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
Check the pointer before use it to avoid potential access violation.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index 6d885f4681f51df49d83dcb1986ac1997c698cc1..42ae6e9bb0cd7d92204907d184f8e4267f5b8ed5 100644 (file)
@@ -30,8 +30,8 @@ SHELL_PARAM_ITEM SfoParamList[] = {
   };\r
 EFI_SHELL_ENVIRONMENT2        *mEfiShellEnvironment2;\r
 EFI_SHELL_INTERFACE           *mEfiShellInterface;\r
-EFI_SHELL_PROTOCOL            *mEfiShellProtocol;\r
-EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
+EFI_SHELL_PROTOCOL            *gEfiShellProtocol;\r
+EFI_SHELL_PARAMETERS_PROTOCOL *gEfiShellParametersProtocol;\r
 EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
 FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
 \r
@@ -84,6 +84,8 @@ ShellIsDecimalDigitCharacter (
   Helper function to find ShellEnvironment2 for constructor.\r
 \r
   @param[in] ImageHandle    A copy of the calling image's handle.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES    Memory allocation failed.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -123,7 +125,9 @@ ShellFindSE2 (
     //\r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
       Buffer = (EFI_HANDLE*)AllocateZeroPool(BufferSize);\r
-      ASSERT(Buffer != NULL);\r
+      if (Buffer == NULL) {\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
       Status = gBS->LocateHandle (ByProtocol,\r
                                   &gEfiShellEnvironment2Guid,\r
                                   NULL, // ignored for ByProtocol\r
@@ -182,7 +186,7 @@ ShellLibConstructorWorker (
   Status = gBS->OpenProtocol(\r
     ImageHandle,\r
     &gEfiShellProtocolGuid,\r
-    (VOID **)&mEfiShellProtocol,\r
+    (VOID **)&gEfiShellProtocol,\r
     ImageHandle,\r
     NULL,\r
     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -194,25 +198,25 @@ ShellLibConstructorWorker (
     Status = gBS->LocateProtocol(\r
       &gEfiShellProtocolGuid,\r
       NULL,\r
-      (VOID **)&mEfiShellProtocol\r
+      (VOID **)&gEfiShellProtocol\r
      );\r
     if (EFI_ERROR(Status)) {\r
-      mEfiShellProtocol = NULL;\r
+      gEfiShellProtocol = NULL;\r
     }\r
   }\r
   Status = gBS->OpenProtocol(\r
     ImageHandle,\r
     &gEfiShellParametersProtocolGuid,\r
-    (VOID **)&mEfiShellParametersProtocol,\r
+    (VOID **)&gEfiShellParametersProtocol,\r
     ImageHandle,\r
     NULL,\r
     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
    );\r
   if (EFI_ERROR(Status)) {\r
-    mEfiShellParametersProtocol = NULL;\r
+    gEfiShellParametersProtocol = NULL;\r
   }\r
 \r
-  if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) {\r
+  if (gEfiShellParametersProtocol == NULL || gEfiShellProtocol == NULL) {\r
     //\r
     // Moved to seperate function due to complexity\r
     //\r
@@ -238,18 +242,18 @@ ShellLibConstructorWorker (
   // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
   //\r
   if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) ||\r
-      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)   ) {\r
-    if (mEfiShellProtocol != NULL) {\r
-      FileFunctionMap.GetFileInfo     = mEfiShellProtocol->GetFileInfo;\r
-      FileFunctionMap.SetFileInfo     = mEfiShellProtocol->SetFileInfo;\r
-      FileFunctionMap.ReadFile        = mEfiShellProtocol->ReadFile;\r
-      FileFunctionMap.WriteFile       = mEfiShellProtocol->WriteFile;\r
-      FileFunctionMap.CloseFile       = mEfiShellProtocol->CloseFile;\r
-      FileFunctionMap.DeleteFile      = mEfiShellProtocol->DeleteFile;\r
-      FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;\r
-      FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;\r
-      FileFunctionMap.FlushFile       = mEfiShellProtocol->FlushFile;\r
-      FileFunctionMap.GetFileSize     = mEfiShellProtocol->GetFileSize;\r
+      (gEfiShellProtocol     != NULL && gEfiShellParametersProtocol != NULL)   ) {\r
+    if (gEfiShellProtocol != NULL) {\r
+      FileFunctionMap.GetFileInfo     = gEfiShellProtocol->GetFileInfo;\r
+      FileFunctionMap.SetFileInfo     = gEfiShellProtocol->SetFileInfo;\r
+      FileFunctionMap.ReadFile        = gEfiShellProtocol->ReadFile;\r
+      FileFunctionMap.WriteFile       = gEfiShellProtocol->WriteFile;\r
+      FileFunctionMap.CloseFile       = gEfiShellProtocol->CloseFile;\r
+      FileFunctionMap.DeleteFile      = gEfiShellProtocol->DeleteFile;\r
+      FileFunctionMap.GetFilePosition = gEfiShellProtocol->GetFilePosition;\r
+      FileFunctionMap.SetFilePosition = gEfiShellProtocol->SetFilePosition;\r
+      FileFunctionMap.FlushFile       = gEfiShellProtocol->FlushFile;\r
+      FileFunctionMap.GetFileSize     = gEfiShellProtocol->GetFileSize;\r
     } else {\r
       FileFunctionMap.GetFileInfo     = (EFI_SHELL_GET_FILE_INFO)FileHandleGetInfo;\r
       FileFunctionMap.SetFileInfo     = (EFI_SHELL_SET_FILE_INFO)FileHandleSetInfo;\r
@@ -285,8 +289,8 @@ ShellLibConstructor (
   )\r
 {\r
   mEfiShellEnvironment2       = NULL;\r
-  mEfiShellProtocol           = NULL;\r
-  mEfiShellParametersProtocol = NULL;\r
+  gEfiShellProtocol           = NULL;\r
+  gEfiShellParametersProtocol = NULL;\r
   mEfiShellInterface          = NULL;\r
   mEfiShellEnvironment2Handle = NULL;\r
 \r
@@ -330,19 +334,19 @@ ShellLibDestructor (
                        NULL);\r
     mEfiShellInterface = NULL;\r
   }\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     gBS->CloseProtocol(ImageHandle,\r
                        &gEfiShellProtocolGuid,\r
                        ImageHandle,\r
                        NULL);\r
-    mEfiShellProtocol = NULL;\r
+    gEfiShellProtocol = NULL;\r
   }\r
-  if (mEfiShellParametersProtocol != NULL) {\r
+  if (gEfiShellParametersProtocol != NULL) {\r
     gBS->CloseProtocol(ImageHandle,\r
                        &gEfiShellParametersProtocolGuid,\r
                        ImageHandle,\r
                        NULL);\r
-    mEfiShellParametersProtocol = NULL;\r
+    gEfiShellParametersProtocol = NULL;\r
   }\r
   mEfiShellEnvironment2Handle = NULL;\r
 \r
@@ -483,20 +487,18 @@ ShellOpenFileByDevicePath(
   EFI_FILE_PROTOCOL               *Handle1;\r
   EFI_FILE_PROTOCOL               *Handle2;\r
 \r
-  //\r
-  // ASERT for FileHandle, FilePath, and DeviceHandle being NULL\r
-  //\r
-  ASSERT(FilePath != NULL);\r
-  ASSERT(FileHandle != NULL);\r
-  ASSERT(DeviceHandle != NULL);\r
+  if (FilePath == NULL || FileHandle == NULL || DeviceHandle == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
   //\r
   // which shell interface should we use\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     //\r
     // use UEFI Shell 2.0 method.\r
     //\r
-    FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath);\r
+    FileName = gEfiShellProtocol->GetFilePathFromDevicePath(*FilePath);\r
     if (FileName == NULL) {\r
       return (EFI_INVALID_PARAMETER);\r
     }\r
@@ -601,7 +603,7 @@ ShellOpenFileByDevicePath(
   otherwise, the Filehandle is NULL. The Attributes is valid only for\r
   EFI_FILE_MODE_CREATE.\r
 \r
-  if FileNAme is NULL then ASSERT()\r
+  if FileName is NULL then ASSERT()\r
 \r
   @param  FileName               pointer to file name\r
   @param  FileHandle           pointer to the file handle.\r
@@ -648,14 +650,14 @@ ShellOpenFileByName(
     return (EFI_INVALID_PARAMETER);\r
   }\r
 \r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE && (Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
       return ShellCreateDirectory(FileName, FileHandle);\r
     }\r
     //\r
     // Use UEFI Shell 2.0 method\r
     //\r
-    Status = mEfiShellProtocol->OpenFileByName(FileName,\r
+    Status = gEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
     if (StrCmp(FileName, L"NUL") != 0 && !EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
@@ -718,11 +720,11 @@ ShellCreateDirectory(
   OUT SHELL_FILE_HANDLE                  *FileHandle\r
   )\r
 {\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     //\r
     // Use UEFI Shell 2.0 method\r
     //\r
-    return (mEfiShellProtocol->CreateFile(DirectoryName,\r
+    return (gEfiShellProtocol->CreateFile(DirectoryName,\r
                           EFI_FILE_DIRECTORY,\r
                           FileHandle\r
                          ));\r
@@ -1033,12 +1035,12 @@ ShellGetExecutionBreakFlag(
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
 \r
     //\r
     // We are using UEFI Shell 2.0; see if the event has been triggered\r
     //\r
-    if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {\r
+    if (gBS->CheckEvent(gEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {\r
       return (FALSE);\r
     }\r
     return (TRUE);\r
@@ -1047,8 +1049,11 @@ ShellGetExecutionBreakFlag(
   //\r
   // using EFI Shell; call the function to check\r
   //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  return (mEfiShellEnvironment2->GetExecutionBreak());\r
+  if (mEfiShellEnvironment2 != NULL) {\r
+    return (mEfiShellEnvironment2->GetExecutionBreak());\r
+  }\r
+\r
+  return (FALSE);\r
 }\r
 /**\r
   return the value of an environment variable\r
@@ -1070,19 +1075,18 @@ ShellGetEnvironmentVariable (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->GetEnv(EnvKey));\r
+  if (gEfiShellProtocol != NULL) {\r
+    return (gEfiShellProtocol->GetEnv(EnvKey));\r
   }\r
 \r
   //\r
-  // ASSERT that we must have EFI shell\r
+  // Check for EFI shell\r
   //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
+  if (mEfiShellEnvironment2 != NULL) {\r
+    return (mEfiShellEnvironment2->GetEnv((CHAR16*)EnvKey));\r
+  }\r
 \r
-  //\r
-  // using EFI Shell\r
-  //\r
-  return (mEfiShellEnvironment2->GetEnv((CHAR16*)EnvKey));\r
+  return NULL;\r
 }\r
 /**\r
   set the value of an environment variable\r
@@ -1115,8 +1119,8 @@ ShellSetEnvironmentVariable (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile));\r
+  if (gEfiShellProtocol != NULL) {\r
+    return (gEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile));\r
   }\r
 \r
   //\r
@@ -1168,26 +1172,30 @@ ShellExecute (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     //\r
     // Call UEFI Shell 2.0 version (not using Output parameter)\r
     //\r
-    return (mEfiShellProtocol->Execute(ParentHandle,\r
+    return (gEfiShellProtocol->Execute(ParentHandle,\r
                                       CommandLine,\r
                                       EnvironmentVariables,\r
                                       Status));\r
   }\r
+\r
   //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  //\r
-  // Call EFI Shell version (not using EnvironmentVariables or Status parameters)\r
-  // Due to oddity in the EFI shell we want to dereference the ParentHandle here\r
+  // Check for EFI shell\r
   //\r
-  return (mEfiShellEnvironment2->Execute(*ParentHandle,\r
-                                        CommandLine,\r
-                                        Output));\r
+  if (mEfiShellEnvironment2 != NULL) {\r
+    //\r
+    // Call EFI Shell version (not using EnvironmentVariables or Status parameters)\r
+    // Due to oddity in the EFI shell we want to dereference the ParentHandle here\r
+    //\r
+    return (mEfiShellEnvironment2->Execute(*ParentHandle,\r
+                                          CommandLine,\r
+                                          Output));\r
+  }\r
+\r
+  return (EFI_UNSUPPORTED);\r
 }\r
 /**\r
   Retreives the current directory path\r
@@ -1210,9 +1218,10 @@ ShellGetCurrentDir (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->GetCurDir(DeviceName));\r
+  if (gEfiShellProtocol != NULL) {\r
+    return (gEfiShellProtocol->GetCurDir(DeviceName));\r
   }\r
+\r
   //\r
   // Check for EFI shell\r
   //\r
@@ -1243,43 +1252,45 @@ ShellSetPageBreakMode (
     //\r
     // check for UEFI Shell 2.0\r
     //\r
-    if (mEfiShellProtocol != NULL) {\r
+    if (gEfiShellProtocol != NULL) {\r
       //\r
       // Enable with UEFI 2.0 Shell\r
       //\r
-      mEfiShellProtocol->EnablePageBreak();\r
+      gEfiShellProtocol->EnablePageBreak();\r
       return;\r
     } else {\r
       //\r
-      // ASSERT that must have EFI Shell\r
-      //\r
-      ASSERT(mEfiShellEnvironment2 != NULL);\r
+      // Check for EFI shell\r
       //\r
-      // Enable with EFI Shell\r
-      //\r
-      mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);\r
-      return;\r
+      if (mEfiShellEnvironment2 != NULL) {\r
+        //\r
+        // Enable with EFI Shell\r
+        //\r
+        mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);\r
+        return;\r
+      }\r
     }\r
   } else {\r
     //\r
     // check for UEFI Shell 2.0\r
     //\r
-    if (mEfiShellProtocol != NULL) {\r
+    if (gEfiShellProtocol != NULL) {\r
       //\r
       // Disable with UEFI 2.0 Shell\r
       //\r
-      mEfiShellProtocol->DisablePageBreak();\r
+      gEfiShellProtocol->DisablePageBreak();\r
       return;\r
     } else {\r
       //\r
-      // ASSERT that must have EFI Shell\r
-      //\r
-      ASSERT(mEfiShellEnvironment2 != NULL);\r
+      // Check for EFI shell\r
       //\r
-      // Disable with EFI Shell\r
-      //\r
-      mEfiShellEnvironment2->DisablePageBreak ();\r
-      return;\r
+      if (mEfiShellEnvironment2 != NULL) {\r
+        //\r
+        // Disable with EFI Shell\r
+        //\r
+        mEfiShellEnvironment2->DisablePageBreak ();\r
+        return;\r
+      }\r
     }\r
   }\r
 }\r
@@ -1306,8 +1317,8 @@ typedef struct {
   EFI_SHELL_FILE_INFO based list.  it is up to the caller to free the memory via\r
   the ShellCloseFileMetaArg function.\r
 \r
-  @param[in] FileList          the EFI shell list type\r
-  @param[in,out] ListHead      the list to add to\r
+  @param[in] FileList           the EFI shell list type\r
+  @param[in, out] ListHead      the list to add to\r
 \r
   @retval the resultant head of the double linked new format list;\r
 **/\r
@@ -1353,8 +1364,9 @@ InternalShellConvertFileListType (
     // allocate a new EFI_SHELL_FILE_INFO object\r
     //\r
     NewInfo               = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
-    ASSERT(NewInfo != NULL);\r
     if (NewInfo == NULL) {\r
+      ShellCloseFileMetaArg(&(EFI_SHELL_FILE_INFO*)ListHead);\r
+      ListHead = NULL;\r
       break;\r
     }\r
 \r
@@ -1377,9 +1389,11 @@ InternalShellConvertFileListType (
     //\r
     // make sure all the memory allocations were sucessful\r
     //\r
-    ASSERT(NewInfo->FullName != NULL);\r
-    ASSERT(NewInfo->FileName != NULL);\r
-    ASSERT(NewInfo->Info     != NULL);\r
+    if (NULL == NewInfo->FullName || NewInfo->FileName == NULL || NewInfo->Info == NULL) {\r
+      ShellCloseFileMetaArg(&(EFI_SHELL_FILE_INFO*)ListHead);\r
+      ListHead = NULL;\r
+      break;\r
+    }\r
 \r
     //\r
     // Copt the strings and structure\r
@@ -1438,7 +1452,7 @@ ShellOpenFileMetaArg (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
+  if (gEfiShellProtocol != NULL) {\r
     if (*ListHead == NULL) {\r
       *ListHead = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
       if (*ListHead == NULL) {\r
@@ -1446,13 +1460,13 @@ ShellOpenFileMetaArg (
       }\r
       InitializeListHead(&((*ListHead)->Link));\r
     }\r
-    Status = mEfiShellProtocol->OpenFileList(Arg,\r
+    Status = gEfiShellProtocol->OpenFileList(Arg,\r
                                            OpenMode,\r
                                            ListHead);\r
     if (EFI_ERROR(Status)) {\r
-      mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+      gEfiShellProtocol->RemoveDupInFileList(ListHead);\r
     } else {\r
-      Status = mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+      Status = gEfiShellProtocol->RemoveDupInFileList(ListHead);\r
     }\r
     if (*ListHead != NULL && IsListEmpty(&(*ListHead)->Link)) {\r
       FreePool(*ListHead);\r
@@ -1463,49 +1477,50 @@ ShellOpenFileMetaArg (
   }\r
 \r
   //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-\r
-  //\r
-  // make sure the list head is initialized\r
+  // Check for EFI shell\r
   //\r
-  InitializeListHead(&mOldStyleFileList);\r
+  if (mEfiShellEnvironment2 != NULL) {\r
+    //\r
+    // make sure the list head is initialized\r
+    //\r
+    InitializeListHead(&mOldStyleFileList);\r
 \r
-  //\r
-  // Get the EFI Shell list of files\r
-  //\r
-  Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList);\r
-  if (EFI_ERROR(Status)) {\r
-    *ListHead = NULL;\r
-    return (Status);\r
-  }\r
+    //\r
+    // Get the EFI Shell list of files\r
+    //\r
+    Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList);\r
+    if (EFI_ERROR(Status)) {\r
+      *ListHead = NULL;\r
+      return (Status);\r
+    }\r
 \r
-  if (*ListHead == NULL) {\r
-    *ListHead = (EFI_SHELL_FILE_INFO    *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
     if (*ListHead == NULL) {\r
-      return (EFI_OUT_OF_RESOURCES);\r
+      *ListHead = (EFI_SHELL_FILE_INFO    *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
+      if (*ListHead == NULL) {\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
+      InitializeListHead(&((*ListHead)->Link));\r
     }\r
-    InitializeListHead(&((*ListHead)->Link));\r
-  }\r
 \r
-  //\r
-  // Convert that to equivalent of UEFI Shell 2.0 structure\r
-  //\r
-  InternalShellConvertFileListType(&mOldStyleFileList, &(*ListHead)->Link);\r
+    //\r
+    // Convert that to equivalent of UEFI Shell 2.0 structure\r
+    //\r
+    InternalShellConvertFileListType(&mOldStyleFileList, &(*ListHead)->Link);\r
 \r
-  //\r
-  // Free the EFI Shell version that was converted.\r
-  //\r
-  mEfiShellEnvironment2->FreeFileList(&mOldStyleFileList);\r
+    //\r
+    // Free the EFI Shell version that was converted.\r
+    //\r
+    mEfiShellEnvironment2->FreeFileList(&mOldStyleFileList);\r
 \r
-  if ((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink && (*ListHead)->Link.BackLink == &((*ListHead)->Link)) {\r
-    FreePool(*ListHead);\r
-    *ListHead = NULL;\r
-    Status = EFI_NOT_FOUND;\r
+    if ((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink && (*ListHead)->Link.BackLink == &((*ListHead)->Link)) {\r
+      FreePool(*ListHead);\r
+      *ListHead = NULL;\r
+      Status = EFI_NOT_FOUND;\r
+    }\r
+    return (Status);\r
   }\r
 \r
-  return (Status);\r
+  return (EFI_UNSUPPORTED);\r
 }\r
 /**\r
   Free the linked list returned from ShellOpenFileMetaArg.\r
@@ -1532,9 +1547,9 @@ ShellCloseFileMetaArg (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->FreeFileList(ListHead));\r
-  } else {\r
+  if (gEfiShellProtocol != NULL) {\r
+    return (gEfiShellProtocol->FreeFileList(ListHead));\r
+  } else if (mEfiShellEnvironment2 != NULL) {\r
     //\r
     // Since this is EFI Shell version we need to free our internally made copy\r
     // of the list\r
@@ -1551,6 +1566,8 @@ ShellCloseFileMetaArg (
     }\r
     return EFI_SUCCESS;\r
   }\r
+\r
+  return (EFI_UNSUPPORTED);\r
 }\r
 \r
 /**\r
@@ -1602,7 +1619,6 @@ ShellFindFilePath (
     Size = StrSize(Path);\r
     Size += StrSize(FileName);\r
     TestPath = AllocateZeroPool(Size);\r
-    ASSERT(TestPath != NULL);\r
     if (TestPath == NULL) {\r
       return (NULL);\r
     }\r
@@ -1709,7 +1725,6 @@ ShellFindFilePathEx (
   Size =  StrSize(FileName);\r
   Size += StrSize(FileExtension);\r
   TestPath = AllocateZeroPool(Size);\r
-  ASSERT(TestPath != NULL);\r
   if (TestPath == NULL) {\r
     return (NULL);\r
   }\r
@@ -1923,6 +1938,10 @@ InternalCommandLineParse (
   // initialize the linked list\r
   //\r
   *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY));\r
+  if (*CheckPackage == NULL) {\r
+    return (EFI_OUT_OF_RESOURCES);\r
+  }\r
+\r
   InitializeListHead(*CheckPackage);\r
 \r
   //\r
@@ -1945,9 +1964,17 @@ InternalCommandLineParse (
       // this is a flag\r
       //\r
       CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE));\r
-      ASSERT(CurrentItemPackage != NULL);\r
+      if (CurrentItemPackage == NULL) {\r
+        ShellCommandLineFreeVarList(*CheckPackage);\r
+        *CheckPackage = NULL;\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
       CurrentItemPackage->Name  = AllocateZeroPool(StrSize(Argv[LoopCounter]));\r
-      ASSERT(CurrentItemPackage->Name != NULL);\r
+      if (CurrentItemPackage->Name == NULL) {\r
+        ShellCommandLineFreeVarList(*CheckPackage);\r
+        *CheckPackage = NULL;\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
       StrCpy(CurrentItemPackage->Name,  Argv[LoopCounter]);\r
       CurrentItemPackage->Type  = CurrentItemType;\r
       CurrentItemPackage->OriginalPosition = (UINTN)(-1);\r
@@ -2011,11 +2038,19 @@ InternalCommandLineParse (
         TempPointer++;\r
       }\r
       CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE));\r
-      ASSERT(CurrentItemPackage != NULL);\r
+      if (CurrentItemPackage == NULL) {\r
+        ShellCommandLineFreeVarList(*CheckPackage);\r
+        *CheckPackage = NULL;\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
       CurrentItemPackage->Name  = NULL;\r
       CurrentItemPackage->Type  = TypePosition;\r
       CurrentItemPackage->Value = AllocateZeroPool(StrSize(TempPointer));\r
-      ASSERT(CurrentItemPackage->Value != NULL);\r
+      if (CurrentItemPackage->Value == NULL) {\r
+        ShellCommandLineFreeVarList(*CheckPackage);\r
+        *CheckPackage = NULL;\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
       StrCpy(CurrentItemPackage->Value, TempPointer);\r
       CurrentItemPackage->OriginalPosition = Count++;\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
@@ -2025,8 +2060,9 @@ InternalCommandLineParse (
       //\r
       if (ProblemParam != NULL) {\r
         *ProblemParam = AllocateZeroPool(StrSize(Argv[LoopCounter]));\r
-        ASSERT(*ProblemParam != NULL);\r
-        StrCpy(*ProblemParam, Argv[LoopCounter]);      \r
+        if (*ProblemParam != NULL) {\r
+          StrCpy(*ProblemParam, Argv[LoopCounter]);      \r
+        }\r
       }\r
       ShellCommandLineFreeVarList(*CheckPackage);\r
       *CheckPackage = NULL;\r
@@ -2089,13 +2125,13 @@ ShellCommandLineParseEx (
   //\r
   // Check for UEFI Shell 2.0 protocols\r
   //\r
-  if (mEfiShellParametersProtocol != NULL) {\r
+  if (gEfiShellParametersProtocol != NULL) {\r
     return (InternalCommandLineParse(CheckList,\r
                                      CheckPackage,\r
                                      ProblemParam,\r
                                      AutoPageBreak,\r
-                                     (CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
-                                     mEfiShellParametersProtocol->Argc,\r
+                                     (CONST CHAR16**) gEfiShellParametersProtocol->Argv,\r
+                                     gEfiShellParametersProtocol->Argc,\r
                                      AlwaysAllowNumbers));\r
   }\r
 \r
@@ -2200,14 +2236,9 @@ ShellCommandLineGetFlag (
   CHAR16                        *TempString;\r
 \r
   //\r
-  // ASSERT that both CheckPackage and KeyString aren't NULL\r
-  //\r
-  ASSERT(KeyString != NULL);\r
-\r
-  //\r
-  // return FALSE for no package\r
+  // return FALSE for no package or KeyString is NULL\r
   //\r
-  if (CheckPackage == NULL) {\r
+  if (CheckPackage == NULL || KeyString == NULL) {\r
     return (FALSE);\r
   }\r
 \r
@@ -2269,9 +2300,9 @@ ShellCommandLineGetValue (
   CHAR16                        *TempString;\r
 \r
   //\r
-  // check for CheckPackage == NULL\r
+  // return NULL for no package or KeyString is NULL\r
   //\r
-  if (CheckPackage == NULL) {\r
+  if (CheckPackage == NULL || KeyString == NULL) {\r
     return (NULL);\r
   }\r
 \r
@@ -2443,14 +2474,14 @@ ShellCommandLineCheckDuplicate (
 \r
   If the string would grow bigger than NewSize it will halt and return error.\r
 \r
-  @param[in] SourceString             The string with source buffer.\r
-  @param[in,out] NewString            The string with resultant buffer.\r
-  @param[in] NewSize                  The size in bytes of NewString.\r
-  @param[in] FindTarget               The string to look for.\r
-  @param[in] ReplaceWith              The string to replace FindTarget with.\r
-  @param[in] SkipPreCarrot            If TRUE will skip a FindTarget that has a '^'\r
-                                      immediately before it.\r
-  @param[in] ParameterReplacing       If TRUE will add "" around items with spaces.\r
+  @param[in] SourceString              The string with source buffer.\r
+  @param[in, out] NewString            The string with resultant buffer.\r
+  @param[in] NewSize                   The size in bytes of NewString.\r
+  @param[in] FindTarget                The string to look for.\r
+  @param[in] ReplaceWith               The string to replace FindTarget with.\r
+  @param[in] SkipPreCarrot             If TRUE will skip a FindTarget that has a '^'\r
+                                       immediately before it.\r
+  @param[in] ParameterReplacing        If TRUE will add "" around items with spaces.\r
 \r
   @retval EFI_INVALID_PARAMETER       SourceString was NULL.\r
   @retval EFI_INVALID_PARAMETER       NewString was NULL.\r
@@ -2491,7 +2522,9 @@ ShellCopySearchAndReplace(
     Replace = StrnCatGrow(&Replace, NULL, ReplaceWith, 0);\r
   } else {\r
     Replace = AllocateZeroPool(StrSize(ReplaceWith) + 2*sizeof(CHAR16));\r
-    UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith);\r
+    if (Replace != NULL) {\r
+      UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith);\r
+    }\r
   }\r
   if (Replace == NULL) {\r
     return (EFI_OUT_OF_RESOURCES);\r
@@ -2547,8 +2580,8 @@ InternalPrintTo (
   if (Size == 0) {\r
     return (EFI_SUCCESS);\r
   }\r
-  if (mEfiShellParametersProtocol != NULL) {\r
-    return (mEfiShellProtocol->WriteFile(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));\r
+  if (gEfiShellParametersProtocol != NULL) {\r
+    return (gEfiShellProtocol->WriteFile(gEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));\r
   }\r
   if (mEfiShellInterface          != NULL) {\r
     //\r
@@ -2664,32 +2697,40 @@ InternalShellPrintWorker(
     // update the attribute\r
     //\r
     if (ResumeLocation != NULL) {\r
-      switch (*(ResumeLocation+1)) {\r
-        case (L'N'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);\r
-          break;\r
-        case (L'E'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
-          break;\r
-        case (L'H'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
-          break;\r
-        case (L'B'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
-          break;\r
-        case (L'V'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
-          break;\r
-        default:\r
-          //\r
-          // Print a simple '%' symbol\r
-          //\r
-          Status = InternalPrintTo(L"%");\r
-          if (EFI_ERROR(Status)) {\r
+      if (*(ResumeLocation-1) == L'^') {\r
+        //\r
+        // Print a simple '%' symbol\r
+        //\r
+        Status = InternalPrintTo(L"%");\r
+        ResumeLocation = ResumeLocation - 1;\r
+      } else {\r
+        switch (*(ResumeLocation+1)) {\r
+          case (L'N'):\r
+            gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);\r
             break;\r
-          }\r
-          ResumeLocation = ResumeLocation - 1;\r
-          break;\r
+          case (L'E'):\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            break;\r
+          case (L'H'):\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            break;\r
+          case (L'B'):\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            break;\r
+          case (L'V'):\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            break;\r
+          default:\r
+            //\r
+            // Print a simple '%' symbol\r
+            //\r
+            Status = InternalPrintTo(L"%");\r
+            if (EFI_ERROR(Status)) {\r
+              break;\r
+            }\r
+            ResumeLocation = ResumeLocation - 1;\r
+            break;\r
+        }\r
       }\r
     } else {\r
       //\r
@@ -2849,13 +2890,13 @@ ShellIsDirectory(
     //\r
     // try good logic first.\r
     //\r
-    if (mEfiShellProtocol != NULL) {\r
+    if (gEfiShellProtocol != NULL) {\r
       TempLocation  = StrnCatGrow(&TempLocation, NULL, DirName, 0);\r
       TempLocation2 = StrStr(TempLocation, L":");\r
       if (TempLocation2 != NULL && StrLen(StrStr(TempLocation, L":")) == 2) {\r
         *(TempLocation2+1) = CHAR_NULL;\r
       }\r
-      if (mEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) {\r
+      if (gEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) {\r
         FreePool(TempLocation);\r
         return (EFI_SUCCESS);\r
       }\r
@@ -3002,8 +3043,8 @@ ShellStrToUintn(
   if Destination's current length (including NULL terminator) is already more then\r
   CurrentSize, then ASSERT()\r
 \r
-  @param[in,out] Destination   The String to append onto\r
-  @param[in,out] CurrentSize   on call the number of bytes in Destination.  On\r
+  @param[in, out] Destination   The String to append onto\r
+  @param[in, out] CurrentSize   on call the number of bytes in Destination.  On\r
                                 return possibly the new size (still in bytes).  if NULL\r
                                 then allocate whatever is needed.\r
   @param[in]      Source        The String to append from\r
@@ -3071,11 +3112,9 @@ StrnCatGrow (
       NewSize += 2 * Count * sizeof(CHAR16);\r
     }\r
     *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);\r
-    ASSERT(*Destination != NULL);\r
     *CurrentSize = NewSize;\r
   } else {\r
     *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));\r
-    ASSERT(*Destination != NULL);\r
   }\r
 \r
   //\r
@@ -3798,3 +3837,158 @@ ShellIsHexOrDecimalNumber (
   }\r
   return (FALSE);\r
 }\r
+\r
+/**\r
+  Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned\r
+  buffer.  The returned buffer must be callee freed.\r
+\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
+  @param[in]       Handle        SHELL_FILE_HANDLE to read from.\r
+  @param[in, out]  Ascii         Boolean value for indicating whether the file is\r
+                                 Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+  @return                        The line of text from the file.\r
+  @retval NULL                   There was not enough memory available.\r
+\r
+  @sa ShellFileHandleReadLine\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+ShellFileHandleReturnLine(\r
+  IN SHELL_FILE_HANDLE            Handle,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  CHAR16          *RetVal;\r
+  UINTN           Size;\r
+  EFI_STATUS      Status;\r
+\r
+  Size = 0;\r
+  RetVal = NULL;\r
+\r
+  Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    RetVal = AllocateZeroPool(Size);\r
+    if (RetVal == NULL) {\r
+      return (NULL);\r
+    }\r
+    Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+    \r
+  }\r
+  if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
+    FreePool(RetVal);\r
+    RetVal = NULL;\r
+  }\r
+  return (RetVal);\r
+}\r
+\r
+/**\r
+  Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE.\r
+\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
+  @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]       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
+                                 If the buffer is is too small and Truncate is FALSE,\r
+                                 then no read will occur.\r
+\r
+  @param[in, out]  Ascii         Boolean value for indicating whether the file is\r
+                                 Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+  @retval EFI_SUCCESS           The operation was successful.  The line is stored in\r
+                                Buffer.\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
+                                Size was updated to the minimum space required.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFileHandleReadLine(\r
+  IN SHELL_FILE_HANDLE          Handle,\r
+  IN OUT CHAR16                 *Buffer,\r
+  IN OUT UINTN                  *Size,\r
+  IN BOOLEAN                    Truncate,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  CHAR16      CharBuffer;\r
+  UINTN       CharSize;\r
+  UINTN       CountSoFar;\r
+  UINT64      OriginalFilePosition;\r
+\r
+\r
+  if (Handle == NULL\r
+    ||Size   == NULL\r
+   ){\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  if (Buffer == NULL) {\r
+    ASSERT(*Size == 0);\r
+  } else {\r
+    *Buffer = CHAR_NULL;\r
+  }\r
+  gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);\r
+  if (OriginalFilePosition == 0) {\r
+    CharSize = sizeof(CHAR16);\r
+    Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+    ASSERT_EFI_ERROR(Status);\r
+    if (CharBuffer == gUnicodeFileTag) {\r
+      *Ascii = FALSE;\r
+    } else {\r
+      *Ascii = TRUE;\r
+      gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+    }\r
+  }\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
+      break;\r
+    }\r
+    //\r
+    // if we have space save it...\r
+    //\r
+    if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
+      ASSERT(Buffer != NULL);\r
+      ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
+      ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // if we ran out of space tell when...\r
+  //\r
+  if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
+    *Size = (CountSoFar+1)*sizeof(CHAR16);\r
+    if (!Truncate) {\r
+      gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+    } else {\r
+      DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));\r
+    }\r
+    return (EFI_BUFFER_TOO_SMALL);\r
+  }\r
+  while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
+    Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
+  }\r
+\r
+  return (Status);\r
+}\r