VirtualBox

Ignore:
Timestamp:
Mar 12, 2019 12:40:12 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129295
Message:

EFI: First step in UDK2018 merge. Does not build yet.

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
3 added
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ConsoleLogger.c

    r58459 r77662  
    22  Provides interface to shell console logger.
    33
    4   Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
    5   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
     4  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
     5  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
     6  (C) Copyright 2016 Hewlett-Packard Development Company, L.P.<BR>
    67  This program and the accompanying materials
    78  are licensed and made available under the terms and conditions of the BSD License
     
    2930**/
    3031EFI_STATUS
    31 EFIAPI
    3232ConsoleLoggerInstall(
    3333  IN CONST UINTN ScreensToSave,
     
    9292  gST->ConOut           = &(*ConsoleInfo)->OurConOut;
    9393
     94  //
     95  // Update the CRC32 in the EFI System Table header
     96  //
     97  gST->Hdr.CRC32 = 0;
     98  gBS->CalculateCrc32 (
     99        (UINT8 *)&gST->Hdr,
     100        gST->Hdr.HeaderSize,
     101        &gST->Hdr.CRC32
     102        );
    94103  return (Status);
    95104}
     
    105114**/
    106115EFI_STATUS
    107 EFIAPI
    108116ConsoleLoggerUninstall(
    109117  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    127135  gST->ConOut = ConsoleInfo->OldConOut;
    128136
     137  //
     138  // Update the CRC32 in the EFI System Table header
     139  //
     140  gST->Hdr.CRC32 = 0;
     141  gBS->CalculateCrc32 (
     142        (UINT8 *)&gST->Hdr,
     143        gST->Hdr.HeaderSize,
     144        &gST->Hdr.CRC32
     145        );
     146
    129147  return (gBS->UninstallProtocolInterface(gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID*)&ConsoleInfo->OurConOut));
    130148}
     
    143161**/
    144162EFI_STATUS
    145 EFIAPI
    146163ConsoleLoggerDisplayHistory(
    147164  IN CONST BOOLEAN  Forward,
     
    219236**/
    220237EFI_STATUS
    221 EFIAPI
    222238ConsoleLoggerStopHistory(
    223239  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    228244    return (EFI_SUCCESS);
    229245  }
     246
     247  //
     248  // Clear the screen
     249  //
     250  ConsoleInfo->OldConOut->ClearScreen(ConsoleInfo->OldConOut);
     251
    230252  ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;
    231253  return (UpdateDisplayFromHistory(ConsoleInfo));
     
    240262**/
    241263EFI_STATUS
    242 EFIAPI
    243264UpdateDisplayFromHistory(
    244265  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    302323        StringSegmentEndChar = CHAR_NULL;
    303324        for ( StringSegmentEnd = StringSegment
    304             ; StringSegmentEnd != CHAR_NULL
     325            ; *StringSegmentEnd != CHAR_NULL
    305326            ; StringSegmentEnd++
    306327            , Column++
     
    411432  if (!EFI_ERROR (Status)) {
    412433    ConsoleLoggerResetBuffers(ConsoleInfo);
     434    if (ExtendedVerification) {
     435      ConsoleInfo->OriginalStartRow = 0;
     436      ConsoleInfo->CurrentStartRow = 0;
     437    }
    413438  }
    414439
     
    425450**/
    426451EFI_STATUS
    427 EFIAPI
    428452AppendStringToHistory(
    429453  IN CONST CHAR16 *String,
     
    580604**/
    581605EFI_STATUS
    582 EFIAPI
    583606ConsoleLoggerOutputStringSplit(
    584607  IN CONST CHAR16   *String,
     
    609632**/
    610633EFI_STATUS
    611 EFIAPI
    612634ConsoleLoggerDoPageBreak(
    613635  VOID
     
    668690**/
    669691EFI_STATUS
    670 EFIAPI
    671692ConsoleLoggerPrintWithPageBreak(
    672693  IN CONST CHAR16   *String,
     
    964985  //
    965986  if (!EFI_ERROR (Status)) {
    966     ConsoleInfo->OurConOut.Mode = gST->ConOut->Mode;
     987    ConsoleInfo->OurConOut.Mode = ConsoleInfo->OldConOut->Mode;
    967988    ConsoleLoggerResetBuffers(ConsoleInfo);
     989    ConsoleInfo->OriginalStartRow = 0;
     990    ConsoleInfo->CurrentStartRow = 0;
     991    ConsoleInfo->OurConOut.ClearScreen (&ConsoleInfo->OurConOut);
    968992  }
    969993
     
    11761200**/
    11771201EFI_STATUS
    1178 EFIAPI
    11791202ConsoleLoggerResetBuffers(
    11801203  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ConsoleLogger.h

    r58459 r77662  
    5959**/
    6060EFI_STATUS
    61 EFIAPI
    6261ConsoleLoggerInstall(
    6362  IN CONST UINTN ScreensToSave,
     
    7574**/
    7675EFI_STATUS
    77 EFIAPI
    7876ConsoleLoggerUninstall(
    7977  IN OUT CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    9391**/
    9492EFI_STATUS
    95 EFIAPI
    9693ConsoleLoggerDisplayHistory(
    9794  IN CONST BOOLEAN  Forward,
     
    110107**/
    111108EFI_STATUS
    112 EFIAPI
    113109ConsoleLoggerStopHistory(
    114110  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    123119**/
    124120EFI_STATUS
    125 EFIAPI
    126121UpdateDisplayFromHistory(
    127122  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
     
    321316**/
    322317EFI_STATUS
    323 EFIAPI
    324318ConsoleLoggerResetBuffers(
    325319  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ConsoleWrappers.c

    r58466 r77662  
    22  Function definitions for shell simple text in and out on top of file handles.
    33
    4   Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
    5   Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
     4  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
     5  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
    66  This program and the accompanying materials
    77  are licensed and made available under the terms and conditions of the BSD License
     
    1515
    1616#include "Shell.h"
     17
     18extern BOOLEAN AsciiRedirection;
    1719
    1820typedef struct {
     
    8284{
    8385  UINTN Size;
     86  UINTN CharSize;
    8487
    8588  //
     
    99102  Size = sizeof(CHAR16);
    100103
     104  if(!AsciiRedirection) {
     105    CharSize = sizeof(CHAR16);
     106  } else {
     107    CharSize = sizeof(CHAR8);
     108  }
    101109  //
    102110  // Decrement the amount of free space by Size or set to zero (for odd length files)
    103111  //
    104   if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > Size) {
    105     ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= Size;
     112  if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > CharSize) {
     113    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= CharSize;
    106114  } else {
    107115    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile = 0;
     
    126134**/
    127135EFI_SIMPLE_TEXT_INPUT_PROTOCOL*
    128 EFIAPI
    129136CreateSimpleTextInOnFile(
    130137  IN SHELL_FILE_HANDLE  FileHandleToUse,
     
    193200**/
    194201EFI_STATUS
    195 EFIAPI
    196202CloseSimpleTextInOnFile(
    197203  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *SimpleTextIn
     
    427433**/
    428434EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
    429 EFIAPI
    430435CreateSimpleTextOutOnFile(
    431436  IN SHELL_FILE_HANDLE               FileHandleToUse,
     
    477482    return ((EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)ProtocolToReturn);
    478483  } else {
    479     FreePool(ProtocolToReturn);
     484    SHELL_FREE_NON_NULL(ProtocolToReturn->SimpleTextOut.Mode);
     485    SHELL_FREE_NON_NULL(ProtocolToReturn);
    480486    return (NULL);
    481487  }
     
    491497**/
    492498EFI_STATUS
    493 EFIAPI
    494499CloseSimpleTextOutOnFile(
    495500  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOut
     
    504509    &gEfiSimpleTextOutProtocolGuid,
    505510    &(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->SimpleTextOut));
     511  FreePool(SimpleTextOut->Mode);
    506512  FreePool(SimpleTextOut);
    507513  return (Status);
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ConsoleWrappers.h

    r58466 r77662  
    22  Function definitions for shell simple text in and out on top of file handles.
    33
    4   Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
     4  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
    55  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
    66  This program and the accompanying materials
     
    2828**/
    2929EFI_SIMPLE_TEXT_INPUT_PROTOCOL*
    30 EFIAPI
    3130CreateSimpleTextInOnFile(
    3231  IN SHELL_FILE_HANDLE  FileHandleToUse,
     
    4342**/
    4443EFI_STATUS
    45 EFIAPI
    4644CloseSimpleTextInOnFile(
    4745  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *SimpleTextIn
     
    6058**/
    6159EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
    62 EFIAPI
    6360CreateSimpleTextOutOnFile(
    6461  IN SHELL_FILE_HANDLE               FileHandleToUse,
     
    7673**/
    7774EFI_STATUS
    78 EFIAPI
    7975CloseSimpleTextOutOnFile(
    8076  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOut
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/FileHandleInternal.h

    r48674 r77662  
    2424**/
    2525VOID
    26 EFIAPI
    2726MoveCursorBackward (
    2827  IN     UINTN                   LineLength,
     
    4039**/
    4140VOID
    42 EFIAPI
    4341MoveCursorForward (
    4442  IN     UINTN                   LineLength,
     
    5856**/
    5957VOID
    60 EFIAPI
    6158PrintCommandHistory (
    6259  IN CONST UINTN TotalCols,
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/FileHandleWrappers.c

    r58466 r77662  
    33  StdIn, StdOut, StdErr, etc...).
    44
    5   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
    6   Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
     5  Copyright 2016 Dell Inc.
     6  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
     7  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
    78  This program and the accompanying materials
    89  are licensed and made available under the terms and conditions of the BSD License
     
    1718#include "Shell.h"
    1819#include "FileHandleInternal.h"
     20
     21#define MEM_WRITE_REALLOC_OVERHEAD 1024
    1922
    2023/**
     
    160163  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
    161164    return (EFI_UNSUPPORTED);
    162   } else {
    163     return (gST->ConOut->OutputString(gST->ConOut, Buffer));
    164   }
     165  }
     166  if (*((CHAR16 *)Buffer) == gUnicodeFileTag) {
     167    return (gST->ConOut->OutputString(gST->ConOut, (CHAR16 *)Buffer + 1));
     168  }
     169  return (gST->ConOut->OutputString(gST->ConOut, Buffer));
    165170}
    166171
     
    286291{
    287292  return (EFI_SUCCESS);
     293}
     294
     295/**
     296  Create the TAB completion list.
     297
     298  @param[in]  InputString       The command line to expand.
     299  @param[in]  StringLen         Length of the command line.
     300  @param[in]  BufferSize        Buffer size.
     301  @param[in, out] TabCompletionList Return the TAB completion list.
     302  @param[in, out] TabUpdatePos      Return the TAB update position.
     303**/
     304EFI_STATUS
     305CreateTabCompletionList (
     306  IN CONST CHAR16             *InputString,
     307  IN CONST UINTN              StringLen,
     308  IN CONST UINTN              BufferSize,
     309  IN OUT EFI_SHELL_FILE_INFO  **TabCompletionList,
     310  IN OUT   UINTN              *TabUpdatePos
     311)
     312{
     313  BOOLEAN             InQuotation;
     314  UINTN               TabPos;
     315  UINTN               Index;
     316  CONST CHAR16        *Cwd;
     317  EFI_STATUS          Status;
     318  CHAR16              *TabStr;
     319  EFI_SHELL_FILE_INFO *FileList;
     320  EFI_SHELL_FILE_INFO *FileInfo;
     321  EFI_SHELL_FILE_INFO *TempFileInfo;
     322
     323  //
     324  // Allocate buffers
     325  //
     326  TabStr = AllocateZeroPool (BufferSize);
     327  if (TabStr == NULL) {
     328    return EFI_OUT_OF_RESOURCES;
     329  }
     330
     331  //
     332  // handle auto complete of file and directory names...
     333  // E.g.: cd fs0:\EFI\Bo<TAB>
     334  //          ^        ^
     335  //          TabPos   TabUpdatePos
     336  //
     337  TabPos        = 0;
     338  *TabUpdatePos = 0;
     339  FileList      = NULL;
     340  InQuotation   = FALSE;
     341  for (Index = 0; Index < StringLen; Index++) {
     342    switch (InputString[Index]) {
     343    case L'\"':
     344      InQuotation = (BOOLEAN) (!InQuotation);
     345      break;
     346
     347    case L' ':
     348      if (!InQuotation) {
     349        TabPos = Index + 1;
     350        *TabUpdatePos = TabPos;
     351      }
     352      break;
     353
     354    case L':':
     355      //
     356      // handle the case "fs0:<TAB>"
     357      // Update the TabUpdatePos as well.
     358      //
     359    case L'\\':
     360      *TabUpdatePos = Index + 1;
     361      break;
     362
     363    default:
     364      break;
     365    }
     366  }
     367
     368  if (StrStr (InputString + TabPos, L":") == NULL) {
     369    //
     370    // If file path doesn't contain ":", ...
     371    //
     372    Cwd = ShellInfoObject.NewEfiShellProtocol->GetCurDir (NULL);
     373    if (Cwd != NULL) {
     374      if (InputString[TabPos] != L'\\') {
     375        //
     376        // and it doesn't begin with "\\", it's a path relative to current directory.
     377        // TabStr = "<cwd>\\"
     378        //
     379        StrnCpyS (TabStr, BufferSize / sizeof (CHAR16), Cwd, (BufferSize) / sizeof (CHAR16) - 1);
     380        StrCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"\\");
     381      } else {
     382        //
     383        // and it begins with "\\", it's a path pointing to root directory of current map.
     384        // TabStr = "fsx:"
     385        //
     386        Index = StrStr (Cwd, L":") - Cwd + 1;
     387        StrnCpyS (TabStr, BufferSize / sizeof (CHAR16), Cwd, Index);
     388      }
     389    }
     390  }
     391  StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), InputString + TabPos, StringLen - TabPos);
     392  StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"*", (BufferSize) / sizeof (CHAR16) - 1 - StrLen (TabStr));
     393  Status  = ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, &FileList);
     394
     395  //
     396  // Filter out the non-directory for "CD" command
     397  // Filter "." and ".." for all
     398  //
     399  if (!EFI_ERROR (Status) && FileList != NULL) {
     400    //
     401    // Skip the spaces in the beginning
     402    //
     403    while (*InputString == L' ') {
     404      InputString++;
     405    }
     406
     407    for (FileInfo = (EFI_SHELL_FILE_INFO *) GetFirstNode (&FileList->Link); !IsNull (&FileList->Link, &FileInfo->Link); ) {
     408      if (((StrCmp (FileInfo->FileName, L".") == 0) || (StrCmp (FileInfo->FileName, L"..") == 0)) ||
     409          (((InputString[0] == L'c' || InputString[0] == L'C') && (InputString[1] == L'd' || InputString[1] == L'D')) &&
     410           (ShellIsDirectory (FileInfo->FullName) != EFI_SUCCESS))) {
     411        TempFileInfo = FileInfo;
     412        FileInfo = (EFI_SHELL_FILE_INFO *) RemoveEntryList (&FileInfo->Link);
     413        InternalFreeShellFileInfoNode (TempFileInfo);
     414      } else {
     415        FileInfo = (EFI_SHELL_FILE_INFO *) GetNextNode (&FileList->Link, &FileInfo->Link);
     416      }
     417    }
     418  }
     419
     420  if (FileList != NULL && !IsListEmpty (&FileList->Link)) {
     421    Status = EFI_SUCCESS;
     422  } else {
     423    ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FileList);
     424    Status = EFI_NOT_FOUND;
     425  }
     426
     427  FreePool (TabStr);
     428
     429  *TabCompletionList = FileList;
     430  return Status;
    288431}
    289432
     
    322465  CHAR16              *CurrentString;
    323466  BOOLEAN             Done;
     467  UINTN               TabUpdatePos;   // Start index of the string updated by TAB stroke
    324468  UINTN               Column;         // Column of current cursor
    325469  UINTN               Row;            // Row of current cursor
     
    330474  UINTN               StringCurPos;   // Line index corresponding to the cursor
    331475  UINTN               MaxStr;         // Maximum possible line length
    332   UINTN               Index;
    333476  UINTN               TotalColumn;     // Num of columns in the console
    334477  UINTN               TotalRow;       // Num of rows in the console
     
    344487  EFI_STATUS          Status;
    345488  BOOLEAN             InTabScrolling; // Whether in TAB-completion state
    346   EFI_SHELL_FILE_INFO *FoundFileList;
    347   EFI_SHELL_FILE_INFO *TabLinePos;
    348   EFI_SHELL_FILE_INFO *TempPos;
    349   CHAR16              *TabStr;
     489  EFI_SHELL_FILE_INFO *TabCompleteList;
     490  EFI_SHELL_FILE_INFO *TabCurrent;
     491  UINTN               EventIndex;
    350492  CHAR16              *TabOutputStr;
    351   BOOLEAN             InQuotationMode;
    352   CHAR16              *TempStr;
    353   UINTN               TabPos;         // Start index of the string to search for TAB completion.
    354   UINTN               TabUpdatePos;   // Start index of the string updated by TAB stroke
    355 //  UINTN               Count;
    356   UINTN               EventIndex;
    357   CONST CHAR16        *Cwd;
    358493
    359494  //
     
    376511  InTabScrolling    = FALSE;
    377512  Status            = EFI_SUCCESS;
    378   TabLinePos        = NULL;
    379   FoundFileList     = NULL;
    380   TempPos           = NULL;
    381   TabPos            = 0;
     513  TabOutputStr      = NULL;
    382514  TabUpdatePos      = 0;
    383 
    384   //
    385   // Allocate buffers
    386   //
    387   TabStr            = AllocateZeroPool (*BufferSize);
    388   if (TabStr == NULL) {
    389     return EFI_OUT_OF_RESOURCES;
    390   }
    391   TabOutputStr      = AllocateZeroPool (*BufferSize);
    392   if (TabOutputStr == NULL) {
    393     FreePool(TabStr);
    394     return EFI_OUT_OF_RESOURCES;
    395   }
     515  TabCompleteList   = NULL;
     516  TabCurrent        = NULL;
    396517
    397518  //
     
    418539    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    419540    if (EFI_ERROR (Status)) {
     541
     542      if (Status == EFI_NOT_READY)
     543        continue;
     544
     545      ZeroMem (CurrentString, MaxStr * sizeof(CHAR16));
     546      StringLen = 0;
    420547      break;
    421548    }
     
    444571    //
    445572    if (InTabScrolling && Key.UnicodeChar != CHAR_TAB) {
    446         if (FoundFileList != NULL) {
    447           ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FoundFileList);
    448           DEBUG_CODE(FoundFileList = NULL;);
    449         }
    450         InTabScrolling = FALSE;
     573      if (TabCompleteList != NULL) {
     574        ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteList);
     575        DEBUG_CODE(TabCompleteList = NULL;);
     576      }
     577      InTabScrolling = FALSE;
    451578    }
    452579
     
    481608
    482609    case CHAR_TAB:
    483       //
    484       // handle auto complete of file and directory names...
    485       //
     610      if (!InTabScrolling) {
     611        TabCurrent = NULL;
     612        //
     613        // Initialize a tab complete operation.
     614        //
     615        Status = CreateTabCompletionList (CurrentString, StringLen, *BufferSize, &TabCompleteList, &TabUpdatePos);
     616        if (!EFI_ERROR(Status)) {
     617          InTabScrolling = TRUE;
     618        }
     619
     620        //
     621        // We do not set up the replacement.
     622        // The next section will do that.
     623        //
     624      }
     625
    486626      if (InTabScrolling) {
    487         ASSERT(FoundFileList != NULL);
    488         ASSERT(TabLinePos != NULL);
    489         TabLinePos = (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileList->Link), &TabLinePos->Link);
    490         if (IsNull(&(FoundFileList->Link), &TabLinePos->Link)) {
    491           TabLinePos = (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileList->Link), &TabLinePos->Link);
     627        //
     628        // We are in a tab complete operation.
     629        // set up the next replacement.
     630        //
     631        ASSERT(TabCompleteList != NULL);
     632        if (TabCurrent == NULL) {
     633          TabCurrent = (EFI_SHELL_FILE_INFO*) GetFirstNode (&TabCompleteList->Link);
     634        } else {
     635          TabCurrent = (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteList->Link, &TabCurrent->Link);
    492636        }
    493       } else {
    494         TabPos          = 0;
    495         TabUpdatePos    = 0;
    496         InQuotationMode = FALSE;
    497         for (Index = 0; Index < StringLen; Index++) {
    498           if (CurrentString[Index] == L'\"') {
    499             InQuotationMode = (BOOLEAN)(!InQuotationMode);
    500           }
    501           if (CurrentString[Index] == L' ' && !InQuotationMode) {
    502             TabPos = Index + 1;
    503             TabUpdatePos = Index + 1;
    504           }
    505           if (CurrentString[Index] == L'\\') {
    506             TabUpdatePos = Index + 1;
    507           }
    508         }
    509         if (StrStr(CurrentString + TabPos, L":") == NULL) {
    510           Cwd = ShellInfoObject.NewEfiShellProtocol->GetCurDir(NULL);
    511           if (Cwd != NULL) {
    512             StrnCpy(TabStr, Cwd, (*BufferSize)/sizeof(CHAR16) - 1);
    513             if (TabStr[StrLen(TabStr)-1] == L'\\' && *(CurrentString + TabPos) == L'\\' ) {
    514               TabStr[StrLen(TabStr)-1] = CHAR_NULL;
    515             }
    516             StrnCat(TabStr, CurrentString + TabPos, (StringLen - TabPos) * sizeof (CHAR16));
    517           } else {
    518             *TabStr = CHAR_NULL;
    519             StrnCat(TabStr, CurrentString + TabPos, (StringLen - TabPos) * sizeof (CHAR16));
    520           }
    521         } else {
    522           StrnCpy(TabStr, CurrentString + TabPos, (*BufferSize)/sizeof(CHAR16) - 1);
    523         }
    524         StrnCat(TabStr, L"*", (*BufferSize)/sizeof(CHAR16) - 1 - StrLen(TabStr));
    525         FoundFileList = NULL;
    526         Status  = ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, &FoundFileList);
    527         for ( TempStr = CurrentString
    528             ; *TempStr == L' '
    529             ; TempStr++); // note the ';'... empty for loop
    530         //
    531         // make sure we have a list before we do anything more...
    532         //
    533         if (EFI_ERROR (Status) || FoundFileList == NULL) {
    534           InTabScrolling = FALSE;
    535           TabLinePos = NULL;
    536           continue;
    537         } else {
    538           //
    539           // enumerate through the list of files
    540           //
    541           for ( TempPos = (EFI_SHELL_FILE_INFO*)GetFirstNode(&(FoundFileList->Link))
    542               ; !IsNull(&FoundFileList->Link, &TempPos->Link)
    543               ; TempPos = (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileList->Link), &(TempPos->Link))
    544              ){
    545             //
    546             // If "cd" is typed, only directory name will be auto-complete filled
    547             // in either case . and .. will be removed.
    548             //
    549             if ((((TempStr[0] == L'c' || TempStr[0] == L'C') &&
    550                 (TempStr[1] == L'd' || TempStr[1] == L'D')
    551                ) && ((ShellIsDirectory(TempPos->FullName) != EFI_SUCCESS)
    552                 ||(StrCmp(TempPos->FileName, L".") == 0)
    553                 ||(StrCmp(TempPos->FileName, L"..") == 0)
    554                )) || ((StrCmp(TempPos->FileName, L".") == 0)
    555                 ||(StrCmp(TempPos->FileName, L"..") == 0))){
    556                 TabLinePos = TempPos;
    557                 TempPos = (EFI_SHELL_FILE_INFO*)(RemoveEntryList(&(TempPos->Link))->BackLink);
    558                 InternalFreeShellFileInfoNode(TabLinePos);
    559             }
    560           }
    561           if (FoundFileList != NULL && !IsListEmpty(&FoundFileList->Link)) {
    562             TabLinePos = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FoundFileList->Link);
    563             InTabScrolling = TRUE;
    564           } else {
    565             FreePool(FoundFileList);
    566             FoundFileList = NULL;
    567           }
     637
     638        //
     639        // Skip over the empty list beginning node
     640        //
     641        if (IsNull(&TabCompleteList->Link, &TabCurrent->Link)) {
     642          TabCurrent = (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteList->Link, &TabCurrent->Link);
    568643        }
    569644      }
     
    706781    //
    707782    if (InTabScrolling) {
     783      TabOutputStr = AllocateZeroPool (*BufferSize);
     784      if (TabOutputStr == NULL) {
     785        Status = EFI_OUT_OF_RESOURCES;
     786      }
     787    }
     788
     789    if (InTabScrolling && TabOutputStr != NULL) {
     790
    708791      //
    709792      // Adjust the column and row to the start of TAB-completion string.
     
    711794      Column = (StartColumn + TabUpdatePos) % TotalColumn;
    712795      Row -= (StartColumn + StringCurPos) / TotalColumn - (StartColumn + TabUpdatePos) / TotalColumn;
    713       OutputLength = StrLen (TabLinePos->FileName);
     796      OutputLength = StrLen (TabCurrent->FileName);
    714797      //
    715798      // if the output string contains  blank space, quotation marks L'\"'
    716799      // should be added to the output.
    717800      //
    718       if (StrStr(TabLinePos->FileName, L" ") != NULL){
     801      if (StrStr(TabCurrent->FileName, L" ") != NULL){
    719802        TabOutputStr[0] = L'\"';
    720         CopyMem (TabOutputStr + 1, TabLinePos->FileName, OutputLength * sizeof (CHAR16));
     803        CopyMem (TabOutputStr + 1, TabCurrent->FileName, OutputLength * sizeof (CHAR16));
    721804        TabOutputStr[OutputLength + 1] = L'\"';
    722805        TabOutputStr[OutputLength + 2] = CHAR_NULL;
    723806      } else {
    724         CopyMem (TabOutputStr, TabLinePos->FileName, OutputLength * sizeof (CHAR16));
     807        CopyMem (TabOutputStr, TabCurrent->FileName, OutputLength * sizeof (CHAR16));
    725808        TabOutputStr[OutputLength] = CHAR_NULL;
    726809      }
     
    733816        Delete = StringLen - TabUpdatePos - OutputLength;
    734817      }
     818
     819      FreePool(TabOutputStr);
    735820    }
    736821
     
    836921  }
    837922
    838   FreePool (TabStr);
    839   FreePool (TabOutputStr);
    840923  //
    841924  // Return the data to the caller
     
    847930  // prevent memory leaks...
    848931  //
    849   ASSERT(FoundFileList == NULL);
     932  if (TabCompleteList != NULL) {
     933    ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteList);
     934  }
     935  ASSERT(TabCompleteList == NULL);
    850936
    851937  return Status;
     
    9541040  UINTN       NewSize;
    9551041  EFI_STATUS  Status;
     1042  BOOLEAN     Volatile;
     1043  UINTN       TotalSize;
    9561044
    9571045  //
     
    9631051  NewBuffer   = NULL;
    9641052  NewSize     = 0;
     1053  TotalSize   = 0;
     1054
     1055  Status = IsVolatileEnv (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &Volatile);
     1056  if (EFI_ERROR (Status)) {
     1057    return Status;
     1058  }
    9651059
    9661060  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
    9671061  if (Status == EFI_BUFFER_TOO_SMALL) {
    968     NewBuffer = AllocateZeroPool(NewSize + sizeof(CHAR16));
     1062    TotalSize = NewSize + sizeof (CHAR16);
     1063    NewBuffer = AllocateZeroPool (TotalSize);
    9691064    if (NewBuffer == NULL) {
    9701065      return EFI_OUT_OF_RESOURCES;
     
    9751070  if (!EFI_ERROR(Status) && NewBuffer != NULL) {
    9761071
    977     if (StrSize(NewBuffer) > 6)
    978     {
    979       if ((((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 2] == CHAR_LINEFEED)
    980            && (((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 3] == CHAR_CARRIAGE_RETURN)) {
    981         ((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 3] = CHAR_NULL;
     1072    if (TotalSize / sizeof (CHAR16) >= 3) {
     1073      if ( (((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 2] == CHAR_LINEFEED) &&
     1074           (((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 3] == CHAR_CARRIAGE_RETURN)
     1075         ) {
     1076        ((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 3] = CHAR_NULL;
     1077        //
     1078        // If the NewBuffer end with \r\n\0, We will repace '\r' by '\0' and then update TotalSize.
     1079        //
     1080        TotalSize -= sizeof(CHAR16) * 2;
    9821081      }
    9831082
    984       if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name)) {
    985         Status = SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
     1083      if (Volatile) {
     1084        Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (
     1085                   ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1086                   TotalSize - sizeof (CHAR16),
     1087                   NewBuffer
     1088                   );
     1089
     1090        if (!EFI_ERROR(Status)) {
     1091          Status = ShellAddEnvVarToList (
     1092                     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1093                     NewBuffer,
     1094                     TotalSize,
     1095                     EFI_VARIABLE_BOOTSERVICE_ACCESS
     1096                     );
     1097        }
    9861098      } else {
    987         Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
     1099        Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (
     1100                   ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1101                   TotalSize - sizeof (CHAR16),
     1102                   NewBuffer
     1103                   );
     1104
     1105        if (!EFI_ERROR(Status)) {
     1106          Status = ShellAddEnvVarToList (
     1107                     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1108                     NewBuffer,
     1109                     TotalSize,
     1110                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
     1111                     );
     1112        }
    9881113      }
    9891114    }
     
    10371162/**
    10381163  File style interface for Volatile Environment Variable (Write).
     1164  This function also caches the environment variable into gShellEnvVarList.
    10391165
    10401166  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
     
    10421168  @param[in] Buffer            The pointer to the buffer to write.
    10431169
    1044   @retval EFI_SUCCESS   The data was read.
     1170  @retval EFI_SUCCESS             The data was successfully write to variable.
     1171  @retval SHELL_OUT_OF_RESOURCES  A memory allocation failed.
    10451172**/
    10461173EFI_STATUS
     
    10551182  UINTN       NewSize;
    10561183  EFI_STATUS  Status;
     1184  UINTN       TotalSize;
    10571185
    10581186  NewBuffer   = NULL;
    10591187  NewSize     = 0;
     1188  TotalSize   = 0;
    10601189
    10611190  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
    1062   if (Status == EFI_BUFFER_TOO_SMALL){
    1063     NewBuffer = AllocateZeroPool(NewSize + *BufferSize + sizeof(CHAR16));
     1191  if (Status == EFI_BUFFER_TOO_SMALL) {
     1192    TotalSize = NewSize + *BufferSize + sizeof (CHAR16);
     1193  } else if (Status == EFI_NOT_FOUND) {
     1194    TotalSize = *BufferSize + sizeof(CHAR16);
     1195  } else {
     1196    return Status;
     1197  }
     1198
     1199  NewBuffer = AllocateZeroPool (TotalSize);
     1200  if (NewBuffer == NULL) {
     1201    return EFI_OUT_OF_RESOURCES;
     1202  }
     1203
     1204  if (Status == EFI_BUFFER_TOO_SMALL) {
    10641205    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
    10651206  }
    1066   if (!EFI_ERROR(Status) && NewBuffer != NULL) {
    1067     while (((CHAR16*)NewBuffer)[NewSize/2] == CHAR_NULL) {
    1068       //
    1069       // We want to overwrite the CHAR_NULL
    1070       //
    1071       NewSize -= 2;
    1072     }
    1073     CopyMem((UINT8*)NewBuffer + NewSize + 2, Buffer, *BufferSize);
    1074     Status = SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
    1075     FreePool(NewBuffer);
    1076     return (Status);
    1077   } else {
    1078     SHELL_FREE_NON_NULL(NewBuffer);
    1079     return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, *BufferSize, Buffer));
    1080   }
     1207
     1208  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
     1209    FreePool (NewBuffer);
     1210    return Status;
     1211  }
     1212
     1213  CopyMem ((UINT8*)NewBuffer + NewSize, Buffer, *BufferSize);
     1214  Status = ShellAddEnvVarToList (
     1215             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1216             NewBuffer,
     1217             TotalSize,
     1218             EFI_VARIABLE_BOOTSERVICE_ACCESS
     1219             );
     1220  if (EFI_ERROR(Status)) {
     1221    FreePool (NewBuffer);
     1222    return Status;
     1223  }
     1224
     1225  Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (
     1226             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1227             TotalSize - sizeof (CHAR16),
     1228             NewBuffer
     1229             );
     1230  if (EFI_ERROR(Status)) {
     1231    ShellRemvoeEnvVarFromList (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name);
     1232  }
     1233
     1234  FreePool (NewBuffer);
     1235  return Status;
    10811236}
    10821237
     
    10841239/**
    10851240  File style interface for Non Volatile Environment Variable (Write).
     1241  This function also caches the environment variable into gShellEnvVarList.
    10861242
    10871243  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
     
    10891245  @param[in] Buffer            The pointer to the buffer to write.
    10901246
    1091   @retval EFI_SUCCESS   The data was read.
     1247  @retval EFI_SUCCESS             The data was successfully write to variable.
     1248  @retval SHELL_OUT_OF_RESOURCES  A memory allocation failed.
    10921249**/
    10931250EFI_STATUS
     
    11021259  UINTN       NewSize;
    11031260  EFI_STATUS  Status;
     1261  UINTN       TotalSize;
    11041262
    11051263  NewBuffer   = NULL;
    11061264  NewSize     = 0;
     1265  TotalSize   = 0;
    11071266
    11081267  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
    1109   if (Status == EFI_BUFFER_TOO_SMALL){
    1110     NewBuffer = AllocateZeroPool(NewSize + *BufferSize);
     1268  if (Status == EFI_BUFFER_TOO_SMALL) {
     1269    TotalSize = NewSize + *BufferSize + sizeof (CHAR16);
     1270  } else if (Status == EFI_NOT_FOUND) {
     1271    TotalSize = *BufferSize + sizeof (CHAR16);
     1272  } else {
     1273    return Status;
     1274  }
     1275
     1276  NewBuffer = AllocateZeroPool (TotalSize);
     1277  if (NewBuffer == NULL) {
     1278    return EFI_OUT_OF_RESOURCES;
     1279  }
     1280
     1281  if (Status == EFI_BUFFER_TOO_SMALL) {
    11111282    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
    11121283  }
    1113   if (!EFI_ERROR(Status)) {
    1114     CopyMem((UINT8*)NewBuffer + NewSize, Buffer, *BufferSize);
    1115     return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
    1116     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
    1117     NewSize + *BufferSize,
    1118     NewBuffer));
    1119   } else {
    1120     return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
    1121     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
    1122     *BufferSize,
    1123     Buffer));
    1124   }
     1284
     1285  if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
     1286    FreePool (NewBuffer);
     1287    return Status;
     1288  }
     1289
     1290  CopyMem ((UINT8*) NewBuffer + NewSize, Buffer, *BufferSize);
     1291  Status = ShellAddEnvVarToList (
     1292             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1293             NewBuffer,
     1294             TotalSize,
     1295             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
     1296             );
     1297  if (EFI_ERROR (Status)) {
     1298    FreePool (NewBuffer);
     1299    return Status;
     1300  }
     1301
     1302  Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (
     1303             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
     1304             TotalSize - sizeof (CHAR16),
     1305             NewBuffer
     1306             );
     1307  if (EFI_ERROR (Status)) {
     1308    ShellRemvoeEnvVarFromList (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name);
     1309  }
     1310
     1311  FreePool (NewBuffer);
     1312  return Status;
    11251313}
    11261314
     
    11351323**/
    11361324EFI_FILE_PROTOCOL*
    1137 EFIAPI
    11381325CreateFileInterfaceEnv(
    11391326  IN CONST CHAR16 *EnvName
    11401327  )
    11411328{
     1329  EFI_STATUS                     Status;
    11421330  EFI_FILE_PROTOCOL_ENVIRONMENT  *EnvFileInterface;
    11431331  UINTN                          EnvNameSize;
     1332  BOOLEAN                        Volatile;
    11441333
    11451334  if (EnvName == NULL) {
    11461335    return (NULL);
     1336  }
     1337
     1338  Status = IsVolatileEnv (EnvName, &Volatile);
     1339  if (EFI_ERROR (Status)) {
     1340    return NULL;
    11471341  }
    11481342
     
    11751369  // Assign the different members for Volatile and Non-Volatile variables
    11761370  //
    1177   if (IsVolatileEnv(EnvName)) {
     1371  if (Volatile) {
    11781372    EnvFileInterface->Write       = FileInterfaceEnvVolWrite;
    11791373  } else {
     
    11911385**/
    11921386VOID
    1193 EFIAPI
    11941387MoveCursorBackward (
    11951388  IN     UINTN                   LineLength,
     
    12211414**/
    12221415VOID
    1223 EFIAPI
    12241416MoveCursorForward (
    12251417  IN     UINTN                   LineLength,
     
    12531445**/
    12541446VOID
    1255 EFIAPI
    12561447PrintCommandHistory (
    12571448  IN CONST UINTN TotalCols,
     
    13181509  UINT64                BufferSize;
    13191510  BOOLEAN               Unicode;
     1511  UINT64                FileSize;
    13201512} EFI_FILE_PROTOCOL_MEM;
    13211513
     
    13361528  )
    13371529{
    1338   if (Position <= ((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) {
     1530  if (Position <= ((EFI_FILE_PROTOCOL_MEM*)This)->FileSize) {
    13391531    ((EFI_FILE_PROTOCOL_MEM*)This)->Position = Position;
    13401532    return (EFI_SUCCESS);
     
    13641556
    13651557/**
     1558  File style interface for Mem (GetInfo).
     1559
     1560  @param  This            Protocol instance pointer.
     1561  @param  InformationType Type of information to return in Buffer.
     1562  @param  BufferSize      On input size of buffer, on output amount of data in buffer.
     1563  @param  Buffer          The buffer to return data.
     1564
     1565  @retval EFI_SUCCESS          Data was returned.
     1566  @retval EFI_UNSUPPORT        InformationType is not supported.
     1567  @retval EFI_NO_MEDIA         The device has no media.
     1568  @retval EFI_DEVICE_ERROR     The device reported an error.
     1569  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
     1570  @retval EFI_WRITE_PROTECTED  The device is write protected.
     1571  @retval EFI_ACCESS_DENIED    The file was open for read only.
     1572  @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
     1573
     1574**/
     1575EFI_STATUS
     1576EFIAPI
     1577FileInterfaceMemGetInfo(
     1578  IN EFI_FILE_PROTOCOL        *This,
     1579  IN EFI_GUID                 *InformationType,
     1580  IN OUT UINTN                *BufferSize,
     1581  OUT VOID                    *Buffer
     1582  )
     1583{
     1584  EFI_FILE_INFO               *FileInfo;
     1585
     1586  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
     1587    if (*BufferSize < sizeof (EFI_FILE_INFO)) {
     1588      *BufferSize = sizeof (EFI_FILE_INFO);
     1589      return EFI_BUFFER_TOO_SMALL;
     1590    }
     1591    if (Buffer == NULL) {
     1592      return EFI_INVALID_PARAMETER;
     1593    }
     1594    FileInfo = (EFI_FILE_INFO *)Buffer;
     1595    FileInfo->Size = sizeof (*FileInfo);
     1596    ZeroMem (FileInfo, sizeof (*FileInfo));
     1597    FileInfo->FileSize = ((EFI_FILE_PROTOCOL_MEM*)This)->FileSize;
     1598    FileInfo->PhysicalSize = FileInfo->FileSize;
     1599    return EFI_SUCCESS;
     1600  }
     1601
     1602  return EFI_UNSUPPORTED;
     1603}
     1604
     1605/**
    13661606  File style interface for Mem (Write).
    13671607
     
    13811621  )
    13821622{
    1383   CHAR8 *AsciiBuffer;
    1384   if (((EFI_FILE_PROTOCOL_MEM*)This)->Unicode) {
     1623  CHAR8                  *AsciiBuffer;
     1624  EFI_FILE_PROTOCOL_MEM  *MemFile;
     1625
     1626  MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
     1627  if (MemFile->Unicode) {
    13851628    //
    13861629    // Unicode
    13871630    //
    1388     if ((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position + (*BufferSize)) > (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize)) {
    1389       ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer = ReallocatePool((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize), (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) + (*BufferSize) + 10, ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer);
    1390       ((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize += (*BufferSize) + 10;
    1391     }
    1392     CopyMem(((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, Buffer, *BufferSize);
    1393     ((EFI_FILE_PROTOCOL_MEM*)This)->Position += (*BufferSize);
     1631    if ((UINTN)(MemFile->Position + (*BufferSize)) > (UINTN)(MemFile->BufferSize)) {
     1632      MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + (*BufferSize) + MEM_WRITE_REALLOC_OVERHEAD, MemFile->Buffer);
     1633      MemFile->BufferSize += (*BufferSize) + MEM_WRITE_REALLOC_OVERHEAD;
     1634    }
     1635    CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, Buffer, *BufferSize);
     1636    MemFile->Position += (*BufferSize);
     1637    MemFile->FileSize = MemFile->Position;
    13941638    return (EFI_SUCCESS);
    13951639  } else {
     
    14021646    }
    14031647    AsciiSPrint(AsciiBuffer, *BufferSize, "%S", Buffer);
    1404     if ((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position + AsciiStrSize(AsciiBuffer)) > (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize)) {
    1405       ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer = ReallocatePool((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize), (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) + AsciiStrSize(AsciiBuffer) + 10, ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer);
    1406       ((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize += AsciiStrSize(AsciiBuffer) + 10;
    1407     }
    1408     CopyMem(((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, AsciiBuffer, AsciiStrSize(AsciiBuffer));
    1409     ((EFI_FILE_PROTOCOL_MEM*)This)->Position += AsciiStrSize(AsciiBuffer);
     1648    if ((UINTN)(MemFile->Position + AsciiStrSize(AsciiBuffer)) > (UINTN)(MemFile->BufferSize)) {
     1649      MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + AsciiStrSize(AsciiBuffer) + MEM_WRITE_REALLOC_OVERHEAD, MemFile->Buffer);
     1650      MemFile->BufferSize += AsciiStrSize(AsciiBuffer) + MEM_WRITE_REALLOC_OVERHEAD;
     1651    }
     1652    CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, AsciiBuffer, AsciiStrSize(AsciiBuffer));
     1653    MemFile->Position += (*BufferSize / sizeof(CHAR16));
     1654    MemFile->FileSize = MemFile->Position;
    14101655    FreePool(AsciiBuffer);
    14111656    return (EFI_SUCCESS);
     
    14301675  )
    14311676{
    1432   if (*BufferSize > (UINTN)((((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) - (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position))) {
    1433     (*BufferSize) = (UINTN)((((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) - (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position));
    1434   }
    1435   CopyMem(Buffer, ((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, (*BufferSize));
    1436   ((EFI_FILE_PROTOCOL_MEM*)This)->Position = ((EFI_FILE_PROTOCOL_MEM*)This)->Position + (*BufferSize);
     1677  EFI_FILE_PROTOCOL_MEM  *MemFile;
     1678
     1679  MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
     1680  if (*BufferSize > (UINTN)((MemFile->FileSize) - (UINTN)(MemFile->Position))) {
     1681    (*BufferSize) = (UINTN)((MemFile->FileSize) - (UINTN)(MemFile->Position));
     1682  }
     1683  CopyMem(Buffer, ((UINT8*)MemFile->Buffer) + MemFile->Position, (*BufferSize));
     1684  MemFile->Position = MemFile->Position + (*BufferSize);
    14371685  return (EFI_SUCCESS);
    14381686}
     
    14681716**/
    14691717EFI_FILE_PROTOCOL*
    1470 EFIAPI
    14711718CreateFileInterfaceMem(
    14721719  IN CONST BOOLEAN Unicode
     
    14911738  FileInterface->GetPosition = FileInterfaceMemGetPosition;
    14921739  FileInterface->SetPosition = FileInterfaceMemSetPosition;
    1493   FileInterface->GetInfo     = FileInterfaceNopGetInfo;
     1740  FileInterface->GetInfo     = FileInterfaceMemGetInfo;
    14941741  FileInterface->SetInfo     = FileInterfaceNopSetInfo;
    14951742  FileInterface->Flush       = FileInterfaceNopGeneric;
     
    15021749  ASSERT(FileInterface->BufferSize  == 0);
    15031750  ASSERT(FileInterface->Position    == 0);
     1751
     1752  if (Unicode) {
     1753    FileInterface->Buffer = AllocateZeroPool(sizeof(gUnicodeFileTag));
     1754    if (FileInterface->Buffer == NULL) {
     1755      FreePool (FileInterface);
     1756      return NULL;
     1757    }
     1758    *((CHAR16 *) (FileInterface->Buffer)) = EFI_UNICODE_BYTE_ORDER_MARK;
     1759    FileInterface->BufferSize = 2;
     1760    FileInterface->Position = 2;
     1761  }
    15041762
    15051763  return ((EFI_FILE_PROTOCOL *)FileInterface);
     
    16671925  )
    16681926{
    1669   CHAR8       *AsciiBuffer;
     1927  CHAR8       *AsciiStrBuffer;
     1928  CHAR16      *UscStrBuffer;
    16701929  UINTN       Size;
     1930  UINTN       CharNum;
    16711931  EFI_STATUS  Status;
    16721932  if (((EFI_FILE_PROTOCOL_FILE*)This)->Unicode) {
     
    16791939    // Ascii
    16801940    //
    1681     AsciiBuffer = AllocateZeroPool((Size = *BufferSize));
    1682     Status = (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiBuffer));
    1683     UnicodeSPrint(Buffer, *BufferSize, L"%a", AsciiBuffer);
    1684     FreePool(AsciiBuffer);
     1941    Size  = (*BufferSize) / sizeof(CHAR16);
     1942    AsciiStrBuffer = AllocateZeroPool(Size + sizeof(CHAR8));
     1943    if (AsciiStrBuffer == NULL) {
     1944      return EFI_OUT_OF_RESOURCES;
     1945    }
     1946    UscStrBuffer = AllocateZeroPool(*BufferSize + sizeof(CHAR16));
     1947    if (UscStrBuffer== NULL) {
     1948      SHELL_FREE_NON_NULL(AsciiStrBuffer);
     1949      return EFI_OUT_OF_RESOURCES;
     1950    }
     1951    Status = (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiStrBuffer));
     1952    if (!EFI_ERROR(Status)) {
     1953      CharNum = UnicodeSPrint(UscStrBuffer, *BufferSize + sizeof(CHAR16), L"%a", AsciiStrBuffer);
     1954      if (CharNum == Size) {
     1955        CopyMem (Buffer, UscStrBuffer, *BufferSize);
     1956      } else {
     1957        Status = EFI_UNSUPPORTED;
     1958      }
     1959    }
     1960    SHELL_FREE_NON_NULL(AsciiStrBuffer);
     1961    SHELL_FREE_NON_NULL(UscStrBuffer);
    16851962    return (Status);
    16861963  }
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/FileHandleWrappers.h

    r48674 r77662  
    5656**/
    5757EFI_FILE_PROTOCOL*
    58 EFIAPI
    5958CreateFileInterfaceEnv(
    6059  CONST CHAR16 *EnvName
     
    7170**/
    7271EFI_FILE_PROTOCOL*
    73 EFIAPI
    7472CreateFileInterfaceMem(
    7573  IN CONST BOOLEAN Unicode
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/Shell.c

    r58466 r77662  
    22  This is THE shell (application)
    33
    4   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
    5   (C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.
     4  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>
    66  This program and the accompanying materials
    77  are licensed and made available under the terms and conditions of the BSD License
     
    2626  {
    2727    {{
     28      0,
    2829      0,
    2930      0,
     
    7071STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
    7172STATIC CONST CHAR16 mStartupScript[]        = L"startup.nsh";
     73CONST CHAR16 mNoNestingEnvVarName[]         = L"nonesting";
     74CONST CHAR16 mNoNestingTrue[]               = L"True";
     75CONST CHAR16 mNoNestingFalse[]              = L"False";
    7276
    7377/**
     
    7781**/
    7882EFI_STATUS
    79 EFIAPI
    8083TrimSpaces(
    8184  IN CHAR16 **String
     
    110113**/
    111114CHAR16*
    112 EFIAPI
    113115FindNextInstance(
    114116  IN CONST CHAR16   *SourceString,
     
    124126
    125127  //
    126   // If nothing found, or we dont care about escape characters
     128  // If nothing found, or we don't care about escape characters
    127129  //
    128130  if (Temp == NULL || !CheckForEscapeCharacter) {
     
    144146
    145147/**
    146   Check whether the string between a pair of % is a valid envifronment variable name.
     148  Check whether the string between a pair of % is a valid environment variable name.
    147149
    148150  @param[in] BeginPercent       pointer to the first percent.
     
    199201**/
    200202BOOLEAN
    201 EFIAPI
    202203ContainsSplit(
    203204  IN CONST CHAR16 *CmdLine
     
    246247
    247248  @retval EFI_SUCCESS           The feature is enabled.
    248   @retval EFI_OUT_OF_RESOURCES  There is not enough mnemory available.
     249  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available.
    249250**/
    250251EFI_STATUS
    251 EFIAPI
    252252InternalEfiShellStartCtrlSMonitor(
    253253  VOID
     
    339339  EFI_HANDLE                      ConInHandle;
    340340  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *OldConIn;
     341  SPLIT_LIST                      *Split;
    341342
    342343  if (PcdGet8(PcdShellSupportLevel) > 3) {
     
    442443    ASSERT_EFI_ERROR(Status);
    443444
     445    Status = ShellInitEnvVarList ();
     446
    444447    //
    445448    // Check the command line
     
    456459      Status = ShellCommandCreateInitialMappingsAndPaths();
    457460    }
     461
     462    //
     463    // Set the environment variable for nesting support
     464    //
     465    Size = 0;
     466    TempString = NULL;
     467    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
     468      //
     469      // No change.  require nesting in Shell Protocol Execute()
     470      //
     471      StrnCatGrow(&TempString,
     472                  &Size,
     473                  L"False",
     474                  0);
     475    } else {
     476      StrnCatGrow(&TempString,
     477                  &Size,
     478                  mNoNestingTrue,
     479                  0);
     480    }
     481    Status = InternalEfiShellSetEnv(mNoNestingEnvVarName, TempString, TRUE);
     482    SHELL_FREE_NON_NULL(TempString);
     483    Size = 0;
    458484
    459485    //
     
    596622
    597623          //
    598           // Reset the CTRL-C event (yes we ignore the return values)
    599           //
    600           Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
    601 
    602           //
    603624          // Display Prompt
    604625          //
     
    638659      InternalEfiShellSetEnv(L"cwd", NULL, TRUE);
    639660    }
    640     CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);
     661    CleanUpShellEnvironment (ShellInfoObject.NewEfiShellProtocol);
    641662    DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);
    642663  }
     
    647668
    648669  if (!IsListEmpty(&ShellInfoObject.SplitList.Link)){
    649     ASSERT(FALSE); ///@todo finish this de-allocation.
     670    ASSERT(FALSE); ///@todo finish this de-allocation (free SplitStdIn/Out when needed).
     671
     672    for ( Split = (SPLIT_LIST*)GetFirstNode (&ShellInfoObject.SplitList.Link)
     673        ; !IsNull (&ShellInfoObject.SplitList.Link, &Split->Link)
     674        ; Split = (SPLIT_LIST *)GetNextNode (&ShellInfoObject.SplitList.Link, &Split->Link)
     675     ) {
     676      RemoveEntryList (&Split->Link);
     677      FreePool (Split);
     678    }
     679
     680    DEBUG_CODE (InitializeListHead (&ShellInfoObject.SplitList.Link););
    650681  }
    651682
     
    676707  }
    677708
     709  ShellFreeEnvVarList ();
     710
    678711  if (ShellCommandGetExit()) {
    679712    return ((EFI_STATUS)ShellCommandGetExitCode());
     
    685718  Sets all the alias' that were registered with the ShellCommandLib library.
    686719
    687   @retval EFI_SUCCESS           all init commands were run sucessfully.
     720  @retval EFI_SUCCESS           all init commands were run successfully.
    688721**/
    689722EFI_STATUS
    690 EFIAPI
    691723SetBuiltInAlias(
     724  VOID
    692725  )
    693726{
     
    727760**/
    728761BOOLEAN
    729 EFIAPI
    730762IsCommand(
    731763  IN CONST CHAR16 *Command1,
     
    748780**/
    749781BOOLEAN
    750 EFIAPI
    751782IsScriptOnlyCommand(
    752783  IN CONST CHAR16 *CommandName
     
    770801  for the file that was loaded.
    771802
    772   @param[in, out] DevPath       On a sucessful return the device path to the loaded image.
    773   @param[in, out] FilePath      On a sucessful return the device path to the file.
    774 
    775   @retval EFI_SUCCESS           The 2 device paths were sucessfully returned.
     803  @param[in, out] DevPath       On a successful return the device path to the loaded image.
     804  @param[in, out] FilePath      On a successful return the device path to the file.
     805
     806  @retval EFI_SUCCESS           The 2 device paths were successfully returned.
    776807  @retval other                 A error from gBS->HandleProtocol.
    777808
     
    779810**/
    780811EFI_STATUS
    781 EFIAPI
    782812GetDevicePathsForImageAndFile (
    783813  IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
     
    855885**/
    856886EFI_STATUS
    857 EFIAPI
    858887ProcessCommandLine(
    859888  VOID
     
    874903
    875904  Status = gBS->LocateProtocol (
    876                   &gEfiUnicodeCollationProtocolGuid,
     905                  &gEfiUnicodeCollation2ProtocolGuid,
    877906                  NULL,
    878907                  (VOID **) &UnicodeCollation
    879908                  );
    880909  if (EFI_ERROR (Status)) {
    881     return Status;
     910    Status = gBS->LocateProtocol (
     911                    &gEfiUnicodeCollationProtocolGuid,
     912                    NULL,
     913                    (VOID **) &UnicodeCollation
     914                    );
     915    if (EFI_ERROR (Status)) {
     916      return Status;
     917    }
    882918  }
    883919
     
    892928  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = FALSE;
    893929  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = FALSE;
     930  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest       = FALSE;
    894931  ShellInfoObject.ShellInitSettings.Delay = 5;
    895932
     
    950987                                 ) == 0) {
    951988      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = TRUE;
     989    }
     990    else if (UnicodeCollation->StriColl (
     991                                 UnicodeCollation,
     992                                 L"-nonest",
     993                                 CurrentArg
     994                                 ) == 0) {
     995      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest       = TRUE;
    952996    }
    953997    else if (UnicodeCollation->StriColl (
     
    9751019    } else if (UnicodeCollation->StriColl (
    9761020                                   UnicodeCollation,
    977                                    L"-_exit",
     1021                                   L"-exit",
    9781022                                   CurrentArg
    9791023                                   ) == 0) {
    9801024      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = TRUE;
    9811025    } else if (StrnCmp (L"-", CurrentArg, 1) == 0) {
    982       // Unrecognised option
     1026      // Unrecognized option
    9831027      ShellPrintHiiEx(-1, -1, NULL,
    9841028        STRING_TOKEN (STR_GEN_PROBLEM),
     
    9951039      }
    9961040
    997       ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);
     1041      ShellInfoObject.ShellInitSettings.FileName = NULL;
     1042      Size = 0;
     1043      //
     1044      // If first argument contains a space, then add double quotes before the argument
     1045      //
     1046      if (StrStr (CurrentArg, L" ") != NULL) {
     1047        StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
     1048        if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
     1049          return (EFI_OUT_OF_RESOURCES);
     1050        }
     1051      }
     1052      StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, CurrentArg, 0);
    9981053      if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
    9991054        return (EFI_OUT_OF_RESOURCES);
     1055      }
     1056      //
     1057      // If first argument contains a space, then add double quotes after the argument
     1058      //
     1059      if (StrStr (CurrentArg, L" ") != NULL) {
     1060        StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
     1061        if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
     1062          return (EFI_OUT_OF_RESOURCES);
     1063        }
    10001064      }
    10011065      //
     
    10081072      for (Size = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
    10091073        ASSERT((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));
    1010         StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
    1011                     &Size,
    1012                     L" ",
    1013                     0);
    1014         if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
    1015           SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
    1016           return (EFI_OUT_OF_RESOURCES);
     1074        //
     1075        // Add a space between arguments
     1076        //
     1077        if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
     1078          StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions, &Size, L" ", 0);
     1079          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
     1080            SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
     1081            return (EFI_OUT_OF_RESOURCES);
     1082          }
     1083        }
     1084        //
     1085        // If an argumnent contains a space, then add double quotes before the argument
     1086        //
     1087        if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
     1088          StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
     1089                      &Size,
     1090                      L"\"",
     1091                      0);
     1092          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
     1093            SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
     1094            return (EFI_OUT_OF_RESOURCES);
     1095          }
    10171096        }
    10181097        StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
     
    10241103          return (EFI_OUT_OF_RESOURCES);
    10251104        }
     1105        //
     1106        // If an argumnent contains a space, then add double quotes after the argument
     1107        //
     1108        if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
     1109          StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
     1110                      &Size,
     1111                      L"\"",
     1112                      0);
     1113          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
     1114            SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
     1115            return (EFI_OUT_OF_RESOURCES);
     1116          }
     1117        }
    10261118      }
    10271119    }
     
    10371129
    10381130/**
     1131  Function try to find location of the Startup.nsh file.
     1132
     1133  The buffer is callee allocated and should be freed by the caller.
     1134
     1135  @param    ImageDevicePath       The path to the image for shell.  first place to look for the startup script
     1136  @param    FileDevicePath        The path to the file for shell.  second place to look for the startup script.
     1137
     1138  @retval   NULL                  No Startup.nsh file was found.
     1139  @return   !=NULL                Pointer to NULL-terminated path.
     1140**/
     1141CHAR16 *
     1142LocateStartupScript (
     1143  IN EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,
     1144  IN EFI_DEVICE_PATH_PROTOCOL *FileDevicePath
     1145  )
     1146{
     1147  CHAR16          *StartupScriptPath;
     1148  CHAR16          *TempSpot;
     1149  CONST CHAR16    *MapName;
     1150  UINTN           Size;
     1151
     1152  StartupScriptPath = NULL;
     1153  Size              = 0;
     1154
     1155  //
     1156  // Try to find 'Startup.nsh' in the directory where the shell itself was launched.
     1157  //
     1158  MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath (&ImageDevicePath);
     1159  if (MapName != NULL) {
     1160    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, MapName, 0);
     1161    if (StartupScriptPath == NULL) {
     1162      //
     1163      // Do not locate the startup script in sys path when out of resource.
     1164      //
     1165      return NULL;
     1166    }
     1167    TempSpot = StrStr (StartupScriptPath, L";");
     1168    if (TempSpot != NULL) {
     1169      *TempSpot = CHAR_NULL;
     1170    }
     1171
     1172    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);
     1173    PathRemoveLastItem (StartupScriptPath);
     1174    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);
     1175  }
     1176
     1177  //
     1178  // Try to find 'Startup.nsh' in the execution path defined by the envrionment variable PATH.
     1179  //
     1180  if ((StartupScriptPath == NULL) || EFI_ERROR (ShellIsFile (StartupScriptPath))) {
     1181    SHELL_FREE_NON_NULL (StartupScriptPath);
     1182    StartupScriptPath = ShellFindFilePath (mStartupScript);
     1183  }
     1184
     1185  return StartupScriptPath;
     1186}
     1187
     1188/**
    10391189  Handles all interaction with the default startup script.
    10401190
     
    10471197**/
    10481198EFI_STATUS
    1049 EFIAPI
    10501199DoStartupScript(
    10511200  IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
     
    10541203{
    10551204  EFI_STATUS                    Status;
     1205  EFI_STATUS                    CalleeStatus;
    10561206  UINTN                         Delay;
    10571207  EFI_INPUT_KEY                 Key;
    1058   SHELL_FILE_HANDLE             FileHandle;
    1059   EFI_DEVICE_PATH_PROTOCOL      *NewPath;
    1060   EFI_DEVICE_PATH_PROTOCOL      *NamePath;
    10611208  CHAR16                        *FileStringPath;
    1062   CHAR16                        *TempSpot;
    10631209  UINTN                         NewSize;
    1064   CONST CHAR16                  *MapName;
    10651210
    10661211  Key.UnicodeChar = CHAR_NULL;
    10671212  Key.ScanCode    = 0;
    1068   FileHandle      = NULL;
    10691213
    10701214  if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup && ShellInfoObject.ShellInitSettings.FileName != NULL) {
     
    10801224      return (EFI_OUT_OF_RESOURCES);
    10811225    }
    1082     StrnCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName, NewSize/sizeof(CHAR16) -1);
     1226    StrCpyS(FileStringPath, NewSize/sizeof(CHAR16), ShellInfoObject.ShellInitSettings.FileName);
    10831227    if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
    1084       StrnCat(FileStringPath, L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
    1085       StrnCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
    1086     }
    1087     Status = RunCommand(FileStringPath);
     1228      StrnCatS(FileStringPath, NewSize/sizeof(CHAR16), L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
     1229      StrnCatS(FileStringPath, NewSize/sizeof(CHAR16), ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
     1230    }
     1231    Status = RunShellCommand(FileStringPath, &CalleeStatus);
     1232    if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit == TRUE) {
     1233      ShellCommandRegisterExit(gEfiShellProtocol->BatchIsActive(), (UINT64)CalleeStatus);
     1234    }
    10881235    FreePool(FileStringPath);
    10891236    return (Status);
     
    11251272  }
    11261273
    1127   //
    1128   // Try the first location (must be file system)
    1129   //
    1130   MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath(&ImagePath);
    1131   if (MapName != NULL) {
    1132     FileStringPath = NULL;
    1133     NewSize = 0;
    1134     FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, MapName, 0);
    1135     if (FileStringPath == NULL) {
    1136       Status = EFI_OUT_OF_RESOURCES;
    1137     } else {
    1138       TempSpot = StrStr(FileStringPath, L";");
    1139       if (TempSpot != NULL) {
    1140         *TempSpot = CHAR_NULL;
    1141       }
    1142       FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, ((FILEPATH_DEVICE_PATH*)FilePath)->PathName, 0);
    1143       PathRemoveLastItem(FileStringPath);
    1144       FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, mStartupScript, 0);
    1145       Status = ShellInfoObject.NewEfiShellProtocol->OpenFileByName(FileStringPath, &FileHandle, EFI_FILE_MODE_READ);
    1146       FreePool(FileStringPath);
    1147     }
    1148   }
    1149   if (EFI_ERROR(Status)) {
    1150     NamePath = FileDevicePath (NULL, mStartupScript);
    1151     NewPath = AppendDevicePathNode (ImagePath, NamePath);
    1152     FreePool(NamePath);
    1153 
    1154     //
    1155     // Try the location
    1156     //
    1157     Status = InternalOpenFileDevicePath(NewPath, &FileHandle, EFI_FILE_MODE_READ, 0);
    1158     FreePool(NewPath);
    1159   }
    1160   //
    1161   // If we got a file, run it
    1162   //
    1163   if (!EFI_ERROR(Status) && FileHandle != NULL) {
    1164     Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
    1165     ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
     1274  FileStringPath = LocateStartupScript (ImagePath, FilePath);
     1275  if (FileStringPath != NULL) {
     1276    Status = RunScriptFile (FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
     1277    FreePool (FileStringPath);
    11661278  } else {
    1167     FileStringPath = ShellFindFilePath(mStartupScript);
    1168     if (FileStringPath == NULL) {
    1169       //
    1170       // we return success since we dont need to have a startup script
    1171       //
    1172       Status = EFI_SUCCESS;
    1173       ASSERT(FileHandle == NULL);
    1174     } else {
    1175       Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
    1176       FreePool(FileStringPath);
    1177     }
    1178   }
    1179 
     1279    //
     1280    // we return success since startup script is not mandatory.
     1281    //
     1282    Status = EFI_SUCCESS;
     1283  }
    11801284
    11811285  return (Status);
     
    11911295**/
    11921296EFI_STATUS
    1193 EFIAPI
    11941297DoShellPrompt (
    11951298  VOID
     
    12021305  UINTN         BufferSize;
    12031306  EFI_STATUS    Status;
     1307  LIST_ENTRY    OldBufferList;
    12041308
    12051309  CurDir  = NULL;
     
    12151319  }
    12161320
     1321  SaveBufferList(&OldBufferList);
    12171322  CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");
    12181323
     
    12371342  //
    12381343  if (!EFI_ERROR (Status)) {
     1344    //
     1345    // Reset the CTRL-C event just before running the command (yes we ignore the return values)
     1346    //
     1347    Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
     1348
    12391349    CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
    12401350    Status = RunCommand(CmdLine);
    1241     }
     1351  }
    12421352
    12431353  //
    12441354  // Done with this command
    12451355  //
     1356  RestoreBufferList(&OldBufferList);
    12461357  FreePool (CmdLine);
    12471358  return Status;
     
    12551366**/
    12561367VOID*
    1257 EFIAPI
    1258 AddBufferToFreeList(
     1368AddBufferToFreeList (
    12591369  VOID *Buffer
    12601370  )
     
    12661376  }
    12671377
    1268   BufferListEntry = AllocateZeroPool(sizeof(BUFFER_LIST));
    1269   ASSERT(BufferListEntry != NULL);
     1378  BufferListEntry = AllocateZeroPool (sizeof (BUFFER_LIST));
     1379  if (BufferListEntry == NULL) {
     1380    return NULL;
     1381  }
     1382
    12701383  BufferListEntry->Buffer = Buffer;
    1271   InsertTailList(&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
     1384  InsertTailList (&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
    12721385  return (Buffer);
    12731386}
    12741387
     1388
     1389/**
     1390  Create a new buffer list and stores the old one to OldBufferList
     1391
     1392  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
     1393**/
     1394VOID
     1395SaveBufferList (
     1396  OUT LIST_ENTRY     *OldBufferList
     1397  )
     1398{
     1399  CopyMem (OldBufferList, &ShellInfoObject.BufferToFreeList.Link, sizeof (LIST_ENTRY));
     1400  InitializeListHead (&ShellInfoObject.BufferToFreeList.Link);
     1401}
     1402
     1403/**
     1404  Restore previous nodes into BufferToFreeList .
     1405
     1406  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
     1407**/
     1408VOID
     1409RestoreBufferList (
     1410  IN OUT LIST_ENTRY     *OldBufferList
     1411  )
     1412{
     1413  FreeBufferList (&ShellInfoObject.BufferToFreeList);
     1414  CopyMem (&ShellInfoObject.BufferToFreeList.Link, OldBufferList, sizeof (LIST_ENTRY));
     1415}
     1416
     1417
    12751418/**
    12761419  Add a buffer to the Line History List
     
    12791422**/
    12801423VOID
    1281 EFIAPI
    12821424AddLineToCommandHistory(
    12831425  IN CONST CHAR16 *Buffer
     
    12851427{
    12861428  BUFFER_LIST *Node;
     1429  BUFFER_LIST *Walker;
     1430  UINT16       MaxHistoryCmdCount;
     1431  UINT16       Count;
     1432
     1433  Count = 0;
     1434  MaxHistoryCmdCount = PcdGet16(PcdShellMaxHistoryCommandCount);
     1435
     1436  if (MaxHistoryCmdCount == 0) {
     1437    return ;
     1438  }
     1439
    12871440
    12881441  Node = AllocateZeroPool(sizeof(BUFFER_LIST));
    1289   ASSERT(Node != NULL);
    1290   Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);
    1291   ASSERT(Node->Buffer != NULL);
    1292 
    1293   InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
     1442  if (Node == NULL) {
     1443    return;
     1444  }
     1445
     1446  Node->Buffer = AllocateCopyPool (StrSize (Buffer), Buffer);
     1447  if (Node->Buffer == NULL) {
     1448    FreePool (Node);
     1449    return;
     1450  }
     1451
     1452  for ( Walker = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link)
     1453      ; !IsNull(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)
     1454      ; Walker = (BUFFER_LIST*)GetNextNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)
     1455   ){
     1456    Count++;
     1457  }
     1458  if (Count < MaxHistoryCmdCount){
     1459    InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
     1460  } else {
     1461    Walker = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link);
     1462    RemoveEntryList(&Walker->Link);
     1463    if (Walker->Buffer != NULL) {
     1464      FreePool(Walker->Buffer);
     1465    }
     1466    FreePool(Walker);
     1467    InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
     1468  }
    12941469}
    12951470
     
    13081483**/
    13091484EFI_STATUS
    1310 EFIAPI
    13111485ShellConvertAlias(
    13121486  IN OUT CHAR16 **CommandString
     
    13331507**/
    13341508EFI_STATUS
    1335 EFIAPI
    13361509StripUnreplacedEnvironmentVariables(
    13371510  IN OUT CHAR16 *CmdLine
     
    13501523    if (FirstPercent == NULL || SecondPercent == NULL) {
    13511524      //
    1352       // If we ever dont have 2 % we are done.
     1525      // If we ever don't have 2 % we are done.
    13531526      //
    13541527      break;
     
    13821555        CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));
    13831556        //
    1384         // dont need to update the locator.  both % characters are gone.
     1557        // don't need to update the locator.  both % characters are gone.
    13851558        //
    13861559      } else {
     
    14021575  @param[in] OriginalCommandLine    The original command line
    14031576
    1404   @retval NULL                      An error ocurred.
     1577  @retval NULL                      An error occurred.
    14051578  @return                           The new command line with no environment variables present.
    14061579**/
    14071580CHAR16*
    1408 EFIAPI
    14091581ShellConvertVariables (
    14101582  IN CONST CHAR16 *OriginalCommandLine
     
    14431615       ){
    14441616        //
    1445         // we need a preceeding and if there is space no ^ preceeding (if no space ignore)
     1617        // we need a preceding and if there is space no ^ preceding (if no space ignore)
    14461618        //
    14471619        if ((((Temp-OriginalCommandLine)>2) && *(Temp-2) != L'^') || ((Temp-OriginalCommandLine)<=2)) {
     
    14641636     ){
    14651637      //
    1466       // we need a preceeding and following % and if there is space no ^ preceeding (if no space ignore)
     1638      // we need a preceding and following % and if there is space no ^ preceding (if no space ignore)
    14671639      //
    14681640      if (*(Temp-1) == L'%' && *(Temp+StrLen(MasterEnvList)) == L'%' &&
     
    14761648  // now do the replacements...
    14771649  //
    1478   NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);
     1650  NewCommandLine1 = AllocateZeroPool (NewSize);
    14791651  NewCommandLine2 = AllocateZeroPool(NewSize);
    14801652  ItemTemp        = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));
     
    14851657    return (NULL);
    14861658  }
     1659  CopyMem (NewCommandLine1, OriginalCommandLine, StrSize (OriginalCommandLine));
     1660
    14871661  for (MasterEnvList = EfiShellGetEnv(NULL)
    14881662    ;  MasterEnvList != NULL && *MasterEnvList != CHAR_NULL
    14891663    ;  MasterEnvList += StrLen(MasterEnvList) + 1
    14901664   ){
    1491     StrnCpy(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1);
    1492     StrnCat(ItemTemp, MasterEnvList, ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));
    1493     StrnCat(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));
     1665    StrCpyS( ItemTemp,
     1666              ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),
     1667              L"%"
     1668              );
     1669    StrCatS( ItemTemp,
     1670              ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),
     1671              MasterEnvList
     1672              );
     1673    StrCatS( ItemTemp,
     1674              ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),
     1675              L"%"
     1676              );
    14941677    ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);
    1495     StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
     1678    StrCpyS(NewCommandLine1, NewSize/sizeof(CHAR16), NewCommandLine2);
    14961679  }
    14971680  if (CurrentScriptFile != NULL) {
     
    15011684   ){
    15021685    ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);
    1503     StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
    1504     }
    1505   }
    1506 
    1507   //
    1508   // Remove non-existant environment variables
     1686    StrCpyS(NewCommandLine1, NewSize/sizeof(CHAR16), NewCommandLine2);
     1687    }
     1688  }
     1689
     1690  //
     1691  // Remove non-existent environment variables
    15091692  //
    15101693  StripUnreplacedEnvironmentVariables(NewCommandLine1);
     
    15141697  //
    15151698  ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);
    1516   StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
     1699  StrCpyS(NewCommandLine1, NewSize/sizeof(CHAR16), NewCommandLine2);
    15171700
    15181701  FreePool(NewCommandLine2);
     
    15331716**/
    15341717EFI_STATUS
    1535 EFIAPI
    15361718RunSplitCommand(
    15371719  IN CONST CHAR16             *CmdLine,
    1538   IN       SHELL_FILE_HANDLE  *StdIn,
    1539   IN       SHELL_FILE_HANDLE  *StdOut
     1720  IN       SHELL_FILE_HANDLE  StdIn,
     1721  IN       SHELL_FILE_HANDLE  StdOut
    15401722  )
    15411723{
     
    15461728  UINTN             Size2;
    15471729  SPLIT_LIST        *Split;
    1548   SHELL_FILE_HANDLE *TempFileHandle;
     1730  SHELL_FILE_HANDLE TempFileHandle;
    15491731  BOOLEAN           Unicode;
    15501732
     
    15701752    SHELL_FREE_NON_NULL(NextCommandLine);
    15711753    return (EFI_INVALID_PARAMETER);
    1572   } else if (NextCommandLine[0] != CHAR_NULL &&
    1573       NextCommandLine[0] == L'a' &&
    1574       NextCommandLine[1] == L' '
    1575      ){
     1754  } else if (NextCommandLine[0] == L'a' &&
     1755             (NextCommandLine[1] == L' ' || NextCommandLine[1] == CHAR_NULL)
     1756            ){
    15761757    CopyMem(NextCommandLine, NextCommandLine+1, StrSize(NextCommandLine) - sizeof(NextCommandLine[0]));
     1758    while (NextCommandLine[0] == L' ') {
     1759      CopyMem(NextCommandLine, NextCommandLine+1, StrSize(NextCommandLine) - sizeof(NextCommandLine[0]));
     1760    }
     1761    if (NextCommandLine[0] == CHAR_NULL) {
     1762      SHELL_FREE_NON_NULL(OurCommandLine);
     1763      SHELL_FREE_NON_NULL(NextCommandLine);
     1764      return (EFI_INVALID_PARAMETER);
     1765    }
    15771766    Unicode = FALSE;
    15781767  } else {
     
    15851774  //
    15861775  Split = AllocateZeroPool(sizeof(SPLIT_LIST));
    1587   ASSERT(Split != NULL);
     1776  if (Split == NULL) {
     1777    return EFI_OUT_OF_RESOURCES;
     1778  }
    15881779  Split->SplitStdIn   = StdIn;
    15891780  Split->SplitStdOut  = ConvertEfiFileProtocolToShellHandle(CreateFileInterfaceMem(Unicode), NULL);
     
    16031794  }
    16041795  Split->SplitStdIn   = TempFileHandle;
    1605   ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
     1796  ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);
    16061797
    16071798  if (!EFI_ERROR(Status)) {
     
    16181809  // Note that the original StdIn is now the StdOut...
    16191810  //
    1620   if (Split->SplitStdOut != NULL && Split->SplitStdOut != StdIn) {
    1621     ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));
     1811  if (Split->SplitStdOut != NULL) {
     1812    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);
    16221813  }
    16231814  if (Split->SplitStdIn != NULL) {
    1624     ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));
     1815    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
    16251816  }
    16261817
     
    16421833**/
    16431834EFI_STATUS
    1644 EFIAPI
    16451835ShellSubstituteVariables(
    16461836  IN CHAR16 **CmdLine
     
    16671857**/
    16681858EFI_STATUS
    1669 EFIAPI
    16701859ShellSubstituteAliases(
    16711860  IN CHAR16 **CmdLine
     
    17391928**/
    17401929SHELL_OPERATION_TYPES
    1741 EFIAPI
    17421930GetOperationType(
    17431931  IN CONST CHAR16 *CmdName
     
    18081996**/
    18091997EFI_STATUS
    1810 EFIAPI
    18111998IsValidSplit(
    18121999  IN CONST CHAR16 *CmdLine
     
    18442031    }
    18452032    TempWalker = (CHAR16*)Temp;
    1846     if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)))) {
     2033    if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine), TRUE))) {
    18472034      if (GetOperationType(FirstParameter) == Unknown_Invalid) {
    18482035        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
     
    18672054**/
    18682055EFI_STATUS
    1869 EFIAPI
    18702056VerifySplit(
    18712057  IN CONST CHAR16 *CmdLine
     
    18742060  CONST CHAR16  *TempSpot;
    18752061  EFI_STATUS    Status;
     2062
     2063  //
     2064  // If this was the only item, then get out
     2065  //
     2066  if (!ContainsSplit(CmdLine)) {
     2067    return (EFI_SUCCESS);
     2068  }
    18762069
    18772070  //
     
    18842077
    18852078  //
    1886   // If this was the only item, then get out
    1887   //
    1888   if (!ContainsSplit(CmdLine)) {
    1889     return (EFI_SUCCESS);
    1890   }
    1891 
    1892   //
    18932079  // recurse to verify the next item
    18942080  //
    18952081  TempSpot = FindFirstCharacter(CmdLine, L"|", L'^') + 1;
     2082  if (*TempSpot == L'a' &&
     2083      (*(TempSpot + 1) == L' ' || *(TempSpot + 1) == CHAR_NULL)
     2084     ) {
     2085    // If it's an ASCII pipe '|a'
     2086    TempSpot += 1;
     2087  }
     2088
    18962089  return (VerifySplit(TempSpot));
    18972090}
     
    19032096
    19042097  @retval EFI_SUCCESS   The operation was successful
    1905   @return               an error occured.
     2098  @return               an error occurred.
    19062099**/
    19072100EFI_STATUS
    1908 EFIAPI
    19092101ProcessNewSplitCommandLine(
    19102102  IN CONST CHAR16 *CmdLine
     
    19472139**/
    19482140EFI_STATUS
    1949 EFIAPI
    19502141ChangeMappedDrive(
    19512142  IN CONST CHAR16 *CmdLine
     
    19832174**/
    19842175EFI_STATUS
    1985 EFIAPI
    19862176DoHelpUpdate(
    19872177  IN OUT CHAR16 **CmdLine
     
    19902180  CHAR16 *CurrentParameter;
    19912181  CHAR16 *Walker;
    1992   CHAR16 *LastWalker;
    19932182  CHAR16 *NewCommandLine;
    19942183  EFI_STATUS Status;
     2184  UINTN  NewCmdLineSize;
    19952185
    19962186  Status = EFI_SUCCESS;
     
    20032193  Walker = *CmdLine;
    20042194  while(Walker != NULL && *Walker != CHAR_NULL) {
    2005     LastWalker = Walker;
    2006     if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)))) {
     2195    if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine), TRUE))) {
    20072196      if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {
    2008         LastWalker[0] = L' ';
    2009         LastWalker[1] = L' ';
    2010         NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));
     2197        CurrentParameter[0] = L' ';
     2198        CurrentParameter[1] = L' ';
     2199        NewCmdLineSize = StrSize(L"help ") + StrSize(*CmdLine);
     2200        NewCommandLine = AllocateZeroPool(NewCmdLineSize);
    20112201        if (NewCommandLine == NULL) {
    20122202          Status = EFI_OUT_OF_RESOURCES;
     
    20172207        // We know the space is sufficient since we just calculated it.
    20182208        //
    2019         StrnCpy(NewCommandLine, L"help ", 5);
    2020         StrnCat(NewCommandLine, *CmdLine, StrLen(*CmdLine));
     2209        StrnCpyS(NewCommandLine, NewCmdLineSize/sizeof(CHAR16), L"help ", 5);
     2210        StrnCatS(NewCommandLine, NewCmdLineSize/sizeof(CHAR16), *CmdLine, StrLen(*CmdLine));
    20212211        SHELL_FREE_NON_NULL(*CmdLine);
    20222212        *CmdLine = NewCommandLine;
     
    20372227**/
    20382228EFI_STATUS
    2039 EFIAPI
    20402229SetLastError(
    20412230  IN CONST SHELL_STATUS   ErrorCode
     
    20612250  @retval EFI_SUCCESS           The operation was successful
    20622251  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
    2063   @return                       some other error occured
     2252  @return                       some other error occurred
    20642253**/
    20652254EFI_STATUS
    2066 EFIAPI
    20672255ProcessCommandLineToFinal(
    20682256  IN OUT CHAR16 **CmdLine
     
    21062294  Run an internal shell command.
    21072295
    2108   This API will upadate the shell's environment since these commands are libraries.
     2296  This API will update the shell's environment since these commands are libraries.
    21092297
    21102298  @param[in] CmdLine          the command line to run.
    21112299  @param[in] FirstParameter   the first parameter on the command line
    21122300  @param[in] ParamProtocol    the shell parameters protocol pointer
     2301  @param[out] CommandStatus   the status from the command line.
    21132302
    21142303  @retval EFI_SUCCESS     The command was completed.
     
    21162305**/
    21172306EFI_STATUS
    2118 EFIAPI
    21192307RunInternalCommand(
    21202308  IN CONST CHAR16                   *CmdLine,
    21212309  IN       CHAR16                   *FirstParameter,
    2122   IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2310  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
     2311  OUT EFI_STATUS                    *CommandStatus
    21232312)
    21242313{
     
    21452334  // get the argc and argv updated for internal commands
    21462335  //
    2147   Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, &Argv, &Argc);
     2336  Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, Internal_Command, &Argv, &Argc);
    21482337  if (!EFI_ERROR(Status)) {
    21492338    //
     
    21532342
    21542343    if (!EFI_ERROR(Status)) {
     2344      if (CommandStatus != NULL) {
     2345        if (CommandReturnedStatus != SHELL_SUCCESS) {
     2346          *CommandStatus = (EFI_STATUS)(CommandReturnedStatus | MAX_BIT);
     2347        } else {
     2348          *CommandStatus = EFI_SUCCESS;
     2349        }
     2350      }
     2351
    21552352      //
    21562353      // Update last error status.
     
    21842381
    21852382  //
    2186   // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
     2383  // This is guaranteed to be called after UpdateArgcArgv no matter what else happened.
    21872384  // This is safe even if the update API failed.  In this case, it may be a no-op.
    21882385  //
     
    21902387
    21912388  //
    2192   // If a script is running and the command is not a scipt only command, then
     2389  // If a script is running and the command is not a script only command, then
    21932390  // change return value to success so the script won't halt (unless aborted).
    21942391  //
     
    22142411  @param[in] FirstParameter   the first parameter on the command line
    22152412  @param[in] ParamProtocol    the shell parameters protocol pointer
     2413  @param[out] CommandStatus   the status from the command line.
    22162414
    22172415  @retval EFI_SUCCESS     The command was completed.
     
    22192417**/
    22202418EFI_STATUS
    2221 EFIAPI
    22222419RunCommandOrFile(
    22232420  IN       SHELL_OPERATION_TYPES    Type,
    22242421  IN CONST CHAR16                   *CmdLine,
    22252422  IN       CHAR16                   *FirstParameter,
    2226   IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2423  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
     2424  OUT EFI_STATUS                    *CommandStatus
    22272425)
    22282426{
     
    22402438  switch (Type) {
    22412439    case   Internal_Command:
    2242       Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);
     2440      Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol, CommandStatus);
    22432441      break;
    22442442    case   Script_File_Name:
     
    23062504          }
    23072505
     2506          if (CommandStatus != NULL) {
     2507            *CommandStatus = CalleeExitStatus;
     2508          }
     2509
    23082510          //
    23092511          // Update last error status.
     
    23382540  @param[in] FirstParameter   the first parameter on the command line.
    23392541  @param[in] ParamProtocol    the shell parameters protocol pointer
     2542  @param[out] CommandStatus   the status from the command line.
    23402543
    23412544  @retval EFI_SUCCESS     The command was completed.
     
    23432546**/
    23442547EFI_STATUS
    2345 EFIAPI
    23462548SetupAndRunCommandOrFile(
    2347   IN SHELL_OPERATION_TYPES          Type,
    2348   IN CHAR16                         *CmdLine,
    2349   IN CHAR16                         *FirstParameter,
    2350   IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2549  IN   SHELL_OPERATION_TYPES          Type,
     2550  IN   CHAR16                         *CmdLine,
     2551  IN   CHAR16                         *FirstParameter,
     2552  IN   EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
     2553  OUT EFI_STATUS                      *CommandStatus
    23512554)
    23522555{
     
    23562559  SHELL_FILE_HANDLE         OriginalStdErr;
    23572560  SYSTEM_TABLE_INFO         OriginalSystemTableInfo;
     2561  CONST SCRIPT_FILE         *ConstScriptFile;
    23582562
    23592563  //
     
    23682572  if (!EFI_ERROR(Status)) {
    23692573    TrimSpaces(&CmdLine);
    2370     Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);
     2574    Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol, CommandStatus);
    23712575  }
    23722576
     
    23752579  //
    23762580  if (EFI_ERROR(Status)) {
    2377     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
     2581    ConstScriptFile = ShellCommandGetCurrentScriptFile();
     2582    if (ConstScriptFile == NULL || ConstScriptFile->CurrentCommand == NULL) {
     2583      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
     2584    } else {
     2585      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR_SCRIPT), ShellInfoObject.HiiHandle, (VOID*)(Status), ConstScriptFile->CurrentCommand->Line);
     2586    }
    23782587  }
    23792588
     
    23932602
    23942603  @param[in] CmdLine      The command line to parse.
     2604  @param[out] CommandStatus   The status from the command line.
    23952605
    23962606  @retval EFI_SUCCESS     The command was completed.
     
    23982608**/
    23992609EFI_STATUS
    2400 EFIAPI
    2401 RunCommand(
    2402   IN CONST CHAR16   *CmdLine
     2610RunShellCommand(
     2611  IN CONST CHAR16   *CmdLine,
     2612  OUT EFI_STATUS    *CommandStatus
    24032613  )
    24042614{
     
    24082618  CHAR16                    *TempWalker;
    24092619  SHELL_OPERATION_TYPES     Type;
     2620  CONST CHAR16              *CurDir;
    24102621
    24112622  ASSERT(CmdLine != NULL);
     
    24282639  // The # character on a line is used to denote that all characters on the same line
    24292640  // and to the right of the # are to be ignored by the shell.
    2430   // Afterward, again remove spaces, in case any were between the last command-parameter and '#'.
     2641  // Afterwards, again remove spaces, in case any were between the last command-parameter and '#'.
    24312642  //
    24322643  for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) {
     
    24572668
    24582669  //
    2459   // We dont do normal processing with a split command line (output from one command input to another)
     2670  // We don't do normal processing with a split command line (output from one command input to another)
    24602671  //
    24612672  if (ContainsSplit(CleanOriginal)) {
     
    24742685  }
    24752686  TempWalker = CleanOriginal;
    2476   if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)))) {
     2687  if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal), TRUE))) {
    24772688    //
    24782689    // Depending on the first parameter we change the behavior
     
    24852696      case   Script_File_Name:
    24862697      case   Efi_Application:
    2487         Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);
     2698        Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol, CommandStatus);
    24882699        break;
    24892700      default:
     
    24992710    SetLastError(SHELL_NOT_FOUND);
    25002711  }
     2712  //
     2713  // Check whether the current file system still exists. If not exist, we need update "cwd" and gShellCurMapping.
     2714  //
     2715  CurDir = EfiShellGetCurDir (NULL);
     2716  if (CurDir != NULL) {
     2717    if (EFI_ERROR(ShellFileExists (CurDir))) {
     2718      //
     2719      // EfiShellSetCurDir() cannot set current directory to NULL.
     2720      // EfiShellSetEnv() is not allowed to set the "cwd" variable.
     2721      // Only InternalEfiShellSetEnv () is allowed setting the "cwd" variable.
     2722      //
     2723      InternalEfiShellSetEnv (L"cwd", NULL, TRUE);
     2724      gShellCurMapping = NULL;
     2725    }
     2726  }
    25012727
    25022728  SHELL_FREE_NON_NULL(CleanOriginal);
     
    25062732}
    25072733
     2734/**
     2735  Function will process and run a command line.
     2736
     2737  This will determine if the command line represents an internal shell
     2738  command or dispatch an external application.
     2739
     2740  @param[in] CmdLine      The command line to parse.
     2741
     2742  @retval EFI_SUCCESS     The command was completed.
     2743  @retval EFI_ABORTED     The command's operation was aborted.
     2744**/
     2745EFI_STATUS
     2746RunCommand(
     2747  IN CONST CHAR16   *CmdLine
     2748  )
     2749{
     2750  return (RunShellCommand(CmdLine, NULL));
     2751}
     2752
     2753
    25082754STATIC CONST UINT16 InvalidChars[] = {L'*', L'?', L'<', L'>', L'\\', L'/', L'\"', 0x0001, 0x0002};
    25092755/**
    2510   Function determins if the CommandName COULD be a valid command.  It does not determine whether
     2756  Function determines if the CommandName COULD be a valid command.  It does not determine whether
    25112757  this is a valid command.  It only checks for invalid characters.
    25122758
     
    25172763**/
    25182764BOOLEAN
    2519 EFIAPI
    25202765IsValidCommandName(
    25212766  IN CONST CHAR16     *CommandName
     
    25442789  @param[in] Name               The name of the script file.
    25452790
    2546   @retval EFI_SUCCESS           the script completed sucessfully
     2791  @retval EFI_SUCCESS           the script completed successfully
    25472792**/
    25482793EFI_STATUS
    2549 EFIAPI
    25502794RunScriptFileHandle (
    25512795  IN SHELL_FILE_HANDLE  Handle,
     
    25562800  SCRIPT_FILE         *NewScriptFile;
    25572801  UINTN               LoopVar;
     2802  UINTN               PrintBuffSize;
    25582803  CHAR16              *CommandLine;
    25592804  CHAR16              *CommandLine2;
     
    25662811  UINTN               LineCount;
    25672812  CHAR16              LeString[50];
     2813  LIST_ENTRY          OldBufferList;
    25682814
    25692815  ASSERT(!ShellCommandGetScriptExit());
    25702816
    25712817  PreScriptEchoState = ShellCommandGetEchoState();
     2818  PrintBuffSize = PcdGet16(PcdShellPrintBufferSize);
    25722819
    25732820  NewScriptFile = (SCRIPT_FILE*)AllocateZeroPool(sizeof(SCRIPT_FILE));
     
    26442891  // Now enumerate through the commands and run each one.
    26452892  //
    2646   CommandLine = AllocateZeroPool(PcdGet16(PcdShellPrintBufferSize));
     2893  CommandLine = AllocateZeroPool(PrintBuffSize);
    26472894  if (CommandLine == NULL) {
    26482895    DeleteScriptFileStruct(NewScriptFile);
    26492896    return (EFI_OUT_OF_RESOURCES);
    26502897  }
    2651   CommandLine2 = AllocateZeroPool(PcdGet16(PcdShellPrintBufferSize));
     2898  CommandLine2 = AllocateZeroPool(PrintBuffSize);
    26522899  if (CommandLine2 == NULL) {
    26532900    FreePool(CommandLine);
     
    26612908  ){
    26622909    ASSERT(CommandLine2 != NULL);
    2663     StrnCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
     2910    StrnCpyS( CommandLine2,
     2911              PrintBuffSize/sizeof(CHAR16),
     2912              NewScriptFile->CurrentCommand->Cl,
     2913              PrintBuffSize/sizeof(CHAR16) - 1
     2914              );
     2915
     2916    SaveBufferList(&OldBufferList);
    26642917
    26652918    //
     
    26822935      // Due to variability in starting the find and replace action we need to have both buffers the same.
    26832936      //
    2684       StrnCpy(CommandLine, CommandLine2, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
     2937      StrnCpyS( CommandLine,
     2938                PrintBuffSize/sizeof(CHAR16),
     2939                CommandLine2,
     2940                PrintBuffSize/sizeof(CHAR16) - 1
     2941                );
    26852942
    26862943      //
     
    26902947        switch (NewScriptFile->Argc) {
    26912948          default:
    2692             Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, TRUE);
     2949            Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%9", NewScriptFile->Argv[9], FALSE, FALSE);
    26932950            ASSERT_EFI_ERROR(Status);
    26942951          case 9:
    2695             Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, TRUE);
     2952            Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%8", NewScriptFile->Argv[8], FALSE, FALSE);
    26962953            ASSERT_EFI_ERROR(Status);
    26972954          case 8:
    2698             Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, TRUE);
     2955            Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%7", NewScriptFile->Argv[7], FALSE, FALSE);
    26992956            ASSERT_EFI_ERROR(Status);
    27002957          case 7:
    2701             Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, TRUE);
     2958            Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%6", NewScriptFile->Argv[6], FALSE, FALSE);
    27022959            ASSERT_EFI_ERROR(Status);
    27032960          case 6:
    2704             Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, TRUE);
     2961            Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%5", NewScriptFile->Argv[5], FALSE, FALSE);
    27052962            ASSERT_EFI_ERROR(Status);
    27062963          case 5:
    2707             Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, TRUE);
     2964            Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%4", NewScriptFile->Argv[4], FALSE, FALSE);
    27082965            ASSERT_EFI_ERROR(Status);
    27092966          case 4:
    2710             Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, TRUE);
     2967            Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%3", NewScriptFile->Argv[3], FALSE, FALSE);
    27112968            ASSERT_EFI_ERROR(Status);
    27122969          case 3:
    2713             Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, TRUE);
     2970            Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%2", NewScriptFile->Argv[2], FALSE, FALSE);
    27142971            ASSERT_EFI_ERROR(Status);
    27152972          case 2:
    2716             Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, TRUE);
     2973            Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%1", NewScriptFile->Argv[1], FALSE, FALSE);
    27172974            ASSERT_EFI_ERROR(Status);
    27182975          case 1:
    2719             Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, TRUE);
     2976            Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%0", NewScriptFile->Argv[0], FALSE, FALSE);
    27202977            ASSERT_EFI_ERROR(Status);
    27212978            break;
     
    27242981        }
    27252982      }
    2726       Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", L"\"\"", FALSE, FALSE);
    2727       Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", L"\"\"", FALSE, FALSE);
    2728       Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", L"\"\"", FALSE, FALSE);
    2729       Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", L"\"\"", FALSE, FALSE);
    2730       Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", L"\"\"", FALSE, FALSE);
    2731       Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", L"\"\"", FALSE, FALSE);
    2732       Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", L"\"\"", FALSE, FALSE);
    2733       Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", L"\"\"", FALSE, FALSE);
    2734       Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE);
    2735 
    2736       StrnCpy(CommandLine2, CommandLine, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
     2983      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%1", L"\"\"", FALSE, FALSE);
     2984      Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%2", L"\"\"", FALSE, FALSE);
     2985      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%3", L"\"\"", FALSE, FALSE);
     2986      Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%4", L"\"\"", FALSE, FALSE);
     2987      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%5", L"\"\"", FALSE, FALSE);
     2988      Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%6", L"\"\"", FALSE, FALSE);
     2989      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%7", L"\"\"", FALSE, FALSE);
     2990      Status = ShellCopySearchAndReplace(CommandLine,  CommandLine2, PrintBuffSize, L"%8", L"\"\"", FALSE, FALSE);
     2991      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PrintBuffSize, L"%9", L"\"\"", FALSE, FALSE);
     2992
     2993      StrnCpyS( CommandLine2,
     2994                PrintBuffSize/sizeof(CHAR16),
     2995                CommandLine,
     2996                PrintBuffSize/sizeof(CHAR16) - 1
     2997                );
    27372998
    27382999      LastCommand = NewScriptFile->CurrentCommand;
     
    27893050          ShellCommandRegisterExit(FALSE, 0);
    27903051          Status = EFI_SUCCESS;
     3052          RestoreBufferList(&OldBufferList);
    27913053          break;
    27923054        }
    27933055        if (ShellGetExecutionBreakFlag()) {
     3056          RestoreBufferList(&OldBufferList);
    27943057          break;
    27953058        }
    27963059        if (EFI_ERROR(Status)) {
     3060          RestoreBufferList(&OldBufferList);
    27973061          break;
    27983062        }
    27993063        if (ShellCommandGetExit()) {
     3064          RestoreBufferList(&OldBufferList);
    28003065          break;
    28013066        }
     
    28163081      }
    28173082    }
     3083    RestoreBufferList(&OldBufferList);
    28183084  }
    28193085
     
    28403106  @param[in] ParamProtocol      the shell parameters protocol pointer
    28413107
    2842   @retval EFI_SUCCESS           the script completed sucessfully
     3108  @retval EFI_SUCCESS           the script completed successfully
    28433109**/
    28443110EFI_STATUS
    2845 EFIAPI
    28463111RunScriptFile (
    28473112  IN CONST CHAR16                   *ScriptPath,
     
    28633128  // get the argc and argv updated for scripts
    28643129  //
    2865   Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
     3130  Status = UpdateArgcArgv(ParamProtocol, CmdLine, Script_File_Name, &Argv, &Argc);
    28663131  if (!EFI_ERROR(Status)) {
    28673132
     
    28883153
    28893154  //
    2890   // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
     3155  // This is guaranteed to be called after UpdateArgcArgv no matter what else happened.
    28913156  // This is safe even if the update API failed.  In this case, it may be a no-op.
    28923157  //
     
    28973162
    28983163/**
    2899   Return the pointer to the first occurance of any character from a list of characters
     3164  Return the pointer to the first occurrence of any character from a list of characters.
    29003165
    29013166  @param[in] String           the string to parse
     
    29073172**/
    29083173CONST CHAR16*
    2909 EFIAPI
    29103174FindFirstCharacter(
    29113175  IN CONST CHAR16 *String,
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/Shell.h

    r58459 r77662  
    22  function definitions for internal to shell functions.
    33
    4   (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
    5   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     4  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
     5  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
    66  This program and the accompanying materials
    77  are licensed and made available under the terms and conditions of the BSD License
     
    1818
    1919#include <Uefi.h>
    20 #include <ShellBase.h>
    2120
    2221#include <Guid/ShellVariableGuid.h>
     
    2524#include <Protocol/LoadedImage.h>
    2625#include <Protocol/SimpleTextOut.h>
    27 #include <Protocol/EfiShell.h>
     26#include <Protocol/Shell.h>
    2827#include <Protocol/EfiShellInterface.h>
    2928#include <Protocol/EfiShellEnvironment2.h>
    30 #include <Protocol/EfiShellParameters.h>
     29#include <Protocol/ShellParameters.h>
    3130#include <Protocol/BlockIo.h>
     31#include <Protocol/HiiPackageList.h>
    3232
    3333#include <Library/BaseLib.h>
     
    4747#include <Library/PrintLib.h>
    4848#include <Library/HandleParsingLib.h>
    49 #include <Library/PathLib.h>
    5049#include <Library/FileHandleLib.h>
     50#include <Library/UefiHiiServicesLib.h>
    5151
    5252#include "ShellParametersProtocol.h"
     
    5858#include "FileHandleWrappers.h"
    5959
     60extern CONST CHAR16 mNoNestingEnvVarName[];
     61extern CONST CHAR16 mNoNestingTrue[];
     62extern CONST CHAR16 mNoNestingFalse[];
     63
    6064typedef struct {
    6165  LIST_ENTRY        Link;           ///< Standard linked list handler.
    62   SHELL_FILE_HANDLE *SplitStdOut;   ///< ConsoleOut for use in the split.
    63   SHELL_FILE_HANDLE *SplitStdIn;    ///< ConsoleIn for use in the split.
     66  SHELL_FILE_HANDLE SplitStdOut;    ///< ConsoleOut for use in the split.
     67  SHELL_FILE_HANDLE SplitStdIn;     ///< ConsoleIn for use in the split.
    6468} SPLIT_LIST;
    6569
     
    7377  UINT32  NoVersion:1;    ///< Was "-noversion"     found on command line.
    7478  UINT32  Delay:1;        ///< Was "-delay[:n]      found on command line
    75   UINT32  Exit:1;         ///< Was "-_exit"          found on command line
     79  UINT32  Exit:1;         ///< Was "-_exit"         found on command line
     80  UINT32  NoNest:1;       ///< Was "-nonest"        found on command line
    7681  UINT32  Reserved:7;     ///< Extra bits
    7782} SHELL_BITS;
     
    124129} SHELL_INFO;
    125130
     131#pragma pack(1)
     132///
     133/// HII specific Vendor Device Path definition.
     134///
     135typedef struct {
     136  VENDOR_DEVICE_PATH             VendorDevicePath;
     137  EFI_DEVICE_PATH_PROTOCOL       End;
     138} SHELL_MAN_HII_VENDOR_DEVICE_PATH;
     139#pragma pack()
     140
    126141extern SHELL_INFO ShellInfoObject;
    127 
    128 typedef enum {
    129   Internal_Command,
    130   Script_File_Name,
    131   Efi_Application,
    132   File_Sys_Change,
    133   Unknown_Invalid
    134 } SHELL_OPERATION_TYPES;
    135142
    136143/**
     
    141148  @retval EFI_SUCCESS           The operation was successful
    142149  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
    143   @return                       some other error occured
    144 **/
    145 EFI_STATUS
    146 EFIAPI
     150  @return                       some other error occurred
     151**/
     152EFI_STATUS
    147153ProcessCommandLineToFinal(
    148154  IN OUT CHAR16 **CmdLine
     
    155161**/
    156162EFI_STATUS
    157 EFIAPI
    158163SetLastError(
    159164  IN CONST SHELL_STATUS   ErrorCode
     
    163168  Sets all the alias' that were registered with the ShellCommandLib library.
    164169
    165   @retval EFI_SUCCESS           all init commands were run sucessfully.
    166 **/
    167 EFI_STATUS
    168 EFIAPI
     170  @retval EFI_SUCCESS           all init commands were run successfully.
     171**/
     172EFI_STATUS
    169173SetBuiltInAlias(
    170174  VOID
     
    177181  for the file that was loaded.
    178182
    179   @param[in, out] DevPath       on a sucessful return the device path to the loaded image
    180   @param[in, out] FilePath      on a sucessful return the device path to the file
    181 
    182   @retval EFI_SUCCESS           the 2 device paths were sucessfully returned.
     183  @param[in, out] DevPath       on a successful return the device path to the loaded image
     184  @param[in, out] FilePath      on a successful return the device path to the file
     185
     186  @retval EFI_SUCCESS           the 2 device paths were successfully returned.
    183187  @return other                 a error from gBS->HandleProtocol
    184188
     
    186190**/
    187191EFI_STATUS
    188 EFIAPI
    189192GetDevicePathsForImageAndFile (
    190193  IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
     
    220223**/
    221224EFI_STATUS
    222 EFIAPI
    223225ProcessCommandLine(
    224226  VOID
     
    236238**/
    237239EFI_STATUS
    238 EFIAPI
    239240DoStartupScript(
    240241  IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
     
    251252**/
    252253EFI_STATUS
    253 EFIAPI
    254254DoShellPrompt (
    255255  VOID
     
    263263**/
    264264VOID*
    265 EFIAPI
    266265AddBufferToFreeList(
    267266  VOID *Buffer
     
    274273**/
    275274VOID
    276 EFIAPI
    277275AddLineToCommandHistory(
    278276  IN CONST CHAR16 *Buffer
     
    290288**/
    291289EFI_STATUS
    292 EFIAPI
    293290RunCommand(
    294291  IN CONST CHAR16   *CmdLine
     
    296293
    297294/**
    298   Function determins if the CommandName COULD be a valid command.  It does not determine whether
     295  Function will process and run a command line.
     296
     297  This will determine if the command line represents an internal shell
     298  command or dispatch an external application.
     299
     300  @param[in] CmdLine      The command line to parse.
     301  @param[out] CommandStatus   The status from the command line.
     302
     303  @retval EFI_SUCCESS     The command was completed.
     304  @retval EFI_ABORTED     The command's operation was aborted.
     305**/
     306EFI_STATUS
     307RunShellCommand(
     308  IN CONST CHAR16   *CmdLine,
     309  OUT EFI_STATUS    *CommandStatus
     310  );
     311
     312/**
     313  Function determines if the CommandName COULD be a valid command.  It does not determine whether
    299314  this is a valid command.  It only checks for invalid characters.
    300315
     
    305320**/
    306321BOOLEAN
    307 EFIAPI
    308322IsValidCommandName(
    309323  IN CONST CHAR16     *CommandName
     
    316330  @param[in] Name               The name of the script file.
    317331
    318   @retval EFI_SUCCESS           the script completed sucessfully
    319 **/
    320 EFI_STATUS
    321 EFIAPI
     332  @retval EFI_SUCCESS           the script completed successfully
     333**/
     334EFI_STATUS
    322335RunScriptFileHandle (
    323336  IN SHELL_FILE_HANDLE  Handle,
     
    333346  @param[in] ParamProtocol      the shell parameters protocol pointer
    334347
    335   @retval EFI_SUCCESS           the script completed sucessfully
    336 **/
    337 EFI_STATUS
    338 EFIAPI
     348  @retval EFI_SUCCESS           the script completed successfully
     349**/
     350EFI_STATUS
    339351RunScriptFile (
    340352  IN CONST CHAR16                   *ScriptPath,
     
    345357
    346358/**
    347   Return the pointer to the first occurance of any character from a list of characters
     359  Return the pointer to the first occurrence of any character from a list of characters.
    348360
    349361  @param[in] String           the string to parse
     
    355367**/
    356368CONST CHAR16*
    357 EFIAPI
    358369FindFirstCharacter(
    359370  IN CONST CHAR16 *String,
     
    362373  );
    363374
     375/**
     376  Cleans off leading and trailing spaces and tabs.
     377
     378  @param[in] String pointer to the string to trim them off.
     379**/
     380EFI_STATUS
     381TrimSpaces(
     382  IN CHAR16 **String
     383  );
     384
     385/**
     386
     387  Create a new buffer list and stores the old one to OldBufferList
     388
     389  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
     390**/
     391VOID
     392SaveBufferList (
     393  OUT LIST_ENTRY     *OldBufferList
     394  );
     395
     396/**
     397  Restore previous nodes into BufferToFreeList .
     398
     399  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
     400**/
     401VOID
     402RestoreBufferList (
     403  IN OUT LIST_ENTRY     *OldBufferList
     404  );
     405
     406
     407
    364408#endif //_SHELL_INTERNAL_HEADER_
    365409
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/Shell.inf

    r58459 r77662  
    22#  This is the shell application
    33#
    4 Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
    5 #  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     4(C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
     5#  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
    66#
    77#  This program and the accompanying materials
     
    1818  INF_VERSION                    = 0x00010006
    1919  BASE_NAME                      = Shell
    20   FILE_GUID                      = 7C04A583-9E3E-4f1c-AD65-E05268D0B4D1
     20  FILE_GUID                      = 7C04A583-9E3E-4f1c-AD65-E05268D0B4D1 # gUefiShellFileGuid
    2121  MODULE_TYPE                    = UEFI_APPLICATION
    2222  VERSION_STRING                 = 1.0
     
    7171  SortLib
    7272  HandleParsingLib
    73   PathLib
     73  UefiHiiServicesLib
    7474
    7575[Guids]
    76   gShellVariableGuid                                      ## CONSUMES ## GUID
    77   gShellMapGuid                                           ## CONSUMES ## GUID
    78   gShellAliasGuid                                         ## CONSUMES ## GUID
     76  gShellVariableGuid                                      ## SOMETIMES_CONSUMES ## GUID
     77  gShellAliasGuid                                         ## SOMETIMES_CONSUMES ## GUID
     78  gShellAliasGuid                                         ## SOMETIMES_PRODUCES ## GUID
    7979
    8080[Protocols]
     
    9090  gEfiSimpleTextInProtocolGuid                            ## CONSUMES
    9191  gEfiSimpleTextOutProtocolGuid                           ## CONSUMES
    92   gEfiSimpleFileSystemProtocolGuid                        ## CONSUMES
     92  gEfiSimpleFileSystemProtocolGuid                        ## SOMETIMES_CONSUMES
    9393  gEfiLoadedImageProtocolGuid                             ## CONSUMES
    94   gEfiComponentName2ProtocolGuid                          ## CONSUMES
     94  gEfiComponentName2ProtocolGuid                          ## SOMETIMES_CONSUMES
    9595  gEfiUnicodeCollation2ProtocolGuid                       ## CONSUMES
    9696  gEfiDevicePathProtocolGuid                              ## CONSUMES
     97  gEfiHiiPackageListProtocolGuid                          ## SOMETIMES_PRODUCES
    9798
    9899[Pcd]
    99   gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel         ## CONSUMES
    100   gEfiShellPkgTokenSpaceGuid.PcdShellSupportOldProtocols  ## CONSUMES
    101   gEfiShellPkgTokenSpaceGuid.PcdShellRequireHiiPlatform   ## CONSUMES
    102   gEfiShellPkgTokenSpaceGuid.PcdShellSupportFrameworkHii  ## CONSUMES
    103   gEfiShellPkgTokenSpaceGuid.PcdShellPageBreakDefault     ## CONSUMES
    104   gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize    ## CONSUMES
    105   gEfiShellPkgTokenSpaceGuid.PcdShellInsertModeDefault    ## CONSUMES
    106   gEfiShellPkgTokenSpaceGuid.PcdShellScreenLogCount       ## CONSUMES
    107   gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength        ## CONSUMES
    108   gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize      ## CONSUMES
    109   gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole         ## CONSUMES
    110   gEfiShellPkgTokenSpaceGuid.PcdShellSupplier             ## CONSUMES
    111 
     100  gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel           ## CONSUMES
     101  gEfiShellPkgTokenSpaceGuid.PcdShellSupportOldProtocols    ## CONSUMES
     102  gEfiShellPkgTokenSpaceGuid.PcdShellRequireHiiPlatform     ## CONSUMES
     103  gEfiShellPkgTokenSpaceGuid.PcdShellSupportFrameworkHii    ## CONSUMES
     104  gEfiShellPkgTokenSpaceGuid.PcdShellPageBreakDefault       ## CONSUMES
     105  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize      ## CONSUMES
     106  gEfiShellPkgTokenSpaceGuid.PcdShellInsertModeDefault      ## CONSUMES
     107  gEfiShellPkgTokenSpaceGuid.PcdShellScreenLogCount         ## CONSUMES
     108  gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength          ## CONSUMES
     109  gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize        ## CONSUMES
     110  gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole           ## CONSUMES
     111  gEfiShellPkgTokenSpaceGuid.PcdShellSupplier               ## CONSUMES
     112  gEfiShellPkgTokenSpaceGuid.PcdShellMaxHistoryCommandCount ## CONSUMES
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/Shell.uni

    r58466 r77662  
    1 // *++
     1// *++
    22//
    3 // Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
    4 // Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved. <BR>
     3// (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
     4// Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved. <BR>
    55// This program and the accompanying materials
    66// are licensed and made available under the terms and conditions of the BSD License
     
    2727#langdef   en-US "English"
    2828
    29 #string STR_SHELL_CURDIR              #language en-US "%E%s> %N"
    30 #string STR_GEN_PROBLEM               #language en-US "%EError. %NThe argument '%B%s%N' is incorrect.\r\n"
     29#string STR_SHELL_CURDIR              #language en-US "%E%s\> %N"
     30#string STR_GEN_PROBLEM               #language en-US "The argument '%B%s%N' is incorrect.\r\n"
    3131#string STR_SHELL_SHELL               #language en-US "%EShell> %N"
    3232
     
    4040#string STR_SHELL_CRLF                #language en-US "\r\n"
    4141
    42 #string STR_SHELL_ERROR               #language en-US  "%NError reported: %r\r\n"
     42#string STR_SHELL_ERROR               #language en-US  "%NCommand Error Status: %r\r\n"
     43#string STR_SHELL_ERROR_SCRIPT        #language en-US  "%NScript Error Status: %r (line number %d)\r\n"
    4344
    44 #string STR_SHELL_INVALID_MAPPING     #language en-US "%N'%B%s%N' is not a correct mapping.\r\n"
    45 #string STR_SHELL_INVALID_SPLIT       #language en-US "%EError.%N Invalid use of pipe (%B|%N).\r\n"
     45#string STR_SHELL_INVALID_MAPPING     #language en-US "%N'%B%s%N' is not a valid mapping.\r\n"
     46#string STR_SHELL_INVALID_SPLIT       #language en-US "Invalid use of pipe (%B|%N).\r\n"
    4647
    47 #string STR_SHELL_INVALID_REDIR       #language en-US "%EError.%N Unable to redirect file.\r\n"
    48 #string STR_SHELL_REDUNDA_REDIR       #language en-US "%EError.%N redundant redirection specified.\r\n"
     48#string STR_SHELL_INVALID_REDIR       #language en-US "Unable to redirect file.\r\n"
     49#string STR_SHELL_REDUNDA_REDIR       #language en-US "Redundant redirection specified.\r\n"
    4950
    5051#string STR_VER_OUTPUT_MAIN_SHELL     #language en-US "UEFI %s Shell v%d.%d\r\n"
     
    5253#string STR_VER_OUTPUT_MAIN_UEFI      #language en-US "UEFI v%d.%02d (%s, 0x%08x)\r\n"
    5354
    54 #string STR_SHELL_NO_IN_EX            #language en-US "%EError. Error.%N  No SimpleTextInputEx was found.  CTRL based features are not usable.\r\n"
     55#string STR_SHELL_NO_IN_EX            #language en-US "No SimpleTextInputEx was found. CTRL-based features are not usable.\r\n"
     56
     57#string STR_SHELL_IMAGE_NOT_APP       #language en-US "The image is not an application.\r\n"
     58
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellEnvVar.c

    r58466 r77662  
    22  function declarations for shell environment functions.
    33
    4   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1818#define INIT_DATA_BUFFER_SIZE  1024
    1919
     20//
     21// The list is used to cache the environment variables.
     22//
     23ENV_VAR_LIST                   gShellEnvVarList;
     24
    2025/**
    2126  Reports whether an environment variable is Volatile or Non-Volatile.
    2227
    2328  @param EnvVarName             The name of the environment variable in question
    24 
    25   @retval TRUE                  This environment variable is Volatile
    26   @retval FALSE                 This environment variable is NON-Volatile
    27 **/
    28 BOOLEAN
    29 EFIAPI
     29  @param Volatile               Return TRUE if the environment variable is volatile
     30
     31  @retval EFI_SUCCESS           The volatile attribute is returned successfully
     32  @retval others                Some errors happened.
     33**/
     34EFI_STATUS
    3035IsVolatileEnv (
    31   IN CONST CHAR16 *EnvVarName
     36  IN CONST CHAR16 *EnvVarName,
     37  OUT BOOLEAN     *Volatile
    3238  )
    3339{
     
    3642  VOID        *Buffer;
    3743  UINT32      Attribs;
     44
     45  ASSERT (Volatile != NULL);
    3846
    3947  Size = 0;
     
    5058  if (Status == EFI_BUFFER_TOO_SMALL) {
    5159    Buffer = AllocateZeroPool(Size);
    52     ASSERT(Buffer != NULL);
     60    if (Buffer == NULL) {
     61      return EFI_OUT_OF_RESOURCES;
     62    }
    5363    Status = gRT->GetVariable((CHAR16*)EnvVarName,
    5464                              &gShellVariableGuid,
     
    6272  //
    6373  if (Status == EFI_NOT_FOUND) {
    64     return (TRUE);
    65   }
    66   ASSERT_EFI_ERROR(Status);
     74    *Volatile = TRUE;
     75    return EFI_SUCCESS;
     76  }
     77  if (EFI_ERROR (Status)) {
     78    return Status;
     79  }
    6780
    6881  //
    6982  // check for the Non Volatile bit
    7083  //
    71   if ((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) {
    72     return (FALSE);
    73   }
    74 
    75   //
    76   // everything else is volatile
    77   //
    78   return (TRUE);
     84  *Volatile = !(BOOLEAN) ((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE);
     85  return EFI_SUCCESS;
    7986}
    8087
     
    8592**/
    8693VOID
    87 EFIAPI
    8894FreeEnvironmentVariableList(
    8995  IN LIST_ENTRY *List
     
    122128**/
    123129EFI_STATUS
    124 EFIAPI
    125130GetEnvironmentVariableList(
    126131  IN OUT LIST_ENTRY *ListHead
     
    174179      } else {
    175180        ValSize = ValBufferSize;
    176         VarList->Val = AllocateZeroPool(ValSize);
     181        //
     182        // We need another CHAR16 to save '\0' in VarList->Val.
     183        //
     184        VarList->Val = AllocateZeroPool (ValSize + sizeof (CHAR16));
    177185        if (VarList->Val == NULL) {
    178186            SHELL_FREE_NON_NULL(VarList);
     
    184192          ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2;
    185193          SHELL_FREE_NON_NULL (VarList->Val);
    186           VarList->Val = AllocateZeroPool(ValBufferSize);
     194          //
     195          // We need another CHAR16 to save '\0' in VarList->Val.
     196          //
     197          VarList->Val = AllocateZeroPool (ValBufferSize + sizeof (CHAR16));
    187198          if (VarList->Val == NULL) {
    188199            SHELL_FREE_NON_NULL(VarList);
     
    232243**/
    233244EFI_STATUS
    234 EFIAPI
    235245SetEnvironmentVariableList(
    236246  IN LIST_ENTRY *ListHead
     
    269279      ; Node = (ENV_VAR_LIST*)GetNextNode(ListHead, &Node->Link)
    270280     ){
    271     Size = StrSize(Node->Val);
     281    Size = StrSize (Node->Val) - sizeof (CHAR16);
    272282    if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
    273283      Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node->Key, Size, Node->Val);
     
    296306**/
    297307EFI_STATUS
    298 EFIAPI
    299308SetEnvironmentVariables(
    300309  IN CONST CHAR16 **Environment
     
    340349    // Copy the string into the Key, leaving the last character allocated as NULL to terminate
    341350    //
    342     StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);
     351    StrnCpyS( Node->Key,
     352              StrStr(CurrentString, L"=") - CurrentString + 1,
     353              CurrentString,
     354              StrStr(CurrentString, L"=") - CurrentString
     355              );
    343356
    344357    //
     
    376389  return (SetEnvironmentVariableList(&VarList->Link));
    377390}
     391
     392/**
     393  Find an environment variable in the gShellEnvVarList.
     394
     395  @param Key        The name of the environment variable.
     396  @param Value      The value of the environment variable, the buffer
     397                    shoule be freed by the caller.
     398  @param ValueSize  The size in bytes of the environment variable
     399                    including the tailing CHAR_NELL.
     400  @param Atts       The attributes of the variable.
     401
     402  @retval EFI_SUCCESS       The command executed successfully.
     403  @retval EFI_NOT_FOUND     The environment variable is not found in
     404                            gShellEnvVarList.
     405
     406**/
     407EFI_STATUS
     408ShellFindEnvVarInList (
     409  IN  CONST CHAR16    *Key,
     410  OUT CHAR16          **Value,
     411  OUT UINTN           *ValueSize,
     412  OUT UINT32          *Atts OPTIONAL
     413  )
     414{
     415  ENV_VAR_LIST      *Node;
     416
     417  if (Key == NULL || Value == NULL || ValueSize == NULL) {
     418    return SHELL_INVALID_PARAMETER;
     419  }
     420
     421  for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)
     422      ; !IsNull(&gShellEnvVarList.Link, &Node->Link)
     423      ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)
     424     ){
     425    if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {
     426      *Value      = AllocateCopyPool(StrSize(Node->Val), Node->Val);
     427      *ValueSize  = StrSize(Node->Val);
     428      if (Atts != NULL) {
     429        *Atts = Node->Atts;
     430      }
     431      return EFI_SUCCESS;
     432    }
     433  }
     434
     435  return EFI_NOT_FOUND;
     436}
     437
     438/**
     439  Add an environment variable into gShellEnvVarList.
     440
     441  @param Key        The name of the environment variable.
     442  @param Value      The value of environment variable.
     443  @param ValueSize  The size in bytes of the environment variable
     444                    including the tailing CHAR_NULL
     445  @param Atts       The attributes of the variable.
     446
     447  @retval EFI_SUCCESS  The environment variable was added to list successfully.
     448  @retval others       Some errors happened.
     449
     450**/
     451EFI_STATUS
     452ShellAddEnvVarToList (
     453  IN CONST CHAR16     *Key,
     454  IN CONST CHAR16     *Value,
     455  IN UINTN            ValueSize,
     456  IN UINT32           Atts
     457  )
     458{
     459  ENV_VAR_LIST      *Node;
     460  CHAR16            *LocalKey;
     461  CHAR16            *LocalValue;
     462
     463  if (Key == NULL || Value == NULL || ValueSize == 0) {
     464    return EFI_INVALID_PARAMETER;
     465  }
     466
     467  LocalValue = AllocateCopyPool (ValueSize, Value);
     468  if (LocalValue == NULL) {
     469    return EFI_OUT_OF_RESOURCES;
     470  }
     471
     472  //
     473  // Update the variable value if it exists in gShellEnvVarList.
     474  //
     475  for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)
     476      ; !IsNull(&gShellEnvVarList.Link, &Node->Link)
     477      ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)
     478     ){
     479    if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {
     480      Node->Atts = Atts;
     481      SHELL_FREE_NON_NULL(Node->Val);
     482      Node->Val  = LocalValue;
     483      return EFI_SUCCESS;
     484    }
     485  }
     486
     487  //
     488  // If the environment varialbe key doesn't exist in list just insert
     489  // a new node.
     490  //
     491  LocalKey = AllocateCopyPool (StrSize(Key), Key);
     492  if (LocalKey == NULL) {
     493    FreePool (LocalValue);
     494    return EFI_OUT_OF_RESOURCES;
     495  }
     496  Node = (ENV_VAR_LIST*)AllocateZeroPool (sizeof(ENV_VAR_LIST));
     497  if (Node == NULL) {
     498    FreePool (LocalKey);
     499    FreePool (LocalValue);
     500    return EFI_OUT_OF_RESOURCES;
     501  }
     502  Node->Key = LocalKey;
     503  Node->Val = LocalValue;
     504  Node->Atts = Atts;
     505  InsertTailList(&gShellEnvVarList.Link, &Node->Link);
     506
     507  return EFI_SUCCESS;
     508}
     509
     510/**
     511  Remove a specified environment variable in gShellEnvVarList.
     512
     513  @param Key        The name of the environment variable.
     514
     515  @retval EFI_SUCCESS       The command executed successfully.
     516  @retval EFI_NOT_FOUND     The environment variable is not found in
     517                            gShellEnvVarList.
     518**/
     519EFI_STATUS
     520ShellRemvoeEnvVarFromList (
     521  IN CONST CHAR16           *Key
     522  )
     523{
     524  ENV_VAR_LIST      *Node;
     525
     526  if (Key == NULL) {
     527    return EFI_INVALID_PARAMETER;
     528  }
     529
     530  for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)
     531      ; !IsNull(&gShellEnvVarList.Link, &Node->Link)
     532      ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)
     533     ){
     534    if (Node->Key != NULL && StrCmp(Key, Node->Key) == 0) {
     535      SHELL_FREE_NON_NULL(Node->Key);
     536      SHELL_FREE_NON_NULL(Node->Val);
     537      RemoveEntryList(&Node->Link);
     538      SHELL_FREE_NON_NULL(Node);
     539      return EFI_SUCCESS;
     540    }
     541  }
     542
     543  return EFI_NOT_FOUND;
     544}
     545
     546/**
     547  Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
     548  variables.
     549
     550**/
     551EFI_STATUS
     552ShellInitEnvVarList (
     553  VOID
     554  )
     555{
     556  EFI_STATUS    Status;
     557
     558  InitializeListHead(&gShellEnvVarList.Link);
     559  Status = GetEnvironmentVariableList (&gShellEnvVarList.Link);
     560
     561  return Status;
     562}
     563
     564/**
     565  Destructe the gShellEnvVarList.
     566
     567**/
     568VOID
     569ShellFreeEnvVarList (
     570  VOID
     571  )
     572{
     573  FreeEnvironmentVariableList (&gShellEnvVarList.Link);
     574  InitializeListHead(&gShellEnvVarList.Link);
     575
     576  return;
     577}
     578
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellEnvVar.h

    r48674 r77662  
    77
    88
    9   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
     9  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
    1010  This program and the accompanying materials
    1111  are licensed and made available under the terms and conditions of the BSD License
     
    2828} ENV_VAR_LIST;
    2929
    30 /**
    31   Reports whether an environment variable is Volatile or Non-Volatile
    32 
    33   This will use the Runtime Services call GetVariable to to search for the variable.
    34 
    35   @param EnvVarName             The name of the environment variable in question
    36 
    37   @retval TRUE                  This environment variable is Volatile
    38   @retval FALSE                 This environment variable is NON-Volatile
    39 **/
    40 BOOLEAN
    41 EFIAPI
     30//
     31// The list is used to cache the environment variables.
     32//
     33extern ENV_VAR_LIST    gShellEnvVarList;
     34
     35
     36/**
     37  Reports whether an environment variable is Volatile or Non-Volatile.
     38
     39  @param EnvVarName             The name of the environment variable in question
     40  @param Volatile               Return TRUE if the environment variable is volatile
     41
     42  @retval EFI_SUCCESS           The volatile attribute is returned successfully
     43  @retval others                Some errors happened.
     44**/
     45EFI_STATUS
    4246IsVolatileEnv (
    43   IN CONST CHAR16 *EnvVarName
     47  IN CONST CHAR16 *EnvVarName,
     48  OUT BOOLEAN     *Volatile
    4449  );
    4550
     
    152157**/
    153158EFI_STATUS
    154 EFIAPI
    155159GetEnvironmentVariableList(
    156160  IN OUT LIST_ENTRY *List
     
    170174**/
    171175EFI_STATUS
    172 EFIAPI
    173176SetEnvironmentVariableList(
    174177  IN LIST_ENTRY *List
     
    191194**/
    192195EFI_STATUS
    193 EFIAPI
    194196SetEnvironmentVariables(
    195197  IN CONST CHAR16 **Environment
     
    202204**/
    203205VOID
    204 EFIAPI
    205206FreeEnvironmentVariableList(
    206207  IN LIST_ENTRY *List
    207208  );
    208209
     210/**
     211  Find an environment variable in the gShellEnvVarList.
     212
     213  @param Key        The name of the environment variable.
     214  @param Value      The value of the environment variable, the buffer
     215                    shoule be freed by the caller.
     216  @param ValueSize  The size in bytes of the environment variable
     217                    including the tailing CHAR_NULL.
     218  @param Atts       The attributes of the variable.
     219
     220  @retval EFI_SUCCESS       The command executed successfully.
     221  @retval EFI_NOT_FOUND     The environment variable is not found in
     222                            gShellEnvVarList.
     223
     224**/
     225EFI_STATUS
     226ShellFindEnvVarInList (
     227  IN  CONST CHAR16    *Key,
     228  OUT CHAR16          **Value,
     229  OUT UINTN           *ValueSize,
     230  OUT UINT32          *Atts OPTIONAL
     231  );
     232
     233/**
     234  Add an environment variable into gShellEnvVarList.
     235
     236  @param Key        The name of the environment variable.
     237  @param Value      The value of environment variable.
     238  @param ValueSize  The size in bytes of the environment variable
     239                    including the tailing CHAR_NULL
     240  @param Atts       The attributes of the variable.
     241
     242  @retval EFI_SUCCESS  The environment variable was added to list successfully.
     243  @retval others       Some errors happened.
     244
     245**/
     246EFI_STATUS
     247ShellAddEnvVarToList (
     248  IN CONST CHAR16     *Key,
     249  IN CONST CHAR16     *Value,
     250  IN UINTN            ValueSize,
     251  IN UINT32           Atts
     252  );
     253
     254/**
     255  Remove a specified environment variable in gShellEnvVarList.
     256
     257  @param Key        The name of the environment variable.
     258
     259  @retval EFI_SUCCESS       The command executed successfully.
     260  @retval EFI_NOT_FOUND     The environment variable is not found in
     261                            gShellEnvVarList.
     262**/
     263EFI_STATUS
     264ShellRemvoeEnvVarFromList (
     265  IN CONST CHAR16           *Key
     266  );
     267
     268/**
     269  Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
     270  variables.
     271
     272**/
     273EFI_STATUS
     274ShellInitEnvVarList (
     275  VOID
     276  );
     277
     278/**
     279  Destructe the gShellEnvVarList.
     280
     281**/
     282VOID
     283ShellFreeEnvVarList (
     284  VOID
     285  );
     286
    209287#endif //_SHELL_ENVIRONMENT_VARIABLE_HEADER_
    210288
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellManParser.c

    r58459 r77662  
    22  Provides interface to shell MAN file parser.
    33
    4   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
     5  Copyright 2015 Dell Inc.
    56  This program and the accompanying materials
    67  are licensed and made available under the terms and conditions of the BSD License
     
    1516#include "Shell.h"
    1617
     18#define SHELL_MAN_HII_GUID \
     19{ \
     20  0xf62ccd0c, 0x2449, 0x453c, { 0x8a, 0xcb, 0x8c, 0xc5, 0x7c, 0xf0, 0x2a, 0x97 } \
     21}
     22
     23EFI_HII_HANDLE  mShellManHiiHandle    = NULL;
     24EFI_HANDLE      mShellManDriverHandle = NULL;
     25
     26
     27SHELL_MAN_HII_VENDOR_DEVICE_PATH  mShellManHiiDevicePath = {
     28  {
     29    {
     30      HARDWARE_DEVICE_PATH,
     31      HW_VENDOR_DP,
     32      {
     33        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
     34        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
     35      }
     36    },
     37    SHELL_MAN_HII_GUID
     38  },
     39  {
     40    END_DEVICE_PATH_TYPE,
     41    END_ENTIRE_DEVICE_PATH_SUBTYPE,
     42    {
     43      (UINT8) (END_DEVICE_PATH_LENGTH),
     44      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
     45    }
     46  }
     47};
     48
     49
     50/**
     51  Convert a Unicode character to upper case only if
     52  it maps to a valid small-case ASCII character.
     53
     54  This internal function only deal with Unicode character
     55  which maps to a valid small-case ASCII character, i.e.
     56  L'a' to L'z'. For other Unicode character, the input character
     57  is returned directly.
     58
     59  @param  Char  The character to convert.
     60
     61  @retval LowerCharacter   If the Char is with range L'a' to L'z'.
     62  @retval Unchanged        Otherwise.
     63
     64**/
     65CHAR16
     66InternalShellCharToUpper (
     67  IN CHAR16  Char
     68  );
     69
     70/**
     71  Verifies that the filename has .EFI on the end.
     72
     73  allocates a new buffer and copies the name (appending .EFI if necessary).
     74  Caller to free the buffer.
     75
     76  @param[in] NameString            original name string
     77
     78  @return                          the new filename with .efi as the extension.
     79**/
     80CHAR16 *
     81GetExecuatableFileName (
     82  IN CONST CHAR16    *NameString
     83  )
     84{
     85  CHAR16  *Buffer;
     86  CHAR16  *SuffixStr;
     87  if (NameString == NULL) {
     88    return (NULL);
     89  }
     90
     91  //
     92  // Fix the file name
     93  //
     94  if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) {
     95    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
     96  } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) {
     97    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
     98    if (Buffer != NULL) {
     99      SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man");
     100      StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi"));
     101    }
     102  } else {
     103    Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16));
     104    if (Buffer != NULL) {
     105      StrnCpyS( Buffer,
     106                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
     107                NameString,
     108                StrLen(NameString)
     109                );
     110      StrnCatS( Buffer,
     111                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
     112                L".efi",
     113                StrLen(L".efi")
     114                );
     115    }
     116  }
     117  return (Buffer);
     118
     119}
     120
    17121/**
    18122  Verifies that the filename has .MAN on the end.
     
    27131**/
    28132CHAR16 *
    29 EFIAPI
    30133GetManFileName(
    31134  IN CONST CHAR16 *ManFileName
     
    44147    Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));
    45148    if (Buffer != NULL) {
    46       StrnCpy(Buffer, ManFileName, StrLen(ManFileName));
    47       StrnCat(Buffer, L".man", 4);
     149      StrnCpyS( Buffer,
     150                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16),
     151                ManFileName,
     152                StrLen(ManFileName)
     153                );
     154      StrnCatS( Buffer,
     155                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16),
     156                L".man",
     157                4
     158                );
    48159    }
    49160  }
     
    66177**/
    67178EFI_STATUS
    68 EFIAPI
    69179SearchPathForFile(
    70180  IN CONST CHAR16             *FileName,
     
    97207
    98208/**
    99   parses through Buffer (which is MAN file formatted) and returns the
    100   detailed help for any sub section specified in the comma seperated list of
    101   sections provided.  If the end of the file or a .TH section is found then
    102   return.
    103 
    104   Upon a sucessful return the caller is responsible to free the memory in *HelpText
    105 
    106   @param[in] Buffer             Buffer to read from
    107   @param[in] Sections           name of command's sub sections to find
    108   @param[in] HelpText           pointer to pointer to string where text goes.
    109   @param[in] HelpSize           pointer to size of allocated HelpText (may be updated)
    110 
    111   @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
    112   @retval EFI_SUCCESS           the section was found and its description sotred in
    113                                 an alloceted buffer.
    114 **/
    115 EFI_STATUS
    116 EFIAPI
    117 ManBufferFindSections(
    118   IN CONST CHAR16 *Buffer,
    119   IN CONST CHAR16 *Sections,
    120   IN CHAR16       **HelpText,
    121   IN UINTN        *HelpSize
    122   )
    123 {
    124   EFI_STATUS          Status;
    125   CONST CHAR16        *CurrentLocation;
    126   BOOLEAN             CurrentlyReading;
    127   CHAR16              *SectionName;
    128   UINTN               SectionLen;
    129   BOOLEAN             Found;
    130   CHAR16              *TempString;
    131   CHAR16              *TempString2;
    132 
    133   if ( Buffer     == NULL
    134     || HelpText   == NULL
    135     || HelpSize   == NULL
    136    ){
    137     return (EFI_INVALID_PARAMETER);
    138   }
    139 
    140   Status            = EFI_SUCCESS;
    141   CurrentlyReading  = FALSE;
    142   Found             = FALSE;
    143 
    144   for (CurrentLocation = Buffer,TempString = NULL
    145     ;  CurrentLocation != NULL && *CurrentLocation != CHAR_NULL
    146     ;  CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL
    147    ){
    148     while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') {
    149       CurrentLocation++;
    150     }
    151     if (CurrentLocation[0] == L'#') {
    152       //
    153       // Skip comment lines
    154       //
    155       continue;
    156     }
    157     if (StrnCmp(CurrentLocation, L".TH", 3) == 0) {
    158       //
    159       // we hit the end of this commands section so stop.
    160       //
    161       break;
    162     }
    163     if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) {
    164       if (Sections == NULL) {
    165         CurrentlyReading = TRUE;
    166         continue;
    167       } else if (CurrentlyReading) {
    168         CurrentlyReading = FALSE;
    169       }
    170       CurrentLocation += 4;
    171       //
    172       // is this a section we want to read in?
    173       //
    174       if (StrLen(CurrentLocation)!=0) {
    175         TempString2 = StrStr(CurrentLocation, L" ");
    176         TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r"));
    177         TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
    178         ASSERT(TempString == NULL);
    179         TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
    180         if (TempString == NULL) {
    181           Status = EFI_OUT_OF_RESOURCES;
    182           break;
    183         }
    184         SectionName = TempString;
    185         SectionLen = StrLen(SectionName);
    186         SectionName = StrStr(Sections, SectionName);
    187         if (SectionName == NULL) {
    188           continue;
    189         }
    190         if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
    191           CurrentlyReading = TRUE;
    192         }
    193       }
    194     } else if (CurrentlyReading) {
    195       Found = TRUE;
    196       if (StrLen(CurrentLocation)!=0) {
    197         TempString2 = StrStr(CurrentLocation, L"\r");
    198         TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
    199         ASSERT(TempString == NULL);
    200         TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
    201         if (TempString == NULL) {
    202           Status = EFI_OUT_OF_RESOURCES;
    203           break;
    204         }
    205         //
    206         // copy and save the current line.
    207         //
    208         ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
    209         StrnCatGrow (HelpText, HelpSize, TempString, 0);
    210         if (HelpText == NULL) {
    211           Status = EFI_OUT_OF_RESOURCES;
    212           break;
    213         }
    214         StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
    215         if (HelpText == NULL) {
    216           Status = EFI_OUT_OF_RESOURCES;
    217           break;
    218         }
    219       }
    220     }
    221     SHELL_FREE_NON_NULL(TempString);
    222   }
    223   if (!Found && !EFI_ERROR(Status)) {
    224     return (EFI_NOT_FOUND);
    225   }
    226   return (Status);
    227 }
    228 
    229 /**
    230209  parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
    231210  detailed help for any sub section specified in the comma seperated list of
     
    246225**/
    247226EFI_STATUS
    248 EFIAPI
    249227ManFileFindSections(
    250228  IN SHELL_FILE_HANDLE  Handle,
     
    344322
    345323/**
    346   parses through the MAN file formatted Buffer and returns the
     324  Parses a line from a MAN file to see if it is the Title Header. If it is, then
     325  if the "Brief Description" is desired, allocate a buffer for it and return a
     326  copy. Upon a sucessful return the caller is responsible to free the memory in
     327  *BriefDesc
     328
     329  Uses a simple state machine that allows "unlimited" whitespace before and after the
     330  ".TH", compares Command and the MAN file commnd name without respect to case, and
     331  allows "unlimited" whitespace and '0' and '1' characters before the Short Description.
     332  The PCRE regex describing this functionality is: ^\s*\.TH\s+(\S)\s[\s01]*(.*)$
     333  where group 1 is the Command Name and group 2 is the Short Description.
     334
     335  @param[in] Command             name of command whose MAN file we think Line came from
     336  @param[in] Line                Pointer to a line from the MAN file
     337  @param[out] BriefDesc          pointer to pointer to string where description goes.
     338  @param[out] BriefSize          pointer to size of allocated BriefDesc
     339  @param[out] Found              TRUE if the Title Header was found and it belongs to Command
     340
     341  @retval TRUE   Line contained the Title Header
     342  @retval FALSE  Line did not contain the Title Header
     343**/
     344BOOLEAN
     345IsTitleHeader(
     346  IN CONST CHAR16       *Command,
     347  IN CHAR16             *Line,
     348  OUT CHAR16            **BriefDesc OPTIONAL,
     349  OUT UINTN             *BriefSize OPTIONAL,
     350  OUT BOOLEAN           *Found
     351  )
     352{
     353  // The states of a simple state machine used to recognize a title header line
     354  // and to extract the Short Description, if desired.
     355  typedef enum {
     356    LookForThMacro, LookForCommandName, CompareCommands, GetBriefDescription, Final
     357  } STATEVALUES;
     358
     359  STATEVALUES  State;
     360  UINTN        CommandIndex; // Indexes Command as we compare its chars to the MAN file.
     361  BOOLEAN      ReturnValue;  // TRUE if this the Title Header line of *some* MAN file.
     362  BOOLEAN      ReturnFound;  // TRUE if this the Title Header line of *the desired* MAN file.
     363
     364  ReturnValue = FALSE;
     365  ReturnFound = FALSE;
     366  CommandIndex = 0;
     367  State = LookForThMacro;
     368
     369  do {
     370
     371    if (*Line == L'\0') {
     372      break;
     373    }
     374
     375    switch (State) {
     376
     377      // Handle "^\s*.TH\s"
     378      // Go to state LookForCommandName if the title header macro is present; otherwise,
     379      // eat white space. If we see something other than white space, this is not a
     380      // title header line.
     381      case LookForThMacro:
     382        if (StrnCmp (L".TH ", Line, 4) == 0 || StrnCmp (L".TH\t", Line, 4) == 0) {
     383          Line += 4;
     384          State = LookForCommandName;
     385        }
     386        else if (*Line == L' ' || *Line == L'\t') {
     387          Line++;
     388        }
     389        else {
     390          State = Final;
     391        }
     392      break;
     393
     394      // Handle "\s*"
     395      // Eat any "extra" whitespace after the title header macro (we have already seen
     396      // at least one white space character). Go to state CompareCommands when a
     397      // non-white space is seen.
     398      case LookForCommandName:
     399        if (*Line == L' ' || *Line == L'\t') {
     400          Line++;
     401        }
     402        else {
     403          ReturnValue = TRUE;  // This is *some* command's title header line.
     404          State = CompareCommands;
     405          // Do not increment Line; it points to the first character of the command
     406          // name on the title header line.
     407        }
     408      break;
     409
     410      // Handle "(\S)\s"
     411      // Compare Command to the title header command name, ignoring case. When we
     412      // reach the end of the command (i.e. we see white space), the next state
     413      // depends on whether the caller wants a copy of the Brief Description.
     414      case CompareCommands:
     415        if (*Line == L' ' || *Line == L'\t') {
     416          ReturnFound = TRUE;  // This is the desired command's title header line.
     417          State = (BriefDesc == NULL) ? Final : GetBriefDescription;
     418        }
     419        else if (InternalShellCharToUpper (*Line) != InternalShellCharToUpper (*(Command + CommandIndex++))) {
     420          State = Final;
     421        }
     422        Line++;
     423      break;
     424
     425      // Handle "[\s01]*(.*)$"
     426      // Skip whitespace, '0', and '1' characters, if any, prior to the brief description.
     427      // Return the description to the caller.
     428      case GetBriefDescription:
     429        if (*Line != L' ' && *Line != L'\t' && *Line != L'0' && *Line != L'1') {
     430          *BriefSize = StrSize(Line);
     431          *BriefDesc = AllocateZeroPool(*BriefSize);
     432          if (*BriefDesc != NULL) {
     433            StrCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), Line);
     434          }
     435          State = Final;
     436        }
     437        Line++;
     438      break;
     439
     440      default:
     441       break;
     442    }
     443
     444  } while (State < Final);
     445
     446  *Found = ReturnFound;
     447  return ReturnValue;
     448}
     449
     450/**
     451  parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
    347452  "Brief Description" for the .TH section as specified by Command.  If the
    348453  command section is not found return EFI_NOT_FOUND.
     
    350455  Upon a sucessful return the caller is responsible to free the memory in *BriefDesc
    351456
    352   @param[in] Handle             Buffer to read from
    353   @param[in] Command            name of command's section to find
    354   @param[in] BriefDesc          pointer to pointer to string where description goes.
    355   @param[in] BriefSize          pointer to size of allocated BriefDesc
    356 
    357   @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
    358   @retval EFI_SUCCESS           the section was found and its description sotred in
    359                                 an alloceted buffer.
    360 **/
    361 EFI_STATUS
    362 EFIAPI
    363 ManBufferFindTitleSection(
    364   IN CHAR16         **Buffer,
    365   IN CONST CHAR16   *Command,
    366   IN CHAR16         **BriefDesc,
    367   IN UINTN          *BriefSize
    368   )
    369 {
    370   EFI_STATUS    Status;
    371   CHAR16        *TitleString;
    372   CHAR16        *TitleEnd;
    373   CHAR16        *CurrentLocation;
    374   UINTN         TitleLength;
    375   CONST CHAR16  StartString[] = L".TH ";
    376   CONST CHAR16  EndString[]   = L" 0 ";
    377 
    378   if ( Buffer     == NULL
    379     || Command    == NULL
    380     || (BriefDesc != NULL && BriefSize == NULL)
    381    ){
    382     return (EFI_INVALID_PARAMETER);
    383   }
    384 
    385   Status    = EFI_SUCCESS;
    386 
    387   //
    388   // more characters for StartString and EndString
    389   //
    390   TitleLength = StrSize(Command) + (StrLen(StartString) + StrLen(EndString)) * sizeof(CHAR16);
    391   TitleString = AllocateZeroPool(TitleLength);
    392   if (TitleString == NULL) {
    393     return (EFI_OUT_OF_RESOURCES);
    394   }
    395   StrnCpy(TitleString, StartString, TitleLength/sizeof(CHAR16) - 1);
    396   StrnCat(TitleString, Command,     TitleLength/sizeof(CHAR16) - 1 - StrLen(TitleString));
    397   StrnCat(TitleString, EndString,   TitleLength/sizeof(CHAR16) - 1 - StrLen(TitleString));
    398 
    399   CurrentLocation = StrStr(*Buffer, TitleString);
    400   if (CurrentLocation == NULL){
    401     Status = EFI_NOT_FOUND;
    402   } else {
    403     //
    404     // we found it so copy out the rest of the line into BriefDesc
    405     // After skipping any spaces or zeroes
    406     //
    407     for (CurrentLocation += StrLen(TitleString)
    408       ;  *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"'
    409       ;  CurrentLocation++);
    410 
    411     TitleEnd = StrStr(CurrentLocation, L"\"");
    412     if (TitleEnd == NULL) {
    413       Status = EFI_DEVICE_ERROR;
    414     } else {
    415       if (BriefDesc != NULL) {
    416         *BriefSize = StrSize(TitleEnd);
    417         *BriefDesc = AllocateZeroPool(*BriefSize);
    418         if (*BriefDesc == NULL) {
    419           Status = EFI_OUT_OF_RESOURCES;
    420         } else {
    421           StrnCpy(*BriefDesc, CurrentLocation, TitleEnd-CurrentLocation);
    422         }
    423       }
    424 
    425       for (CurrentLocation = TitleEnd
    426         ;  *CurrentLocation != L'\n'
    427         ;  CurrentLocation++);
    428       for (
    429         ;  *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r'
    430         ;  CurrentLocation++);
    431       *Buffer = CurrentLocation;
    432     }
    433   }
    434 
    435   FreePool(TitleString);
    436   return (Status);
    437 }
    438 
    439 /**
    440   parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
    441   "Brief Description" for the .TH section as specified by Command.  if the
    442   command section is not found return EFI_NOT_FOUND.
    443 
    444   Upon a sucessful return the caller is responsible to free the memory in *BriefDesc
    445 
    446457  @param[in] Handle              FileHandle to read from
    447   @param[in] Command             name of command's section to find
     458  @param[in] Command             name of command's section to find as entered on the
     459                                 command line (may be a relative or absolute path or
     460                                 be in any case: upper, lower, or mixed in numerous ways!).
    448461  @param[out] BriefDesc          pointer to pointer to string where description goes.
    449462  @param[out] BriefSize          pointer to size of allocated BriefDesc
     
    452465
    453466  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
    454   @retval EFI_SUCCESS           the section was found and its description sotred in
    455                                 an alloceted buffer.
     467  @retval EFI_SUCCESS           the section was found and its description stored in
     468                                an allocated buffer if requested.
    456469**/
    457470EFI_STATUS
    458 EFIAPI
    459471ManFileFindTitleSection(
    460472  IN SHELL_FILE_HANDLE  Handle,
     
    466478{
    467479  EFI_STATUS  Status;
    468   CHAR16      *TitleString;
    469480  CHAR16      *ReadLine;
    470481  UINTN       Size;
    471   CHAR16      *TitleEnd;
    472   UINTN       TitleLen;
    473482  BOOLEAN     Found;
    474   UINTN       TitleSize;
     483  UINTN       Start;
    475484
    476485  if ( Handle     == NULL
     
    490499  }
    491500
    492   TitleSize = (4*sizeof(CHAR16)) + StrSize(Command);
    493   TitleString = AllocateZeroPool(TitleSize);
    494   if (TitleString == NULL) {
    495     FreePool(ReadLine);
    496     return (EFI_OUT_OF_RESOURCES);
    497   }
    498   StrnCpy(TitleString, L".TH ", TitleSize/sizeof(CHAR16) - 1);
    499   StrnCat(TitleString, Command, TitleSize/sizeof(CHAR16) - 1 - StrLen(TitleString));
    500 
    501   TitleLen = StrLen(TitleString);
     501  //
     502  // Do not pass any leading path information that may be present to IsTitleHeader().
     503  //
     504  Start = StrLen(Command);
     505  while ((Start != 0)
     506         && (*(Command + Start - 1) != L'\\')
     507         && (*(Command + Start - 1) != L'/')
     508         && (*(Command + Start - 1) != L':')) {
     509    --Start;
     510  }
     511
    502512  for (;!ShellFileHandleEof(Handle);Size = 1024) {
    503513   Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);
    504     if (ReadLine[0] == L'#') {
    505       //
    506       // Skip comment lines
    507       //
    508       continue;
    509     }
    510514    //
    511515    // ignore too small of buffer...
    512516    //
    513     if (Status == EFI_BUFFER_TOO_SMALL) {
    514       Status = EFI_SUCCESS;
    515     }
    516     if (EFI_ERROR(Status)) {
    517       break;
    518     }
    519     if (StrnCmp(ReadLine, TitleString, TitleLen) == 0) {
    520       Found = TRUE;
    521       //
    522       // we found it so copy out the rest of the line into BriefDesc
    523       // After skipping any spaces or zeroes
    524       //
    525       for ( TitleEnd = ReadLine+TitleLen
    526           ; *TitleEnd == L' ' || *TitleEnd == L'0' || *TitleEnd == L'1'
    527           ; TitleEnd++);
    528       if (BriefDesc != NULL) {
    529         *BriefSize = StrSize(TitleEnd);
    530         *BriefDesc = AllocateZeroPool(*BriefSize);
    531         if (*BriefDesc == NULL) {
    532           Status = EFI_OUT_OF_RESOURCES;
    533           break;
    534         }
    535         StrnCpy(*BriefDesc, TitleEnd, (*BriefSize)/sizeof(CHAR16) - 1);
    536       }
    537       break;
    538     }
    539   }
     517    if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
     518      break;
     519    }
     520
     521    Status = EFI_NOT_FOUND;
     522    if (IsTitleHeader (Command+Start, ReadLine, BriefDesc, BriefSize, &Found)) {
     523      Status = Found ? EFI_SUCCESS : EFI_NOT_FOUND;
     524      break;
     525    }
     526  }
     527
    540528  FreePool(ReadLine);
    541   FreePool(TitleString);
    542   if (!Found && !EFI_ERROR(Status)) {
    543     return (EFI_NOT_FOUND);
    544   }
    545529  return (Status);
    546530}
     
    577561**/
    578562EFI_STATUS
    579 EFIAPI
    580563ProcessManFile(
    581564  IN CONST CHAR16 *ManFileName,
     
    588571  CHAR16            *TempString;
    589572  SHELL_FILE_HANDLE FileHandle;
     573  EFI_HANDLE        CmdFileImgHandle;
    590574  EFI_STATUS        Status;
    591575  UINTN             HelpSize;
    592576  UINTN             BriefSize;
     577  UINTN             StringIdWalker;
    593578  BOOLEAN           Ascii;
    594   CHAR16            *TempString2;
    595   EFI_DEVICE_PATH_PROTOCOL  *FileDevPath;
    596   EFI_DEVICE_PATH_PROTOCOL  *DevPath;
     579  CHAR16            *CmdFileName;
     580  CHAR16            *CmdFilePathName;
     581  EFI_DEVICE_PATH_PROTOCOL      *FileDevPath;
     582  EFI_DEVICE_PATH_PROTOCOL      *DevPath;
     583  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
    597584
    598585  if ( ManFileName == NULL
     
    603590  }
    604591
    605   HelpSize    = 0;
    606   BriefSize   = 0;
    607   TempString  = NULL;
    608   Ascii       = FALSE;
     592  HelpSize          = 0;
     593  BriefSize         = 0;
     594  StringIdWalker    = 0;
     595  TempString        = NULL;
     596  Ascii             = FALSE;
     597  CmdFileName       = NULL;
     598  CmdFilePathName   = NULL;
     599  CmdFileImgHandle  = NULL;
     600  PackageListHeader = NULL;
     601  FileDevPath       = NULL;
     602  DevPath           = NULL;
     603
    609604  //
    610605  // See if it's in HII first
     
    612607  TempString = ShellCommandGetCommandHelp(Command);
    613608  if (TempString != NULL) {
    614     TempString2 = TempString;
    615     Status = ManBufferFindTitleSection(&TempString2, Command, BriefDesc, &BriefSize);
     609    FileHandle = ConvertEfiFileProtocolToShellHandle (CreateFileInterfaceMem (TRUE), NULL);
     610    HelpSize = StrLen (TempString) * sizeof (CHAR16);
     611    ShellWriteFile (FileHandle, &HelpSize, TempString);
     612    ShellSetFilePosition (FileHandle, 0);
     613    HelpSize  = 0;
     614    BriefSize = 0;
     615    Status = ManFileFindTitleSection(FileHandle, Command, BriefDesc, &BriefSize, &Ascii);
    616616    if (!EFI_ERROR(Status) && HelpText != NULL){
    617       Status = ManBufferFindSections(TempString2, Sections, HelpText, &HelpSize);
    618     }
     617      Status = ManFileFindSections(FileHandle, Sections, HelpText, &HelpSize, Ascii);
     618    }
     619    ShellCloseFile (&FileHandle);
    619620  } else {
     621    //
     622    // If the image is a external app, check .MAN file first.
     623    //
    620624    FileHandle    = NULL;
    621625    TempString  = GetManFileName(ManFileName);
     
    629633      DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, FileDevPath);
    630634      Status = InternalOpenFileDevicePath(DevPath, &FileHandle, EFI_FILE_MODE_READ, 0);
    631       FreePool(FileDevPath);
    632       FreePool(DevPath);
     635      SHELL_FREE_NON_NULL(FileDevPath);
     636      SHELL_FREE_NON_NULL(DevPath);
    633637    }
    634638
     
    641645      }
    642646      ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
    643     } else {
     647      if (!EFI_ERROR(Status)) {
     648        //
     649        // Get help text from .MAN file success.
     650        //
     651        goto Done;
     652      }
     653    }
     654
     655    //
     656    // Load the app image to check  EFI_HII_PACKAGE_LIST_PROTOCOL.
     657    //
     658    CmdFileName     = GetExecuatableFileName(TempString);
     659    if (CmdFileName == NULL) {
     660      Status = EFI_OUT_OF_RESOURCES;
     661      goto Done;
     662    }
     663    //
     664    // If the file in CWD then use the file name, else use the full
     665    // path name.
     666    //
     667    CmdFilePathName = ShellFindFilePath(CmdFileName);
     668    if (CmdFilePathName == NULL) {
     669      Status = EFI_NOT_FOUND;
     670      goto Done;
     671    }
     672    DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CmdFilePathName);
     673    Status      = gBS->LoadImage(FALSE, gImageHandle, DevPath, NULL, 0, &CmdFileImgHandle);
     674    if(EFI_ERROR(Status)) {
    644675      *HelpText = NULL;
    645     }
    646   }
    647   if (TempString != NULL) {
    648     FreePool(TempString);
    649   }
     676      goto Done;
     677    }
     678    Status = gBS->OpenProtocol(
     679                    CmdFileImgHandle,
     680                    &gEfiHiiPackageListProtocolGuid,
     681                    (VOID**)&PackageListHeader,
     682                    gImageHandle,
     683                    NULL,
     684                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
     685                    );
     686    if(EFI_ERROR(Status)) {
     687      *HelpText = NULL;
     688      goto Done;
     689    }
     690
     691    //
     692    // If get package list on image handle, install it on HiiDatabase.
     693    //
     694    Status = gBS->InstallProtocolInterface (
     695                    &mShellManDriverHandle,
     696                    &gEfiDevicePathProtocolGuid,
     697                    EFI_NATIVE_INTERFACE,
     698                    &mShellManHiiDevicePath
     699                    );
     700    if (EFI_ERROR(Status)) {
     701      goto Done;
     702    }
     703
     704    Status = gHiiDatabase->NewPackageList (
     705                            gHiiDatabase,
     706                            PackageListHeader,
     707                            mShellManDriverHandle,
     708                            &mShellManHiiHandle
     709                            );
     710    if (EFI_ERROR (Status)) {
     711      goto Done;
     712    }
     713
     714    StringIdWalker = 1;
     715    do {
     716        SHELL_FREE_NON_NULL(TempString);
     717        if (BriefDesc != NULL) {
     718          SHELL_FREE_NON_NULL(*BriefDesc);
     719        }
     720        TempString = HiiGetString (mShellManHiiHandle, (EFI_STRING_ID)StringIdWalker, NULL);
     721        if (TempString == NULL) {
     722          Status = EFI_NOT_FOUND;
     723          goto Done;
     724        }
     725        FileHandle = ConvertEfiFileProtocolToShellHandle (CreateFileInterfaceMem (TRUE), NULL);
     726        HelpSize = StrLen (TempString) * sizeof (CHAR16);
     727        ShellWriteFile (FileHandle, &HelpSize, TempString);
     728        ShellSetFilePosition (FileHandle, 0);
     729        HelpSize  = 0;
     730        BriefSize = 0;
     731        Status = ManFileFindTitleSection(FileHandle, Command, BriefDesc, &BriefSize, &Ascii);
     732        if (!EFI_ERROR(Status) && HelpText != NULL){
     733          Status = ManFileFindSections(FileHandle, Sections, HelpText, &HelpSize, Ascii);
     734        }
     735        ShellCloseFile (&FileHandle);
     736        if (!EFI_ERROR(Status)){
     737          //
     738          // Found what we need and return
     739          //
     740          goto Done;
     741        }
     742
     743        StringIdWalker += 1;
     744    } while (StringIdWalker < 0xFFFF && TempString != NULL);
     745
     746  }
     747
     748Done:
     749  if (mShellManDriverHandle != NULL) {
     750    gBS->UninstallProtocolInterface (
     751            mShellManDriverHandle,
     752            &gEfiDevicePathProtocolGuid,
     753            &mShellManHiiDevicePath
     754           );
     755    mShellManDriverHandle = NULL;
     756  }
     757
     758  if (mShellManHiiHandle != NULL) {
     759    HiiRemovePackages (mShellManHiiHandle);
     760    mShellManHiiHandle = NULL;
     761  }
     762
     763  if (CmdFileImgHandle != NULL) {
     764    Status = gBS->UnloadImage (CmdFileImgHandle);
     765  }
     766
     767  SHELL_FREE_NON_NULL(TempString);
     768  SHELL_FREE_NON_NULL(CmdFileName);
     769  SHELL_FREE_NON_NULL(CmdFilePathName);
     770  SHELL_FREE_NON_NULL(FileDevPath);
     771  SHELL_FREE_NON_NULL(DevPath);
    650772
    651773  return (Status);
    652774}
     775
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellManParser.h

    r48674 r77662  
    4646**/
    4747EFI_STATUS
    48 EFIAPI
    4948ProcessManFile(
    5049  IN CONST CHAR16 *ManFileName,
     
    7473**/
    7574EFI_STATUS
    76 EFIAPI
    7775ManFileFindSections(
    7876  IN SHELL_FILE_HANDLE  Handle,
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellParametersProtocol.c

    r58466 r77662  
    33  manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
    44
     5  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
    56  Copyright (C) 2014, Red Hat, Inc.
    6   Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
    7   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     7  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
     8  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
    89  This program and the accompanying materials
    910  are licensed and made available under the terms and conditions of the BSD License
     
    1819#include "Shell.h"
    1920
     21BOOLEAN AsciiRedirection = FALSE;
     22
    2023/**
    2124  Return the next parameter's end from a command line string.
     
    2427**/
    2528CONST CHAR16*
    26 EFIAPI
    2729FindEndOfParameter(
    2830  IN CONST CHAR16 *String
     
    7375  This will also remove all remaining ^ characters after processing.
    7476
    75   @param[in, out] Walker        pointer to string of command line.  Adjusted to
    76                                 reminaing command line on return
    77   @param[in, out] TempParameter pointer to string of command line item extracted.
    78   @param[in]      Length        buffer size of TempParameter.
     77  @param[in, out] Walker          pointer to string of command line.  Adjusted to
     78                                  reminaing command line on return
     79  @param[in, out] TempParameter   pointer to string of command line item extracted.
     80  @param[in]      Length          buffer size of TempParameter.
     81  @param[in]      StripQuotation  if TRUE then strip the quotation marks surrounding
     82                                  the parameters.
    7983
    8084  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.
     
    8286**/
    8387EFI_STATUS
    84 EFIAPI
    8588GetNextParameter(
    8689  IN OUT CHAR16   **Walker,
    8790  IN OUT CHAR16   **TempParameter,
    88   IN CONST UINTN  Length
     91  IN CONST UINTN  Length,
     92  IN BOOLEAN      StripQuotation
    8993  )
    9094{
     
    126130  }
    127131
    128   StrnCpy(*TempParameter, (*Walker), NextDelim - *Walker);
     132  StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker);
    129133
    130134  //
     
    160164      // eliminate the unescaped quote
    161165      //
    162       CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
     166      if (StripQuotation) {
     167        CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
     168          } else{
     169        NextDelim++;
     170          }
    163171    }
    164172  }
     
    177185  etc... must be complete before calling this API.
    178186
    179   @param[in] CommandLine         String of command line to parse
    180   @param[in, out] Argv           pointer to array of strings; one for each parameter
    181   @param[in, out] Argc           pointer to number of strings in Argv array
     187  @param[in] CommandLine          String of command line to parse
     188  @param[in] StripQuotation       if TRUE then strip the quotation marks surrounding
     189                                  the parameters.
     190  @param[in, out] Argv            pointer to array of strings; one for each parameter
     191  @param[in, out] Argc            pointer to number of strings in Argv array
    182192
    183193  @return EFI_SUCCESS           the operation was sucessful
     
    185195**/
    186196EFI_STATUS
    187 EFIAPI
    188197ParseCommandLineToArgs(
    189198  IN CONST CHAR16 *CommandLine,
    190   IN OUT CHAR16 ***Argv,
    191   IN OUT UINTN *Argc
     199  IN BOOLEAN      StripQuotation,
     200  IN OUT CHAR16   ***Argv,
     201  IN OUT UINTN    *Argc
    192202  )
    193203{
     
    196206  CHAR16      *Walker;
    197207  CHAR16      *NewParam;
     208  CHAR16      *NewCommandLine;
    198209  UINTN       Size;
     210  EFI_STATUS  Status;
    199211
    200212  ASSERT(Argc != NULL);
     
    207219  }
    208220
    209   Size = StrSize(CommandLine);
     221  NewCommandLine = AllocateCopyPool(StrSize(CommandLine), CommandLine);
     222  if (NewCommandLine == NULL){
     223    return (EFI_OUT_OF_RESOURCES);
     224  }
     225
     226  TrimSpaces(&NewCommandLine);
     227  Size = StrSize(NewCommandLine);
    210228  TempParameter = AllocateZeroPool(Size);
    211229  if (TempParameter == NULL) {
     230    SHELL_FREE_NON_NULL(NewCommandLine);
    212231    return (EFI_OUT_OF_RESOURCES);
    213232  }
    214233
    215234  for ( Count = 0
    216       , Walker = (CHAR16*)CommandLine
     235      , Walker = (CHAR16*)NewCommandLine
    217236      ; Walker != NULL && *Walker != CHAR_NULL
    218237      ; Count++
    219238      ) {
    220     if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
     239    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, TRUE))) {
    221240      break;
    222241    }
     
    228247  (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*));
    229248  if (*Argv == NULL) {
    230     SHELL_FREE_NON_NULL(TempParameter);
    231     return (EFI_OUT_OF_RESOURCES);
     249    Status = EFI_OUT_OF_RESOURCES;
     250    goto Done;
    232251  }
    233252
    234253  *Argc = 0;
    235   Walker = (CHAR16*)CommandLine;
     254  Walker = (CHAR16*)NewCommandLine;
    236255  while(Walker != NULL && *Walker != CHAR_NULL) {
    237256    SetMem16(TempParameter, Size, CHAR_NULL);
    238     if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
    239       SHELL_FREE_NON_NULL(TempParameter);
    240       return (EFI_INVALID_PARAMETER);
     257    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, StripQuotation))) {
     258      Status = EFI_INVALID_PARAMETER;
     259      goto Done;
    241260    }
    242261
    243262    NewParam = AllocateCopyPool(StrSize(TempParameter), TempParameter);
    244263    if (NewParam == NULL){
    245       SHELL_FREE_NON_NULL(TempParameter);
    246       return (EFI_OUT_OF_RESOURCES);
     264      Status = EFI_OUT_OF_RESOURCES;
     265      goto Done;
    247266    }
    248267    ((CHAR16**)(*Argv))[(*Argc)] = NewParam;
     
    250269  }
    251270  ASSERT(Count >= (*Argc));
     271  Status = EFI_SUCCESS;
     272
     273Done:
    252274  SHELL_FREE_NON_NULL(TempParameter);
    253   return (EFI_SUCCESS);
     275  SHELL_FREE_NON_NULL(NewCommandLine);
     276  return (Status);
    254277}
    255278
     
    271294**/
    272295EFI_STATUS
    273 EFIAPI
    274296CreatePopulateInstallShellParametersProtocol (
    275297  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  **NewShellParameters,
     
    361383    //
    362384    Status = ParseCommandLineToArgs(FullCommandLine,
     385                                    TRUE,
    363386                                    &(*NewShellParameters)->Argv,
    364387                                    &(*NewShellParameters)->Argc);
     
    412435**/
    413436EFI_STATUS
    414 EFIAPI
    415437CleanUpShellParametersProtocol (
    416438  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *NewShellParameters
     
    459481**/
    460482EFI_STATUS
    461 EFIAPI
    462483IsUnicodeFile(
    463484  IN CONST CHAR16 *FileName
     
    494515**/
    495516VOID
    496 EFIAPI
    497517StripQuotes (
    498518  IN OUT CHAR16 *TheString
     
    546566**/
    547567CHAR16*
    548 EFIAPI
    549568FixFileName (
    550569  IN CHAR16 *FileName
     
    589608**/
    590609CHAR16*
    591 EFIAPI
    592610FixVarName (
    593611  IN CHAR16 *FileName
     
    618636**/
    619637EFI_STATUS
    620 EFIAPI
    621638RemoveFileTag(
    622639  IN SHELL_FILE_HANDLE *Handle
     
    682699**/
    683700EFI_STATUS
    684 EFIAPI
    685701UpdateStdInStdOutStdErr(
    686702  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
     
    711727  SPLIT_LIST        *Split;
    712728  CHAR16            *FirstLocation;
     729  BOOLEAN           Volatile;
    713730
    714731  OutUnicode      = TRUE;
    715732  InUnicode       = TRUE;
     733  AsciiRedirection = FALSE;
    716734  ErrUnicode      = TRUE;
    717735  StdInVarName    = NULL;
     
    9921010      StdInFileName   = CommandLineWalker += 4;
    9931011      InUnicode       = FALSE;
     1012      AsciiRedirection = TRUE;
    9941013    }
    9951014    if (StrStr(CommandLineWalker, L" <a ") != NULL) {
     
    10131032  // re-populate the string to support any filenames that were in quotes.
    10141033  //
    1015   StrnCpy(CommandLineCopy, NewCommandLine, StrLen(NewCommandLine));
     1034  StrnCpyS(CommandLineCopy, StrSize(CommandLineCopy)/sizeof(CHAR16), NewCommandLine, StrLen(NewCommandLine));
    10161035
    10171036  if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
    1018     && ((UINTN)(FirstLocation - CommandLineCopy) < StrLen(NewCommandLine))
     1037    && (((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof(CHAR16) < StrLen(NewCommandLine))
    10191038    ){
    1020     *(NewCommandLine + (UINTN)(FirstLocation - CommandLineCopy)) = CHAR_NULL;
     1039    *(NewCommandLine + ((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof(CHAR16)) = CHAR_NULL;
    10211040  }
    10221041
     
    10841103      // Check for no volatile environment variables
    10851104      //
    1086       ||(StdErrVarName  != NULL && !IsVolatileEnv(StdErrVarName))
    1087       ||(StdOutVarName  != NULL && !IsVolatileEnv(StdOutVarName))
     1105      ||(StdErrVarName  != NULL && !EFI_ERROR (IsVolatileEnv (StdErrVarName, &Volatile)) && !Volatile)
     1106      ||(StdOutVarName  != NULL && !EFI_ERROR (IsVolatileEnv (StdOutVarName, &Volatile)) && !Volatile)
    10881107      //
    10891108      // Cant redirect during a reconnect operation.
     
    11461165          Status = EFI_INVALID_PARAMETER;
    11471166        } else {
    1148           if (StrStr(StdOutFileName, L"NUL")==StdOutFileName) {
     1167          if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, StdOutFileName, L"NUL")) {
    11491168            //no-op
    11501169          } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
     
    12381257          EFI_FILE_MODE_READ,
    12391258          0);
    1240         if (InUnicode) {
    1241           //
    1242           // Chop off the 0xFEFF if it's there...
    1243           //
    1244           RemoveFileTag(&TempHandle);
    1245         } else if (!EFI_ERROR(Status)) {
    1246           //
    1247           // Create the ASCII->Unicode conversion layer
    1248           //
    1249           TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
    1250         }
    12511259        if (!EFI_ERROR(Status)) {
     1260          if (!InUnicode) {
     1261            //
     1262            // Create the ASCII->Unicode conversion layer
     1263            //
     1264            TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
     1265          }
    12521266          ShellParameters->StdIn = TempHandle;
    12531267          gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
     
    12841298**/
    12851299EFI_STATUS
    1286 EFIAPI
    12871300RestoreStdInStdOutStdErr (
    12881301  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
     
    13531366  @param[in, out] ShellParameters        Pointer to parameter structure to modify.
    13541367  @param[in] NewCommandLine              The new command line to parse and use.
     1368  @param[in] Type                        The type of operation.
    13551369  @param[out] OldArgv                    Pointer to old list of parameters.
    13561370  @param[out] OldArgc                    Pointer to old number of items in Argv list.
     
    13601374**/
    13611375EFI_STATUS
    1362 EFIAPI
    13631376UpdateArgcArgv(
    13641377  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
    13651378  IN CONST CHAR16                       *NewCommandLine,
     1379  IN SHELL_OPERATION_TYPES              Type,
    13661380  OUT CHAR16                            ***OldArgv OPTIONAL,
    13671381  OUT UINTN                             *OldArgc OPTIONAL
    13681382  )
    13691383{
     1384  BOOLEAN                 StripParamQuotation;
     1385
    13701386  ASSERT(ShellParameters != NULL);
     1387  StripParamQuotation = TRUE;
    13711388
    13721389  if (OldArgc != NULL) {
     
    13771394  }
    13781395
    1379   return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
     1396  if (Type == Script_File_Name) {
     1397    StripParamQuotation = FALSE;
     1398  }
     1399
     1400  return ParseCommandLineToArgs( NewCommandLine,
     1401                                 StripParamQuotation,
     1402                                 &(ShellParameters->Argv),
     1403                                 &(ShellParameters->Argc)
     1404                                );
    13801405}
    13811406
     
    13901415**/
    13911416VOID
    1392 EFIAPI
    13931417RestoreArgcArgv(
    13941418  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellParametersProtocol.h

    r58459 r77662  
    1919#include "Shell.h"
    2020
     21typedef enum {
     22  Internal_Command,
     23  Script_File_Name,
     24  Efi_Application,
     25  File_Sys_Change,
     26  Unknown_Invalid
     27} SHELL_OPERATION_TYPES;
     28
    2129/**
    2230  creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
     
    3644**/
    3745EFI_STATUS
    38 EFIAPI
    3946CreatePopulateInstallShellParametersProtocol (
    4047  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  **NewShellParameters,
     
    5562**/
    5663EFI_STATUS
    57 EFIAPI
    5864CleanUpShellParametersProtocol (
    5965  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *NewShellParameters
     
    6773  @param[in, out] ShellParameters       pointer to parameter structure to modify
    6874  @param[in] NewCommandLine             the new command line to parse and use
     75  @param[in] Type                       the type of operation.
    6976  @param[out] OldArgv                   pointer to old list of parameters
    7077  @param[out] OldArgc                   pointer to old number of items in Argv list
     
    7481**/
    7582EFI_STATUS
    76 EFIAPI
    7783UpdateArgcArgv(
    7884  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
    7985  IN CONST CHAR16                       *NewCommandLine,
     86  IN SHELL_OPERATION_TYPES              Type,
    8087  OUT CHAR16                            ***OldArgv,
    8188  OUT UINTN                             *OldArgc
     
    9299**/
    93100VOID
    94 EFIAPI
    95101RestoreArgcArgv(
    96102  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
     
    126132**/
    127133EFI_STATUS
    128 EFIAPI
    129134UpdateStdInStdOutStdErr(
    130135  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
     
    147152**/
    148153EFI_STATUS
    149 EFIAPI
    150154RestoreStdInStdOutStdErr (
    151155  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
     
    163167  delimited and quote surrounded parameter definition.
    164168
    165   @param[in] CommandLine         String of command line to parse
    166   @param[in, out] Argv           pointer to array of strings; one for each parameter
    167   @param[in, out] Argc           pointer to number of strings in Argv array
     169  @param[in] CommandLine          String of command line to parse
     170  @param[in] StripQuotation       if TRUE then strip the quotation marks surrounding
     171                                  the parameters.
     172  @param[in, out] Argv            pointer to array of strings; one for each parameter
     173  @param[in, out] Argc            pointer to number of strings in Argv array
    168174
    169175  @return EFI_SUCCESS           the operation was sucessful
     
    171177**/
    172178EFI_STATUS
    173 EFIAPI
    174179ParseCommandLineToArgs(
    175180  IN CONST CHAR16 *CommandLine,
    176   IN OUT CHAR16 ***Argv,
    177   IN OUT UINTN *Argc
     181  IN BOOLEAN      StripQuotation,
     182  IN OUT CHAR16   ***Argv,
     183  IN OUT UINTN    *Argc
    178184  );
    179185
     
    188194  function.
    189195
    190   @param[in, out] Walker        pointer to string of command line.  Adjusted to
    191                                 reminaing command line on return
    192   @param[in, out] TempParameter pointer to string of command line item extracted.
    193   @param[in]      Length        Length of (*TempParameter) in bytes
     196  @param[in, out] Walker          pointer to string of command line.  Adjusted to
     197                                  reminaing command line on return
     198  @param[in, out] TempParameter   pointer to string of command line item extracted.
     199  @param[in]      Length          Length of (*TempParameter) in bytes
     200  @param[in]      StripQuotation  if TRUE then strip the quotation marks surrounding
     201                                  the parameters.
    194202
    195203  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.
     
    197205**/
    198206EFI_STATUS
    199 EFIAPI
    200207GetNextParameter(
    201208  IN OUT CHAR16   **Walker,
    202209  IN OUT CHAR16   **TempParameter,
    203   IN CONST UINTN  Length
     210  IN CONST UINTN  Length,
     211  IN BOOLEAN      StripQuotation
    204212  );
    205213
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellProtocol.c

    r58466 r77662  
    33  manipulation, and initialization of EFI_SHELL_PROTOCOL.
    44
    5   (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
    6   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
     6  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
     7  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
    78  This program and the accompanying materials
    89  are licensed and made available under the terms and conditions of the BSD License
     
    5051**/
    5152BOOLEAN
    52 EFIAPI
    5353InternalShellProtocolIsBlockIoPresent(
    5454  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
     
    8080**/
    8181BOOLEAN
    82 EFIAPI
    8382InternalShellProtocolIsSimpleFileSystemPresent(
    8483  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
     
    113112**/
    114113EFI_STATUS
    115 EFIAPI
    116114InternalShellProtocolDebugPrintMessage (
    117115  IN CONST CHAR16                   *Mapping,
     
    186184          if (StringNoCaseCompare(&MapListNode->MapName, &Mapping) == 0) {
    187185            RemoveEntryList(&MapListNode->Link);
     186            SHELL_FREE_NON_NULL(MapListNode->DevicePath);
     187            SHELL_FREE_NON_NULL(MapListNode->MapName);
     188            SHELL_FREE_NON_NULL(MapListNode->CurrentDirectoryPath);
    188189            FreePool(MapListNode);
    189190            return (EFI_SUCCESS);
     
    450451         ){
    451452        //
    452         // all the rest should be file path nodes
     453        // If any node is not a file path node, then the conversion can not be completed
    453454        //
    454455        if ((DevicePathType(&FilePath->Header) != MEDIA_DEVICE_PATH) ||
    455456            (DevicePathSubType(&FilePath->Header) != MEDIA_FILEPATH_DP)) {
    456457          FreePool(PathForReturn);
    457           PathForReturn = NULL;
    458           ASSERT(FALSE);
    459         } else {
    460           //
    461           // append the path part onto the filepath.
    462           //
    463           ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
    464 
    465           AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath);
    466           ASSERT (AlignedNode != NULL);
    467 
    468           // File Path Device Path Nodes 'can optionally add a "\" separator to
    469           //  the beginning and/or the end of the Path Name string.'
    470           // (UEFI Spec 2.4 section 9.3.6.4).
    471           // If necessary, add a "\", but otherwise don't
    472           // (This is specified in the above section, and also implied by the
    473           //  UEFI Shell spec section 3.7)
    474           if ((PathSize != 0)                        &&
    475               (PathForReturn != NULL)                &&
    476               (PathForReturn[PathSize - 1] != L'\\') &&
    477               (AlignedNode->PathName[0]    != L'\\')) {
    478             PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L"\\", 1);
    479           }
    480 
    481           PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, AlignedNode->PathName, 0);
    482           FreePool(AlignedNode);
     458          return NULL;
    483459        }
     460
     461        //
     462        // append the path part onto the filepath.
     463        //
     464        ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
     465
     466        AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath);
     467        if (AlignedNode == NULL) {
     468          FreePool (PathForReturn);
     469          return NULL;
     470        }
     471
     472        // File Path Device Path Nodes 'can optionally add a "\" separator to
     473        //  the beginning and/or the end of the Path Name string.'
     474        // (UEFI Spec 2.4 section 9.3.6.4).
     475        // If necessary, add a "\", but otherwise don't
     476        // (This is specified in the above section, and also implied by the
     477        //  UEFI Shell spec section 3.7)
     478        if ((PathSize != 0)                        &&
     479            (PathForReturn != NULL)                &&
     480            (PathForReturn[PathSize / sizeof (CHAR16) - 1] != L'\\') &&
     481            (AlignedNode->PathName[0]    != L'\\')) {
     482          PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L"\\", 1);
     483        }
     484
     485        PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, AlignedNode->PathName, 0);
     486        FreePool(AlignedNode);
    484487      } // for loop of remaining nodes
    485488    }
     
    533536      return (NULL);
    534537    }
    535     Size = StrSize(Cwd) + StrSize(Path) - sizeof(CHAR16);
     538    Size = StrSize(Cwd) + StrSize(Path);
    536539    NewPath = AllocateZeroPool(Size);
    537540    if (NewPath == NULL) {
    538541      return (NULL);
    539542    }
    540     StrnCpy(NewPath, Cwd, Size/sizeof(CHAR16)-1);
     543    StrCpyS(NewPath, Size/sizeof(CHAR16), Cwd);
     544    StrCatS(NewPath, Size/sizeof(CHAR16), L"\\");
    541545    if (*Path == L'\\') {
    542546      Path++;
    543547      while (PathRemoveLastItem(NewPath)) ;
    544548    }
    545     StrnCat(NewPath, Path, Size/sizeof(CHAR16) - 1 - StrLen(NewPath));
     549    StrCatS(NewPath, Size/sizeof(CHAR16), Path);
    546550    DevicePathForReturn = EfiShellGetDevicePathFromFilePath(NewPath);
    547551    FreePool(NewPath);
     
    595599  // build the full device path
    596600  //
    597   if (*(Path+StrLen(MapName)+1) == CHAR_NULL) {
     601  if ((*(Path+StrLen(MapName)) != CHAR_NULL) &&
     602      (*(Path+StrLen(MapName)+1) == CHAR_NULL)) {
    598603    DevicePathForReturn = FileDevicePath(Handle, L"\\");
    599604  } else {
     
    823828                                could not be opened.
    824829  @retval EFI_VOLUME_CORRUPTED  The data structures in the volume were corrupted.
    825   @retval EFI_DEVICE_ERROR      The device had an error
     830  @retval EFI_DEVICE_ERROR      The device had an error.
     831  @retval Others                Error status returned from EFI_SIMPLE_FILE_SYSTEM_PROTOCOL->OpenVolume().
    826832**/
    827833EFI_STATUS
     
    863869  //
    864870  Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &RealFileHandle);
     871  if (EFI_ERROR(Status)) {
     872    return Status;
     873  }
     874
    865875  *FileHandle = ConvertEfiFileProtocolToShellHandle(RealFileHandle, EfiShellGetMapFromDevicePath(&DevPath));
    866   return (Status);
     876  return (EFI_SUCCESS);
    867877}
    868878
     
    945955**/
    946956EFI_STATUS
    947 EFIAPI
    948957InternalOpenFileDevicePath(
    949958  IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
     
    11271136  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
    11281137  EFI_STATUS                Status;
     1138  BOOLEAN                   Volatile;
    11291139
    11301140  //
     
    11331143  //
    11341144  if (StrStr(FileName, L">v") == FileName) {
    1135     if (!IsVolatileEnv(FileName+2)) {
     1145    Status = IsVolatileEnv (FileName + 2, &Volatile);
     1146    if (EFI_ERROR (Status)) {
     1147      return Status;
     1148    }
     1149    if (!Volatile) {
    11361150      return (EFI_INVALID_PARAMETER);
    11371151    }
     
    12431257  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
    12441258  EFI_STATUS                      Status;
     1259  BOOLEAN                         Volatile;
    12451260
    12461261  *FileHandle = NULL;
     
    12761291
    12771292  //
    1278   // Is this for NUL file
    1279   //
    1280   if (StrCmp(FileName, L"NUL") == 0) {
     1293  // Is this for NUL / NULL file
     1294  //
     1295  if ((gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)FileName, L"NUL") == 0) ||
     1296      (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)FileName, L"NULL") == 0)) {
    12811297    *FileHandle = &FileInterfaceNulFile;
    12821298    return (EFI_SUCCESS);
     
    13021318  //
    13031319  if (StrStr(FileName, L">v") == FileName) {
    1304     if (!IsVolatileEnv(FileName+2) &&
     1320    Status = IsVolatileEnv (FileName + 2, &Volatile);
     1321    if (EFI_ERROR (Status)) {
     1322      return Status;
     1323    }
     1324    if (!Volatile &&
    13051325        ((OpenMode & EFI_FILE_MODE_WRITE) != 0)) {
    13061326      return (EFI_INVALID_PARAMETER);
     
    13621382  // now delete the file
    13631383  //
     1384  ShellFileHandleRemove(FileHandle);
    13641385  return (ShellInfoObject.NewEfiShellProtocol->DeleteFile(FileHandle));
    13651386}
     
    14121433**/
    14131434EFI_STATUS
    1414 EFIAPI
    14151435InternalShellExecuteDevicePath(
    14161436  IN CONST EFI_HANDLE               *ParentImageHandle,
     
    14381458
    14391459  InitializeListHead(&OrigEnvs);
     1460  ZeroMem(&ShellParamsProtocol, sizeof(EFI_SHELL_PARAMETERS_PROTOCOL));
    14401461
    14411462  NewHandle = NULL;
     
    14681489      gBS->UnloadImage(NewHandle);
    14691490    }
     1491    FreePool (NewCmdLine);
    14701492    return (Status);
    14711493  }
     
    14791501
    14801502  if (!EFI_ERROR(Status)) {
     1503    //
     1504    // If the image is not an app abort it.
     1505    //
     1506    if (LoadedImage->ImageCodeType != EfiLoaderCode){
     1507      ShellPrintHiiEx(
     1508        -1,
     1509        -1,
     1510        NULL,
     1511        STRING_TOKEN (STR_SHELL_IMAGE_NOT_APP),
     1512        ShellInfoObject.HiiHandle
     1513      );
     1514      goto UnloadImage;
     1515    }
     1516
    14811517    ASSERT(LoadedImage->LoadOptionsSize == 0);
    14821518    if (NewCmdLine != NULL) {
     
    15011537    ShellParamsProtocol.StdOut  = ShellInfoObject.NewShellParametersProtocol->StdOut;
    15021538    ShellParamsProtocol.StdErr  = ShellInfoObject.NewShellParametersProtocol->StdErr;
    1503     Status = UpdateArgcArgv(&ShellParamsProtocol, NewCmdLine, NULL, NULL);
     1539    Status = UpdateArgcArgv(&ShellParamsProtocol, NewCmdLine, Efi_Application, NULL, NULL);
    15041540    ASSERT_EFI_ERROR(Status);
    15051541    //
     
    15841620  return(Status);
    15851621}
     1622
     1623/**
     1624  internal worker function to load and run an image in the current shell.
     1625
     1626  @param CommandLine            Points to the NULL-terminated UCS-2 encoded string
     1627                                containing the command line. If NULL then the command-
     1628                                line will be empty.
     1629  @param Environment            Points to a NULL-terminated array of environment
     1630                                variables with the format 'x=y', where x is the
     1631                                environment variable name and y is the value. If this
     1632                                is NULL, then the current shell environment is used.
     1633
     1634  @param[out] StartImageStatus  Returned status from the command line.
     1635
     1636  @retval EFI_SUCCESS       The command executed successfully. The  status code
     1637                            returned by the command is pointed to by StatusCode.
     1638  @retval EFI_INVALID_PARAMETER The parameters are invalid.
     1639  @retval EFI_OUT_OF_RESOURCES Out of resources.
     1640  @retval EFI_UNSUPPORTED   Nested shell invocations are not allowed.
     1641**/
     1642EFI_STATUS
     1643InternalShellExecute(
     1644  IN CONST CHAR16                   *CommandLine OPTIONAL,
     1645  IN CONST CHAR16                   **Environment OPTIONAL,
     1646  OUT EFI_STATUS                    *StartImageStatus OPTIONAL
     1647  )
     1648{
     1649  EFI_STATUS                    Status;
     1650  EFI_STATUS                    CleanupStatus;
     1651  LIST_ENTRY                    OrigEnvs;
     1652
     1653  InitializeListHead(&OrigEnvs);
     1654
     1655  //
     1656  // Save our current environment settings for later restoration if necessary
     1657  //
     1658  if (Environment != NULL) {
     1659    Status = GetEnvironmentVariableList(&OrigEnvs);
     1660    if (!EFI_ERROR(Status)) {
     1661      Status = SetEnvironmentVariables(Environment);
     1662    } else {
     1663      return Status;
     1664    }
     1665  }
     1666
     1667  Status = RunShellCommand(CommandLine, StartImageStatus);
     1668
     1669  // Restore environment variables
     1670  if (!IsListEmpty(&OrigEnvs)) {
     1671    CleanupStatus = SetEnvironmentVariableList(&OrigEnvs);
     1672    ASSERT_EFI_ERROR (CleanupStatus);
     1673  }
     1674
     1675  return(Status);
     1676}
     1677
     1678/**
     1679  Determine if the UEFI Shell is currently running with nesting enabled or disabled.
     1680
     1681  @retval FALSE   nesting is required
     1682  @retval other   nesting is enabled
     1683**/
     1684STATIC
     1685BOOLEAN
     1686NestingEnabled(
     1687  VOID
     1688)
     1689{
     1690  EFI_STATUS  Status;
     1691  CHAR16      *Temp;
     1692  CHAR16      *Temp2;
     1693  UINTN       TempSize;
     1694  BOOLEAN     RetVal;
     1695
     1696  RetVal = TRUE;
     1697  Temp   = NULL;
     1698  Temp2  = NULL;
     1699
     1700  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
     1701    TempSize = 0;
     1702    Temp     = NULL;
     1703    Status = SHELL_GET_ENVIRONMENT_VARIABLE(mNoNestingEnvVarName, &TempSize, Temp);
     1704    if (Status == EFI_BUFFER_TOO_SMALL) {
     1705      Temp = AllocateZeroPool(TempSize + sizeof(CHAR16));
     1706      if (Temp != NULL) {
     1707        Status = SHELL_GET_ENVIRONMENT_VARIABLE(mNoNestingEnvVarName, &TempSize, Temp);
     1708      }
     1709    }
     1710    Temp2 = StrnCatGrow(&Temp2, NULL, mNoNestingTrue, 0);
     1711    if (Temp != NULL && Temp2 != NULL && StringNoCaseCompare(&Temp, &Temp2) == 0) {
     1712      //
     1713      // Use the no nesting method.
     1714      //
     1715      RetVal = FALSE;
     1716    }
     1717  }
     1718
     1719  SHELL_FREE_NON_NULL(Temp);
     1720  SHELL_FREE_NON_NULL(Temp2);
     1721  return (RetVal);
     1722}
     1723
    15861724/**
    15871725  Execute the command line.
     
    16071745                            environment variable name and y is the value. If this
    16081746                            is NULL, then the current shell environment is used.
    1609   @param StatusCode         Points to the status code returned by the command.
     1747  @param StatusCode         Points to the status code returned by the CommandLine.
    16101748
    16111749  @retval EFI_SUCCESS       The command executed successfully. The  status code
     
    16361774  }
    16371775
    1638   DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
    1639 
    1640   DEBUG_CODE_BEGIN();
    1641   Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);
    1642   FreePool(Temp);
    1643   Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);
    1644   FreePool(Temp);
    1645   Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
    1646   FreePool(Temp);
    1647   DEBUG_CODE_END();
    1648 
    1649   Temp = NULL;
    1650   Size = 0;
    1651   ASSERT((Temp == NULL && Size == 0) || (Temp != NULL));
    1652   StrnCatGrow(&Temp, &Size, L"Shell.efi -_exit ", 0);
    1653   StrnCatGrow(&Temp, &Size, CommandLine, 0);
    1654 
    1655   Status = InternalShellExecuteDevicePath(
    1656     ParentImageHandle,
    1657     DevPath,
    1658     Temp,
    1659     (CONST CHAR16**)Environment,
    1660     StatusCode);
    1661 
    1662   //
    1663   // de-allocate and return
    1664   //
    1665   FreePool(DevPath);
    1666   FreePool(Temp);
     1776  if (NestingEnabled()) {
     1777    DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
     1778
     1779    DEBUG_CODE_BEGIN();
     1780    Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);
     1781    FreePool(Temp);
     1782    Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);
     1783    FreePool(Temp);
     1784    Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
     1785    FreePool(Temp);
     1786    DEBUG_CODE_END();
     1787
     1788    Temp = NULL;
     1789    Size = 0;
     1790    ASSERT((Temp == NULL && Size == 0) || (Temp != NULL));
     1791    StrnCatGrow(&Temp, &Size, L"Shell.efi -exit ", 0);
     1792    StrnCatGrow(&Temp, &Size, CommandLine, 0);
     1793
     1794    Status = InternalShellExecuteDevicePath(
     1795      ParentImageHandle,
     1796      DevPath,
     1797      Temp,
     1798      (CONST CHAR16**)Environment,
     1799      StatusCode);
     1800
     1801    //
     1802    // de-allocate and return
     1803    //
     1804    FreePool(DevPath);
     1805    FreePool(Temp);
     1806  } else {
     1807    Status = InternalShellExecute(
     1808      (CONST CHAR16*)CommandLine,
     1809      (CONST CHAR16**)Environment,
     1810      StatusCode);
     1811  }
     1812
    16671813  return(Status);
    16681814}
     
    16771823**/
    16781824VOID
    1679 EFIAPI
    16801825InternalFreeShellFileInfoNode(
    16811826  IN EFI_SHELL_FILE_INFO *FileListNode
     
    18051950**/
    18061951EFI_SHELL_FILE_INFO*
    1807 EFIAPI
    18081952InternalDuplicateShellFileInfo(
    18091953  IN       EFI_SHELL_FILE_INFO *Node,
     
    18582002**/
    18592003EFI_SHELL_FILE_INFO *
    1860 EFIAPI
    18612004CreateAndPopulateShellFileInfo(
    18622005  IN CONST CHAR16 *BasePath,
     
    20022145      ; Status = FileHandleFindNextFile(FileDirHandle, FileInfo, &NoFile)
    20032146     ){
     2147    if (ShellFileList == NULL) {
     2148      ShellFileList = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
     2149      if (ShellFileList == NULL) {
     2150        SHELL_FREE_NON_NULL (BasePath);
     2151        return EFI_OUT_OF_RESOURCES;
     2152      }
     2153      InitializeListHead(&ShellFileList->Link);
     2154    }
    20042155    //
    20052156    // allocate a new EFI_SHELL_FILE_INFO and populate it...
     
    20112162      NULL,         // no handle since not open
    20122163      FileInfo);
    2013 
    2014     if (ShellFileList == NULL) {
    2015       ShellFileList = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
    2016       ASSERT(ShellFileList != NULL);
    2017       InitializeListHead(&ShellFileList->Link);
     2164    if (ShellFileListItem == NULL) {
     2165      Status = EFI_OUT_OF_RESOURCES;
     2166      //
     2167      // Free resources outside the loop.
     2168      //
     2169      break;
    20182170    }
    20192171    InsertTailList(&ShellFileList->Link, &ShellFileListItem->Link);
     
    20632215
    20642216  if (!EFI_ERROR(Status)) {
    2065     CopyGuid(NewGuid, Guid);
     2217    CopyGuid(Guid, NewGuid);
    20662218  }
    20672219
     
    21202272**/
    21212273EFI_STATUS
    2122 EFIAPI
    21232274UpdateFileName(
    21242275  IN CONST CHAR16 *BasePath,
     
    21812332**/
    21822333EFI_STATUS
    2183 EFIAPI
    21842334ShellSearchHandle(
    21852335  IN     CONST CHAR16                         *FilePattern,
     
    22202370
    22212371  CurrentFilePattern = AllocateZeroPool((NextFilePatternStart-FilePattern+1)*sizeof(CHAR16));
    2222   ASSERT(CurrentFilePattern != NULL);
    2223   StrnCpy(CurrentFilePattern, FilePattern, NextFilePatternStart-FilePattern);
     2372  if (CurrentFilePattern == NULL) {
     2373    return EFI_OUT_OF_RESOURCES;
     2374  }
     2375
     2376  StrnCpyS(CurrentFilePattern, NextFilePatternStart-FilePattern+1, FilePattern, NextFilePatternStart-FilePattern);
    22242377
    22252378  if (CurrentFilePattern[0]   == CHAR_NULL
     
    22792432        if (UnicodeCollation->MetaiMatch(UnicodeCollation, (CHAR16*)ShellInfoNode->FileName, CurrentFilePattern)){
    22802433          if (ShellInfoNode->FullName != NULL && StrStr(ShellInfoNode->FullName, L":") == NULL) {
    2281             Size = StrSize(ShellInfoNode->FullName);
    2282             Size += StrSize(MapName) + sizeof(CHAR16);
     2434            Size = StrSize (ShellInfoNode->FullName) + StrSize (MapName);
    22832435            NewFullName = AllocateZeroPool(Size);
    22842436            if (NewFullName == NULL) {
    22852437              Status = EFI_OUT_OF_RESOURCES;
    22862438            } else {
    2287               StrnCpy(NewFullName, MapName, Size/sizeof(CHAR16)-1);
    2288               StrnCat(NewFullName, ShellInfoNode->FullName+1, (Size/sizeof(CHAR16))-StrLen(NewFullName)-1);
    2289               FreePool((VOID*)ShellInfoNode->FullName);
     2439              StrCpyS(NewFullName, Size / sizeof(CHAR16), MapName);
     2440              StrCatS(NewFullName, Size / sizeof(CHAR16), ShellInfoNode->FullName);
     2441              FreePool ((VOID *) ShellInfoNode->FullName);
    22902442              ShellInfoNode->FullName = NewFullName;
    22912443            }
     
    23172469              //
    23182470              Status = ShellSearchHandle(NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode, MapName);
     2471              EfiShellClose(ShellInfoNode->Handle);
     2472              ShellInfoNode->Handle = NULL;
    23192473            }
    23202474          } else if (!EFI_ERROR(Status)) {
     
    23272481            //
    23282482            NewShellNode = InternalDuplicateShellFileInfo(ShellInfoNode, FALSE);
    2329             ASSERT(NewShellNode != NULL);
    23302483            if (NewShellNode == NULL) {
    23312484              Status = EFI_OUT_OF_RESOURCES;
     
    23542507  }
    23552508
     2509  if (*FileList == NULL || (*FileList != NULL && IsListEmpty(&(*FileList)->Link))) {
     2510    Status = EFI_NOT_FOUND;
     2511  }
     2512
    23562513  FreePool(CurrentFilePattern);
    23572514  return (Status);
     
    24162573  PatternCopy = PathCleanUpDirectories(PatternCopy);
    24172574
    2418   Count = StrStr(PatternCopy, L":") - PatternCopy;
    2419   Count += 2;
     2575  Count = StrStr(PatternCopy, L":") - PatternCopy + 1;
     2576  ASSERT (Count <= StrLen (PatternCopy));
    24202577
    24212578  ASSERT(MapName == NULL);
     
    24352592        PatternCurrentLocation++;
    24362593        Status = ShellSearchHandle(PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL, MapName);
     2594        EfiShellClose(RootFileHandle);
    24372595      }
    24382596      FreePool(RootDevicePath);
     
    24962654    ASSERT((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
    24972655    StrnCatGrow(&Path2, &Path2Size, CurDir, 0);
     2656    StrnCatGrow(&Path2, &Path2Size, L"\\", 0);
    24982657    if (*Path == L'\\') {
    24992658      Path++;
     
    25722731  VOID        *Buffer;
    25732732  UINTN       Size;
    2574   LIST_ENTRY  List;
    25752733  ENV_VAR_LIST *Node;
    25762734  CHAR16      *CurrentWriteLocation;
     
    25802738
    25812739  if (Name == NULL) {
    2582     //
    2583     // Get all our environment variables
    2584     //
    2585     InitializeListHead(&List);
    2586     Status = GetEnvironmentVariableList(&List);
    2587     if (EFI_ERROR(Status)){
    2588       return (NULL);
    2589     }
    25902740
    25912741    //
    25922742    // Build the semi-colon delimited list. (2 passes)
    25932743    //
    2594     for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
    2595       ; !IsNull(&List, &Node->Link)
    2596       ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     2744    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)
     2745      ; !IsNull(&gShellEnvVarList.Link, &Node->Link)
     2746      ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)
    25972747     ){
    25982748      ASSERT(Node->Key != NULL);
     
    26042754    Buffer = AllocateZeroPool(Size);
    26052755    if (Buffer == NULL) {
    2606       if (!IsListEmpty (&List)) {
    2607         FreeEnvironmentVariableList(&List);
    2608       }
    26092756      return (NULL);
    26102757    }
    26112758    CurrentWriteLocation = (CHAR16*)Buffer;
    26122759
    2613     for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
    2614       ; !IsNull(&List, &Node->Link)
    2615       ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     2760    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&gShellEnvVarList.Link)
     2761      ; !IsNull(&gShellEnvVarList.Link, &Node->Link)
     2762      ; Node = (ENV_VAR_LIST*)GetNextNode(&gShellEnvVarList.Link, &Node->Link)
    26162763     ){
    26172764      ASSERT(Node->Key != NULL);
    2618       StrnCpy(CurrentWriteLocation, Node->Key,  (Size)/sizeof(CHAR16) - (CurrentWriteLocation - ((CHAR16*)Buffer)) - 1);
     2765      StrCpyS( CurrentWriteLocation,
     2766                (Size)/sizeof(CHAR16) - (CurrentWriteLocation - ((CHAR16*)Buffer)),
     2767                Node->Key
     2768                );
    26192769      CurrentWriteLocation += StrLen(CurrentWriteLocation) + 1;
    26202770    }
    26212771
    2622     //
    2623     // Free the list...
    2624     //
    2625     if (!IsListEmpty (&List)) {
    2626       FreeEnvironmentVariableList(&List);
    2627     }
    26282772  } else {
    26292773    //
    26302774    // We are doing a specific environment variable
    26312775    //
    2632 
    2633     //
    2634     // get the size we need for this EnvVariable
    2635     //
    2636     Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(Name, Attributes, &Size, Buffer);
    2637     if (Status == EFI_BUFFER_TOO_SMALL) {
     2776    Status = ShellFindEnvVarInList(Name, (CHAR16**)&Buffer, &Size, Attributes);
     2777
     2778    if (EFI_ERROR(Status)){
    26382779      //
    2639       // Allocate the space and recall the get function
     2780      // get the size we need for this EnvVariable
    26402781      //
    2641       Buffer = AllocateZeroPool(Size);
    26422782      Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(Name, Attributes, &Size, Buffer);
    2643     }
    2644     //
    2645     // we didnt get it (might not exist)
    2646     // free the memory if we allocated any and return NULL
    2647     //
    2648     if (EFI_ERROR(Status)) {
    2649       if (Buffer != NULL) {
    2650         FreePool(Buffer);
     2783      if (Status == EFI_BUFFER_TOO_SMALL) {
     2784        //
     2785        // Allocate the space and recall the get function
     2786        //
     2787        Buffer = AllocateZeroPool(Size);
     2788        Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(Name, Attributes, &Size, Buffer);
    26512789      }
    2652       return (NULL);
     2790      //
     2791      // we didnt get it (might not exist)
     2792      // free the memory if we allocated any and return NULL
     2793      //
     2794      if (EFI_ERROR(Status)) {
     2795        if (Buffer != NULL) {
     2796          FreePool(Buffer);
     2797        }
     2798        return (NULL);
     2799      } else {
     2800        //
     2801        // If we did not find the environment variable in the gShellEnvVarList
     2802        // but get it from UEFI variable storage successfully then we need update
     2803        // the gShellEnvVarList.
     2804        //
     2805        ShellFreeEnvVarList ();
     2806        Status = ShellInitEnvVarList ();
     2807        ASSERT (Status == EFI_SUCCESS);
     2808      }
    26532809    }
    26542810  }
     
    27032859**/
    27042860EFI_STATUS
    2705 EFIAPI
    27062861InternalEfiShellSetEnv(
    27072862  IN CONST CHAR16 *Name,
     
    27102865  )
    27112866{
     2867  EFI_STATUS      Status;
     2868
    27122869  if (Value == NULL || StrLen(Value) == 0) {
    2713     return (SHELL_DELETE_ENVIRONMENT_VARIABLE(Name));
     2870    Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Name);
     2871    if (!EFI_ERROR(Status)) {
     2872      ShellRemvoeEnvVarFromList(Name);
     2873    }
    27142874  } else {
    27152875    SHELL_DELETE_ENVIRONMENT_VARIABLE(Name);
    2716     if (Volatile) {
    2717       return (SHELL_SET_ENVIRONMENT_VARIABLE_V(Name, StrSize(Value), Value));
    2718     } else {
    2719       return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(Name, StrSize(Value), Value));
    2720     }
    2721   }
     2876    Status = ShellAddEnvVarToList(
     2877               Name, Value, StrSize(Value),
     2878               EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE)
     2879               );
     2880    if (!EFI_ERROR (Status)) {
     2881      Status = Volatile
     2882             ? SHELL_SET_ENVIRONMENT_VARIABLE_V (Name, StrSize (Value) - sizeof (CHAR16), Value)
     2883             : SHELL_SET_ENVIRONMENT_VARIABLE_NV (Name, StrSize (Value) - sizeof (CHAR16), Value);
     2884      if (EFI_ERROR (Status)) {
     2885        ShellRemvoeEnvVarFromList(Name);
     2886      }
     2887    }
     2888  }
     2889  return Status;
    27222890}
    27232891
     
    27812949        (CHAR16*)Name,
    27822950        L"uefiversion") == 0
     2951    ||(!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest &&
     2952      gUnicodeCollation->StriColl(
     2953        gUnicodeCollation,
     2954        (CHAR16*)Name,
     2955        (CHAR16*)mNoNestingEnvVarName) == 0)
    27832956       ){
    27842957    return (EFI_INVALID_PARAMETER);
     
    27942967  FileSystemMapping. In both cases, the returned name includes the file system
    27952968  mapping (i.e. fs0:\current-dir).
     2969
     2970  Note that the current directory string should exclude the tailing backslash character.
    27962971
    27972972  @param FileSystemMapping      A pointer to the file system mapping. If NULL,
     
    28503025  %cwd% environment variable will be updated
    28513026
     3027  Note that the current directory string should exclude the tailing backslash character.
     3028
    28523029  @param FileSystem             A pointer to the file system's mapped name. If NULL, then the current working
    28533030                                directory is changed.
     
    29103087      //
    29113088      if (MapListItem != NULL) {
    2912         gShellCurDir = MapListItem;
     3089        gShellCurMapping = MapListItem;
    29133090      }
    29143091    } else {
    2915       MapListItem = gShellCurDir;
     3092      MapListItem = gShellCurMapping;
    29163093    }
    29173094
    29183095    if (MapListItem == NULL) {
     3096      FreePool (DirectoryName);
     3097      SHELL_FREE_NON_NULL(MapName);
    29193098      return (EFI_NOT_FOUND);
    29203099    }
     
    29333112        MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, DirectoryName+StrLen(MapName), 0);
    29343113      }
     3114      FreePool (MapName);
    29353115    } else {
    29363116      ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
    29373117      MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
    29383118    }
    2939     if ((MapListItem->CurrentDirectoryPath != NULL && MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] != L'\\') || (MapListItem->CurrentDirectoryPath == NULL)) {
     3119    if ((MapListItem->CurrentDirectoryPath != NULL && MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] == L'\\') || (MapListItem->CurrentDirectoryPath == NULL)) {
    29403120      ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
    2941       MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
     3121      if (MapListItem->CurrentDirectoryPath != NULL) {
     3122        MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
     3123    }
    29423124    }
    29433125  } else {
     
    29463128    //
    29473129    if (StrStr(DirectoryName, L":") != NULL) {
     3130      FreePool (DirectoryName);
    29483131      return (EFI_INVALID_PARAMETER);
    29493132    }
     
    29533136    MapListItem = ShellCommandFindMapItem(FileSystem);
    29543137    if (MapListItem == NULL) {
     3138      FreePool (DirectoryName);
    29553139      return (EFI_INVALID_PARAMETER);
    29563140    }
    2957 //    gShellCurDir = MapListItem;
     3141//    gShellCurMapping = MapListItem;
    29583142    if (DirectoryName != NULL) {
    29593143      //
     
    29713155      ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
    29723156      MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
    2973       if (MapListItem->CurrentDirectoryPath != NULL && MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] != L'\\') {
     3157      if (MapListItem->CurrentDirectoryPath != NULL && MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] == L'\\') {
    29743158        ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
    2975         MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
     3159        MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
    29763160      }
    29773161    }
    29783162  }
     3163  FreePool (DirectoryName);
    29793164  //
    29803165  // if updated the current directory then update the environment variable
    29813166  //
    2982   if (MapListItem == gShellCurDir) {
     3167  if (MapListItem == gShellCurMapping) {
    29833168    Size = 0;
    29843169    ASSERT((TempString == NULL && Size == 0) || (TempString != NULL));
     
    30453230    ) {
    30463231      FixCommand = AllocateZeroPool(StrSize(Command) - 4 * sizeof (CHAR16));
    3047       ASSERT(FixCommand != NULL);
    3048 
    3049       StrnCpy(FixCommand, Command, StrLen(Command)-4);
     3232      if (FixCommand == NULL) {
     3233        return EFI_OUT_OF_RESOURCES;
     3234      }
     3235
     3236      StrnCpyS( FixCommand,
     3237                (StrSize(Command) - 4 * sizeof (CHAR16))/sizeof(CHAR16),
     3238                Command,
     3239                StrLen(Command)-4
     3240                );
    30503241      Status = ProcessManFile(FixCommand, FixCommand, Sections, NULL, HelpText);
    30513242      FreePool(FixCommand);
     
    31013292**/
    31023293CHAR16 *
    3103 EFIAPI
    31043294InternalEfiShellGetListAlias(
     3295  VOID
    31053296  )
    31063297{
     
    32153406  EFI_STATUS  Status;
    32163407  CHAR16      *AliasLower;
     3408  CHAR16      *AliasVal;
    32173409
    32183410  // Convert to lowercase to make aliases case-insensitive
    32193411  if (Alias != NULL) {
    32203412    AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
    3221     ASSERT (AliasLower != NULL);
     3413    if (AliasLower == NULL) {
     3414      return NULL;
     3415    }
    32223416    ToLower (AliasLower);
    32233417
    32243418    if (Volatile == NULL) {
    3225       return (AddBufferToFreeList(GetVariable(AliasLower, &gShellAliasGuid)));
     3419      GetVariable2 (AliasLower, &gShellAliasGuid, (VOID **)&AliasVal, NULL);
     3420      FreePool(AliasLower);
     3421      return (AddBufferToFreeList(AliasVal));
    32263422    }
    32273423    RetSize = 0;
     
    32363432        FreePool(RetVal);
    32373433      }
     3434      FreePool(AliasLower);
    32383435      return (NULL);
    32393436    }
     
    32673464**/
    32683465EFI_STATUS
    3269 EFIAPI
    32703466InternalSetAlias(
    32713467  IN CONST CHAR16 *Command,
     
    32763472  EFI_STATUS  Status;
    32773473  CHAR16      *AliasLower;
    3278 
     3474  BOOLEAN     DeleteAlias;
     3475
     3476  DeleteAlias = FALSE;
     3477  if (Alias == NULL) {
     3478    //
     3479    // We must be trying to remove one if Alias is NULL
     3480    // remove an alias (but passed in COMMAND parameter)
     3481    //
     3482    Alias       = Command;
     3483    DeleteAlias = TRUE;
     3484  }
     3485  ASSERT (Alias != NULL);
     3486
     3487  //
    32793488  // Convert to lowercase to make aliases case-insensitive
    3280   if (Alias != NULL) {
    3281     AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
    3282     ASSERT (AliasLower != NULL);
    3283     ToLower (AliasLower);
     3489  //
     3490  AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
     3491  if (AliasLower == NULL) {
     3492    return EFI_OUT_OF_RESOURCES;
     3493  }
     3494  ToLower (AliasLower);
     3495
     3496  if (DeleteAlias) {
     3497    Status = gRT->SetVariable (AliasLower, &gShellAliasGuid, 0, 0, NULL);
    32843498  } else {
    3285     AliasLower = NULL;
    3286   }
    3287 
    3288   //
    3289   // We must be trying to remove one if Alias is NULL
    3290   //
    3291   if (Alias == NULL) {
    3292     //
    3293     // remove an alias (but passed in COMMAND parameter)
    3294     //
    3295     Status = (gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL));
    3296   } else {
    3297     //
    3298     // Add and replace are the same
    3299     //
    3300 
    3301     // We dont check the error return on purpose since the variable may not exist.
    3302     gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL);
    3303 
    3304     Status = (gRT->SetVariable((CHAR16*)Alias, &gShellAliasGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS|(Volatile?0:EFI_VARIABLE_NON_VOLATILE), StrSize(Command), (VOID*)Command));
    3305   }
    3306 
    3307   if (Alias != NULL) {
    3308     FreePool (AliasLower);
    3309   }
     3499    Status = gRT->SetVariable (
     3500                    AliasLower, &gShellAliasGuid,
     3501                    EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE),
     3502                    StrSize (Command), (VOID *) Command
     3503                    );
     3504  }
     3505
     3506  FreePool (AliasLower);
     3507
    33103508  return Status;
    33113509}
     
    34293627**/
    34303628EFI_STATUS
    3431 EFIAPI
    34323629CreatePopulateInstallShellProtocol (
    34333630  IN OUT EFI_SHELL_PROTOCOL  **NewShell
     
    34393636  UINTN                       HandleCounter;
    34403637  SHELL_PROTOCOL_HANDLE_LIST  *OldProtocolNode;
     3638  EFI_SHELL_PROTOCOL          *OldShell;
    34413639
    34423640  if (NewShell == NULL) {
     
    34903688    //
    34913689    for (HandleCounter = 0 ; HandleCounter < (BufferSize/sizeof(EFI_HANDLE)) ; HandleCounter++) {
    3492       OldProtocolNode = AllocateZeroPool(sizeof(SHELL_PROTOCOL_HANDLE_LIST));
    3493       ASSERT(OldProtocolNode != NULL);
    34943690      Status = gBS->OpenProtocol(Buffer[HandleCounter],
    34953691                                &gEfiShellProtocolGuid,
    3496                                 (VOID **) &(OldProtocolNode->Interface),
     3692                                (VOID **) &OldShell,
    34973693                                gImageHandle,
    34983694                                NULL,
     
    35003696                               );
    35013697      if (!EFI_ERROR(Status)) {
     3698        OldProtocolNode = AllocateZeroPool(sizeof(SHELL_PROTOCOL_HANDLE_LIST));
     3699        if (OldProtocolNode == NULL) {
     3700          if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {
     3701            CleanUpShellProtocol (&mShellProtocol);
     3702          }
     3703          Status = EFI_OUT_OF_RESOURCES;
     3704          break;
     3705        }
    35023706        //
    35033707        // reinstall over the old one...
    35043708        //
    3505         OldProtocolNode->Handle = Buffer[HandleCounter];
     3709        OldProtocolNode->Handle    = Buffer[HandleCounter];
     3710        OldProtocolNode->Interface = OldShell;
    35063711        Status = gBS->ReinstallProtocolInterface(
    35073712                            OldProtocolNode->Handle,
     
    35563761**/
    35573762EFI_STATUS
    3558 EFIAPI
    35593763CleanUpShellProtocol (
    35603764  IN OUT EFI_SHELL_PROTOCOL  *NewShell
    35613765  )
    35623766{
     3767  SHELL_PROTOCOL_HANDLE_LIST        *Node2;
     3768
     3769  //
     3770  // if we need to restore old protocols...
     3771  //
     3772  if (!IsListEmpty(&ShellInfoObject.OldShellList.Link)) {
     3773    for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *) GetFirstNode (&ShellInfoObject.OldShellList.Link)
     3774         ; !IsListEmpty (&ShellInfoObject.OldShellList.Link)
     3775         ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *) GetFirstNode (&ShellInfoObject.OldShellList.Link)
     3776         ) {
     3777      RemoveEntryList (&Node2->Link);
     3778      gBS->ReinstallProtocolInterface (Node2->Handle, &gEfiShellProtocolGuid, NewShell, Node2->Interface);
     3779      FreePool (Node2);
     3780    }
     3781  } else {
     3782    //
     3783    // no need to restore
     3784    //
     3785    gBS->UninstallProtocolInterface (gImageHandle, &gEfiShellProtocolGuid, NewShell);
     3786  }
     3787  return EFI_SUCCESS;
     3788}
     3789
     3790/**
     3791  Cleanup the shell environment.
     3792
     3793  @param[in, out] NewShell   The pointer to the new shell protocol structure.
     3794
     3795  @retval EFI_SUCCESS       The operation was successful.
     3796**/
     3797EFI_STATUS
     3798CleanUpShellEnvironment (
     3799  IN OUT EFI_SHELL_PROTOCOL  *NewShell
     3800  )
     3801{
    35633802  EFI_STATUS                        Status;
    3564   SHELL_PROTOCOL_HANDLE_LIST        *Node2;
    35653803  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
    35663804
    3567   //
    3568   // if we need to restore old protocols...
    3569   //
    3570   if (!IsListEmpty(&ShellInfoObject.OldShellList.Link)) {
    3571     for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode(&ShellInfoObject.OldShellList.Link)
    3572          ; !IsListEmpty (&ShellInfoObject.OldShellList.Link)
    3573          ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode(&ShellInfoObject.OldShellList.Link)
    3574         ){
    3575       RemoveEntryList(&Node2->Link);
    3576       Status = gBS->ReinstallProtocolInterface(Node2->Handle,
    3577                                                &gEfiShellProtocolGuid,
    3578                                                NewShell,
    3579                                                Node2->Interface);
    3580       FreePool(Node2);
    3581     }
    3582   } else {
    3583     //
    3584     // no need to restore
    3585     //
    3586     Status = gBS->UninstallProtocolInterface(gImageHandle,
    3587                                              &gEfiShellProtocolGuid,
    3588                                              NewShell);
    3589   }
     3805  CleanUpShellProtocol (NewShell);
     3806
    35903807  Status = gBS->CloseEvent(NewShell->ExecutionBreak);
    35913808  NewShell->ExecutionBreak = NULL;
     
    36493866**/
    36503867EFI_STATUS
    3651 EFIAPI
    36523868InernalEfiShellStartMonitor(
    36533869  VOID
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/Shell/ShellProtocol.h

    r58466 r77662  
    33  manipulation, and initialization of EFI_SHELL_PROTOCOL.
    44
    5   (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
    6   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
     6  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
    77  This program and the accompanying materials
    88  are licensed and made available under the terms and conditions of the BSD License
     
    4444**/
    4545EFI_STATUS
    46 EFIAPI
    4746CreatePopulateInstallShellProtocol (
    4847  IN OUT EFI_SHELL_PROTOCOL  **NewShell
     
    6059**/
    6160EFI_STATUS
    62 EFIAPI
    6361CleanUpShellProtocol (
     62  IN OUT EFI_SHELL_PROTOCOL  *NewShell
     63  );
     64
     65/**
     66  Cleanup the shell environment.
     67
     68  @param[in, out] NewShell   The pointer to the new shell protocol structure.
     69
     70  @retval EFI_SUCCESS       The operation was successful.
     71**/
     72EFI_STATUS
     73CleanUpShellEnvironment (
    6474  IN OUT EFI_SHELL_PROTOCOL  *NewShell
    6575  );
     
    284294**/
    285295EFI_STATUS
    286 EFIAPI
    287296InternalOpenFileDevicePath(
    288297  IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath2,
     
    454463**/
    455464EFI_STATUS
    456 EFIAPI
    457465InternalShellExecuteDevicePath(
    458466  IN CONST EFI_HANDLE               *ParentImageHandle,
     
    512520**/
    513521VOID
    514 EFIAPI
    515522FreeShellFileInfoNode(
    516523  IN EFI_SHELL_FILE_INFO *FileListNode
     
    563570**/
    564571EFI_SHELL_FILE_INFO *
    565 EFIAPI
    566572CreateAndPopulateShellFileInfo(
    567573  IN CONST CHAR16 *BasePath,
     
    846852**/
    847853EFI_STATUS
    848 EFIAPI
    849854InternalSetAlias(
    850855  IN CONST CHAR16 *Command,
     
    891896**/
    892897VOID
    893 EFIAPI
    894898InternalFreeShellFileInfoNode(
    895899  IN EFI_SHELL_FILE_INFO *FileListNode
     
    907911**/
    908912EFI_STATUS
    909 EFIAPI
    910913InternalEfiShellSetEnv(
    911914  IN CONST CHAR16 *Name,
     
    922925**/
    923926EFI_STATUS
    924 EFIAPI
    925927InernalEfiShellStartMonitor(
    926928  VOID
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/ShellCTestApp/ShellCTestApp.c

    r48674 r77662  
    33  for a shell application.
    44
    5   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     5  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
    66  This program and the accompanying materials
    77  are licensed and made available under the terms and conditions of the BSD License
     
    4141{
    4242  UINTN  Index;
    43 
    44   Print(L"ShellCTestApp.c:ShellAppMain called with %d parameters\n", Argc);
    45   for (Index = 0; Index < Argc; Index++) {
    46     Print(L"Argv[%d]: %s\n", Index, Argv[Index]);
     43  if (Argc == 1) {
     44    Print (L"Argv[1] = NULL\n");
     45  }
     46  for (Index = 1; Index < Argc; Index++) {
     47    Print(L"Argv[%d]: \"%s\"\n", Index, Argv[Index]);
    4748  }
    4849
  • trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Application/ShellSortTestApp/ShellSortTestApp.inf

    r48674 r77662  
    22#  This is the shell sorting testing application
    33#
    4 #  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
     4#  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
    55#
    66#  This program and the accompanying materials
     
    3434  MdePkg/MdePkg.dec
    3535  ShellPkg/ShellPkg.dec
     36  MdeModulePkg/MdeModulePkg.dec
    3637
    3738[LibraryClasses]
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette