VirtualBox

Ignore:
Timestamp:
Oct 28, 2015 8:17:18 PM (9 years ago)
Author:
vboxsync
Message:

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

Location:
trunk/src/VBox/Devices/EFI/Firmware
Files:
16 edited

Legend:

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

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

    r48674 r58459  
    22  Provides interface to shell console logger.
    33
    4   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
     5  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
    56  This program and the accompanying materials
    67  are licensed and made available under the terms and conditions of the BSD License
     
    1213**/
    1314
    14 #include "ConsoleLogger.h"
    1515#include "Shell.h"
    16 
    17 STATIC CONST CHAR16                     mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
    1816
    1917/**
     
    474472            ; Index++
    475473           ){
    476           *(ConsoleInfo->Attributes + (CopySize/sizeof(ConsoleInfo->Attributes)) + Index) = ConsoleInfo->HistoryMode.Attribute;
     474          *(ConsoleInfo->Attributes + (CopySize/sizeof(ConsoleInfo->Attributes[0])) + Index) = ConsoleInfo->HistoryMode.Attribute;
    477475        }
    478476
     
    644642    FreePool(Resp);
    645643    ShellInfoObject.ConsoleInfo->Enabled = FALSE;
     644    //
     645    // When user wants to quit, the shell should stop running the command.
     646    //
     647    gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
    646648    return (EFI_DEVICE_ERROR);
    647649  } else {
     
    818820  )
    819821{
    820   EFI_INPUT_KEY               Key;
    821   UINTN                       EventIndex;
    822   CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
     822  EFI_STATUS                        Status;
     823  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx;
     824  EFI_KEY_DATA                      KeyData;
     825  UINTN                             EventIndex;
     826  CONSOLE_LOGGER_PRIVATE_DATA       *ConsoleInfo;
     827
    823828  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
    824829  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
     
    826831  }
    827832  ASSERT(ShellInfoObject.ConsoleInfo == ConsoleInfo);
    828   if (ShellInfoObject.HaltOutput) {
    829     //
    830     // just get some key
    831     //
    832     gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
    833     gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    834     ShellInfoObject.HaltOutput = FALSE;
    835   }
     833
     834  Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
     835  if (!EFI_ERROR (Status)) {
     836    while (ShellInfoObject.HaltOutput) {
     837
     838      ShellInfoObject.HaltOutput = FALSE;
     839      //
     840      // just get some key
     841      //
     842      Status = gBS->WaitForEvent (1, &TxtInEx->WaitForKeyEx, &EventIndex);
     843      ASSERT_EFI_ERROR (Status);
     844      Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
     845      if (EFI_ERROR(Status)) {
     846        break;
     847      }
     848
     849      if ((KeyData.Key.UnicodeChar == L's') && (KeyData.Key.ScanCode == SCAN_NULL) &&
     850          ((KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED)) ||
     851           (KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED))
     852          )
     853         ) {
     854        ShellInfoObject.HaltOutput = TRUE;
     855      }
     856    }
     857  }
     858
    836859  if (!ShellInfoObject.ConsoleInfo->Enabled) {
    837860    return (EFI_DEVICE_ERROR);
     
    10291052  //
    10301053  if (!EFI_ERROR (Status)) {
    1031     Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 1) * ConsoleInfo->CurrentStartRow];
     1054    Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
    10321055    Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
    10331056    for ( Row = ConsoleInfo->OriginalStartRow
     
    10471070      // Skip the NULL on each column end in text buffer only
    10481071      //
    1049       Screen++;
     1072      Screen += 2;
    10501073    }
    10511074    ConsoleInfo->HistoryMode.CursorColumn = 0;
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ConsoleLogger.h

    r48674 r58459  
    1515#define _CONSOLE_LOGGER_HEADER_
    1616
    17 #include <Uefi.h>
    18 
    19 #include <Protocol/SimpleTextOut.h>
    20 #include <Protocol/EfiShell.h>
    21 #include <Protocol/EfiShellParameters.h>
    22 
    23 #include <Library/DebugLib.h>
    24 #include <Library/BaseLib.h>
    25 #include <Library/BaseMemoryLib.h>
    26 #include <Library/MemoryAllocationLib.h>
    27 #include <Library/UefiBootServicesTableLib.h>
    28 #include <Library/HiiLib.h>
    29 #include <Library/ShellLib.h>
     17#include "Shell.h"
    3018
    3119#define CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('c', 'o', 'P', 'D')
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ConsoleWrappers.c

    r48674 r58459  
    22  Function definitions for shell simple text in and out on top of file handles.
    33
    4   Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
     5  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    56  This program and the accompanying materials
    67  are licensed and made available under the terms and conditions of the BSD License
     
    1314**/
    1415
    15 #include <Uefi.h>
    16 #include <ShellBase.h>
    17 
    18 #include "ConsoleWrappers.h"
    1916#include "Shell.h"
    2017
     
    2320  SHELL_FILE_HANDLE               FileHandle;
    2421  EFI_HANDLE                      TheHandle;
     22  UINT64                          RemainingBytesOfInputFile;
    2523} SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
    2624
     
    2927  SHELL_FILE_HANDLE               FileHandle;
    3028  EFI_HANDLE                      TheHandle;
     29  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalSimpleTextOut;
    3130} SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
    3231
     
    4645  )
    4746{
    48   UINT64 Position;
    49   UINT64 Size;
    50   //
    51   // Someone is waiting on the keystroke event, if there's
    52   // a key pending, signal the event
    53   //
    54   // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
    55   //
    56   ShellInfoObject.NewEfiShellProtocol->GetFilePosition(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Position);
    57   ShellInfoObject.NewEfiShellProtocol->GetFileSize    (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Size    );
    58   if (Position < Size) {
    59     gBS->SignalEvent (Event);
    60   }
     47  gBS->SignalEvent (Event);
    6148}
    6249
     
    9582{
    9683  UINTN Size;
    97   Size = sizeof(CHAR16);
     84
     85  //
     86  // Verify the parameters
     87  //
    9888  if (Key == NULL || This == NULL) {
    9989    return (EFI_INVALID_PARAMETER);
    10090  }
     91
     92  //
     93  // Check if we have any characters left in the stream.
     94  //
     95  if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile == 0) {
     96    return (EFI_NOT_READY);
     97  }
     98
     99  Size = sizeof(CHAR16);
     100
     101  //
     102  // Decrement the amount of free space by Size or set to zero (for odd length files)
     103  //
     104  if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > Size) {
     105    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= Size;
     106  } else {
     107    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile = 0;
     108  }
     109
    101110  Key->ScanCode = 0;
    102111  return (ShellInfoObject.NewEfiShellProtocol->ReadFile(
     
    125134  SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *ProtocolToReturn;
    126135  EFI_STATUS                            Status;
     136  UINT64                                CurrentPosition;
     137  UINT64                                FileSize;
    127138
    128139  if (HandleLocation == NULL || FileHandleToUse == NULL) {
     
    134145    return (NULL);
    135146  }
    136   ProtocolToReturn->FileHandle                  = FileHandleToUse;
     147
     148  ShellGetFileSize    (FileHandleToUse, &FileSize);
     149  ShellGetFilePosition(FileHandleToUse, &CurrentPosition);
     150
     151  //
     152  // Initialize the protocol members
     153  //
     154  ProtocolToReturn->RemainingBytesOfInputFile  = FileSize - CurrentPosition;
     155  ProtocolToReturn->FileHandle                 = FileHandleToUse;
    137156  ProtocolToReturn->SimpleTextIn.Reset         = FileBasedSimpleTextInReset;
    138157  ProtocolToReturn->SimpleTextIn.ReadKeyStroke = FileBasedSimpleTextInReadKeyStroke;
     
    258277  )
    259278{
    260   return (EFI_UNSUPPORTED);
     279  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol;
     280 
     281  PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
     282 
     283  // Pass the QueryMode call thru to the original SimpleTextOutProtocol
     284  return (PassThruProtocol->QueryMode(
     285    PassThruProtocol,
     286    ModeNumber,
     287    Columns,
     288    Rows));
    261289}
    262290
     
    391419  SHELL_FILE_HANDLE to support redirecting output from a file.
    392420
    393   @param[in]  FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
    394   @param[in]  HandleLocation  The pointer of a location to copy handle with protocol to.
     421  @param[in]  FileHandleToUse  The pointer to the SHELL_FILE_HANDLE to use.
     422  @param[in]  HandleLocation   The pointer of a location to copy handle with protocol to.
     423  @param[in]  OriginalProtocol The pointer to the original output protocol for pass thru of functions.
    395424
    396425  @retval NULL                There was insufficient memory available.
     
    400429EFIAPI
    401430CreateSimpleTextOutOnFile(
    402   IN SHELL_FILE_HANDLE  FileHandleToUse,
    403   IN EFI_HANDLE         *HandleLocation
     431  IN SHELL_FILE_HANDLE               FileHandleToUse,
     432  IN EFI_HANDLE                      *HandleLocation,
     433  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
    404434  )
    405435{
     
    416446  }
    417447  ProtocolToReturn->FileHandle                      = FileHandleToUse;
     448  ProtocolToReturn->OriginalSimpleTextOut           = OriginalProtocol;
    418449  ProtocolToReturn->SimpleTextOut.Reset             = FileBasedSimpleTextOutReset;
    419450  ProtocolToReturn->SimpleTextOut.TestString        = FileBasedSimpleTextOutTestString;
     
    430461    return (NULL);
    431462  }
    432   ProtocolToReturn->SimpleTextOut.Mode->MaxMode       = 0;
    433   ProtocolToReturn->SimpleTextOut.Mode->Mode          = 0;
    434   ProtocolToReturn->SimpleTextOut.Mode->Attribute     = 0;
    435   ProtocolToReturn->SimpleTextOut.Mode->CursorColumn  = 0;
    436   ProtocolToReturn->SimpleTextOut.Mode->CursorRow     = 0;
    437   ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = FALSE;
     463  ProtocolToReturn->SimpleTextOut.Mode->MaxMode       = OriginalProtocol->Mode->MaxMode;
     464  ProtocolToReturn->SimpleTextOut.Mode->Mode          = OriginalProtocol->Mode->Mode;
     465  ProtocolToReturn->SimpleTextOut.Mode->Attribute     = OriginalProtocol->Mode->Attribute;
     466  ProtocolToReturn->SimpleTextOut.Mode->CursorColumn  = OriginalProtocol->Mode->CursorColumn;
     467  ProtocolToReturn->SimpleTextOut.Mode->CursorRow     = OriginalProtocol->Mode->CursorRow;
     468  ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;
    438469
    439470  Status = gBS->InstallProtocolInterface(
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ConsoleWrappers.h

    r48674 r58459  
    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.
    45  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
    56  This program and the accompanying materials
     
    5152  SHELL_FILE_HANDLE to support redirecting output from a file.
    5253
    53   @param[in]  FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
    54   @param[in]  HandleLocation  The pointer of a location to copy handle with protocol to.
     54  @param[in]  FileHandleToUse  The pointer to the SHELL_FILE_HANDLE to use.
     55  @param[in]  HandleLocation   The pointer of a location to copy handle with protocol to.
     56  @param[in]  OriginalProtocol The pointer to the original output protocol for pass thru of functions.
    5557
    5658  @retval NULL                There was insufficient memory available.
     
    6062EFIAPI
    6163CreateSimpleTextOutOnFile(
    62   IN SHELL_FILE_HANDLE  FileHandleToUse,
    63   IN EFI_HANDLE         *HandleLocation
     64  IN SHELL_FILE_HANDLE               FileHandleToUse,
     65  IN EFI_HANDLE                      *HandleLocation,
     66  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
    6467  );
    6568
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/FileHandleWrappers.c

    r48674 r58459  
    33  StdIn, StdOut, StdErr, etc...).
    44
    5   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     5  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
     6  Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
    67  This program and the accompanying materials
    78  are licensed and made available under the terms and conditions of the BSD License
     
    417418    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    418419    if (EFI_ERROR (Status)) {
    419       continue;
     420      break;
    420421    }
    421422
     
    509510          Cwd = ShellInfoObject.NewEfiShellProtocol->GetCurDir(NULL);
    510511          if (Cwd != NULL) {
    511             StrCpy(TabStr, Cwd);
     512            StrnCpy(TabStr, Cwd, (*BufferSize)/sizeof(CHAR16) - 1);
    512513            if (TabStr[StrLen(TabStr)-1] == L'\\' && *(CurrentString + TabPos) == L'\\' ) {
    513514              TabStr[StrLen(TabStr)-1] = CHAR_NULL;
     
    515516            StrnCat(TabStr, CurrentString + TabPos, (StringLen - TabPos) * sizeof (CHAR16));
    516517          } else {
    517             StrCpy(TabStr, L"");
     518            *TabStr = CHAR_NULL;
    518519            StrnCat(TabStr, CurrentString + TabPos, (StringLen - TabPos) * sizeof (CHAR16));
    519520          }
    520521        } else {
    521           StrCpy(TabStr, CurrentString + TabPos);
     522          StrnCpy(TabStr, CurrentString + TabPos, (*BufferSize)/sizeof(CHAR16) - 1);
    522523        }
    523         StrCat(TabStr, L"*");
     524        StrnCat(TabStr, L"*", (*BufferSize)/sizeof(CHAR16) - 1 - StrLen(TabStr));
    524525        FoundFileList = NULL;
    525 //        TabStr = PathCleanUpDirectories(TabStr);
    526526        Status  = ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, &FoundFileList);
    527527        for ( TempStr = CurrentString
     
    849849  ASSERT(FoundFileList == NULL);
    850850
    851   return EFI_SUCCESS;
     851  return Status;
    852852}
    853853
     
    951951  )
    952952{
     953  VOID*       NewBuffer;
     954  UINTN       NewSize;
     955  EFI_STATUS  Status;
     956
     957  //
     958  // Most if not all UEFI commands will have an '\r\n' at the end of any output.
     959  // Since the output was redirected to a variable, it does not make sense to
     960  // keep this.  So, before closing, strip the trailing '\r\n' from the variable
     961  // if it exists.
     962  //
     963  NewBuffer   = NULL;
     964  NewSize     = 0;
     965
     966  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
     967  if (Status == EFI_BUFFER_TOO_SMALL) {
     968    NewBuffer = AllocateZeroPool(NewSize + sizeof(CHAR16));
     969    if (NewBuffer == NULL) {
     970      return EFI_OUT_OF_RESOURCES;
     971    } 
     972    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
     973  }
     974 
     975  if (!EFI_ERROR(Status) && NewBuffer != NULL) {
     976   
     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;   
     982      }
     983   
     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);
     986      } else {
     987        Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
     988      }
     989    }
     990  }
     991 
     992  SHELL_FREE_NON_NULL(NewBuffer);
    953993  FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT*)This);
    954   return (EFI_SUCCESS);
     994  return (Status);
    955995}
    956996
     
    11011141{
    11021142  EFI_FILE_PROTOCOL_ENVIRONMENT  *EnvFileInterface;
     1143  UINTN                          EnvNameSize;
    11031144
    11041145  if (EnvName == NULL) {
     
    11091150  // Get some memory
    11101151  //
    1111   EnvFileInterface = AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT)+StrSize(EnvName));
     1152  EnvNameSize = StrSize(EnvName);
     1153  EnvFileInterface = AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT)+EnvNameSize);
    11121154  if (EnvFileInterface == NULL){
    11131155    return (NULL);
     
    11271169  EnvFileInterface->Delete      = FileInterfaceEnvDelete;
    11281170  EnvFileInterface->Read        = FileInterfaceEnvRead;
    1129 
    1130   StrCpy(EnvFileInterface->Name, EnvName);
     1171 
     1172  CopyMem(EnvFileInterface->Name, EnvName, EnvNameSize);
    11311173
    11321174  //
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/Shell.c

    r48674 r58459  
    22  This is THE shell (application)
    33
    4   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.
    56  This program and the accompanying materials
    67  are licensed and made available under the terms and conditions of the BSD License
     
    2425  FALSE,
    2526  {
    26     0,
    27     0,
    28     0,
    29     0,
    30     0,
    31     0,
    32     0,
    33     0,
    34     0,
     27    {{
     28      0,
     29      0,
     30      0,
     31      0,
     32      0,
     33      0,
     34      0,
     35      0,
     36      0
     37    }},
    3538    0,
    3639    NULL,
    3740    NULL
    3841  },
    39   {0,0},
     42  {{NULL, NULL}, NULL},
    4043  {
    41     {0,0},
     44    {{NULL, NULL}, NULL},
    4245    0,
    4346    0,
     
    5154  NULL,
    5255  NULL,
    53   {0,0,NULL,NULL},
    54   {0,0},
     56  {{NULL, NULL}, NULL, NULL},
     57  {{NULL, NULL}, NULL, NULL},
     58  NULL,
     59  NULL,
     60  NULL,
     61  NULL,
    5562  NULL,
    5663  NULL,
     
    6370STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
    6471STATIC CONST CHAR16 mStartupScript[]        = L"startup.nsh";
     72
     73/**
     74  Cleans off leading and trailing spaces and tabs.
     75
     76  @param[in] String pointer to the string to trim them off.
     77**/
     78EFI_STATUS
     79EFIAPI
     80TrimSpaces(
     81  IN CHAR16 **String
     82  )
     83{
     84  ASSERT(String != NULL);
     85  ASSERT(*String!= NULL);
     86  //
     87  // Remove any spaces and tabs at the beginning of the (*String).
     88  //
     89  while (((*String)[0] == L' ') || ((*String)[0] == L'\t')) {
     90    CopyMem((*String), (*String)+1, StrSize((*String)) - sizeof((*String)[0]));
     91  }
     92
     93  //
     94  // Remove any spaces and tabs at the end of the (*String).
     95  //
     96  while ((StrLen (*String) > 0) && (((*String)[StrLen((*String))-1] == L' ') || ((*String)[StrLen((*String))-1] == L'\t'))) {
     97    (*String)[StrLen((*String))-1] = CHAR_NULL;
     98  }
     99
     100  return (EFI_SUCCESS);
     101}
     102
     103/**
     104  Parse for the next instance of one string within another string. Can optionally make sure that
     105  the string was not escaped (^ character) per the shell specification.
     106
     107  @param[in] SourceString             The string to search within
     108  @param[in] FindString               The string to look for
     109  @param[in] CheckForEscapeCharacter  TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
     110**/
     111CHAR16*
     112EFIAPI
     113FindNextInstance(
     114  IN CONST CHAR16   *SourceString,
     115  IN CONST CHAR16   *FindString,
     116  IN CONST BOOLEAN  CheckForEscapeCharacter
     117  )
     118{
     119  CHAR16 *Temp;
     120  if (SourceString == NULL) {
     121    return (NULL);
     122  }
     123  Temp = StrStr(SourceString, FindString);
     124
     125  //
     126  // If nothing found, or we dont care about escape characters
     127  //
     128  if (Temp == NULL || !CheckForEscapeCharacter) {
     129    return (Temp);
     130  }
     131
     132  //
     133  // If we found an escaped character, try again on the remainder of the string
     134  //
     135  if ((Temp > (SourceString)) && *(Temp-1) == L'^') {
     136    return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);
     137  }
     138
     139  //
     140  // we found the right character
     141  //
     142  return (Temp);
     143}
     144
     145/**
     146  Check whether the string between a pair of % is a valid envifronment variable name.
     147
     148  @param[in] BeginPercent       pointer to the first percent.
     149  @param[in] EndPercent          pointer to the last percent.
     150
     151  @retval TRUE                          is a valid environment variable name.
     152  @retval FALSE                         is NOT a valid environment variable name.
     153**/
     154BOOLEAN
     155IsValidEnvironmentVariableName(
     156  IN CONST CHAR16     *BeginPercent,
     157  IN CONST CHAR16     *EndPercent
     158  )
     159{
     160  CONST CHAR16    *Walker;
     161 
     162  Walker = NULL;
     163
     164  ASSERT (BeginPercent != NULL);
     165  ASSERT (EndPercent != NULL);
     166  ASSERT (BeginPercent < EndPercent);
     167 
     168  if ((BeginPercent + 1) == EndPercent) {
     169    return FALSE;
     170  }
     171
     172  for (Walker = BeginPercent + 1; Walker < EndPercent; Walker++) {
     173    if (
     174        (*Walker >= L'0' && *Walker <= L'9') ||
     175        (*Walker >= L'A' && *Walker <= L'Z') ||
     176        (*Walker >= L'a' && *Walker <= L'z') ||
     177        (*Walker == L'_')
     178      ) {
     179      if (Walker == BeginPercent + 1 && (*Walker >= L'0' && *Walker <= L'9')) {
     180        return FALSE;
     181      } else {
     182        continue;
     183      }
     184    } else {
     185      return FALSE;
     186    }
     187  }
     188
     189  return TRUE;
     190}
     191
     192/**
     193  Determine if a command line contains a split operation
     194
     195  @param[in] CmdLine      The command line to parse.
     196
     197  @retval TRUE            CmdLine has a valid split.
     198  @retval FALSE           CmdLine does not have a valid split.
     199**/
     200BOOLEAN
     201EFIAPI
     202ContainsSplit(
     203  IN CONST CHAR16 *CmdLine
     204  )
     205{
     206  CONST CHAR16 *TempSpot;
     207  CONST CHAR16 *FirstQuote;
     208  CONST CHAR16 *SecondQuote;
     209
     210  FirstQuote    = FindNextInstance (CmdLine, L"\"", TRUE);
     211  SecondQuote   = NULL;
     212  TempSpot      = FindFirstCharacter(CmdLine, L"|", L'^');
     213
     214  if (FirstQuote == NULL    ||
     215      TempSpot == NULL      ||
     216      TempSpot == CHAR_NULL ||
     217      FirstQuote > TempSpot
     218      ) {
     219    return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
     220  }
     221
     222  while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {
     223    if (FirstQuote == NULL || FirstQuote > TempSpot) {
     224      break;
     225    }   
     226    SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);
     227    if (SecondQuote == NULL) {
     228      break;
     229    }
     230    if (SecondQuote < TempSpot) {
     231      FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
     232      continue;
     233    } else {
     234      FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
     235      TempSpot = FindFirstCharacter(TempSpot + 1, L"|", L'^');
     236      continue;
     237    }
     238  }
     239 
     240  return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
     241}
    65242
    66243/**
     
    125302      &KeyData,
    126303      NotificationFunction,
    127       &ShellInfoObject.CtrlSNotifyHandle2);
     304      &ShellInfoObject.CtrlSNotifyHandle3);
    128305  } 
    129306  KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
     
    133310      &KeyData,
    134311      NotificationFunction,
    135       &ShellInfoObject.CtrlSNotifyHandle2);
     312      &ShellInfoObject.CtrlSNotifyHandle4);
    136313  }
    137314  return (Status);
     
    237414      }
    238415      if (ShellInfoObject.HiiHandle == NULL) {
    239         return (EFI_NOT_STARTED);
     416        Status = EFI_NOT_STARTED;
     417        goto FreeResources;
    240418      }
    241419    }
     
    267445    // Check the command line
    268446    //
    269     Status = ProcessCommandLine();
     447    Status = ProcessCommandLine ();
     448    if (EFI_ERROR (Status)) {
     449      goto FreeResources;
     450    }
    270451
    271452    //
     
    291472        gST->ConOut->Mode->CursorRow,
    292473        NULL,
    293         STRING_TOKEN (STR_VER_OUTPUT_MAIN),
     474        STRING_TOKEN (STR_VER_OUTPUT_MAIN_SHELL),
    294475        ShellInfoObject.HiiHandle,
    295476        SupportLevel[PcdGet8(PcdShellSupportLevel)],
    296477        gEfiShellProtocol->MajorVersion,
    297         gEfiShellProtocol->MinorVersion,
     478        gEfiShellProtocol->MinorVersion
     479       );
     480
     481      ShellPrintHiiEx (
     482        -1,
     483        -1,
     484        NULL,
     485        STRING_TOKEN (STR_VER_OUTPUT_MAIN_SUPPLIER),
     486        ShellInfoObject.HiiHandle,
     487        (CHAR16 *) PcdGetPtr (PcdShellSupplier)
     488       );
     489
     490      ShellPrintHiiEx (
     491        -1,
     492        -1,
     493        NULL,
     494        STRING_TOKEN (STR_VER_OUTPUT_MAIN_UEFI),
     495        ShellInfoObject.HiiHandle,
    298496        (gST->Hdr.Revision&0xffff0000)>>16,
    299497        (gST->Hdr.Revision&0x0000ffff),
     
    376574      }
    377575
    378       if (!ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
     576      if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
    379577        //
    380578        // begin the UI waiting loop
     
    393591          //
    394592          ShellInfoObject.PageBreakEnabled        = PcdGetBool(PcdShellPageBreakDefault);
     593          ASSERT (ShellInfoObject.ConsoleInfo != NULL);
    395594          ShellInfoObject.ConsoleInfo->Enabled    = TRUE;
    396595          ShellInfoObject.ConsoleInfo->RowCounter = 0;
     
    415614  }
    416615
     616FreeResources:
    417617  //
    418618  // uninstall protocols / free memory / etc...
     
    436636  if (ShellInfoObject.NewEfiShellProtocol != NULL){
    437637    if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){
    438       ShellInfoObject.NewEfiShellProtocol->SetEnv(L"cwd", L"", TRUE);
     638      InternalEfiShellSetEnv(L"cwd", NULL, TRUE);
    439639    }
    440640    CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);
     
    627827}
    628828
    629 STATIC CONST SHELL_PARAM_ITEM mShellParamList[] = {
    630   {L"-nostartup",     TypeFlag},
    631   {L"-startup",       TypeFlag},
    632   {L"-noconsoleout",  TypeFlag},
    633   {L"-noconsolein",   TypeFlag},
    634   {L"-nointerrupt",   TypeFlag},
    635   {L"-nomap",         TypeFlag},
    636   {L"-noversion",     TypeFlag},
    637   {L"-startup",       TypeFlag},
    638   {L"-delay",         TypeValue},
    639   {NULL, TypeMax}
    640   };
    641 
    642829/**
    643830  Process all Uefi Shell 2.0 command line options.
     
    673860  )
    674861{
    675   EFI_STATUS    Status;
    676   LIST_ENTRY    *Package;
    677   UINTN         Size;
    678   CONST CHAR16  *TempConst;
    679   UINTN         Count;
    680   UINTN         LoopVar;
    681   CHAR16        *ProblemParam;
    682   UINT64        Intermediate;
    683 
    684   Package       = NULL;
    685   ProblemParam  = NULL;
    686  
    687   Status = ShellCommandLineParse (mShellParamList, &Package, NULL, FALSE);
    688 
    689   Count = 1;
    690   Size = 0;
    691   TempConst = ShellCommandLineGetRawValue(Package, Count++);
    692   if (TempConst != NULL && StrLen(TempConst)) {
    693     ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(TempConst));
    694     if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
    695       return (EFI_OUT_OF_RESOURCES);
    696     }
    697     StrCpy(ShellInfoObject.ShellInitSettings.FileName, TempConst);
    698     ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
    699     for (LoopVar = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
    700       if (StrCmp(gEfiShellParametersProtocol->Argv[LoopVar], ShellInfoObject.ShellInitSettings.FileName)==0) {
    701         LoopVar++;
    702         //
    703         // We found the file... add the rest of the params...
    704         //
    705         for ( ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
    706           ASSERT((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));
    707           StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
    708                       &Size,
    709                       L" ",
    710                       0);
    711           if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
    712             SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
    713             return (EFI_OUT_OF_RESOURCES);
    714           }
    715           StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
    716                       &Size,
    717                       gEfiShellParametersProtocol->Argv[LoopVar],
    718                       0);
    719           if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
    720             SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
    721             return (EFI_OUT_OF_RESOURCES);
    722           }
     862  UINTN                           Size;
     863  UINTN                           LoopVar;
     864  CHAR16                          *CurrentArg;
     865  CHAR16                          *DelayValueStr;
     866  UINT64                          DelayValue;
     867  EFI_STATUS                      Status;
     868  EFI_UNICODE_COLLATION_PROTOCOL  *UnicodeCollation;
     869
     870  // `file-name-options` will contain arguments to `file-name` that we don't
     871  // know about. This would cause ShellCommandLineParse to error, so we parse
     872  // arguments manually, ignoring those after the first thing that doesn't look
     873  // like a shell option (which is assumed to be `file-name`).
     874
     875  Status = gBS->LocateProtocol (
     876                  &gEfiUnicodeCollationProtocolGuid,
     877                  NULL,
     878                  (VOID **) &UnicodeCollation
     879                  );
     880  if (EFI_ERROR (Status)) {
     881    return Status;
     882  }
     883
     884  // Set default options
     885  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup      = FALSE;
     886  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup    = FALSE;
     887  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = FALSE;
     888  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn  = FALSE;
     889  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt  = FALSE;
     890  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap        = FALSE;
     891  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = FALSE;
     892  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = FALSE;
     893  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = FALSE;
     894  ShellInfoObject.ShellInitSettings.Delay = 5;
     895
     896  //
     897  // Start LoopVar at 0 to parse only optional arguments at Argv[0]
     898  // and parse other parameters from Argv[1].  This is for use case that
     899  // UEFI Shell boot option is created, and OptionalData is provided
     900  // that starts with shell command-line options.
     901  //
     902  for (LoopVar = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
     903    CurrentArg = gEfiShellParametersProtocol->Argv[LoopVar];
     904    if (UnicodeCollation->StriColl (
     905                            UnicodeCollation,
     906                            L"-startup",
     907                            CurrentArg
     908                            ) == 0) {
     909      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup      = TRUE;
     910    }
     911    else if (UnicodeCollation->StriColl (
     912                                 UnicodeCollation,
     913                                 L"-nostartup",
     914                                 CurrentArg
     915                                 ) == 0) {
     916      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup    = TRUE;
     917    }
     918    else if (UnicodeCollation->StriColl (
     919                                 UnicodeCollation,
     920                                 L"-noconsoleout",
     921                                 CurrentArg
     922                                 ) == 0) {
     923      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = TRUE;
     924    }
     925    else if (UnicodeCollation->StriColl (
     926                                 UnicodeCollation,
     927                                 L"-noconsolein",
     928                                 CurrentArg
     929                                 ) == 0) {
     930      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn  = TRUE;
     931    }
     932    else if (UnicodeCollation->StriColl (
     933                                 UnicodeCollation,
     934                                 L"-nointerrupt",
     935                                 CurrentArg
     936                                 ) == 0) {
     937      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt  = TRUE;
     938    }
     939    else if (UnicodeCollation->StriColl (
     940                                 UnicodeCollation,
     941                                 L"-nomap",
     942                                 CurrentArg
     943                                 ) == 0) {
     944      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap        = TRUE;
     945    }
     946    else if (UnicodeCollation->StriColl (
     947                                 UnicodeCollation,
     948                                 L"-noversion",
     949                                 CurrentArg
     950                                 ) == 0) {
     951      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = TRUE;
     952    }
     953    else if (UnicodeCollation->StriColl (
     954                                 UnicodeCollation,
     955                                 L"-delay",
     956                                 CurrentArg
     957                                 ) == 0) {
     958      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = TRUE;
     959      // Check for optional delay value following "-delay"
     960      DelayValueStr = gEfiShellParametersProtocol->Argv[LoopVar + 1];
     961      if (DelayValueStr != NULL){
     962        if (*DelayValueStr == L':') {
     963          DelayValueStr++;
    723964        }
    724       }
    725     }
    726   } else {
    727     ShellCommandLineFreeVarList(Package);
    728     Package = NULL;
    729     Status = ShellCommandLineParse (mShellParamList, &Package, &ProblemParam, FALSE);
    730     if (EFI_ERROR(Status)) {
    731       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), ShellInfoObject.HiiHandle, ProblemParam);
    732       FreePool(ProblemParam);
    733       ShellCommandLineFreeVarList(Package);
    734       return (EFI_INVALID_PARAMETER);
    735     }
    736   }
    737 
    738   ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup      = ShellCommandLineGetFlag(Package, L"-startup");
    739   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup    = ShellCommandLineGetFlag(Package, L"-nostartup");
    740   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = ShellCommandLineGetFlag(Package, L"-noconsoleout");
    741   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn  = ShellCommandLineGetFlag(Package, L"-noconsolein");
    742   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt  = ShellCommandLineGetFlag(Package, L"-nointerrupt");
    743   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap        = ShellCommandLineGetFlag(Package, L"-nomap");
    744   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = ShellCommandLineGetFlag(Package, L"-noversion");
    745   ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = ShellCommandLineGetFlag(Package, L"-delay");
    746 
    747   ShellInfoObject.ShellInitSettings.Delay = 5;
    748 
     965        if (!EFI_ERROR(ShellConvertStringToUint64 (
     966                        DelayValueStr,
     967                        &DelayValue,
     968                        FALSE,
     969                        FALSE
     970                        ))) {
     971          ShellInfoObject.ShellInitSettings.Delay = (UINTN)DelayValue;
     972          LoopVar++;
     973        }
     974      }
     975    } else if (UnicodeCollation->StriColl (
     976                                   UnicodeCollation,
     977                                   L"-_exit",
     978                                   CurrentArg
     979                                   ) == 0) {
     980      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = TRUE;
     981    } else if (StrnCmp (L"-", CurrentArg, 1) == 0) {
     982      // Unrecognised option
     983      ShellPrintHiiEx(-1, -1, NULL,
     984        STRING_TOKEN (STR_GEN_PROBLEM),
     985        ShellInfoObject.HiiHandle,
     986        CurrentArg
     987        );
     988      return EFI_INVALID_PARAMETER;
     989    } else {
     990      //
     991      // First argument should be Shell.efi image name
     992      //
     993      if (LoopVar == 0) {
     994        continue;
     995      }
     996
     997      ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);
     998      if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
     999        return (EFI_OUT_OF_RESOURCES);
     1000      }
     1001      //
     1002      // We found `file-name`.
     1003      //
     1004      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
     1005      LoopVar++;
     1006
     1007      // Add `file-name-options`
     1008      for (Size = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
     1009        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);
     1017        }
     1018        StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
     1019                    &Size,
     1020                    gEfiShellParametersProtocol->Argv[LoopVar],
     1021                    0);
     1022        if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
     1023          SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
     1024          return (EFI_OUT_OF_RESOURCES);
     1025        }
     1026      }
     1027    }
     1028  }
     1029
     1030  // "-nointerrupt" overrides "-delay"
    7491031  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
    7501032    ShellInfoObject.ShellInitSettings.Delay = 0;
    751   } else if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay) {
    752     TempConst = ShellCommandLineGetValue(Package, L"-delay");
    753     if (TempConst != NULL && *TempConst == L':') {
    754       TempConst++;
    755     }
    756     if (TempConst != NULL && !EFI_ERROR(ShellConvertStringToUint64(TempConst, &Intermediate, FALSE, FALSE))) {
    757       ShellInfoObject.ShellInitSettings.Delay = (UINTN)Intermediate;
    758     }
    759   }
    760   ShellCommandLineFreeVarList(Package);
    761 
    762   return (Status);
     1033  }
     1034
     1035  return EFI_SUCCESS;
    7631036}
    7641037
     
    7761049EFIAPI
    7771050DoStartupScript(
    778   EFI_DEVICE_PATH_PROTOCOL *ImagePath,
    779   EFI_DEVICE_PATH_PROTOCOL *FilePath
     1051  IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
     1052  IN EFI_DEVICE_PATH_PROTOCOL *FilePath
    7801053  )
    7811054{
     
    8071080      return (EFI_OUT_OF_RESOURCES);
    8081081    }
    809     StrCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName);
     1082    StrnCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName, NewSize/sizeof(CHAR16) -1);
    8101083    if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
    811       StrCat(FileStringPath, L" ");
    812       StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions);
     1084      StrnCat(FileStringPath, L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
     1085      StrnCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
    8131086    }
    8141087    Status = RunCommand(FileStringPath);
     
    8281101  }
    8291102
     1103  gST->ConOut->EnableCursor(gST->ConOut, FALSE);
    8301104  //
    8311105  // print out our warning and see if they press a key
    8321106  //
    833   for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay * 10
     1107  for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay
    8341108      ; Delay != 0 && EFI_ERROR(Status)
    8351109      ; Delay--
    8361110     ){
    837     ShellPrintHiiEx(0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay/10);
    838     gBS->Stall (100000);
     1111    ShellPrintHiiEx(0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay);
     1112    gBS->Stall (1000000);
    8391113    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
    8401114      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
     
    8421116  }
    8431117  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CRLF), ShellInfoObject.HiiHandle);
     1118  gST->ConOut->EnableCursor(gST->ConOut, TRUE);
    8441119
    8451120  //
     
    8871162  //
    8881163  if (!EFI_ERROR(Status) && FileHandle != NULL) {
    889     Status = RunScriptFileHandle (FileHandle, mStartupScript);
     1164    Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
    8901165    ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
    8911166  } else {
     
    8981173      ASSERT(FileHandle == NULL);
    8991174    } else {
    900       Status = RunScriptFile(FileStringPath);
     1175      Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
    9011176      FreePool(FileStringPath);
    9021177    }
     
    9641239    CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
    9651240    Status = RunCommand(CmdLine);
    966   }
     1241    }
    9671242
    9681243  //
     
    10131288  Node = AllocateZeroPool(sizeof(BUFFER_LIST));
    10141289  ASSERT(Node != NULL);
    1015   Node->Buffer = AllocateZeroPool(StrSize(Buffer));
     1290  Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);
    10161291  ASSERT(Node->Buffer != NULL);
    1017   StrCpy(Node->Buffer, Buffer);
    10181292
    10191293  InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
     
    10461320  }
    10471321  FreePool(*CommandString);
    1048   *CommandString = AllocateZeroPool(StrSize(NewString));
     1322  *CommandString = AllocateCopyPool(StrSize(NewString), NewString);
    10491323  if (*CommandString == NULL) {
    10501324    return (EFI_OUT_OF_RESOURCES);
    10511325  }
    1052   StrCpy(*CommandString, NewString);
     1326  return (EFI_SUCCESS);
     1327}
     1328
     1329/**
     1330  This function will eliminate unreplaced (and therefore non-found) environment variables.
     1331
     1332  @param[in,out] CmdLine   The command line to update.
     1333**/
     1334EFI_STATUS
     1335EFIAPI
     1336StripUnreplacedEnvironmentVariables(
     1337  IN OUT CHAR16 *CmdLine
     1338  )
     1339{
     1340  CHAR16 *FirstPercent;
     1341  CHAR16 *FirstQuote;
     1342  CHAR16 *SecondPercent;
     1343  CHAR16 *SecondQuote;
     1344  CHAR16 *CurrentLocator;
     1345
     1346  for (CurrentLocator = CmdLine ; CurrentLocator != NULL ; ) {
     1347    FirstQuote = FindNextInstance(CurrentLocator, L"\"", TRUE);
     1348    FirstPercent = FindNextInstance(CurrentLocator, L"%", TRUE);
     1349    SecondPercent = FirstPercent!=NULL?FindNextInstance(FirstPercent+1, L"%", TRUE):NULL;
     1350    if (FirstPercent == NULL || SecondPercent == NULL) {
     1351      //
     1352      // If we ever dont have 2 % we are done.
     1353      //
     1354      break;
     1355    }
     1356
     1357    if (FirstQuote!= NULL && FirstQuote < FirstPercent) {
     1358      SecondQuote = FindNextInstance(FirstQuote+1, L"\"", TRUE);
     1359      //
     1360      // Quote is first found
     1361      //
     1362
     1363      if (SecondQuote < FirstPercent) {
     1364        //
     1365        // restart after the pair of "
     1366        //
     1367        CurrentLocator = SecondQuote + 1;
     1368      } else /* FirstPercent < SecondQuote */{
     1369        //
     1370        // Restart on the first percent
     1371        //
     1372        CurrentLocator = FirstPercent;
     1373      }
     1374      continue;
     1375    }
     1376   
     1377    if (FirstQuote == NULL || SecondPercent < FirstQuote) {
     1378      if (IsValidEnvironmentVariableName(FirstPercent, SecondPercent)) {
     1379        //
     1380        // We need to remove from FirstPercent to SecondPercent
     1381        //
     1382        CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));
     1383        //
     1384        // dont need to update the locator.  both % characters are gone.
     1385        //
     1386      } else {
     1387        CurrentLocator = SecondPercent + 1;
     1388      }
     1389      continue;
     1390    }
     1391    CurrentLocator = FirstQuote;
     1392  }
    10531393  return (EFI_SUCCESS);
    10541394}
     
    11341474
    11351475  //
    1136   // Quick out if none were found...
    1137   //
    1138   if (NewSize == StrSize(OriginalCommandLine)) {
    1139     ASSERT(Temp == NULL);
    1140     Temp = StrnCatGrow(&Temp, NULL, OriginalCommandLine, 0);
    1141     return (Temp);
    1142   }
    1143 
    1144   //
    11451476  // now do the replacements...
    11461477  //
    1147   NewCommandLine1 = AllocateZeroPool(NewSize);
     1478  NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);
    11481479  NewCommandLine2 = AllocateZeroPool(NewSize);
    11491480  ItemTemp        = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));
     
    11541485    return (NULL);
    11551486  }
    1156   StrCpy(NewCommandLine1, OriginalCommandLine);
    11571487  for (MasterEnvList = EfiShellGetEnv(NULL)
    1158     ;  MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL
     1488    ;  MasterEnvList != NULL && *MasterEnvList != CHAR_NULL
    11591489    ;  MasterEnvList += StrLen(MasterEnvList) + 1
    11601490   ){
    1161     StrCpy(ItemTemp, L"%");
    1162     StrCat(ItemTemp, MasterEnvList);
    1163     StrCat(ItemTemp, L"%");
     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));
    11641494    ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);
    1165     StrCpy(NewCommandLine1, NewCommandLine2);
     1495    StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
    11661496  }
    11671497  if (CurrentScriptFile != NULL) {
     
    11711501   ){
    11721502    ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);
    1173     StrCpy(NewCommandLine1, NewCommandLine2);
    1174     }
    1175   }
    1176 
     1503    StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
     1504    }
     1505  }
     1506
     1507  //
     1508  // Remove non-existant environment variables
     1509  //
     1510  StripUnreplacedEnvironmentVariables(NewCommandLine1);
     1511
     1512  //
     1513  // Now cleanup any straggler intentionally ignored "%" characters
     1514  //
     1515  ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);
     1516  StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
     1517 
    11771518  FreePool(NewCommandLine2);
    11781519  FreePool(ItemTemp);
     
    12251566    SHELL_FREE_NON_NULL(NextCommandLine);
    12261567    return (EFI_OUT_OF_RESOURCES);
    1227   }
    1228   if (NextCommandLine[0] != CHAR_NULL &&
     1568  } else if (StrStr(OurCommandLine, L"|") != NULL || Size1 == 0 || Size2 == 0) {
     1569    SHELL_FREE_NON_NULL(OurCommandLine);
     1570    SHELL_FREE_NON_NULL(NextCommandLine);
     1571    return (EFI_INVALID_PARAMETER);
     1572  } else if (NextCommandLine[0] != CHAR_NULL &&
    12291573      NextCommandLine[0] == L'a' &&
    12301574      NextCommandLine[1] == L' '
     
    12471591  InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);
    12481592
    1249   ASSERT(StrStr(OurCommandLine, L"|") == NULL);
    12501593  Status = RunCommand(OurCommandLine);
    12511594
     
    12901633
    12911634/**
    1292   Function will process and run a command line.
    1293 
    1294   This will determine if the command line represents an internal shell
    1295   command or dispatch an external application.
     1635  Take the original command line, substitute any variables, free
     1636  the original string, return the modified copy.
     1637
     1638  @param[in] CmdLine  pointer to the command line to update.
     1639
     1640  @retval EFI_SUCCESS           the function was successful.
     1641  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
     1642**/
     1643EFI_STATUS
     1644EFIAPI
     1645ShellSubstituteVariables(
     1646  IN CHAR16 **CmdLine
     1647  )
     1648{
     1649  CHAR16      *NewCmdLine;
     1650  NewCmdLine = ShellConvertVariables(*CmdLine);
     1651  SHELL_FREE_NON_NULL(*CmdLine);
     1652  if (NewCmdLine == NULL) {
     1653    return (EFI_OUT_OF_RESOURCES);
     1654  }
     1655  *CmdLine = NewCmdLine;
     1656  return (EFI_SUCCESS);
     1657}
     1658
     1659/**
     1660  Take the original command line, substitute any alias in the first group of space delimited characters, free
     1661  the original string, return the modified copy.
     1662
     1663  @param[in] CmdLine  pointer to the command line to update.
     1664
     1665  @retval EFI_SUCCESS           the function was successful.
     1666  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
     1667**/
     1668EFI_STATUS
     1669EFIAPI
     1670ShellSubstituteAliases(
     1671  IN CHAR16 **CmdLine
     1672  )
     1673{
     1674  CHAR16      *NewCmdLine;
     1675  CHAR16      *CommandName;
     1676  EFI_STATUS  Status;
     1677  UINTN       PostAliasSize;
     1678  ASSERT(CmdLine != NULL);
     1679  ASSERT(*CmdLine!= NULL);
     1680
     1681
     1682  CommandName = NULL;
     1683  if (StrStr((*CmdLine), L" ") == NULL){
     1684    StrnCatGrow(&CommandName, NULL, (*CmdLine), 0);
     1685  } else {
     1686    StrnCatGrow(&CommandName, NULL, (*CmdLine), StrStr((*CmdLine), L" ") - (*CmdLine));
     1687  }
     1688
     1689  //
     1690  // This cannot happen 'inline' since the CmdLine can need extra space.
     1691  //
     1692  NewCmdLine = NULL;
     1693  if (!ShellCommandIsCommandOnList(CommandName)) {
     1694    //
     1695    // Convert via alias
     1696    //
     1697    Status = ShellConvertAlias(&CommandName);
     1698    if (EFI_ERROR(Status)){
     1699      return (Status);
     1700    }
     1701    PostAliasSize = 0;
     1702    NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, CommandName, 0);
     1703    if (NewCmdLine == NULL) {
     1704      SHELL_FREE_NON_NULL(CommandName);
     1705      SHELL_FREE_NON_NULL(*CmdLine);
     1706      return (EFI_OUT_OF_RESOURCES);
     1707    }
     1708    NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, StrStr((*CmdLine), L" "), 0);
     1709    if (NewCmdLine == NULL) {
     1710      SHELL_FREE_NON_NULL(CommandName);
     1711      SHELL_FREE_NON_NULL(*CmdLine);
     1712      return (EFI_OUT_OF_RESOURCES);
     1713    }
     1714  } else {
     1715    NewCmdLine = StrnCatGrow(&NewCmdLine, NULL, (*CmdLine), 0);
     1716  }
     1717
     1718  SHELL_FREE_NON_NULL(*CmdLine);
     1719  SHELL_FREE_NON_NULL(CommandName);
     1720 
     1721  //
     1722  // re-assign the passed in double pointer to point to our newly allocated buffer
     1723  //
     1724  *CmdLine = NewCmdLine;
     1725
     1726  return (EFI_SUCCESS);
     1727}
     1728
     1729/**
     1730  Takes the Argv[0] part of the command line and determine the meaning of it.
     1731
     1732  @param[in] CmdName  pointer to the command line to update.
     1733 
     1734  @retval Internal_Command    The name is an internal command.
     1735  @retval File_Sys_Change     the name is a file system change.
     1736  @retval Script_File_Name    the name is a NSH script file.
     1737  @retval Unknown_Invalid     the name is unknown.
     1738  @retval Efi_Application     the name is an application (.EFI).
     1739**/
     1740SHELL_OPERATION_TYPES
     1741EFIAPI
     1742GetOperationType(
     1743  IN CONST CHAR16 *CmdName
     1744  )
     1745{
     1746        CHAR16* FileWithPath;
     1747  CONST CHAR16* TempLocation;
     1748  CONST CHAR16* TempLocation2;
     1749
     1750  FileWithPath = NULL;
     1751  //
     1752  // test for an internal command.
     1753  //
     1754  if (ShellCommandIsCommandOnList(CmdName)) {
     1755    return (Internal_Command);
     1756  }
     1757
     1758  //
     1759  // Test for file system change request.  anything ending with first : and cant have spaces.
     1760  //
     1761  if (CmdName[(StrLen(CmdName)-1)] == L':') {
     1762    if ( StrStr(CmdName, L" ") != NULL
     1763      || StrLen(StrStr(CmdName, L":")) > 1
     1764      ) {
     1765      return (Unknown_Invalid);
     1766    }
     1767    return (File_Sys_Change);
     1768  }
     1769
     1770  //
     1771  // Test for a file
     1772  //
     1773  if ((FileWithPath = ShellFindFilePathEx(CmdName, mExecutableExtensions)) != NULL) {
     1774    //
     1775    // See if that file has a script file extension
     1776    //
     1777    if (StrLen(FileWithPath) > 4) {
     1778      TempLocation = FileWithPath+StrLen(FileWithPath)-4;
     1779      TempLocation2 = mScriptExtension;
     1780      if (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0) {
     1781        SHELL_FREE_NON_NULL(FileWithPath);
     1782        return (Script_File_Name);
     1783      }
     1784    }
     1785
     1786    //
     1787    // Was a file, but not a script.  we treat this as an application.
     1788    //
     1789    SHELL_FREE_NON_NULL(FileWithPath);
     1790    return (Efi_Application);
     1791  }
     1792 
     1793  SHELL_FREE_NON_NULL(FileWithPath);
     1794  //
     1795  // No clue what this is... return invalid flag...
     1796  //
     1797  return (Unknown_Invalid);
     1798}
     1799
     1800/**
     1801  Determine if the first item in a command line is valid.
     1802
     1803  @param[in] CmdLine            The command line to parse.
     1804
     1805  @retval EFI_SUCCESS           The item is valid.
     1806  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
     1807  @retval EFI_NOT_FOUND         The operation type is unknown or invalid.
     1808**/
     1809EFI_STATUS
     1810EFIAPI
     1811IsValidSplit(
     1812  IN CONST CHAR16 *CmdLine
     1813  )
     1814{
     1815  CHAR16        *Temp;
     1816  CHAR16        *FirstParameter;
     1817  CHAR16        *TempWalker;
     1818  EFI_STATUS    Status;
     1819
     1820  Temp           = NULL;
     1821
     1822  Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0);
     1823  if (Temp == NULL) {
     1824    return (EFI_OUT_OF_RESOURCES);
     1825  }
     1826
     1827  FirstParameter = StrStr(Temp, L"|");
     1828  if (FirstParameter != NULL) {
     1829    *FirstParameter = CHAR_NULL;
     1830  }
     1831
     1832  FirstParameter = NULL;
     1833
     1834  //
     1835  // Process the command line
     1836  //
     1837  Status = ProcessCommandLineToFinal(&Temp);
     1838
     1839  if (!EFI_ERROR(Status)) {
     1840    FirstParameter = AllocateZeroPool(StrSize(CmdLine));
     1841    if (FirstParameter == NULL) {
     1842      SHELL_FREE_NON_NULL(Temp);
     1843      return (EFI_OUT_OF_RESOURCES);
     1844    }
     1845    TempWalker = (CHAR16*)Temp;
     1846    if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)))) {
     1847      if (GetOperationType(FirstParameter) == Unknown_Invalid) {
     1848        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
     1849        SetLastError(SHELL_NOT_FOUND);
     1850        Status = EFI_NOT_FOUND;
     1851      }
     1852    }
     1853  }
     1854
     1855  SHELL_FREE_NON_NULL(Temp);
     1856  SHELL_FREE_NON_NULL(FirstParameter);
     1857  return Status;
     1858}
     1859
     1860/**
     1861  Determine if a command line contains with a split contains only valid commands.
    12961862
    12971863  @param[in] CmdLine      The command line to parse.
     1864
     1865  @retval EFI_SUCCESS     CmdLine has only valid commands, application, or has no split.
     1866  @retval EFI_ABORTED     CmdLine has at least one invalid command or application.
     1867**/
     1868EFI_STATUS
     1869EFIAPI
     1870VerifySplit(
     1871  IN CONST CHAR16 *CmdLine
     1872  )
     1873{
     1874  CONST CHAR16  *TempSpot;
     1875  EFI_STATUS    Status;
     1876
     1877  //
     1878  // Verify up to the pipe or end character
     1879  //
     1880  Status = IsValidSplit(CmdLine);
     1881  if (EFI_ERROR(Status)) {
     1882    return (Status);
     1883  }
     1884
     1885  //
     1886  // If this was the only item, then get out
     1887  //
     1888  if (!ContainsSplit(CmdLine)) {
     1889    return (EFI_SUCCESS);
     1890  }
     1891
     1892  //
     1893  // recurse to verify the next item
     1894  //
     1895  TempSpot = FindFirstCharacter(CmdLine, L"|", L'^') + 1;
     1896  return (VerifySplit(TempSpot));
     1897}
     1898
     1899/**
     1900  Process a split based operation.
     1901
     1902  @param[in] CmdLine    pointer to the command line to process
     1903
     1904  @retval EFI_SUCCESS   The operation was successful
     1905  @return               an error occured.
     1906**/
     1907EFI_STATUS
     1908EFIAPI
     1909ProcessNewSplitCommandLine(
     1910  IN CONST CHAR16 *CmdLine
     1911  )
     1912{
     1913  SPLIT_LIST                *Split;
     1914  EFI_STATUS                Status;
     1915
     1916  Status = VerifySplit(CmdLine);
     1917  if (EFI_ERROR(Status)) {
     1918    return (Status);
     1919  }
     1920
     1921  Split = NULL;
     1922
     1923  //
     1924  // are we in an existing split???
     1925  //
     1926  if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
     1927    Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
     1928  }
     1929
     1930  if (Split == NULL) {
     1931    Status = RunSplitCommand(CmdLine, NULL, NULL);
     1932  } else {
     1933    Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);
     1934  }
     1935  if (EFI_ERROR(Status)) {
     1936    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);
     1937  }
     1938  return (Status);
     1939}
     1940
     1941/**
     1942  Handle a request to change the current file system.
     1943
     1944  @param[in] CmdLine  The passed in command line.
     1945
     1946  @retval EFI_SUCCESS The operation was successful.
     1947**/
     1948EFI_STATUS
     1949EFIAPI
     1950ChangeMappedDrive(
     1951  IN CONST CHAR16 *CmdLine
     1952  )
     1953{
     1954  EFI_STATUS Status;
     1955  Status = EFI_SUCCESS;
     1956
     1957  //
     1958  // make sure we are the right operation
     1959  //
     1960  ASSERT(CmdLine[(StrLen(CmdLine)-1)] == L':' && StrStr(CmdLine, L" ") == NULL);
     1961 
     1962  //
     1963  // Call the protocol API to do the work
     1964  //
     1965  Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, CmdLine);
     1966
     1967  //
     1968  // Report any errors
     1969  //
     1970  if (EFI_ERROR(Status)) {
     1971    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, CmdLine);
     1972  }
     1973
     1974  return (Status);
     1975}
     1976
     1977/**
     1978  Reprocess the command line to direct all -? to the help command.
     1979
     1980  if found, will add "help" as argv[0], and move the rest later.
     1981
     1982  @param[in,out] CmdLine        pointer to the command line to update
     1983**/
     1984EFI_STATUS
     1985EFIAPI
     1986DoHelpUpdate(
     1987  IN OUT CHAR16 **CmdLine
     1988  )
     1989{
     1990  CHAR16 *CurrentParameter;
     1991  CHAR16 *Walker;
     1992  CHAR16 *LastWalker;
     1993  CHAR16 *NewCommandLine;
     1994  EFI_STATUS Status;
     1995
     1996  Status = EFI_SUCCESS;
     1997
     1998  CurrentParameter = AllocateZeroPool(StrSize(*CmdLine));
     1999  if (CurrentParameter == NULL) {
     2000    return (EFI_OUT_OF_RESOURCES);
     2001  }
     2002
     2003  Walker = *CmdLine;
     2004  while(Walker != NULL && *Walker != CHAR_NULL) {
     2005    LastWalker = Walker;
     2006    if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)))) {
     2007      if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {
     2008        LastWalker[0] = L' ';
     2009        LastWalker[1] = L' ';
     2010        NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));
     2011        if (NewCommandLine == NULL) {
     2012          Status = EFI_OUT_OF_RESOURCES;
     2013          break;
     2014        }
     2015
     2016        //
     2017        // We know the space is sufficient since we just calculated it.
     2018        //
     2019        StrnCpy(NewCommandLine, L"help ", 5);
     2020        StrnCat(NewCommandLine, *CmdLine, StrLen(*CmdLine));
     2021        SHELL_FREE_NON_NULL(*CmdLine);
     2022        *CmdLine = NewCommandLine;
     2023        break;
     2024      }
     2025    }
     2026  }
     2027
     2028  SHELL_FREE_NON_NULL(CurrentParameter);
     2029
     2030  return (Status);
     2031}
     2032
     2033/**
     2034  Function to update the shell variable "lasterror".
     2035
     2036  @param[in] ErrorCode      the error code to put into lasterror.
     2037**/
     2038EFI_STATUS
     2039EFIAPI
     2040SetLastError(
     2041  IN CONST SHELL_STATUS   ErrorCode
     2042  )
     2043{
     2044  CHAR16 LeString[19];
     2045  if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
     2046    UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ErrorCode);
     2047  } else {
     2048    UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", ErrorCode);
     2049  }
     2050  DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
     2051  InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
     2052
     2053  return (EFI_SUCCESS);
     2054}
     2055
     2056/**
     2057  Converts the command line to it's post-processed form.  this replaces variables and alias' per UEFI Shell spec.
     2058
     2059  @param[in,out] CmdLine        pointer to the command line to update
     2060
     2061  @retval EFI_SUCCESS           The operation was successful
     2062  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
     2063  @return                       some other error occured
     2064**/
     2065EFI_STATUS
     2066EFIAPI
     2067ProcessCommandLineToFinal(
     2068  IN OUT CHAR16 **CmdLine
     2069  )
     2070{
     2071  EFI_STATUS                Status;
     2072  TrimSpaces(CmdLine);
     2073
     2074  Status = ShellSubstituteAliases(CmdLine);
     2075  if (EFI_ERROR(Status)) {
     2076    return (Status);
     2077  }
     2078
     2079  TrimSpaces(CmdLine);
     2080
     2081  Status = ShellSubstituteVariables(CmdLine);
     2082  if (EFI_ERROR(Status)) {
     2083    return (Status);
     2084  }
     2085  ASSERT (*CmdLine != NULL);
     2086
     2087  TrimSpaces(CmdLine);
     2088
     2089  //
     2090  // update for help parsing
     2091  //
     2092  if (StrStr(*CmdLine, L"?") != NULL) {
     2093    //
     2094    // This may do nothing if the ? does not indicate help.
     2095    // Save all the details for in the API below.
     2096    //
     2097    Status = DoHelpUpdate(CmdLine);
     2098  }
     2099
     2100  TrimSpaces(CmdLine);
     2101
     2102  return (EFI_SUCCESS);
     2103}
     2104
     2105/**
     2106  Run an internal shell command.
     2107
     2108  This API will upadate the shell's environment since these commands are libraries.
     2109 
     2110  @param[in] CmdLine          the command line to run.
     2111  @param[in] FirstParameter   the first parameter on the command line
     2112  @param[in] ParamProtocol    the shell parameters protocol pointer
    12982113
    12992114  @retval EFI_SUCCESS     The command was completed.
     
    13022117EFI_STATUS
    13032118EFIAPI
    1304 RunCommand(
    1305   IN CONST CHAR16   *CmdLine
    1306   )
     2119RunInternalCommand(
     2120  IN CONST CHAR16                   *CmdLine,
     2121  IN       CHAR16                   *FirstParameter,
     2122  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2123)
    13072124{
    13082125  EFI_STATUS                Status;
    1309   CHAR16                    *CommandName;
    1310   SHELL_STATUS              ShellStatus;
    13112126  UINTN                     Argc;
    13122127  CHAR16                    **Argv;
     2128  SHELL_STATUS              CommandReturnedStatus;
    13132129  BOOLEAN                   LastError;
    1314   CHAR16                    LeString[11];
    1315   CHAR16                    *PostAliasCmdLine;
    1316   UINTN                     PostAliasSize;
    1317   CHAR16                    *PostVariableCmdLine;
     2130  CHAR16                    *Walker;
     2131  CHAR16                    *NewCmdLine; 
     2132
     2133  NewCmdLine = AllocateCopyPool (StrSize (CmdLine), CmdLine);
     2134  if (NewCmdLine == NULL) {
     2135    return EFI_OUT_OF_RESOURCES;
     2136  }
     2137
     2138  for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL ; Walker++) {
     2139    if (*Walker == L'^' && *(Walker+1) == L'#') {
     2140      CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0]));
     2141    }
     2142  }
     2143
     2144  //
     2145  // get the argc and argv updated for internal commands
     2146  //
     2147  Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, &Argv, &Argc);
     2148  if (!EFI_ERROR(Status)) {
     2149    //
     2150    // Run the internal command.
     2151    //
     2152    Status = ShellCommandRunCommandHandler(FirstParameter, &CommandReturnedStatus, &LastError);
     2153
     2154    if (!EFI_ERROR(Status)) {
     2155      //
     2156      // Update last error status.
     2157      // some commands do not update last error.
     2158      //
     2159      if (LastError) {
     2160        SetLastError(CommandReturnedStatus);
     2161      }
     2162
     2163      //
     2164      // Pass thru the exitcode from the app.
     2165      //
     2166      if (ShellCommandGetExit()) {
     2167        //
     2168        // An Exit was requested ("exit" command), pass its value up.
     2169        //
     2170        Status = CommandReturnedStatus;
     2171      } else if (CommandReturnedStatus != SHELL_SUCCESS && IsScriptOnlyCommand(FirstParameter)) {
     2172        //
     2173        // Always abort when a script only command fails for any reason
     2174        //
     2175        Status = EFI_ABORTED;
     2176      } else if (ShellCommandGetCurrentScriptFile() != NULL && CommandReturnedStatus == SHELL_ABORTED) {
     2177        //
     2178        // Abort when in a script and a command aborted
     2179        //
     2180        Status = EFI_ABORTED;
     2181      }
     2182    }
     2183  }
     2184
     2185  //
     2186  // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
     2187  // This is safe even if the update API failed.  In this case, it may be a no-op.
     2188  //
     2189  RestoreArgcArgv(ParamProtocol, &Argv, &Argc);
     2190
     2191  //
     2192  // If a script is running and the command is not a scipt only command, then
     2193  // change return value to success so the script won't halt (unless aborted).
     2194  //
     2195  // Script only commands have to be able halt the script since the script will
     2196  // not operate if they are failing.
     2197  //
     2198  if ( ShellCommandGetCurrentScriptFile() != NULL
     2199    && !IsScriptOnlyCommand(FirstParameter)
     2200    && Status != EFI_ABORTED
     2201    ) {
     2202    Status = EFI_SUCCESS;
     2203  }
     2204
     2205  FreePool (NewCmdLine);
     2206  return (Status);
     2207}
     2208
     2209/**
     2210  Function to run the command or file.
     2211
     2212  @param[in] Type             the type of operation being run.
     2213  @param[in] CmdLine          the command line to run.
     2214  @param[in] FirstParameter   the first parameter on the command line
     2215  @param[in] ParamProtocol    the shell parameters protocol pointer
     2216
     2217  @retval EFI_SUCCESS     The command was completed.
     2218  @retval EFI_ABORTED     The command's operation was aborted.
     2219**/
     2220EFI_STATUS
     2221EFIAPI
     2222RunCommandOrFile(
     2223  IN       SHELL_OPERATION_TYPES    Type,
     2224  IN CONST CHAR16                   *CmdLine,
     2225  IN       CHAR16                   *FirstParameter,
     2226  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2227)
     2228{
     2229  EFI_STATUS                Status;
     2230  EFI_STATUS                StartStatus;
    13182231  CHAR16                    *CommandWithPath;
    1319   CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath;
    1320   CONST CHAR16              *TempLocation;
    1321   CONST CHAR16              *TempLocation2;
     2232  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
     2233  SHELL_STATUS              CalleeExitStatus;
     2234
     2235  Status            = EFI_SUCCESS;
     2236  CommandWithPath   = NULL;
     2237  DevPath           = NULL;
     2238  CalleeExitStatus  = SHELL_INVALID_PARAMETER;
     2239
     2240  switch (Type) {
     2241    case   Internal_Command:
     2242      Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);
     2243      break;
     2244    case   Script_File_Name:
     2245    case   Efi_Application:
     2246      //
     2247      // Process a fully qualified path
     2248      //
     2249      if (StrStr(FirstParameter, L":") != NULL) {
     2250        ASSERT (CommandWithPath == NULL);
     2251        if (ShellIsFile(FirstParameter) == EFI_SUCCESS) {
     2252          CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, FirstParameter, 0);
     2253        }
     2254      }
     2255
     2256      //
     2257      // Process a relative path and also check in the path environment variable
     2258      //
     2259      if (CommandWithPath == NULL) {
     2260        CommandWithPath = ShellFindFilePathEx(FirstParameter, mExecutableExtensions);
     2261      }
     2262
     2263      //
     2264      // This should be impossible now.
     2265      //
     2266      ASSERT(CommandWithPath != NULL);
     2267
     2268      //
     2269      // Make sure that path is not just a directory (or not found)
     2270      //
     2271      if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) {
     2272        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
     2273        SetLastError(SHELL_NOT_FOUND);
     2274      }
     2275      switch (Type) {
     2276        case   Script_File_Name:
     2277          Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);
     2278          break;
     2279        case   Efi_Application:
     2280          //
     2281          // Get the device path of the application image
     2282          //
     2283          DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);
     2284          if (DevPath == NULL){
     2285            Status = EFI_OUT_OF_RESOURCES;
     2286            break;
     2287          }
     2288
     2289          //
     2290          // Execute the device path
     2291          //
     2292          Status = InternalShellExecuteDevicePath(
     2293            &gImageHandle,
     2294            DevPath,
     2295            CmdLine,
     2296            NULL,
     2297            &StartStatus
     2298           );
     2299
     2300          SHELL_FREE_NON_NULL(DevPath);
     2301
     2302          if(EFI_ERROR (Status)) {
     2303            CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT));
     2304          } else {
     2305            CalleeExitStatus = (SHELL_STATUS) StartStatus;
     2306          }
     2307
     2308          //
     2309          // Update last error status.
     2310          //
     2311          // Status is an EFI_STATUS. Clear top bit to convert to SHELL_STATUS
     2312          SetLastError(CalleeExitStatus);
     2313          break;
     2314        default:
     2315          //
     2316          // Do nothing.
     2317          //
     2318          break;
     2319      }
     2320      break;
     2321    default:
     2322      //
     2323      // Do nothing.
     2324      //
     2325      break;
     2326  }
     2327
     2328  SHELL_FREE_NON_NULL(CommandWithPath);
     2329
     2330  return (Status);
     2331}
     2332
     2333/**
     2334  Function to setup StdIn, StdErr, StdOut, and then run the command or file.
     2335
     2336  @param[in] Type             the type of operation being run.
     2337  @param[in] CmdLine          the command line to run.
     2338  @param[in] FirstParameter   the first parameter on the command line.
     2339  @param[in] ParamProtocol    the shell parameters protocol pointer
     2340
     2341  @retval EFI_SUCCESS     The command was completed.
     2342  @retval EFI_ABORTED     The command's operation was aborted.
     2343**/
     2344EFI_STATUS
     2345EFIAPI
     2346SetupAndRunCommandOrFile(
     2347  IN SHELL_OPERATION_TYPES          Type,
     2348  IN CHAR16                         *CmdLine,
     2349  IN CHAR16                         *FirstParameter,
     2350  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     2351)
     2352{
     2353  EFI_STATUS                Status;
    13222354  SHELL_FILE_HANDLE         OriginalStdIn;
    13232355  SHELL_FILE_HANDLE         OriginalStdOut;
    13242356  SHELL_FILE_HANDLE         OriginalStdErr;
    13252357  SYSTEM_TABLE_INFO         OriginalSystemTableInfo;
    1326   CHAR16                    *TempLocation3;
    1327   UINTN                     Count;
    1328   UINTN                     Count2;
     2358
     2359  //
     2360  // Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII
     2361  //
     2362  Status = UpdateStdInStdOutStdErr(ParamProtocol, CmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
     2363
     2364  //
     2365  // The StdIn, StdOut, and StdErr are set up.
     2366  // Now run the command, script, or application
     2367  //
     2368  if (!EFI_ERROR(Status)) {
     2369    TrimSpaces(&CmdLine);
     2370    Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);
     2371  }
     2372
     2373  //
     2374  // Now print errors
     2375  //
     2376  if (EFI_ERROR(Status)) {
     2377    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
     2378  }
     2379
     2380  //
     2381  // put back the original StdIn, StdOut, and StdErr
     2382  //
     2383  RestoreStdInStdOutStdErr(ParamProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
     2384
     2385  return (Status);
     2386}
     2387
     2388/**
     2389  Function will process and run a command line.
     2390
     2391  This will determine if the command line represents an internal shell
     2392  command or dispatch an external application.
     2393
     2394  @param[in] CmdLine      The command line to parse.
     2395
     2396  @retval EFI_SUCCESS     The command was completed.
     2397  @retval EFI_ABORTED     The command's operation was aborted.
     2398**/
     2399EFI_STATUS
     2400EFIAPI
     2401RunCommand(
     2402  IN CONST CHAR16   *CmdLine
     2403  )
     2404{
     2405  EFI_STATUS                Status;
    13292406  CHAR16                    *CleanOriginal;
    1330   SPLIT_LIST                *Split;
     2407  CHAR16                    *FirstParameter;
     2408  CHAR16                    *TempWalker;
     2409  SHELL_OPERATION_TYPES     Type;
    13312410
    13322411  ASSERT(CmdLine != NULL);
     
    13352414  }
    13362415
    1337   CommandName         = NULL;
    1338   PostVariableCmdLine = NULL;
    1339   PostAliasCmdLine    = NULL;
    1340   CommandWithPath     = NULL;
    1341   DevPath             = NULL;
    13422416  Status              = EFI_SUCCESS;
    13432417  CleanOriginal       = NULL;
    1344   Split               = NULL;
    13452418
    13462419  CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0);
     
    13482421    return (EFI_OUT_OF_RESOURCES);
    13492422  }
    1350   while (CleanOriginal[StrLen(CleanOriginal)-1] == L' ') {
    1351     CleanOriginal[StrLen(CleanOriginal)-1] = CHAR_NULL;
    1352   }
    1353   while (CleanOriginal[0] == L' ') {
    1354     CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));
    1355   }
    1356 
    1357   CommandName = NULL;
    1358   if (StrStr(CleanOriginal, L" ") == NULL){
    1359     StrnCatGrow(&CommandName, NULL, CleanOriginal, 0);
     2423
     2424  TrimSpaces(&CleanOriginal);
     2425
     2426  //
     2427  // NULL out comments (leveraged from RunScriptFileHandle() ).
     2428  // The # character on a line is used to denote that all characters on the same line
     2429  // 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 '#'.
     2431  //
     2432  for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) {
     2433    if (*TempWalker == L'^') {
     2434      if (*(TempWalker + 1) == L'#') {
     2435        TempWalker++;
     2436      }
     2437    } else if (*TempWalker == L'#') {
     2438      *TempWalker = CHAR_NULL;
     2439    }
     2440  }
     2441
     2442  TrimSpaces(&CleanOriginal);
     2443
     2444  //
     2445  // Handle case that passed in command line is just 1 or more " " characters.
     2446  //
     2447  if (StrLen (CleanOriginal) == 0) {
     2448    SHELL_FREE_NON_NULL(CleanOriginal);
     2449    return (EFI_SUCCESS);
     2450  }
     2451
     2452  Status = ProcessCommandLineToFinal(&CleanOriginal);
     2453  if (EFI_ERROR(Status)) {
     2454    SHELL_FREE_NON_NULL(CleanOriginal);
     2455    return (Status);
     2456  }
     2457
     2458  //
     2459  // We dont do normal processing with a split command line (output from one command input to another)
     2460  //
     2461  if (ContainsSplit(CleanOriginal)) {
     2462    Status = ProcessNewSplitCommandLine(CleanOriginal);
     2463    SHELL_FREE_NON_NULL(CleanOriginal);
     2464    return (Status);
     2465  }
     2466
     2467  //
     2468  // We need the first parameter information so we can determine the operation type
     2469  //
     2470  FirstParameter = AllocateZeroPool(StrSize(CleanOriginal));
     2471  if (FirstParameter == NULL) {
     2472    SHELL_FREE_NON_NULL(CleanOriginal);
     2473    return (EFI_OUT_OF_RESOURCES);
     2474  }
     2475  TempWalker = CleanOriginal;
     2476  if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)))) {
     2477    //
     2478    // Depending on the first parameter we change the behavior
     2479    //
     2480    switch (Type = GetOperationType(FirstParameter)) {
     2481      case   File_Sys_Change:
     2482        Status = ChangeMappedDrive (FirstParameter);
     2483        break;
     2484      case   Internal_Command:
     2485      case   Script_File_Name:
     2486      case   Efi_Application:
     2487        Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);
     2488        break;
     2489      default:
     2490        //
     2491        // Whatever was typed, it was invalid.
     2492        //
     2493        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
     2494        SetLastError(SHELL_NOT_FOUND);
     2495        break;
     2496    }
    13602497  } else {
    1361     StrnCatGrow(&CommandName, NULL, CleanOriginal, StrStr(CleanOriginal, L" ") - CleanOriginal);
    1362   }
    1363 
    1364   ASSERT(PostAliasCmdLine == NULL);
    1365   if (!ShellCommandIsCommandOnList(CommandName)) {
    1366     //
    1367     // Convert via alias
    1368     //
    1369     Status = ShellConvertAlias(&CommandName);
    1370     PostAliasSize = 0;
    1371     PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, CommandName, 0);
    1372     PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, StrStr(CleanOriginal, L" "), 0);
    1373     ASSERT_EFI_ERROR(Status);
    1374   } else {
    1375     PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, NULL, CleanOriginal, 0);
    1376   }
    1377 
    1378   if (CleanOriginal != NULL) {
    1379     FreePool(CleanOriginal);
    1380     CleanOriginal = NULL;
    1381   }
    1382 
    1383   if (CommandName != NULL) {
    1384     FreePool(CommandName);
    1385     CommandName = NULL;
    1386   }
    1387 
    1388   PostVariableCmdLine = ShellConvertVariables(PostAliasCmdLine);
    1389 
    1390   //
    1391   // we can now free the modified by alias command line
    1392   //
    1393   if (PostAliasCmdLine != NULL) {
    1394     FreePool(PostAliasCmdLine);
    1395     PostAliasCmdLine = NULL;
    1396   }
    1397 
    1398   if (PostVariableCmdLine == NULL) {
    1399     return (EFI_OUT_OF_RESOURCES);
    1400   }
    1401 
    1402   while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
    1403     PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
    1404   }
    1405   while (PostVariableCmdLine[0] == L' ') {
    1406     CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
    1407   }
    1408 
    1409   //
    1410   // We dont do normal processing with a split command line (output from one command input to another)
    1411   //
    1412   TempLocation3 = NULL;
    1413   if (StrStr(PostVariableCmdLine, L"|") != NULL) {
    1414     for (TempLocation3 = PostVariableCmdLine ; TempLocation3 != NULL && *TempLocation3 != CHAR_NULL ; TempLocation3++) {
    1415       if (*TempLocation3 == L'^' && *(TempLocation3+1) == L'|') {
    1416         TempLocation3++;
    1417       } else if (*TempLocation3 == L'|') {
    1418         break;
    1419       }
    1420     }
    1421   }
    1422   if (TempLocation3 != NULL && *TempLocation3 != CHAR_NULL) {
    1423     //
    1424     // are we in an existing split???
    1425     //
    1426     if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
    1427       Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
    1428     }
    1429 
    1430     if (Split == NULL) {
    1431       Status = RunSplitCommand(PostVariableCmdLine, NULL, NULL);
    1432     } else {
    1433       Status = RunSplitCommand(PostVariableCmdLine, Split->SplitStdIn, Split->SplitStdOut);
    1434     }
    1435   } else {
    1436 
    1437     //
    1438     // If this is a mapped drive change handle that...
    1439     //
    1440     if (PostVariableCmdLine[(StrLen(PostVariableCmdLine)-1)] == L':' && StrStr(PostVariableCmdLine, L" ") == NULL) {
    1441       Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, PostVariableCmdLine);
    1442       if (EFI_ERROR(Status)) {
    1443         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, PostVariableCmdLine);
    1444       }
    1445       FreePool(PostVariableCmdLine);
    1446       return (Status);
    1447     }
    1448 
    1449     ///@todo update this section to divide into 3 ways - run internal command, run split (above), and run an external file...
    1450     ///      We waste a lot of time doing processing like StdIn,StdOut,Argv,Argc for things that are external files...
    1451 
    1452 
    1453 
    1454     Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
    1455     if (EFI_ERROR(Status)) {
    1456       if (Status == EFI_NOT_FOUND) {
    1457         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
    1458       } else {
    1459         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
    1460       }
    1461     } else {
    1462       while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
    1463         PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
    1464       }
    1465       while (PostVariableCmdLine[0] == L' ') {
    1466         CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
    1467       }
    1468 
    1469       //
    1470       // get the argc and argv updated for internal commands
    1471       //
    1472       Status = UpdateArgcArgv(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &Argv, &Argc);
    1473       ASSERT_EFI_ERROR(Status);
    1474 
    1475       for (Count = 0 ; Count < ShellInfoObject.NewShellParametersProtocol->Argc ; Count++) {
    1476         if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[Count], L"-?") == ShellInfoObject.NewShellParametersProtocol->Argv[Count]
    1477         ||  (ShellInfoObject.NewShellParametersProtocol->Argv[0][0] == L'?' && ShellInfoObject.NewShellParametersProtocol->Argv[0][1] == CHAR_NULL)
    1478           ) {
    1479           //
    1480           // We need to redo the arguments since a parameter was -?
    1481           // move them all down 1 to the end, then up one then replace the first with help
    1482           //
    1483           FreePool(ShellInfoObject.NewShellParametersProtocol->Argv[Count]);
    1484           ShellInfoObject.NewShellParametersProtocol->Argv[Count] = NULL;
    1485           for (Count2 = Count ; (Count2 + 1) < ShellInfoObject.NewShellParametersProtocol->Argc ; Count2++) {
    1486             ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2+1];
    1487           }
    1488           ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = NULL;
    1489           for (Count2 = ShellInfoObject.NewShellParametersProtocol->Argc -1 ; Count2 > 0 ; Count2--) {
    1490             ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2-1];
    1491           }
    1492           ShellInfoObject.NewShellParametersProtocol->Argv[0] = NULL;
    1493           ShellInfoObject.NewShellParametersProtocol->Argv[0] = StrnCatGrow(&ShellInfoObject.NewShellParametersProtocol->Argv[0], NULL, L"help", 0);
    1494           break;
    1495         }
    1496       }
    1497 
    1498       //
    1499       // command or file?
    1500       //
    1501       if (ShellCommandIsCommandOnList(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
    1502         //
    1503         // Run the command (which was converted if it was an alias)
    1504         //
    1505         if (!EFI_ERROR(Status))  {
    1506           Status = ShellCommandRunCommandHandler(ShellInfoObject.NewShellParametersProtocol->Argv[0], &ShellStatus, &LastError);
    1507           ASSERT_EFI_ERROR(Status);
    1508           UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%08x", ShellStatus);
    1509           DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
    1510           if (LastError) {
    1511             InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
    1512           }
    1513           //
    1514           // Pass thru the exitcode from the app.
    1515           //
    1516           if (ShellCommandGetExit()) {
    1517             Status = ShellStatus;
    1518           } else if (ShellStatus != 0 && IsScriptOnlyCommand(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
    1519             Status = EFI_ABORTED;
    1520           }
    1521         }
    1522       } else {
    1523         //
    1524         // run an external file (or script)
    1525         //
    1526         if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[0], L":") != NULL) {
    1527           ASSERT (CommandWithPath == NULL);
    1528           if (ShellIsFile(ShellInfoObject.NewShellParametersProtocol->Argv[0]) == EFI_SUCCESS) {
    1529             CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
    1530           }
    1531         }
    1532         if (CommandWithPath == NULL) {
    1533           CommandWithPath = ShellFindFilePathEx(ShellInfoObject.NewShellParametersProtocol->Argv[0], mExecutableExtensions);
    1534         }
    1535         if (CommandWithPath == NULL || ShellIsDirectory(CommandWithPath) == EFI_SUCCESS) {
    1536           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, ShellInfoObject.NewShellParametersProtocol->Argv[0]);
    1537         } else {
    1538           //
    1539           // Check if it's a NSH (script) file.
    1540           //
    1541           TempLocation = CommandWithPath+StrLen(CommandWithPath)-4;
    1542           TempLocation2 = mScriptExtension;
    1543           if ((StrLen(CommandWithPath) > 4) && (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0)) {
    1544             Status = RunScriptFile (CommandWithPath);
    1545           } else {
    1546             DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);
    1547             ASSERT(DevPath != NULL);
    1548             Status = InternalShellExecuteDevicePath(
    1549               &gImageHandle,
    1550               DevPath,
    1551               PostVariableCmdLine,
    1552               NULL,
    1553               NULL
    1554              );
    1555           }
    1556         }
    1557       }
    1558       CommandName = StrnCatGrow(&CommandName, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
    1559 
    1560       RestoreArgcArgv(ShellInfoObject.NewShellParametersProtocol, &Argv, &Argc);
    1561 
    1562       RestoreStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
    1563     }
    1564     if (CommandName != NULL) {
    1565       if (ShellCommandGetCurrentScriptFile() != NULL &&  !IsScriptOnlyCommand(CommandName)) {
    1566         //
    1567         // if this is NOT a scipt only command return success so the script won't quit.
    1568         // prevent killing the script - this is the only place where we know the actual command name (after alias and variable replacement...)
    1569         //
    1570         Status = EFI_SUCCESS;
    1571       }
    1572     }
    1573   }
    1574 
    1575   SHELL_FREE_NON_NULL(CommandName);
    1576   SHELL_FREE_NON_NULL(CommandWithPath);
    1577   SHELL_FREE_NON_NULL(PostVariableCmdLine);
     2498    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
     2499    SetLastError(SHELL_NOT_FOUND);
     2500  }
     2501 
     2502  SHELL_FREE_NON_NULL(CleanOriginal);
     2503  SHELL_FREE_NON_NULL(FirstParameter);
    15782504
    15792505  return (Status);
     
    16922618    CommandLine = ShellFileHandleReturnLine(Handle, &Ascii);
    16932619    LineCount++;
    1694     if (CommandLine == NULL || StrLen(CommandLine) == 0) {
     2620    if (CommandLine == NULL || StrLen(CommandLine) == 0 || CommandLine[0] == '#') {
     2621      SHELL_FREE_NON_NULL(CommandLine);
    16952622      continue;
    16962623    }
    16972624    NewScriptFile->CurrentCommand = AllocateZeroPool(sizeof(SCRIPT_COMMAND_LIST));
    16982625    if (NewScriptFile->CurrentCommand == NULL) {
     2626      SHELL_FREE_NON_NULL(CommandLine);
    16992627      DeleteScriptFileStruct(NewScriptFile);
    17002628      return (EFI_OUT_OF_RESOURCES);
     
    17332661  ){
    17342662    ASSERT(CommandLine2 != NULL);
    1735     StrCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl);
     2663    StrnCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
    17362664
    17372665    //
     
    17402668    for (CommandLine3 = CommandLine2 ; CommandLine3 != NULL && *CommandLine3 != CHAR_NULL ; CommandLine3++) {
    17412669      if (*CommandLine3 == L'^') {
    1742         if (*(CommandLine3+1) == L'#' || *(CommandLine3+1) == L':') {
     2670        if ( *(CommandLine3+1) == L':') {
    17432671          CopyMem(CommandLine3, CommandLine3+1, StrSize(CommandLine3) - sizeof(CommandLine3[0]));
     2672        } else if (*(CommandLine3+1) == L'#') {
     2673          CommandLine3++;
    17442674        }
    17452675      } else if (*CommandLine3 == L'#') {
     
    17522682      // Due to variability in starting the find and replace action we need to have both buffers the same.
    17532683      //
    1754       StrCpy(CommandLine, CommandLine2);
     2684      StrnCpy(CommandLine, CommandLine2, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
    17552685
    17562686      //
     
    18042734      Status = ShellCopySearchAndReplace(CommandLine2,  CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE);
    18052735
    1806       StrCpy(CommandLine2, CommandLine);
     2736      StrnCpy(CommandLine2, CommandLine, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
    18072737
    18082738      LastCommand = NewScriptFile->CurrentCommand;
     
    18262756
    18272757            //
    1828             // Now restore the pre-'@' echo state.
     2758            // If command was "@echo -off" or "@echo -on" then don't restore echo state
    18292759            //
    1830             ShellCommandSetEchoState(PreCommandEchoState);
     2760            if (StrCmp (L"@echo -off", CommandLine3) != 0 &&
     2761                StrCmp (L"@echo -on", CommandLine3) != 0) {
     2762              //
     2763              // Now restore the pre-'@' echo state.
     2764              //
     2765              ShellCommandSetEchoState(PreCommandEchoState);
     2766            }
    18312767          } else {
    18322768            if (ShellCommandGetEchoState()) {
     
    18442780
    18452781        if (ShellCommandGetScriptExit()) {
    1846           UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%Lx", ShellCommandGetExitCode());
    1847           DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
    1848           InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
     2782          //
     2783          // ShellCommandGetExitCode() always returns a UINT64
     2784          //
     2785          UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());
     2786          DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
     2787          InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
    18492788
    18502789          ShellCommandRegisterExit(FALSE, 0);
    18512790          Status = EFI_SUCCESS;
     2791          break;
     2792        }
     2793        if (ShellGetExecutionBreakFlag()) {
    18522794          break;
    18532795        }
     
    18942836
    18952837  @param[in] ScriptPath         Pointer to the script file name (including file system path).
     2838  @param[in] Handle             the handle of the script file already opened.
     2839  @param[in] CmdLine            the command line to run.
     2840  @param[in] ParamProtocol      the shell parameters protocol pointer
    18962841
    18972842  @retval EFI_SUCCESS           the script completed sucessfully
     
    19002845EFIAPI
    19012846RunScriptFile (
    1902   IN CONST CHAR16 *ScriptPath
     2847  IN CONST CHAR16                   *ScriptPath,
     2848  IN SHELL_FILE_HANDLE              Handle OPTIONAL,
     2849  IN CONST CHAR16                   *CmdLine,
     2850  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
    19032851  )
    19042852{
    19052853  EFI_STATUS          Status;
    19062854  SHELL_FILE_HANDLE   FileHandle;
     2855  UINTN                     Argc;
     2856  CHAR16                    **Argv;
    19072857
    19082858  if (ShellIsFile(ScriptPath) != EFI_SUCCESS) {
     
    19102860  }
    19112861
    1912   Status = ShellOpenFileByName(ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
    1913   if (EFI_ERROR(Status)) {
    1914     return (Status);
    1915   }
    1916 
    1917   Status = RunScriptFileHandle(FileHandle, ScriptPath);
    1918 
    1919   ShellCloseFile(&FileHandle);
     2862  //
     2863  // get the argc and argv updated for scripts
     2864  //
     2865  Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
     2866  if (!EFI_ERROR(Status)) {
     2867
     2868    if (Handle == NULL) {
     2869      //
     2870      // open the file
     2871      //
     2872      Status = ShellOpenFileByName(ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
     2873      if (!EFI_ERROR(Status)) {
     2874        //
     2875        // run it
     2876        //
     2877        Status = RunScriptFileHandle(FileHandle, ScriptPath);
     2878
     2879        //
     2880        // now close the file
     2881        //
     2882        ShellCloseFile(&FileHandle);
     2883      }
     2884    } else {
     2885      Status = RunScriptFileHandle(Handle, ScriptPath);
     2886    }
     2887  }
     2888
     2889  //
     2890  // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
     2891  // This is safe even if the update API failed.  In this case, it may be a no-op.
     2892  //
     2893  RestoreArgcArgv(ParamProtocol, &Argv, &Argc);
    19202894
    19212895  return (Status);
    19222896}
     2897
     2898/**
     2899  Return the pointer to the first occurance of any character from a list of characters
     2900
     2901  @param[in] String           the string to parse
     2902  @param[in] CharacterList    the list of character to look for
     2903  @param[in] EscapeCharacter  An escape character to skip
     2904
     2905  @return the location of the first character in the string
     2906  @retval CHAR_NULL no instance of any character in CharacterList was found in String
     2907**/
     2908CONST CHAR16*
     2909EFIAPI
     2910FindFirstCharacter(
     2911  IN CONST CHAR16 *String,
     2912  IN CONST CHAR16 *CharacterList,
     2913  IN CONST CHAR16 EscapeCharacter
     2914  )
     2915{
     2916  UINT32 WalkChar;
     2917  UINT32 WalkStr;
     2918
     2919  for (WalkStr = 0; WalkStr < StrLen(String); WalkStr++) {
     2920    if (String[WalkStr] == EscapeCharacter) {
     2921      WalkStr++;
     2922      continue;
     2923    }
     2924    for (WalkChar = 0; WalkChar < StrLen(CharacterList); WalkChar++) {
     2925      if (String[WalkStr] == CharacterList[WalkChar]) {
     2926        return (&String[WalkStr]);
     2927      }
     2928    }
     2929  }
     2930  return (String + StrLen(String));
     2931}
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/Shell.h

    r48674 r58459  
    22  function definitions for internal to shell functions.
    33
    4   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4  (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
     5  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
    56  This program and the accompanying materials
    67  are licensed and made available under the terms and conditions of the BSD License
     
    2021
    2122#include <Guid/ShellVariableGuid.h>
     23#include <Guid/ShellAliasGuid.h>
    2224
    2325#include <Protocol/LoadedImage.h>
     
    4648#include <Library/HandleParsingLib.h>
    4749#include <Library/PathLib.h>
     50#include <Library/FileHandleLib.h>
    4851
    4952#include "ShellParametersProtocol.h"
     
    5356#include "ShellManParser.h"
    5457#include "ConsoleWrappers.h"
     58#include "FileHandleWrappers.h"
    5559
    5660typedef struct {
     
    6973  UINT32  NoVersion:1;    ///< Was "-noversion"     found on command line.
    7074  UINT32  Delay:1;        ///< Was "-delay[:n]      found on command line
    71   UINT32  Reserved:8;     ///< Extra bits
     75  UINT32  Exit:1;         ///< Was "-_exit"          found on command line
     76  UINT32  Reserved:7;     ///< Extra bits
    7277} SHELL_BITS;
    7378
     
    108113  SHELL_PROTOCOL_HANDLE_LIST    OldShellList;         ///< List of other instances to reinstall when closing.
    109114  SPLIT_LIST                    SplitList;            ///< List of Splits in FILO stack.
    110   EFI_HANDLE                    CtrlCNotifyHandle1;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    111   EFI_HANDLE                    CtrlCNotifyHandle2;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    112   EFI_HANDLE                    CtrlCNotifyHandle3;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    113   EFI_HANDLE                    CtrlCNotifyHandle4;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    114   EFI_HANDLE                    CtrlSNotifyHandle1;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    115   EFI_HANDLE                    CtrlSNotifyHandle2;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    116   EFI_HANDLE                    CtrlSNotifyHandle3;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    117   EFI_HANDLE                    CtrlSNotifyHandle4;   ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     115  VOID                          *CtrlCNotifyHandle1;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     116  VOID                          *CtrlCNotifyHandle2;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     117  VOID                          *CtrlCNotifyHandle3;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     118  VOID                          *CtrlCNotifyHandle4;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     119  VOID                          *CtrlSNotifyHandle1;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     120  VOID                          *CtrlSNotifyHandle2;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     121  VOID                          *CtrlSNotifyHandle3;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
     122  VOID                          *CtrlSNotifyHandle4;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
    118123  BOOLEAN                       HaltOutput;           ///< TRUE to start a CTRL-S halt.
    119124} SHELL_INFO;
    120125
    121126extern SHELL_INFO ShellInfoObject;
     127
     128typedef enum {
     129  Internal_Command,
     130  Script_File_Name,
     131  Efi_Application,
     132  File_Sys_Change,
     133  Unknown_Invalid
     134} SHELL_OPERATION_TYPES;
     135
     136/**
     137  Converts the command line to it's post-processed form.  this replaces variables and alias' per UEFI Shell spec.
     138
     139  @param[in,out] CmdLine        pointer to the command line to update
     140
     141  @retval EFI_SUCCESS           The operation was successful
     142  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
     143  @return                       some other error occured
     144**/
     145EFI_STATUS
     146EFIAPI
     147ProcessCommandLineToFinal(
     148  IN OUT CHAR16 **CmdLine
     149  );
     150
     151/**
     152  Function to update the shell variable "lasterror".
     153
     154  @param[in] ErrorCode      the error code to put into lasterror
     155**/
     156EFI_STATUS
     157EFIAPI
     158SetLastError(
     159  IN CONST SHELL_STATUS   ErrorCode
     160  );
    122161
    123162/**
     
    290329
    291330  @param[in] ScriptPath         Pointer to the script file name (including file system path).
     331  @param[in] Handle             the handle of the script file already opened.
     332  @param[in] CmdLine            the command line to run.
     333  @param[in] ParamProtocol      the shell parameters protocol pointer
    292334
    293335  @retval EFI_SUCCESS           the script completed sucessfully
     
    296338EFIAPI
    297339RunScriptFile (
    298   IN CONST CHAR16 *ScriptPath
    299   );
    300 
     340  IN CONST CHAR16                   *ScriptPath,
     341  IN SHELL_FILE_HANDLE              Handle OPTIONAL,
     342  IN CONST CHAR16                   *CmdLine,
     343  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
     344  );
     345
     346/**
     347  Return the pointer to the first occurance of any character from a list of characters
     348
     349  @param[in] String           the string to parse
     350  @param[in] CharacterList    the list of character to look for
     351  @param[in] EscapeCharacter  An escape character to skip
     352
     353  @return the location of the first character in the string
     354  @retval CHAR_NULL no instance of any character in CharacterList was found in String
     355**/
     356CONST CHAR16*
     357EFIAPI
     358FindFirstCharacter(
     359  IN CONST CHAR16 *String,
     360  IN CONST CHAR16 *CharacterList,
     361  IN CONST CHAR16 EscapeCharacter
     362  );
    301363
    302364#endif //_SHELL_INTERNAL_HEADER_
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/Shell.inf

    r48674 r58459  
    22#  This is the shell application
    33#
    4 #  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4#  Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
     5#  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
    56#
    67#  This program and the accompanying materials
     
    7374
    7475[Guids]
    75   gShellVariableGuid                                      # ALWAYS_CONSUMED
    76   gShellMapGuid                                           # ALWAYS_CONSUMED
    77   gShellAliasGuid                                         # ALWAYS_CONSUMED
     76  gShellVariableGuid                                      ## CONSUMES ## GUID
     77  gShellMapGuid                                           ## CONSUMES ## GUID
     78  gShellAliasGuid                                         ## CONSUMES ## GUID
    7879
    7980[Protocols]
    80   gEfiShellProtocolGuid                                   # ALWAYS_PRODUCED
    81                                                           # SOMETIMES_CONSUMED
    82   gEfiShellParametersProtocolGuid                         # ALWAYS_PRODUCED
    83                                                           # SOMETIMES_CONSUMED
     81  gEfiShellProtocolGuid                                   ## PRODUCES
     82                                                          ## SOMETIMES_CONSUMES
     83  gEfiShellParametersProtocolGuid                         ## PRODUCES
     84                                                          ## SOMETIMES_CONSUMES
    8485
    85 #  gEfiShellEnvironment2Guid                               # SOMETIMES_PRODUCED
    86 #  gEfiShellInterfaceGuid                                  # SOMETIMES_PRODUCED
     86#  gEfiShellEnvironment2Guid                              ## SOMETIMES_PRODUCES
     87#  gEfiShellInterfaceGuid                                 ## SOMETIMES_PRODUCES
    8788
    88   gEfiSimpleTextInputExProtocolGuid                       # ALWAYS_CONSUMED
    89   gEfiSimpleTextInProtocolGuid                            # ALWAYS_CONSUMED
    90   gEfiSimpleTextOutProtocolGuid                           # ALWAYS_CONSUMED
    91   gEfiSimpleFileSystemProtocolGuid                        # ALWAYS_CONSUMED
    92   gEfiLoadedImageProtocolGuid                             # ALWAYS_CONSUMED
    93   gEfiComponentName2ProtocolGuid                          # ALWAYS_CONSUMED
    94   gEfiUnicodeCollation2ProtocolGuid                       # ALWAYS_CONSUMED
    95   gEfiDevicePathProtocolGuid                              # ALWAYS_CONSUMED
    96   gEfiDevicePathToTextProtocolGuid                        # ALWAYS_CONSUMED
     89  gEfiSimpleTextInputExProtocolGuid                       ## CONSUMES
     90  gEfiSimpleTextInProtocolGuid                            ## CONSUMES
     91  gEfiSimpleTextOutProtocolGuid                           ## CONSUMES
     92  gEfiSimpleFileSystemProtocolGuid                        ## CONSUMES
     93  gEfiLoadedImageProtocolGuid                             ## CONSUMES
     94  gEfiComponentName2ProtocolGuid                          ## CONSUMES
     95  gEfiUnicodeCollation2ProtocolGuid                       ## CONSUMES
     96  gEfiDevicePathProtocolGuid                              ## CONSUMES
    9797
    9898[Pcd]
    99   gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel         # ALWAYS_CONSUMED
    100   gEfiShellPkgTokenSpaceGuid.PcdShellSupportOldProtocols  # ALWAYS_CONSUMED
    101   gEfiShellPkgTokenSpaceGuid.PcdShellRequireHiiPlatform   # ALWAYS_CONSUMED
    102   gEfiShellPkgTokenSpaceGuid.PcdShellSupportFrameworkHii  # ALWAYS_CONSUMED
    103   gEfiShellPkgTokenSpaceGuid.PcdShellPageBreakDefault     # ALWAYS_CONSUMED
    104   gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize    # ALWAYS_CONSUMED
    105   gEfiShellPkgTokenSpaceGuid.PcdShellInsertModeDefault    # ALWAYS_CONSUMED
    106   gEfiShellPkgTokenSpaceGuid.PcdShellScreenLogCount       # ALWAYS_CONSUMED
    107   gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength        # ALWAYS_CONSUMED
    108   gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize      # ALWAYS_CONSUMED
    109   gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole         # ALWAYS_CONSUMED
     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
    110111
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellEnvVar.c

    r48674 r58459  
    22  function declarations for shell environment functions.
    33
    4   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2009 - 2015, 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
     
    1313**/
    1414
    15 #include <Uefi.h>
    16 #include <ShellBase.h>
    17 
    18 #include <Guid/ShellVariableGuid.h>
    19 
    20 #include <Library/BaseLib.h>
    21 #include <Library/UefiRuntimeServicesTableLib.h>
    22 #include <Library/MemoryAllocationLib.h>
    23 #include <Library/DebugLib.h>
    24 #include <Library/BaseMemoryLib.h>
    25 
    26 #include "ShellEnvVar.h"
     15#include "Shell.h"
     16
     17#define INIT_NAME_BUFFER_SIZE  128
     18#define INIT_DATA_BUFFER_SIZE  1024
    2719
    2820/**
     
    10698
    10799  for ( Node = (ENV_VAR_LIST*)GetFirstNode(List)
    108       ; IsListEmpty(List)
     100      ; !IsListEmpty(List)
    109101      ; Node = (ENV_VAR_LIST*)GetFirstNode(List)
    110102     ){
     
    137129  CHAR16            *VariableName;
    138130  UINTN             NameSize;
    139   UINT64            MaxStorSize;
    140   UINT64            RemStorSize;
    141   UINT64            MaxVarSize;
     131  UINTN             NameBufferSize;
    142132  EFI_STATUS        Status;
    143133  EFI_GUID          Guid;
    144134  UINTN             ValSize;
     135  UINTN             ValBufferSize;
    145136  ENV_VAR_LIST      *VarList;
    146137
     
    148139    return (EFI_INVALID_PARAMETER);
    149140  }
    150 
    151   if (gRT->Hdr.Revision >= EFI_2_00_SYSTEM_TABLE_REVISION) {
    152     Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);
    153     if (EFI_ERROR(Status)) {
    154       return (Status);
    155     }
    156   } else {
    157     Status = EFI_SUCCESS;
    158     MaxVarSize = 16384;
    159   }
    160 
    161   NameSize = (UINTN)MaxVarSize;
    162   VariableName = AllocateZeroPool(NameSize);
     141 
     142  Status = EFI_SUCCESS;
     143 
     144  ValBufferSize = INIT_DATA_BUFFER_SIZE;
     145  NameBufferSize = INIT_NAME_BUFFER_SIZE;
     146  VariableName = AllocateZeroPool(NameBufferSize);
    163147  if (VariableName == NULL) {
    164148    return (EFI_OUT_OF_RESOURCES);
    165149  }
    166   StrCpy(VariableName, L"");
     150  *VariableName = CHAR_NULL;
    167151
    168152  while (!EFI_ERROR(Status)) {
    169     NameSize = (UINTN)MaxVarSize;
     153    NameSize = NameBufferSize;
    170154    Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
    171155    if (Status == EFI_NOT_FOUND){
    172156      Status = EFI_SUCCESS;
    173157      break;
    174     }
     158    } else if (Status == EFI_BUFFER_TOO_SMALL) {
     159      NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
     160      SHELL_FREE_NON_NULL(VariableName);
     161      VariableName = AllocateZeroPool(NameBufferSize);
     162      if (VariableName == NULL) {
     163        Status = EFI_OUT_OF_RESOURCES;
     164        break;
     165      }
     166      NameSize = NameBufferSize;
     167      Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
     168    }
     169   
    175170    if (!EFI_ERROR(Status) && CompareGuid(&Guid, &gShellVariableGuid)){
    176171      VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
     
    178173        Status = EFI_OUT_OF_RESOURCES;
    179174      } else {
    180         ValSize = 0;
     175        ValSize = ValBufferSize;
     176        VarList->Val = AllocateZeroPool(ValSize);
     177        if (VarList->Val == NULL) {
     178            SHELL_FREE_NON_NULL(VarList);
     179            Status = EFI_OUT_OF_RESOURCES;
     180            break;
     181        }
    181182        Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
    182183        if (Status == EFI_BUFFER_TOO_SMALL){
    183           VarList->Val = AllocateZeroPool(ValSize);
     184          ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2;
     185          SHELL_FREE_NON_NULL (VarList->Val);
     186          VarList->Val = AllocateZeroPool(ValBufferSize);
    184187          if (VarList->Val == NULL) {
    185188            SHELL_FREE_NON_NULL(VarList);
    186189            Status = EFI_OUT_OF_RESOURCES;
    187           } else {
    188             Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
     190            break;
    189191          }
     192         
     193          ValSize = ValBufferSize;
     194          Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
    190195        }
    191         if (!EFI_ERROR(Status) && VarList != NULL) {
    192           VarList->Key = AllocateZeroPool(StrSize(VariableName));
     196        if (!EFI_ERROR(Status)) {
     197          VarList->Key = AllocateCopyPool(StrSize(VariableName), VariableName);
    193198          if (VarList->Key == NULL) {
    194199            SHELL_FREE_NON_NULL(VarList->Val);
     
    196201            Status = EFI_OUT_OF_RESOURCES;
    197202          } else {
    198             StrCpy(VarList->Key, VariableName);
    199203            InsertTailList(ListHead, &VarList->Link);
    200204          }
     205        } else {
     206          SHELL_FREE_NON_NULL(VarList->Val);
     207          SHELL_FREE_NON_NULL(VarList);
    201208        }
    202       }
     209      } // if (VarList == NULL) ... else ...
    203210    } // compare guid
    204211  } // while
    205   FreePool(VariableName);
     212  SHELL_FREE_NON_NULL (VariableName);
    206213
    207214  if (EFI_ERROR(Status)) {
     
    298305  ENV_VAR_LIST  *VarList;
    299306  ENV_VAR_LIST  *Node;
    300   UINTN         NewSize;
    301307
    302308  VarList = NULL;
     
    319325    ASSERT(StrStr(CurrentString, L"=") != NULL);
    320326    Node = AllocateZeroPool(sizeof(ENV_VAR_LIST));
    321     ASSERT(Node != NULL);
     327    if (Node == NULL) {
     328      SetEnvironmentVariableList(&VarList->Link);
     329      return (EFI_OUT_OF_RESOURCES);
     330    }
     331
    322332    Node->Key = AllocateZeroPool((StrStr(CurrentString, L"=") - CurrentString + 1) * sizeof(CHAR16));
    323     ASSERT(Node->Key != NULL);
     333    if (Node->Key == NULL) {
     334      SHELL_FREE_NON_NULL(Node);
     335      SetEnvironmentVariableList(&VarList->Link);
     336      return (EFI_OUT_OF_RESOURCES);
     337    }
     338
     339    //
     340    // Copy the string into the Key, leaving the last character allocated as NULL to terminate
     341    //
    324342    StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);
    325     NewSize = StrSize(CurrentString);
    326     NewSize -= StrLen(Node->Key) - 1;
    327     Node->Val = AllocateZeroPool(NewSize);
    328     ASSERT(Node->Val != NULL);
    329     StrCpy(Node->Val, CurrentString + StrLen(Node->Key) + 1);
     343
     344    //
     345    // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
     346    //
     347    Node->Val = AllocateCopyPool(StrSize(CurrentString) - StrSize(Node->Key), CurrentString + StrLen(Node->Key) + 1);
     348    if (Node->Val == NULL) {
     349      SHELL_FREE_NON_NULL(Node->Key);
     350      SHELL_FREE_NON_NULL(Node);
     351      SetEnvironmentVariableList(&VarList->Link);
     352      return (EFI_OUT_OF_RESOURCES);
     353    }
     354
    330355    Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;
    331356
    332357    if (VarList == NULL) {
    333358      VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
    334       ASSERT(VarList != NULL);
     359      if (VarList == NULL) {
     360        SHELL_FREE_NON_NULL(Node->Key);
     361        SHELL_FREE_NON_NULL(Node->Val);
     362        SHELL_FREE_NON_NULL(Node);
     363        return (EFI_OUT_OF_RESOURCES);
     364      }
    335365      InitializeListHead(&VarList->Link);
    336366    }
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellManParser.c

    r48674 r58459  
    22  Provides interface to shell MAN file parser.
    33
    4   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2009 - 2014, 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
     
    4040  //
    4141  if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) {
    42     Buffer = AllocateZeroPool(StrSize(ManFileName));
    43     if (Buffer != NULL) {
    44       StrCpy(Buffer, ManFileName);
    45     }
     42    Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName);
    4643  } else {
    4744    Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));
    4845    if (Buffer != NULL) {
    49       StrCpy(Buffer, ManFileName);
    50       StrCat(Buffer, L".man");
     46      StrnCpy(Buffer, ManFileName, StrLen(ManFileName));
     47      StrnCat(Buffer, L".man", 4);
    5148    }
    5249  }
     
    375372  CHAR16        *TitleEnd;
    376373  CHAR16        *CurrentLocation;
     374  UINTN         TitleLength;
     375  CONST CHAR16  StartString[] = L".TH ";
     376  CONST CHAR16  EndString[]   = L" 0 ";
    377377
    378378  if ( Buffer     == NULL
     
    385385  Status    = EFI_SUCCESS;
    386386
    387   TitleString = AllocateZeroPool((7*sizeof(CHAR16)) + StrSize(Command));
     387  //
     388  // more characters for StartString and EndString
     389  //
     390  TitleLength = StrSize(Command) + (StrLen(StartString) + StrLen(EndString)) * sizeof(CHAR16);
     391  TitleString = AllocateZeroPool(TitleLength);
    388392  if (TitleString == NULL) {
    389393    return (EFI_OUT_OF_RESOURCES);
    390394  }
    391   StrCpy(TitleString, L".TH ");
    392   StrCat(TitleString, Command);
    393   StrCat(TitleString, L" 0 ");
     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));
    394398
    395399  CurrentLocation = StrStr(*Buffer, TitleString);
     
    468472  UINTN       TitleLen;
    469473  BOOLEAN     Found;
     474  UINTN       TitleSize;
    470475
    471476  if ( Handle     == NULL
     
    485490  }
    486491
    487   TitleString = AllocateZeroPool((4*sizeof(CHAR16)) + StrSize(Command));
     492  TitleSize = (4*sizeof(CHAR16)) + StrSize(Command);
     493  TitleString = AllocateZeroPool(TitleSize);
    488494  if (TitleString == NULL) {
    489495    FreePool(ReadLine);
    490496    return (EFI_OUT_OF_RESOURCES);
    491497  }
    492   StrCpy(TitleString, L".TH ");
    493   StrCat(TitleString, Command);
     498  StrnCpy(TitleString, L".TH ", TitleSize/sizeof(CHAR16) - 1);
     499  StrnCat(TitleString, Command, TitleSize/sizeof(CHAR16) - 1 - StrLen(TitleString));
     500
    494501  TitleLen = StrLen(TitleString);
    495502  for (;!ShellFileHandleEof(Handle);Size = 1024) {
     
    526533          break;
    527534        }
    528         StrCpy(*BriefDesc, TitleEnd);
     535        StrnCpy(*BriefDesc, TitleEnd, (*BriefSize)/sizeof(CHAR16) - 1);
    529536      }
    530537      break;
     
    599606  BriefSize   = 0;
    600607  TempString  = NULL;
     608  Ascii       = FALSE;
    601609  //
    602610  // See if it's in HII first
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellParametersProtocol.c

    r48674 r58459  
    33  manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
    44
    5   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     5  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>
    68  This program and the accompanying materials
    79  are licensed and made available under the terms and conditions of the BSD License
     
    1416**/
    1517
    16 #include "ShellParametersProtocol.h"
    17 #include "ConsoleWrappers.h"
    18 
    19 /**
    20   return the next parameter from a command line string;
     18#include "Shell.h"
     19
     20/**
     21  Return the next parameter's end from a command line string.
     22
     23  @param[in] String        the string to parse
     24**/
     25CONST CHAR16*
     26EFIAPI
     27FindEndOfParameter(
     28  IN CONST CHAR16 *String
     29  )
     30{
     31  CONST CHAR16 *First;
     32  CONST CHAR16 *CloseQuote;
     33
     34  First = FindFirstCharacter(String, L" \"", L'^');
     35
     36  //
     37  // nothing, all one parameter remaining
     38  //
     39  if (*First == CHAR_NULL) {
     40    return (First);
     41  }
     42
     43  //
     44  // If space before a quote (or neither found, i.e. both CHAR_NULL),
     45  // then that's the end.
     46  //
     47  if (*First == L' ') {
     48    return (First);
     49  }
     50
     51  CloseQuote = FindFirstCharacter (First+1, L"\"", L'^');
     52
     53  //
     54  // We did not find a terminator...
     55  //
     56  if (*CloseQuote == CHAR_NULL) {
     57    return (NULL);
     58  }
     59
     60  return (FindEndOfParameter (CloseQuote+1));
     61}
     62
     63/**
     64  Return the next parameter from a command line string.
    2165
    2266  This function moves the next parameter from Walker into TempParameter and moves
     
    2771  function.
    2872
     73  This will also remove all remaining ^ characters after processing.
     74
    2975  @param[in, out] Walker        pointer to string of command line.  Adjusted to
    3076                                reminaing command line on return
    3177  @param[in, out] TempParameter pointer to string of command line item extracted.
    32 
    33 **/
    34 VOID
     78  @param[in]      Length        buffer size of TempParameter.
     79
     80  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.
     81  @return   EFI_NOT_FOUND         A closing " could not be found on the specified string
     82**/
     83EFI_STATUS
    3584EFIAPI
    3685GetNextParameter(
    37   CHAR16 **Walker,
    38   CHAR16 **TempParameter
    39   )
    40 {
    41   CHAR16 *NextDelim;
    42   CHAR16 *TempLoc;
    43 
    44   ASSERT(Walker           != NULL);
    45   ASSERT(*Walker          != NULL);
    46   ASSERT(TempParameter    != NULL);
    47   ASSERT(*TempParameter   != NULL);
     86  IN OUT CHAR16   **Walker,
     87  IN OUT CHAR16   **TempParameter,
     88  IN CONST UINTN  Length
     89  )
     90{
     91  CONST CHAR16 *NextDelim;
     92
     93  if (Walker           == NULL
     94    ||*Walker          == NULL
     95    ||TempParameter    == NULL
     96    ||*TempParameter   == NULL
     97    ){
     98    return (EFI_INVALID_PARAMETER);
     99  }
     100
    48101
    49102  //
     
    58111  //
    59112  if (StrLen(*Walker) == 0) {
    60     ASSERT((*Walker)[0] == CHAR_NULL);
    61     *Walker = NULL;
    62     return;
    63   }
    64 
    65   //
    66   // we have a quoted parameter
    67   // could be the last parameter, but SHOULD have a trailing quote
    68   //
    69   if ((*Walker)[0] == L'\"') {
    70     NextDelim = NULL;
    71     for (TempLoc = *Walker + 1 ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
    72       if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') {
    73         TempLoc++;
    74       } else if (*TempLoc == L'\"') {
    75         NextDelim = TempLoc;
    76         break;
    77       }
    78     }
    79 
    80     if (NextDelim - ((*Walker)+1) == 0) {
    81       //
    82       // found ""
    83       //
    84       StrCpy(*TempParameter, L"");
    85       *Walker = NextDelim + 1;
    86     } else if (NextDelim != NULL) {
    87       StrnCpy(*TempParameter, (*Walker)+1, NextDelim - ((*Walker)+1));
    88       *Walker = NextDelim + 1;
    89     } else {
    90       //
    91       // last one... someone forgot the training quote!
    92       //
    93       StrCpy(*TempParameter, *Walker);
    94       *Walker = NULL;
    95     }
    96     for (TempLoc = *TempParameter ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
    97       if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') {
    98         CopyMem(TempLoc, TempLoc+1, StrSize(TempLoc) - sizeof(TempLoc[0]));
    99       }
    100     }
    101   } else {
    102     //
    103     // we have a regular parameter (no quote) OR
    104     // we have the final parameter (no trailing space)
    105     //
    106     NextDelim = StrStr((*Walker), L" ");
    107     if (NextDelim != NULL) {
    108       StrnCpy(*TempParameter, *Walker, NextDelim - (*Walker));
    109       (*TempParameter)[NextDelim - (*Walker)] = CHAR_NULL;
    110       *Walker = NextDelim+1;
    111     } else {
    112       //
    113       // last one.
    114       //
    115       StrCpy(*TempParameter, *Walker);
    116       *Walker = NULL;
    117     }
    118     for (NextDelim = *TempParameter ; NextDelim != NULL && *NextDelim != CHAR_NULL ; NextDelim++) {
    119       if (*NextDelim == L'^' && *(NextDelim+1) == L'^') {
    120         CopyMem(NextDelim, NextDelim+1, StrSize(NextDelim) - sizeof(NextDelim[0]));
    121       }
    122     }
    123     while ((*TempParameter)[StrLen(*TempParameter)-1] == L' ') {
    124       (*TempParameter)[StrLen(*TempParameter)-1] = CHAR_NULL;
    125     }
    126     while ((*TempParameter)[0] == L' ') {
    127       CopyMem(*TempParameter, (*TempParameter)+1, StrSize(*TempParameter) - sizeof((*TempParameter)[0]));
    128     }
    129   }
    130   return;
     113DEBUG_CODE_BEGIN();
     114    *Walker        = NULL;
     115DEBUG_CODE_END();
     116    return (EFI_INVALID_PARAMETER);
     117  }
     118
     119  NextDelim = FindEndOfParameter(*Walker);
     120
     121  if (NextDelim == NULL){
     122DEBUG_CODE_BEGIN();
     123    *Walker        = NULL;
     124DEBUG_CODE_END();
     125    return (EFI_NOT_FOUND);
     126  }
     127
     128  StrnCpy(*TempParameter, (*Walker), NextDelim - *Walker);
     129
     130  //
     131  // Add a CHAR_NULL if we didnt get one via the copy
     132  //
     133  if (*NextDelim != CHAR_NULL) {
     134    (*TempParameter)[NextDelim - *Walker] = CHAR_NULL;
     135  }
     136
     137  //
     138  // Update Walker for the next iteration through the function
     139  //
     140  *Walker = (CHAR16*)NextDelim;
     141
     142  //
     143  // Remove any non-escaped quotes in the string
     144  // Remove any remaining escape characters in the string
     145  //
     146  for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL)
     147    ; *NextDelim != CHAR_NULL
     148    ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL)
     149    ) {
     150    if (*NextDelim == L'^') {
     151
     152      //
     153      // eliminate the escape ^
     154      //
     155      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
     156      NextDelim++;
     157    } else if (*NextDelim == L'\"') {
     158
     159      //
     160      // eliminate the unescaped quote
     161      //
     162      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
     163    }
     164  }
     165
     166  return EFI_SUCCESS;
    131167}
    132168
     
    137173  parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL.  this supports space
    138174  delimited and quote surrounded parameter definition.
     175
     176  All special character processing (alias, environment variable, redirection,
     177  etc... must be complete before calling this API.
    139178
    140179  @param[in] CommandLine         String of command line to parse
     
    177216      , Walker = (CHAR16*)CommandLine
    178217      ; Walker != NULL && *Walker != CHAR_NULL
    179       ; GetNextParameter(&Walker, &TempParameter)
    180       , Count++
    181      );
    182 
    183 /*  Count = 0;
    184   Walker = (CHAR16*)CommandLine;
    185   while(Walker != NULL) {
    186     GetNextParameter(&Walker, &TempParameter);
    187     Count++;
    188   }
    189 */
     218      ; Count++
     219      ) {
     220    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
     221      break;
     222    }
     223  }
     224
    190225  //
    191226  // lets allocate the pointer array
     
    193228  (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*));
    194229  if (*Argv == NULL) {
     230    SHELL_FREE_NON_NULL(TempParameter);
    195231    return (EFI_OUT_OF_RESOURCES);
    196232  }
     
    200236  while(Walker != NULL && *Walker != CHAR_NULL) {
    201237    SetMem16(TempParameter, Size, CHAR_NULL);
    202     GetNextParameter(&Walker, &TempParameter);
    203     NewParam = AllocateZeroPool(StrSize(TempParameter));
    204     ASSERT(NewParam != NULL);
    205     StrCpy(NewParam, TempParameter);
     238    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
     239      SHELL_FREE_NON_NULL(TempParameter);
     240      return (EFI_INVALID_PARAMETER);
     241    }
     242
     243    NewParam = AllocateCopyPool(StrSize(TempParameter), TempParameter);
     244    if (NewParam == NULL){
     245      SHELL_FREE_NON_NULL(TempParameter);
     246      return (EFI_OUT_OF_RESOURCES);
     247    }
    206248    ((CHAR16**)(*Argv))[(*Argc)] = NewParam;
    207249    (*Argc)++;
    208250  }
    209251  ASSERT(Count >= (*Argc));
     252  SHELL_FREE_NON_NULL(TempParameter);
    210253  return (EFI_SUCCESS);
    211254}
     
    290333  // Build the full command line
    291334  //
    292   Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
     335  Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, FullCommandLine);
    293336  if (Status == EFI_BUFFER_TOO_SMALL) {
    294337    FullCommandLine = AllocateZeroPool(Size + LoadedImage->LoadOptionsSize);
    295     Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
     338    Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, FullCommandLine);
    296339  }
    297340  if (Status == EFI_NOT_FOUND) {
     
    313356  }
    314357  if (FullCommandLine != NULL) {
    315     if (LoadedImage->LoadOptionsSize != 0){
    316       StrCpy(FullCommandLine, LoadedImage->LoadOptions);
    317     }
     358    CopyMem (FullCommandLine, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
    318359    //
    319360    // Populate Argc and Argv
     
    524565  } else {
    525566    Copy = FileName;
     567    while(Copy[0] == L' ') {
     568      Copy++;
     569    }
    526570    if ((TempLocation = StrStr(Copy , L" ")) != NULL) {
    527571      TempLocation[0] = CHAR_NULL;
     
    535579  return (Copy);
    536580}
     581
     582/**
     583  Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.
     584
     585  @param[in]  FileName    The filename to start with.
     586
     587  @retval NULL  FileName was invalid.
     588  @return       The modified FileName.
     589**/
     590CHAR16*
     591EFIAPI
     592FixVarName (
     593  IN CHAR16 *FileName
     594  )
     595{
     596  CHAR16  *Copy;
     597  CHAR16  *TempLocation;
     598
     599  Copy = FileName;
     600
     601  if (FileName[0] == L'%') {
     602    Copy = FileName+1;
     603    if ((TempLocation = StrStr(Copy , L"%")) != NULL) {
     604      TempLocation[0] = CHAR_NULL;
     605    }   
     606  }
     607
     608  return (FixFileName(Copy));
     609}
     610
     611/**
     612  Remove the unicode file tag from the begining of the file buffer since that will not be
     613  used by StdIn.
     614 
     615  @param[in]  Handle    Pointer to the handle of the file to be processed.
     616 
     617  @retval EFI_SUCCESS   The unicode file tag has been moved successfully.
     618**/
     619EFI_STATUS
     620EFIAPI
     621RemoveFileTag(
     622  IN SHELL_FILE_HANDLE *Handle
     623  )
     624{
     625  UINTN             CharSize;
     626  CHAR16            CharBuffer;
     627
     628  CharSize    = sizeof(CHAR16);
     629  CharBuffer  = 0;
     630  gEfiShellProtocol->ReadFile(*Handle, &CharSize, &CharBuffer);
     631  if (CharBuffer != gUnicodeFileTag) {
     632    gEfiShellProtocol->SetFilePosition(*Handle, 0);
     633  }
     634  return (EFI_SUCCESS);
     635}
     636
     637/**
     638  Write the unicode file tag to the specified file.
     639
     640  It is the caller's responsibility to ensure that
     641  ShellInfoObject.NewEfiShellProtocol has been initialized before calling this
     642  function.
     643
     644  @param[in] FileHandle  The file to write the unicode file tag to.
     645
     646  @return  Status code from ShellInfoObject.NewEfiShellProtocol->WriteFile.
     647**/
     648EFI_STATUS
     649WriteFileTag (
     650  IN SHELL_FILE_HANDLE FileHandle
     651  )
     652{
     653  CHAR16     FileTag;
     654  UINTN      Size;
     655  EFI_STATUS Status;
     656
     657  FileTag = gUnicodeFileTag;
     658  Size = sizeof FileTag;
     659  Status = ShellInfoObject.NewEfiShellProtocol->WriteFile (FileHandle, &Size,
     660                                                  &FileTag);
     661  ASSERT (EFI_ERROR (Status) || Size == sizeof FileTag);
     662  return Status;
     663}
     664
    537665
    538666/**
     
    581709  BOOLEAN           ErrAppend;
    582710  UINTN             Size;
    583   CHAR16            TagBuffer[2];
    584711  SPLIT_LIST        *Split;
    585712  CHAR16            *FirstLocation;
     
    607734  SystemTableInfo->ConOut         = gST->ConOut;
    608735  SystemTableInfo->ConOutHandle   = gST->ConsoleOutHandle;
    609   SystemTableInfo->ConErr         = gST->StdErr;
    610   SystemTableInfo->ConErrHandle   = gST->StandardErrorHandle;
     736  SystemTableInfo->ErrOut         = gST->StdErr;
     737  SystemTableInfo->ErrOutHandle   = gST->StandardErrorHandle;
    611738  *OldStdIn                       = ShellParameters->StdIn;
    612739  *OldStdOut                      = ShellParameters->StdOut;
     
    8861013  // re-populate the string to support any filenames that were in quotes.
    8871014  //
    888   StrCpy(CommandLineCopy, NewCommandLine);
     1015  StrnCpy(CommandLineCopy, NewCommandLine, StrLen(NewCommandLine));
    8891016
    8901017  if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
     
    9121039    }
    9131040    if (StdErrVarName  != NULL) {
    914       if ((StdErrVarName     = FixFileName(StdErrVarName)) == NULL) {
     1041      if ((StdErrVarName     = FixVarName(StdErrVarName)) == NULL) {
    9151042        Status = EFI_INVALID_PARAMETER;
    9161043      }
    9171044    }
    9181045    if (StdOutVarName  != NULL) {
    919       if ((StdOutVarName     = FixFileName(StdOutVarName)) == NULL) {
     1046      if ((StdOutVarName     = FixVarName(StdOutVarName)) == NULL) {
    9201047        Status = EFI_INVALID_PARAMETER;
    9211048      }
    9221049    }
    9231050    if (StdInVarName   != NULL) {
    924       if ((StdInVarName      = FixFileName(StdInVarName)) == NULL) {
     1051      if ((StdInVarName      = FixVarName(StdInVarName)) == NULL) {
    9251052        Status = EFI_INVALID_PARAMETER;
    9261053      }
     
    9931120        Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
    9941121        if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
    995           //
    996           // Write out the gUnicodeFileTag
    997           //
    998           Size = sizeof(CHAR16);
    999           TagBuffer[0] = gUnicodeFileTag;
    1000           TagBuffer[1] = CHAR_NULL;
    1001           ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
     1122          Status = WriteFileTag (TempHandle);
    10021123        }
    10031124        if (!ErrUnicode && !EFI_ERROR(Status)) {
     
    10071128        if (!EFI_ERROR(Status)) {
    10081129          ShellParameters->StdErr = TempHandle;
    1009           gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
     1130          gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
    10101131        }
    10111132      }
     
    10281149            //no-op
    10291150          } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
    1030             //
    1031             // Write out the gUnicodeFileTag
    1032             //
    1033             Size = sizeof(CHAR16);
    1034             TagBuffer[0] = gUnicodeFileTag;
    1035             TagBuffer[1] = CHAR_NULL;
    1036             ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
     1151            Status = WriteFileTag (TempHandle);
    10371152          } else if (OutAppend) {
    1038             //
    1039             // Move to end of file
    1040             //
    10411153            Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
    10421154            if (!EFI_ERROR(Status)) {
    1043               Status = ShellInfoObject.NewEfiShellProtocol->SetFilePosition(TempHandle, FileSize);
     1155              //
     1156              // When appending to a new unicode file, write the file tag.
     1157              // Otherwise (ie. when appending to a new ASCII file, or an
     1158              // existent file with any encoding), just seek to the end.
     1159              //
     1160              Status = (FileSize == 0 && OutUnicode) ?
     1161                         WriteFileTag (TempHandle) :
     1162                         ShellInfoObject.NewEfiShellProtocol->SetFilePosition (
     1163                                                                TempHandle,
     1164                                                                FileSize);
    10441165            }
    10451166          }
     
    10501171          if (!EFI_ERROR(Status)) {
    10511172            ShellParameters->StdOut = TempHandle;
    1052             gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
     1173            gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
    10531174          }
    10541175        }
     
    10681189        ASSERT(TempHandle != NULL);
    10691190        ShellParameters->StdOut = TempHandle;
    1070         gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
     1191        gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
    10711192      }
    10721193
     
    10841205        ASSERT(TempHandle != NULL);
    10851206        ShellParameters->StdErr = TempHandle;
    1086         gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
     1207        gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
    10871208      }
    10881209
     
    11171238          EFI_FILE_MODE_READ,
    11181239          0);
    1119         if (!InUnicode && !EFI_ERROR(Status)) {
     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          //
    11201249          TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
    11211250        }
     
    11321261
    11331262  if (gST->ConIn == NULL ||gST->ConOut == NULL) {
    1134     return (EFI_OUT_OF_RESOURCES);
    1135   }
     1263    Status = EFI_OUT_OF_RESOURCES;
     1264  }
     1265
     1266  if (Status == EFI_NOT_FOUND) {
     1267    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
     1268  } else if (EFI_ERROR(Status)) {
     1269    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
     1270  }
     1271
    11361272  return (Status);
    11371273}
     
    11981334    gST->ConsoleOutHandle     = SystemTableInfo->ConOutHandle;
    11991335  }
    1200   if (gST->StdErr != SystemTableInfo->ConErr) {
     1336  if (gST->StdErr != SystemTableInfo->ErrOut) {
    12011337    CloseSimpleTextOutOnFile(gST->StdErr);
    1202     gST->StdErr               = SystemTableInfo->ConErr;
    1203     gST->StandardErrorHandle  = SystemTableInfo->ConErrHandle;
     1338    gST->StdErr               = SystemTableInfo->ErrOut;
     1339    gST->StandardErrorHandle  = SystemTableInfo->ErrOutHandle;
    12041340  }
    12051341
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellParametersProtocol.h

    r48674 r58459  
    33  manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
    44
    5   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
     5  Copyright (c) 2009 - 2012, 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
     
    1717#define _SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_
    1818
    19 #include <Uefi.h>
    20 
    21 #include <Protocol/SimpleFileSystem.h>
    22 #include <Protocol/EfiShellParameters.h>
    23 #include <Protocol/LoadedImage.h>
    24 #include <Protocol/SimpleTextOut.h>
    25 #include <Protocol/SimpleTextIn.h>
    26 
    27 #include <Guid/ShellVariableGuid.h>
    28 
    29 #include <Library/UefiBootServicesTableLib.h>
    30 #include <Library/UefiRuntimeServicesTableLib.h>
    31 #include <Library/MemoryAllocationLib.h>
    32 #include <Library/UefiLib.h>
    33 #include <Library/DebugLib.h>
    34 #include <Library/ShellLib.h>
    35 #include <Library/FileHandleLib.h>
    36 
    37 #include "ShellEnvVar.h"
    38 #include "FileHandleWrappers.h"
    3919#include "Shell.h"
    4020
     
    124104  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *ConOut;
    125105  EFI_HANDLE                            ConOutHandle;
    126   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *ConErr;
    127   EFI_HANDLE                            ConErrHandle;
     106  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *ErrOut;
     107  EFI_HANDLE                            ErrOutHandle;
    128108} SYSTEM_TABLE_INFO;
    129109
     
    211191                                reminaing command line on return
    212192  @param[in, out] TempParameter pointer to string of command line item extracted.
    213 
    214 **/
    215 VOID
     193  @param[in]      Length        Length of (*TempParameter) in bytes
     194
     195  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.
     196  @return   EFI_NOT_FOUND         A closing " could not be found on the specified string
     197**/
     198EFI_STATUS
    216199EFIAPI
    217200GetNextParameter(
    218   CHAR16 **Walker,
    219   CHAR16 **TempParameter
     201  IN OUT CHAR16   **Walker,
     202  IN OUT CHAR16   **TempParameter,
     203  IN CONST UINTN  Length
    220204  );
    221205
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellProtocol.c

    r48674 r58459  
    33  manipulation, and initialization of EFI_SHELL_PROTOCOL.
    44
    5   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
     6  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
    67  This program and the accompanying materials
    78  are licensed and made available under the terms and conditions of the BSD License
     
    1516
    1617#include "Shell.h"
    17 #include <Library/FileHandleLib.h>
     18
     19#define INIT_NAME_BUFFER_SIZE  128
    1820
    1921/**
     
    117119  )
    118120{
    119   EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathToText;
    120121  EFI_STATUS                        Status;
    121122  CHAR16                            *Temp;
     
    123124  Status = EFI_SUCCESS;
    124125  DEBUG_CODE_BEGIN();
    125   DevicePathToText = NULL;
    126 
    127   Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid,
    128                                NULL,
    129                                (VOID**)&DevicePathToText);
     126
    130127  if (Mapping != NULL) {
    131128    DEBUG((EFI_D_INFO, "Added new map item:\"%S\"\r\n", Mapping));
    132129  }
    133   if (!EFI_ERROR(Status)) {
    134     if (DevicePath != NULL) {
    135       Temp = DevicePathToText->ConvertDevicePathToText(DevicePath, TRUE, TRUE);
    136       DEBUG((EFI_D_INFO, "DevicePath: %S\r\n", Temp));
    137       FreePool(Temp);
    138     }
    139   }
     130  Temp = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
     131  DEBUG((EFI_D_INFO, "DevicePath: %S\r\n", Temp));
     132  FreePool(Temp);
     133
    140134  DEBUG_CODE_END();
    141135  return (Status);
     
    468462          //
    469463          ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
    470           PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L"\\", 1);
    471464
    472465          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
    473481          PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, AlignedNode->PathName, 0);
    474482          FreePool(AlignedNode);
     
    525533      return (NULL);
    526534    }
    527     Size = StrSize(Cwd);
    528     Size += StrSize(Path);
     535    Size = StrSize(Cwd) + StrSize(Path) - sizeof(CHAR16);
    529536    NewPath = AllocateZeroPool(Size);
    530537    if (NewPath == NULL) {
    531538      return (NULL);
    532539    }
    533     StrCpy(NewPath, Cwd);
     540    StrnCpy(NewPath, Cwd, Size/sizeof(CHAR16)-1);
    534541    if (*Path == L'\\') {
    535542      Path++;
    536543      while (PathRemoveLastItem(NewPath)) ;
    537544    }
    538     StrCat(NewPath, Path);
     545    StrnCat(NewPath, Path, Size/sizeof(CHAR16) - 1 - StrLen(NewPath));
    539546    DevicePathForReturn = EfiShellGetDevicePathFromFilePath(NewPath);
    540547    FreePool(NewPath);
     
    649656  EFI_STATUS                        Status;
    650657  EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
    651   EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathToText;
    652658  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
    653659  EFI_HANDLE                        *HandleList;
     
    656662  CHAR16                            *DeviceNameToReturn;
    657663  CHAR8                             *Lang;
    658   CHAR8                             *TempChar;
    659 
    660664  UINTN                             ParentControllerCount;
    661665  EFI_HANDLE                        *ParentControllerBuffer;
     
    714718        continue;
    715719      }
    716       if (Language == NULL) {
    717         Lang = AllocateZeroPool(AsciiStrSize(CompName2->SupportedLanguages));
    718         if (Lang == NULL) {
    719           return (EFI_OUT_OF_RESOURCES);
    720         }
    721         AsciiStrCpy(Lang, CompName2->SupportedLanguages);
    722         TempChar = AsciiStrStr(Lang, ";");
    723         if (TempChar != NULL){
    724           *TempChar = CHAR_NULL;
    725         }
    726       } else {
    727         Lang = AllocateZeroPool(AsciiStrSize(Language));
    728         if (Lang == NULL) {
    729           return (EFI_OUT_OF_RESOURCES);
    730         }
    731         AsciiStrCpy(Lang, Language);
    732       }
     720      Lang = GetBestLanguageForDriver(CompName2->SupportedLanguages, Language, FALSE);
    733721      Status = CompName2->GetControllerName(CompName2, DeviceHandle, NULL, Lang, &DeviceNameToReturn);
    734722      FreePool(Lang);
     
    773761            continue;
    774762          }
    775           if (Language == NULL) {
    776             Lang = AllocateZeroPool(AsciiStrSize(CompName2->SupportedLanguages));
    777             if (Lang == NULL) {
    778               return (EFI_OUT_OF_RESOURCES);
    779             }
    780             AsciiStrCpy(Lang, CompName2->SupportedLanguages);
    781             TempChar = AsciiStrStr(Lang, ";");
    782             if (TempChar != NULL){
    783               *TempChar = CHAR_NULL;
    784             }
    785           } else {
    786             Lang = AllocateZeroPool(AsciiStrSize(Language));
    787             if (Lang == NULL) {
    788               return (EFI_OUT_OF_RESOURCES);
    789             }
    790             AsciiStrCpy(Lang, Language);
    791           }
     763          Lang = GetBestLanguageForDriver(CompName2->SupportedLanguages, Language, FALSE);
    792764          Status = CompName2->GetControllerName(CompName2, ParentControllerBuffer[LoopVar], DeviceHandle, Lang, &DeviceNameToReturn);
    793765          FreePool(Lang);
     
    817789  }
    818790  if ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) != 0) {
    819     Status = gBS->LocateProtocol(
    820       &gEfiDevicePathToTextProtocolGuid,
     791    Status = gBS->OpenProtocol(
     792      DeviceHandle,
     793      &gEfiDevicePathProtocolGuid,
     794      (VOID**)&DevicePath,
     795      gImageHandle,
    821796      NULL,
    822       (VOID**)&DevicePathToText);
    823     //
    824     // we now have the device path to text protocol
    825     //
     797      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    826798    if (!EFI_ERROR(Status)) {
    827       Status = gBS->OpenProtocol(
    828         DeviceHandle,
    829         &gEfiDevicePathProtocolGuid,
    830         (VOID**)&DevicePath,
    831         gImageHandle,
    832         NULL,
    833         EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    834       if (!EFI_ERROR(Status)) {
    835         //
    836         // use device path to text on the device path
    837         //
    838         *BestDeviceName = DevicePathToText->ConvertDevicePathToText(DevicePath, TRUE, TRUE);
    839         return (EFI_SUCCESS);
    840       }
     799      //
     800      // use device path to text on the device path
     801      //
     802      *BestDeviceName = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
     803      return (EFI_SUCCESS);
    841804    }
    842805  }
     
    996959  EFI_FILE_PROTOCOL               *Handle1;
    997960  EFI_FILE_PROTOCOL               *Handle2;
    998   EFI_DEVICE_PATH_PROTOCOL        *DpCopy;
    999961  FILEPATH_DEVICE_PATH            *AlignedNode;
    1000962
     
    1006968  Handle2       = NULL;
    1007969  Handle        = NULL;
    1008   DpCopy        = DevicePath;
    1009970  ShellHandle   = NULL;
    1010971  FilePathNode  = NULL;
     
    11871148  }
    11881149
    1189   Status = InternalOpenFileDevicePath(DevicePath, FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, FileAttribs); // 0 = no specific file attributes
     1150  Status = InternalOpenFileDevicePath(DevicePath, FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, FileAttribs);
    11901151  FreePool(DevicePath);
    11911152
    11921153  return(Status);
     1154}
     1155
     1156/**
     1157  Register a GUID and a localized human readable name for it.
     1158
     1159  If Guid is not assigned a name, then assign GuidName to Guid.  This list of GUID
     1160  names must be used whenever a shell command outputs GUID information.
     1161
     1162  This function is only available when the major and minor versions in the
     1163  EfiShellProtocol are greater than or equal to 2 and 1, respectively.
     1164
     1165  @param[in] Guid       A pointer to the GUID being registered.
     1166  @param[in] GuidName   A pointer to the localized name for the GUID being registered.
     1167
     1168  @retval EFI_SUCCESS             The operation was successful.
     1169  @retval EFI_INVALID_PARAMETER   Guid was NULL.
     1170  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
     1171  @retval EFI_ACCESS_DENIED       Guid already is assigned a name.
     1172**/
     1173EFI_STATUS
     1174EFIAPI
     1175EfiShellRegisterGuidName(
     1176  IN CONST EFI_GUID *Guid,
     1177  IN CONST CHAR16   *GuidName
     1178  )
     1179{
     1180  return (AddNewGuidNameMapping(Guid, GuidName, NULL));
    11931181}
    11941182
     
    13601348  EFI_STATUS        Status;
    13611349
     1350  FileHandle = NULL;
     1351
    13621352  //
    13631353  // get a handle to the file
     
    14021392  internal worker function to load and run an image via device path.
    14031393
    1404   @param ParentImageHandle  A handle of the image that is executing the specified
    1405                             command line.
    1406   @param DevicePath         device path of the file to execute
    1407   @param CommandLine        Points to the NULL-terminated UCS-2 encoded string
    1408                             containing the command line. If NULL then the command-
    1409                             line will be empty.
    1410   @param Environment        Points to a NULL-terminated array of environment
    1411                             variables with the format 'x=y', where x is the
    1412                             environment variable name and y is the value. If this
    1413                             is NULL, then the current shell environment is used.
    1414   @param StatusCode         Points to the status code returned by the command.
     1394  @param ParentImageHandle      A handle of the image that is executing the specified
     1395                                command line.
     1396  @param DevicePath             device path of the file to execute
     1397  @param CommandLine            Points to the NULL-terminated UCS-2 encoded string
     1398                                containing the command line. If NULL then the command-
     1399                                line will be empty.
     1400  @param Environment            Points to a NULL-terminated array of environment
     1401                                variables with the format 'x=y', where x is the
     1402                                environment variable name and y is the value. If this
     1403                                is NULL, then the current shell environment is used.
     1404                           
     1405  @param[out] StartImageStatus  Returned status from gBS->StartImage.
    14151406
    14161407  @retval EFI_SUCCESS       The command executed successfully. The  status code
     
    14271418  IN CONST CHAR16                   *CommandLine OPTIONAL,
    14281419  IN CONST CHAR16                   **Environment OPTIONAL,
    1429   OUT EFI_STATUS                    *StatusCode OPTIONAL
     1420  OUT EFI_STATUS                    *StartImageStatus OPTIONAL
    14301421  )
    14311422{
    14321423  EFI_STATUS                    Status;
     1424  EFI_STATUS                    StartStatus;
     1425  EFI_STATUS                    CleanupStatus;
    14331426  EFI_HANDLE                    NewHandle;
    14341427  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
    14351428  LIST_ENTRY                    OrigEnvs;
    14361429  EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;
     1430  CHAR16                        *ImagePath;
     1431  UINTN                         Index;
     1432  CHAR16                        *Walker;
     1433  CHAR16                        *NewCmdLine;
    14371434
    14381435  if (ParentImageHandle == NULL) {
     
    14431440
    14441441  NewHandle = NULL;
     1442 
     1443  NewCmdLine = AllocateCopyPool (StrSize (CommandLine), CommandLine);
     1444  if (NewCmdLine == NULL) {
     1445    return EFI_OUT_OF_RESOURCES;
     1446  }
     1447
     1448  for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL ; Walker++) {
     1449    if (*Walker == L'^' && *(Walker+1) == L'#') {
     1450      CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0]));
     1451    }
     1452  }
    14451453
    14461454  //
     
    14721480  if (!EFI_ERROR(Status)) {
    14731481    ASSERT(LoadedImage->LoadOptionsSize == 0);
    1474     if (CommandLine != NULL) {
    1475       LoadedImage->LoadOptionsSize  = (UINT32)StrSize(CommandLine);
    1476       LoadedImage->LoadOptions      = (VOID*)CommandLine;
     1482    if (NewCmdLine != NULL) {
     1483      LoadedImage->LoadOptionsSize  = (UINT32)StrSize(NewCmdLine);
     1484      LoadedImage->LoadOptions      = (VOID*)NewCmdLine;
    14771485    }
    14781486
     
    14931501    ShellParamsProtocol.StdOut  = ShellInfoObject.NewShellParametersProtocol->StdOut;
    14941502    ShellParamsProtocol.StdErr  = ShellInfoObject.NewShellParametersProtocol->StdErr;
    1495     Status = UpdateArgcArgv(&ShellParamsProtocol, CommandLine, NULL, NULL);
     1503    Status = UpdateArgcArgv(&ShellParamsProtocol, NewCmdLine, NULL, NULL);
    14961504    ASSERT_EFI_ERROR(Status);
     1505    //
     1506    // Replace Argv[0] with the full path of the binary we're executing:
     1507    // If the command line was "foo", the binary might be called "foo.efi".
     1508    // "The first entry in [Argv] is always the full file path of the
     1509    //  executable" - UEFI Shell Spec section 2.3
     1510    //
     1511    ImagePath = EfiShellGetFilePathFromDevicePath (DevicePath);
     1512    // The image we're executing isn't necessarily in a filesystem - it might
     1513    // be memory mapped. In this case EfiShellGetFilePathFromDevicePath will
     1514    // return NULL, and we'll leave Argv[0] as UpdateArgcArgv set it.
     1515    if (ImagePath != NULL) {
     1516      if (ShellParamsProtocol.Argv == NULL) {
     1517        // Command line was empty or null.
     1518        // (UpdateArgcArgv sets Argv to NULL when CommandLine is "" or NULL)
     1519        ShellParamsProtocol.Argv = AllocatePool (sizeof (CHAR16 *));
     1520        if (ShellParamsProtocol.Argv == NULL) {
     1521          Status = EFI_OUT_OF_RESOURCES;
     1522          goto UnloadImage;
     1523        }
     1524        ShellParamsProtocol.Argc = 1;
     1525      } else {
     1526        // Free the string UpdateArgcArgv put in Argv[0];
     1527        FreePool (ShellParamsProtocol.Argv[0]);
     1528      }
     1529      ShellParamsProtocol.Argv[0] = ImagePath;
     1530    }
     1531
    14971532    Status = gBS->InstallProtocolInterface(&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);
    14981533    ASSERT_EFI_ERROR(Status);
     
    15041539    //
    15051540    if (!EFI_ERROR(Status)) {
    1506       if (StatusCode != NULL) {
    1507         *StatusCode = gBS->StartImage(NewHandle, NULL, NULL);
    1508       } else {
    1509         Status      = gBS->StartImage(NewHandle, NULL, NULL);
     1541      StartStatus      = gBS->StartImage(
     1542                          NewHandle,
     1543                          0,
     1544                          NULL
     1545                          );
     1546      if (StartImageStatus != NULL) {
     1547        *StartImageStatus = StartStatus;
    15101548      }
    1511     }
    1512 
    1513     //
    1514     // Cleanup (and dont overwrite errors)
    1515     //
    1516     if (EFI_ERROR(Status)) {
    1517       gBS->UninstallProtocolInterface(NewHandle, &gEfiShellParametersProtocolGuid, &ShellParamsProtocol);
    1518     } else {
    1519       Status = gBS->UninstallProtocolInterface(NewHandle, &gEfiShellParametersProtocolGuid, &ShellParamsProtocol);
    1520       ASSERT_EFI_ERROR(Status);
    1521     }
    1522   }
    1523 
     1549
     1550      CleanupStatus = gBS->UninstallProtocolInterface(
     1551                            NewHandle,
     1552                            &gEfiShellParametersProtocolGuid,
     1553                            &ShellParamsProtocol
     1554                            );
     1555      ASSERT_EFI_ERROR(CleanupStatus);
     1556
     1557      goto FreeAlloc;
     1558    }
     1559
     1560UnloadImage:
     1561    // Unload image - We should only get here if we didn't call StartImage
     1562    gBS->UnloadImage (NewHandle);
     1563
     1564FreeAlloc:
     1565    // Free Argv (Allocated in UpdateArgcArgv)
     1566    if (ShellParamsProtocol.Argv != NULL) {
     1567      for (Index = 0; Index < ShellParamsProtocol.Argc; Index++) {
     1568        if (ShellParamsProtocol.Argv[Index] != NULL) {
     1569          FreePool (ShellParamsProtocol.Argv[Index]);
     1570        }
     1571      }
     1572      FreePool (ShellParamsProtocol.Argv);
     1573    }
     1574  }
     1575
     1576  // Restore environment variables
    15241577  if (!IsListEmpty(&OrigEnvs)) {
    1525     if (EFI_ERROR(Status)) {
    1526       SetEnvironmentVariableList(&OrigEnvs);
    1527     } else {
    1528       Status = SetEnvironmentVariableList(&OrigEnvs);
    1529     }
    1530   }
     1578    CleanupStatus = SetEnvironmentVariableList(&OrigEnvs);
     1579    ASSERT_EFI_ERROR (CleanupStatus);
     1580  }
     1581
     1582  FreePool (NewCmdLine);
    15311583
    15321584  return(Status);
     
    15871639
    15881640  DEBUG_CODE_BEGIN();
    1589   Temp = gDevPathToText->ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);
     1641  Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);
    15901642  FreePool(Temp);
    1591   Temp = gDevPathToText->ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);
     1643  Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);
    15921644  FreePool(Temp);
    1593   Temp = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE);
     1645  Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
    15941646  FreePool(Temp);
    15951647  DEBUG_CODE_END();
     
    15981650  Size = 0;
    15991651  ASSERT((Temp == NULL && Size == 0) || (Temp != NULL));
    1600   StrnCatGrow(&Temp, &Size, L"Shell.efi ", 0);
     1652  StrnCatGrow(&Temp, &Size, L"Shell.efi -_exit ", 0);
    16011653  StrnCatGrow(&Temp, &Size, CommandLine, 0);
    16021654
     
    16751727    InternalFreeShellFileInfoNode(ShellFileListItem);
    16761728  }
     1729  InternalFreeShellFileInfoNode(*FileList);
     1730  *FileList = NULL;
    16771731  return(EFI_SUCCESS);
    16781732}
     
    16961750  EFI_SHELL_FILE_INFO *ShellFileListItem;
    16971751  EFI_SHELL_FILE_INFO *ShellFileListItem2;
     1752  EFI_SHELL_FILE_INFO *TempNode;
    16981753
    16991754  if (FileList == NULL || *FileList == NULL) {
     
    17131768            (CHAR16*)ShellFileListItem2->FullName) == 0
    17141769         ){
     1770        TempNode = (EFI_SHELL_FILE_INFO *)GetPreviousNode(
     1771                                            &(*FileList)->Link,
     1772                                            &ShellFileListItem2->Link
     1773                                            );
    17151774        RemoveEntryList(&ShellFileListItem2->Link);
    17161775        InternalFreeShellFileInfoNode(ShellFileListItem2);
     1776        // Set ShellFileListItem2 to PreviousNode so we don't access Freed
     1777        // memory in GetNextNode in the loop expression above.
     1778        ShellFileListItem2 = TempNode;
    17171779      }
    17181780    }
     
    17201782  return (EFI_SUCCESS);
    17211783}
     1784
     1785//
     1786// This is the same structure as the external version, but it has no CONST qualifiers.
     1787//
     1788typedef struct {
     1789  LIST_ENTRY        Link;       ///< Linked list members.
     1790  EFI_STATUS        Status;     ///< Status of opening the file.  Valid only if Handle != NULL.
     1791        CHAR16      *FullName;  ///< Fully qualified filename.
     1792        CHAR16      *FileName;  ///< name of this file.
     1793  SHELL_FILE_HANDLE Handle;     ///< Handle for interacting with the opened file or NULL if closed.
     1794  EFI_FILE_INFO     *Info;      ///< Pointer to the FileInfo struct for this file or NULL.
     1795} EFI_SHELL_FILE_INFO_NO_CONST;
     1796
    17221797/**
    17231798  Allocates and duplicates a EFI_SHELL_FILE_INFO node.
     
    17361811  )
    17371812{
    1738   EFI_SHELL_FILE_INFO *NewNode;
     1813  EFI_SHELL_FILE_INFO_NO_CONST *NewNode;
     1814
     1815  //
     1816  // try to confirm that the objects are in sync
     1817  //
     1818  ASSERT(sizeof(EFI_SHELL_FILE_INFO_NO_CONST) == sizeof(EFI_SHELL_FILE_INFO));
    17391819
    17401820  NewNode = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
     
    17421822    return (NULL);
    17431823  }
    1744   NewNode->FullName = AllocateZeroPool(StrSize(Node->FullName));
    1745 
    1746   NewNode->FileName = AllocateZeroPool(StrSize(Node->FileName));
    1747   NewNode->Info     = AllocateZeroPool((UINTN)Node->Info->Size);
     1824  NewNode->FullName = AllocateCopyPool(StrSize(Node->FullName), Node->FullName);
     1825  NewNode->FileName = AllocateCopyPool(StrSize(Node->FileName), Node->FileName);
     1826  NewNode->Info     = AllocateCopyPool((UINTN)Node->Info->Size, Node->Info);
    17481827  if ( NewNode->FullName == NULL
    17491828    || NewNode->FileName == NULL
    17501829    || NewNode->Info == NULL
    1751    ){
     1830  ){
     1831    SHELL_FREE_NON_NULL(NewNode->FullName);
     1832    SHELL_FREE_NON_NULL(NewNode->FileName);
     1833    SHELL_FREE_NON_NULL(NewNode->Info);
     1834    SHELL_FREE_NON_NULL(NewNode);
    17521835    return(NULL);
    17531836  }
     
    17571840    Node->Handle = NULL;
    17581841  }
    1759   StrCpy((CHAR16*)NewNode->FullName, Node->FullName);
    1760   StrCpy((CHAR16*)NewNode->FileName, Node->FileName);
    1761   CopyMem(NewNode->Info, Node->Info, (UINTN)Node->Info->Size);
    1762 
    1763   return(NewNode);
     1842
     1843  return((EFI_SHELL_FILE_INFO*)NewNode);
    17641844}
    17651845
     
    17701850  @param[in] BasePath         the Path to prepend onto filename for FullPath
    17711851  @param[in] Status           Status member initial value.
    1772   @param[in] FullName         FullName member initial value.
    17731852  @param[in] FileName         FileName member initial value.
    17741853  @param[in] Handle           Handle member initial value.
     
    17831862  IN CONST CHAR16 *BasePath,
    17841863  IN CONST EFI_STATUS Status,
    1785   IN CONST CHAR16 *FullName,
    17861864  IN CONST CHAR16 *FileName,
    17871865  IN CONST SHELL_FILE_HANDLE Handle,
     
    18001878    return (NULL);
    18011879  }
    1802   if (Info != NULL) {
     1880  if (Info != NULL && Info->Size != 0) {
    18031881    ShellFileListItem->Info = AllocateZeroPool((UINTN)Info->Size);
    18041882    if (ShellFileListItem->Info == NULL) {
     
    18281906    if (TempString == NULL) {
    18291907      FreePool((VOID*)ShellFileListItem->FileName);
    1830       FreePool(ShellFileListItem->Info);
     1908      SHELL_FREE_NON_NULL(ShellFileListItem->Info);
    18311909      FreePool(ShellFileListItem);
    18321910      return (NULL);
     
    18431921    }
    18441922  }
     1923
     1924  TempString = PathCleanUpDirectories(TempString);
    18451925
    18461926  ShellFileListItem->FullName = TempString;
     
    18821962  CHAR16                    *TempSpot;
    18831963
     1964  BasePath = NULL;
    18841965  Status = FileHandleGetFileName(FileDirHandle, &BasePath);
    18851966  if (EFI_ERROR(Status)) {
     
    18921973    TempString        = StrnCatGrow(&TempString, &Size, ShellFileHandleGetPath(FileDirHandle), 0);
    18931974    if (TempString == NULL) {
     1975      SHELL_FREE_NON_NULL(BasePath);
    18941976      return (EFI_OUT_OF_RESOURCES);
    18951977    }
     
    19021984    TempString        = StrnCatGrow(&TempString, &Size, BasePath, 0);
    19031985    if (TempString == NULL) {
     1986      SHELL_FREE_NON_NULL(BasePath);
    19041987      return (EFI_OUT_OF_RESOURCES);
    19051988    }
     1989    SHELL_FREE_NON_NULL(BasePath);
    19061990    BasePath          = TempString;
    19071991  }
     
    19182002      ; Status = FileHandleFindNextFile(FileDirHandle, FileInfo, &NoFile)
    19192003     ){
    1920     TempString  = NULL;
    1921     Size        = 0;
    19222004    //
    19232005    // allocate a new EFI_SHELL_FILE_INFO and populate it...
    19242006    //
    1925     ASSERT((TempString == NULL && Size == 0) || (TempString != NULL));
    1926     TempString = StrnCatGrow(&TempString, &Size, BasePath, 0);
    1927     TempString = StrnCatGrow(&TempString, &Size, FileInfo->FileName, 0);
    19282007    ShellFileListItem = CreateAndPopulateShellFileInfo(
    19292008      BasePath,
    1930       EFI_SUCCESS, // success since we didnt fail to open it...
    1931       TempString,
     2009      EFI_SUCCESS,  // success since we didnt fail to open it...
    19322010      FileInfo->FileName,
    1933       NULL, // no handle since not open
     2011      NULL,         // no handle since not open
    19342012      FileInfo);
    19352013
     
    19492027  SHELL_FREE_NON_NULL(BasePath);
    19502028  return(Status);
     2029}
     2030
     2031/**
     2032  Get the GUID value from a human readable name.
     2033
     2034  If GuidName is a known GUID name, then update Guid to have the correct value for
     2035  that GUID.
     2036
     2037  This function is only available when the major and minor versions in the
     2038  EfiShellProtocol are greater than or equal to 2 and 1, respectively.
     2039
     2040  @param[in]  GuidName   A pointer to the localized name for the GUID being queried.
     2041  @param[out] Guid       A pointer to the GUID structure to be filled in.
     2042
     2043  @retval EFI_SUCCESS             The operation was successful.
     2044  @retval EFI_INVALID_PARAMETER   Guid was NULL.
     2045  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
     2046  @retval EFI_NOT_FOUND           GuidName is not a known GUID Name.
     2047**/
     2048EFI_STATUS
     2049EFIAPI
     2050EfiShellGetGuidFromName(
     2051  IN  CONST CHAR16   *GuidName,
     2052  OUT       EFI_GUID *Guid
     2053  )
     2054{
     2055  EFI_GUID    *NewGuid;
     2056  EFI_STATUS  Status;
     2057
     2058  if (Guid == NULL || GuidName == NULL) {
     2059    return (EFI_INVALID_PARAMETER);
     2060  }
     2061 
     2062  Status = GetGuidFromStringName(GuidName, NULL, &NewGuid);
     2063
     2064  if (!EFI_ERROR(Status)) {
     2065    CopyGuid(NewGuid, Guid);
     2066  }
     2067
     2068  return (Status);
     2069}
     2070
     2071/**
     2072  Get the human readable name for a GUID from the value.
     2073
     2074  If Guid is assigned a name, then update *GuidName to point to the name. The callee
     2075  should not modify the value.
     2076
     2077  This function is only available when the major and minor versions in the
     2078  EfiShellProtocol are greater than or equal to 2 and 1, respectively.
     2079
     2080  @param[in]  Guid       A pointer to the GUID being queried.
     2081  @param[out] GuidName   A pointer to a pointer the localized to name for the GUID being requested
     2082
     2083  @retval EFI_SUCCESS             The operation was successful.
     2084  @retval EFI_INVALID_PARAMETER   Guid was NULL.
     2085  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
     2086  @retval EFI_NOT_FOUND           Guid is not assigned a name.
     2087**/
     2088EFI_STATUS
     2089EFIAPI
     2090EfiShellGetGuidName(
     2091  IN  CONST EFI_GUID *Guid,
     2092  OUT CONST CHAR16   **GuidName
     2093  )
     2094{
     2095  CHAR16   *Name;
     2096
     2097  if (Guid == NULL || GuidName == NULL) {
     2098    return (EFI_INVALID_PARAMETER);
     2099  }
     2100
     2101  Name = GetStringNameFromGuid(Guid, NULL);
     2102  if (Name == NULL || StrLen(Name) == 0) {
     2103    SHELL_FREE_NON_NULL(Name);
     2104    return (EFI_NOT_FOUND);
     2105  }
     2106
     2107  *GuidName = AddBufferToFreeList(Name);
     2108
     2109  return (EFI_SUCCESS);
    19512110}
    19522111
     
    20382197  EFI_SHELL_FILE_INFO *ShellInfoNode;
    20392198  EFI_SHELL_FILE_INFO *NewShellNode;
     2199  EFI_FILE_INFO       *FileInfo;
    20402200  BOOLEAN             Directory;
    20412201  CHAR16              *NewFullName;
     
    20652225  if (CurrentFilePattern[0]   == CHAR_NULL
    20662226    &&NextFilePatternStart[0] == CHAR_NULL
    2067    ){
    2068     //
    2069     // Add the current parameter FileHandle to the list, then end...
     2227    ){
     2228    //
     2229    // we want the parent or root node (if no parent)
    20702230    //
    20712231    if (ParentNode == NULL) {
    2072       Status = EFI_INVALID_PARAMETER;
     2232      //
     2233      // We want the root node.  create the node.
     2234      //
     2235      FileInfo = FileHandleGetInfo(FileHandle);
     2236      NewShellNode = CreateAndPopulateShellFileInfo(
     2237        MapName,
     2238        EFI_SUCCESS,
     2239        L"\\",
     2240        FileHandle,
     2241        FileInfo
     2242        );
     2243      SHELL_FREE_NON_NULL(FileInfo);
    20732244    } else {
     2245      //
     2246      // Add the current parameter FileHandle to the list, then end...
     2247      //
    20742248      NewShellNode = InternalDuplicateShellFileInfo((EFI_SHELL_FILE_INFO*)ParentNode, TRUE);
    2075       if (NewShellNode == NULL) {
    2076         Status = EFI_OUT_OF_RESOURCES;
    2077       } else {
    2078         NewShellNode->Handle = NULL;
    2079         if (*FileList == NULL) {
    2080           *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
    2081           InitializeListHead(&((*FileList)->Link));
    2082         }
    2083 
    2084         //
    2085         // Add to the returning to use list
    2086         //
    2087         InsertTailList(&(*FileList)->Link, &NewShellNode->Link);
    2088 
    2089         Status = EFI_SUCCESS;
     2249    }
     2250    if (NewShellNode == NULL) {
     2251      Status = EFI_OUT_OF_RESOURCES;
     2252    } else {
     2253      NewShellNode->Handle = NULL;
     2254      if (*FileList == NULL) {
     2255        *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
     2256        InitializeListHead(&((*FileList)->Link));
    20902257      }
     2258
     2259      //
     2260      // Add to the returning to use list
     2261      //
     2262      InsertTailList(&(*FileList)->Link, &NewShellNode->Link);
     2263
     2264      Status = EFI_SUCCESS;
    20912265    }
    20922266  } else {
     
    21112285              Status = EFI_OUT_OF_RESOURCES;
    21122286            } else {
    2113               StrCpy(NewFullName, MapName);
    2114               StrCat(NewFullName, ShellInfoNode->FullName+1);
     2287              StrnCpy(NewFullName, MapName, Size/sizeof(CHAR16)-1);
     2288              StrnCat(NewFullName, ShellInfoNode->FullName+1, (Size/sizeof(CHAR16))-StrLen(NewFullName)-1);
    21152289              FreePool((VOID*)ShellInfoNode->FullName);
    21162290              ShellInfoNode->FullName = NewFullName;
     
    22352409  RootFileHandle = NULL;
    22362410  MapName        = NULL;
    2237   PatternCopy = AllocateZeroPool(StrSize(FilePattern));
     2411  PatternCopy = AllocateCopyPool(StrSize(FilePattern), FilePattern);
    22382412  if (PatternCopy == NULL) {
    22392413    return (EFI_OUT_OF_RESOURCES);
    22402414  }
    2241   StrCpy(PatternCopy, FilePattern);
    22422415
    22432416  PatternCopy = PathCleanUpDirectories(PatternCopy);
     
    23682541
    23692542/**
    2370   This function updated with errata.
    2371 
     2543  Gets the environment variable and Attributes, or list of environment variables.  Can be
     2544  used instead of GetEnv().
     2545
     2546  This function returns the current value of the specified environment variable and
     2547  the Attributes. If no variable name was specified, then all of the known
     2548  variables will be returned.
     2549
     2550  @param[in] Name               A pointer to the environment variable name. If Name is NULL,
     2551                                then the function will return all of the defined shell
     2552                                environment variables. In the case where multiple environment
     2553                                variables are being returned, each variable will be terminated
     2554                                by a NULL, and the list will be terminated by a double NULL.
     2555  @param[out] Attributes        If not NULL, a pointer to the returned attributes bitmask for
     2556                                the environment variable. In the case where Name is NULL, and
     2557                                multiple environment variables are being returned, Attributes
     2558                                is undefined.
     2559
     2560  @retval NULL                  The environment variable doesn't exist.
     2561  @return                       A non-NULL value points to the variable's value. The returned
     2562                                pointer does not need to be freed by the caller.
     2563**/
     2564CONST CHAR16 *
     2565EFIAPI
     2566EfiShellGetEnvEx(
     2567  IN  CONST CHAR16 *Name,
     2568  OUT       UINT32 *Attributes OPTIONAL
     2569  )
     2570{
     2571  EFI_STATUS  Status;
     2572  VOID        *Buffer;
     2573  UINTN       Size;
     2574  LIST_ENTRY  List;
     2575  ENV_VAR_LIST *Node;
     2576  CHAR16      *CurrentWriteLocation;
     2577
     2578  Size = 0;
     2579  Buffer = NULL;
     2580
     2581  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    }
     2590
     2591    //
     2592    // Build the semi-colon delimited list. (2 passes)
     2593    //
     2594    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
     2595      ; !IsNull(&List, &Node->Link)
     2596      ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     2597     ){
     2598      ASSERT(Node->Key != NULL);
     2599      Size += StrSize(Node->Key);
     2600    }
     2601
     2602    Size += 2*sizeof(CHAR16);
     2603
     2604    Buffer = AllocateZeroPool(Size);
     2605    if (Buffer == NULL) {
     2606      if (!IsListEmpty (&List)) {
     2607        FreeEnvironmentVariableList(&List);
     2608      }
     2609      return (NULL);
     2610    }
     2611    CurrentWriteLocation = (CHAR16*)Buffer;
     2612
     2613    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
     2614      ; !IsNull(&List, &Node->Link)
     2615      ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     2616     ){
     2617      ASSERT(Node->Key != NULL);
     2618      StrnCpy(CurrentWriteLocation, Node->Key,  (Size)/sizeof(CHAR16) - (CurrentWriteLocation - ((CHAR16*)Buffer)) - 1);
     2619      CurrentWriteLocation += StrLen(CurrentWriteLocation) + 1;
     2620    }
     2621
     2622    //
     2623    // Free the list...
     2624    //
     2625    if (!IsListEmpty (&List)) {
     2626      FreeEnvironmentVariableList(&List);
     2627    }
     2628  } else {
     2629    //
     2630    // We are doing a specific environment variable
     2631    //
     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) {
     2638      //
     2639      // Allocate the space and recall the get function
     2640      //
     2641      Buffer = AllocateZeroPool(Size);
     2642      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);
     2651      }
     2652      return (NULL);
     2653    }
     2654  }
     2655
     2656  //
     2657  // return the buffer
     2658  //
     2659  return (AddBufferToFreeList(Buffer));
     2660}
     2661
     2662/**
    23722663  Gets either a single or list of environment variables.
    23732664
     
    23862677                                NULL.
    23872678
    2388   @return !=NULL                A pointer to the returned string.
     2679  @retval !=NULL                A pointer to the returned string.
    23892680                                The returned pointer does not need to be freed by the caller.
    23902681
     
    23982689  )
    23992690{
    2400   EFI_STATUS  Status;
    2401   VOID        *Buffer;
    2402   UINTN       Size;
    2403   LIST_ENTRY  List;
    2404   ENV_VAR_LIST *Node;
    2405   CHAR16      *CurrentWriteLocation;
    2406 
    2407   Size = 0;
    2408   Buffer = NULL;
    2409 
    2410   if (Name == NULL) {
    2411     //
    2412     // Get all our environment variables
    2413     //
    2414     InitializeListHead(&List);
    2415     Status = GetEnvironmentVariableList(&List);
    2416     if (EFI_ERROR(Status)){
    2417       return (NULL);
    2418     }
    2419 
    2420     //
    2421     // Build the semi-colon delimited list. (2 passes)
    2422     //
    2423     for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
    2424       ; !IsNull(&List, &Node->Link)
    2425       ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
    2426      ){
    2427       ASSERT(Node->Key != NULL);
    2428       Size += StrSize(Node->Key);
    2429     }
    2430 
    2431     Size += 2*sizeof(CHAR16);
    2432 
    2433     Buffer = AllocateZeroPool(Size);
    2434     if (Buffer == NULL) {
    2435       if (!IsListEmpty (&List)) {
    2436         FreeEnvironmentVariableList(&List);
    2437       }
    2438       return (NULL);
    2439     }
    2440     CurrentWriteLocation = (CHAR16*)Buffer;
    2441 
    2442     for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
    2443       ; !IsNull(&List, &Node->Link)
    2444       ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
    2445      ){
    2446       ASSERT(Node->Key != NULL);
    2447       StrCpy(CurrentWriteLocation, Node->Key);
    2448       CurrentWriteLocation += StrLen(CurrentWriteLocation) + 1;
    2449     }
    2450 
    2451     //
    2452     // Free the list...
    2453     //
    2454     if (!IsListEmpty (&List)) {
    2455       FreeEnvironmentVariableList(&List);
    2456     }
    2457   } else {
    2458     //
    2459     // We are doing a specific environment variable
    2460     //
    2461 
    2462     //
    2463     // get the size we need for this EnvVariable
    2464     //
    2465     Status = SHELL_GET_ENVIRONMENT_VARIABLE(Name, &Size, Buffer);
    2466     if (Status == EFI_BUFFER_TOO_SMALL) {
    2467       //
    2468       // Allocate the space and recall the get function
    2469       //
    2470       Buffer = AllocateZeroPool(Size);
    2471       ASSERT(Buffer != NULL);
    2472       Status = SHELL_GET_ENVIRONMENT_VARIABLE(Name, &Size, Buffer);
    2473     }
    2474     //
    2475     // we didnt get it (might not exist)
    2476     // free the memory if we allocated any and return NULL
    2477     //
    2478     if (EFI_ERROR(Status)) {
    2479       if (Buffer != NULL) {
    2480         FreePool(Buffer);
    2481       }
    2482       return (NULL);
    2483     }
    2484   }
    2485 
    2486   //
    2487   // return the buffer
    2488   //
    2489   return (AddBufferToFreeList(Buffer));
     2691  return (EfiShellGetEnvEx(Name, NULL));
    24902692}
    24912693
     
    28253027{
    28263028  CONST CHAR16  *ManFileName;
     3029  CHAR16        *FixCommand;
     3030  EFI_STATUS    Status;
    28273031
    28283032  ASSERT(HelpText != NULL);
     3033  FixCommand = NULL;
    28293034
    28303035  ManFileName = ShellCommandGetManFileNameHandler(Command);
     
    28333038    return (ProcessManFile(ManFileName, Command, Sections, NULL, HelpText));
    28343039  } else {
    2835     return (ProcessManFile(Command, Command, Sections, NULL, HelpText));
     3040    if ((StrLen(Command)> 4)
     3041    && (Command[StrLen(Command)-1] == L'i' || Command[StrLen(Command)-1] == L'I')
     3042    && (Command[StrLen(Command)-2] == L'f' || Command[StrLen(Command)-2] == L'F')
     3043    && (Command[StrLen(Command)-3] == L'e' || Command[StrLen(Command)-3] == L'E')
     3044    && (Command[StrLen(Command)-4] == L'.')
     3045    ) {
     3046      FixCommand = AllocateZeroPool(StrSize(Command) - 4 * sizeof (CHAR16));
     3047      ASSERT(FixCommand != NULL);
     3048
     3049      StrnCpy(FixCommand, Command, StrLen(Command)-4);
     3050      Status = ProcessManFile(FixCommand, FixCommand, Sections, NULL, HelpText);
     3051      FreePool(FixCommand);
     3052      return Status;
     3053    } else {
     3054      return (ProcessManFile(Command, Command, Sections, NULL, HelpText));
     3055    }
    28363056  }
    28373057}
     
    28853105  )
    28863106{
    2887   UINT64            MaxStorSize;
    2888   UINT64            RemStorSize;
    2889   UINT64            MaxVarSize;
     3107 
    28903108  EFI_STATUS        Status;
    28913109  EFI_GUID          Guid;
    28923110  CHAR16            *VariableName;
    28933111  UINTN             NameSize;
     3112  UINTN             NameBufferSize;
    28943113  CHAR16            *RetVal;
    28953114  UINTN             RetSize;
    2896   CHAR16            *Alias;
    2897 
    2898   Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);
    2899   ASSERT_EFI_ERROR(Status);
    2900 
    2901   VariableName  = AllocateZeroPool((UINTN)MaxVarSize);
     3115
     3116  NameBufferSize = INIT_NAME_BUFFER_SIZE;
     3117  VariableName  = AllocateZeroPool(NameBufferSize);
    29023118  RetSize       = 0;
    29033119  RetVal        = NULL;
     
    29103126
    29113127  while (TRUE) {
    2912     NameSize = (UINTN)MaxVarSize;
     3128    NameSize = NameBufferSize;
    29133129    Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
    29143130    if (Status == EFI_NOT_FOUND){
    29153131      break;
    2916     }
    2917     ASSERT_EFI_ERROR(Status);
    2918     if (EFI_ERROR(Status)) {
     3132    } else if (Status == EFI_BUFFER_TOO_SMALL) {
     3133      NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
     3134      SHELL_FREE_NON_NULL(VariableName);
     3135      VariableName = AllocateZeroPool(NameBufferSize);
     3136      if (VariableName == NULL) {
     3137        Status = EFI_OUT_OF_RESOURCES;
     3138        SHELL_FREE_NON_NULL(RetVal);
     3139        RetVal = NULL;
     3140        break;
     3141      }
     3142     
     3143      NameSize = NameBufferSize;
     3144      Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
     3145    }
     3146   
     3147    if (EFI_ERROR (Status)) {
     3148      SHELL_FREE_NON_NULL(RetVal);
     3149      RetVal = NULL;
    29193150      break;
    29203151    }
     3152   
    29213153    if (CompareGuid(&Guid, &gShellAliasGuid)){
    2922       Alias = GetVariable(VariableName, &gShellAliasGuid);
    29233154      ASSERT((RetVal == NULL && RetSize == 0) || (RetVal != NULL));
    29243155      RetVal = StrnCatGrow(&RetVal, &RetSize, VariableName, 0);
     
    29263157    } // compare guid
    29273158  } // while
    2928   FreePool(VariableName);
     3159  SHELL_FREE_NON_NULL(VariableName);
    29293160
    29303161  return (RetVal);
     3162}
     3163
     3164/**
     3165  Convert a null-terminated unicode string, in-place, to all lowercase.
     3166  Then return it.
     3167 
     3168  @param  Str    The null-terminated string to be converted to all lowercase.
     3169 
     3170  @return        The null-terminated string converted into all lowercase. 
     3171**/
     3172CHAR16 *
     3173ToLower (
     3174  CHAR16 *Str
     3175  )
     3176{
     3177  UINTN Index;
     3178
     3179  for (Index = 0; Str[Index] != L'\0'; Index++) {
     3180    if (Str[Index] >= L'A' && Str[Index] <= L'Z') {
     3181      Str[Index] -= (CHAR16)(L'A' - L'a');
     3182    }
     3183  }
     3184  return Str;
    29313185}
    29323186
     
    29603214  UINT32      Attribs;
    29613215  EFI_STATUS  Status;
    2962 
     3216  CHAR16      *AliasLower;
     3217
     3218  // Convert to lowercase to make aliases case-insensitive
    29633219  if (Alias != NULL) {
     3220    AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
     3221    ASSERT (AliasLower != NULL);
     3222    ToLower (AliasLower);
     3223
    29643224    if (Volatile == NULL) {
    2965       return (AddBufferToFreeList(GetVariable((CHAR16*)Alias, &gShellAliasGuid)));
     3225      return (AddBufferToFreeList(GetVariable(AliasLower, &gShellAliasGuid)));
    29663226    }
    29673227    RetSize = 0;
    29683228    RetVal = NULL;
    2969     Status = gRT->GetVariable((CHAR16*)Alias, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
     3229    Status = gRT->GetVariable(AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
    29703230    if (Status == EFI_BUFFER_TOO_SMALL) {
    29713231      RetVal = AllocateZeroPool(RetSize);
    2972       Status = gRT->GetVariable((CHAR16*)Alias, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
     3232      Status = gRT->GetVariable(AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
    29733233    }
    29743234    if (EFI_ERROR(Status)) {
     
    29843244    }
    29853245
     3246    FreePool (AliasLower);
    29863247    return (AddBufferToFreeList(RetVal));
    29873248  }
     
    30133274  )
    30143275{
     3276  EFI_STATUS  Status;
     3277  CHAR16      *AliasLower;
     3278
     3279  // 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);
     3284  } else {
     3285    AliasLower = NULL;
     3286  }
     3287
    30153288  //
    30163289  // We must be trying to remove one if Alias is NULL
     
    30203293    // remove an alias (but passed in COMMAND parameter)
    30213294    //
    3022     return (gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL));
     3295    Status = (gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL));
    30233296  } else {
    30243297    //
     
    30293302    gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL);
    30303303
    3031     return (gRT->SetVariable((CHAR16*)Alias, &gShellAliasGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS|(Volatile?0:EFI_VARIABLE_NON_VOLATILE), StrSize(Command), (VOID*)Command));
    3032   }
     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  }
     3310  return Status;
    30333311}
    30343312
     
    30523330  @retval EFI_ACCESS_DENIED     The alias is a built-in alias or already existed and Replace was set to
    30533331                                FALSE.
     3332  @retval EFI_INVALID_PARAMETER Command is null or the empty string.
    30543333**/
    30553334EFI_STATUS
     
    30623341  )
    30633342{
    3064   //
    3065   // cant set over a built in alias
    3066   //
    30673343  if (ShellCommandIsOnAliasList(Alias==NULL?Command:Alias)) {
     3344    //
     3345    // cant set over a built in alias
     3346    //
    30683347    return (EFI_ACCESS_DENIED);
    3069   }
    3070   if (Command == NULL || *Command == CHAR_NULL || StrLen(Command) == 0) {
     3348  } else if (Command == NULL || *Command == CHAR_NULL || StrLen(Command) == 0) {
     3349    //
     3350    // Command is null or empty
     3351    //
    30713352    return (EFI_INVALID_PARAMETER);
    3072   }
    3073 
    3074   if (EfiShellGetAlias(Command, NULL) != NULL && !Replace) {
     3353  } else if (EfiShellGetAlias(Command, NULL) != NULL && !Replace) {
     3354    //
     3355    // Alias already exists, Replace not set
     3356    //
    30753357    return (EFI_ACCESS_DENIED);
    3076   }
    3077 
    3078   return (InternalSetAlias(Command, Alias, Volatile));
     3358  } else {
     3359    return (InternalSetAlias(Command, Alias, Volatile));
     3360  }
    30793361}
    30803362
     
    31233405  NULL,
    31243406  SHELL_MAJOR_VERSION,
    3125   SHELL_MINOR_VERSION
     3407  SHELL_MINOR_VERSION,
     3408
     3409  // New for UEFI Shell 2.1
     3410  EfiShellRegisterGuidName,
     3411  EfiShellGetGuidName,
     3412  EfiShellGetGuidFromName,
     3413  EfiShellGetEnvEx
    31263414};
    31273415
     
    33373625  )
    33383626{
    3339 //  ShellPrintEx(-1,-1,L"  <Notify>  ");
    3340    if ((KeyData->Key.UnicodeChar == L'c' || KeyData->Key.UnicodeChar == 3) &&
    3341       (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState  == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED))
     3627  if ( ((KeyData->Key.UnicodeChar == L'c') &&
     3628        (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState  == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED))) ||
     3629      (KeyData->Key.UnicodeChar == 3)
    33423630      ){
    33433631    if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {
     
    34293717  return (Status);
    34303718}
     3719
  • trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Application/Shell/ShellProtocol.h

    r48674 r58459  
    33  manipulation, and initialization of EFI_SHELL_PROTOCOL.
    44
    5   Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
     5  (C) Copyright 2014, Hewlett-Packard Development Company, L.P.
     6  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
    67  This program and the accompanying materials
    78  are licensed and made available under the terms and conditions of the BSD License
     
    1718#define _SHELL_PROTOCOL_HEADER_
    1819
    19 #include <Uefi.h>
    20 #include <ShellBase.h>
    21 
    22 #include <Guid/ShellVariableGuid.h>
    23 #include <Guid/ShellMapGuid.h>
    24 #include <Guid/ShellAliasGuid.h>
    25 
    26 #include <Protocol/EfiShell.h>
    27 #include <Protocol/EfiShellParameters.h>
    28 #include <Protocol/SimpleFileSystem.h>
    29 #include <Protocol/DevicePathToText.h>
    30 #include <Protocol/ComponentName2.h>
    31 #include <Protocol/LoadedImage.h>
    32 #include <Protocol/UnicodeCollation.h>
    33 #include <Protocol/DevicePath.h>
    34 #include <Protocol/SimpleTextInEx.h>
    35 
    36 #include <Library/UefiBootServicesTableLib.h>
    37 #include <Library/BaseLib.h>
    38 #include <Library/ShellCommandLib.h>
    39 #include <Library/PrintLib.h>
    40 #include <Library/DevicePathLib.h>
    41 #include <Library/UefiRuntimeServicesTableLib.h>
    42 #include <Library/DebugLib.h>
    43 #include <Library/MemoryAllocationLib.h>
    44 #include <Library/BaseMemoryLib.h>
    45 #include <Library/UefiLib.h>
    46 #include <Library/SortLib.h>
    47 #include <Library/PcdLib.h>
    48 #include <Library/ShellLib.h>
    49 
    50 #include "FileHandleWrappers.h"
    51 #include "ShellEnvVar.h"
    52 #include "ShellManParser.h"
     20#include "Shell.h"
    5321
    5422typedef struct {
     
    467435  internal worker function to run a command via Device Path
    468436
    469   @param ParentImageHandle  A handle of the image that is executing the specified
    470                             command line.
    471   @param DevicePath         device path of the file to execute
    472   @param CommandLine        Points to the NULL-terminated UCS-2 encoded string
    473                             containing the command line. If NULL then the command-
    474                             line will be empty.
    475   @param Environment        Points to a NULL-terminated array of environment
    476                             variables with the format 'x=y', where x is the
    477                             environment variable name and y is the value. If this
    478                             is NULL, then the current shell environment is used.
    479   @param StatusCode         Points to the status code returned by the command.
     437  @param ParentImageHandle      A handle of the image that is executing the specified
     438                                command line.
     439  @param DevicePath             device path of the file to execute
     440  @param CommandLine            Points to the NULL-terminated UCS-2 encoded string
     441                                containing the command line. If NULL then the command-
     442                                line will be empty.
     443  @param Environment            Points to a NULL-terminated array of environment
     444                                variables with the format 'x=y', where x is the
     445                                environment variable name and y is the value. If this
     446                                is NULL, then the current shell environment is used.
     447  @param[out] StartImageStatus  Returned status from gBS->StartImage.
    480448
    481449  @retval EFI_SUCCESS       The command executed successfully. The  status code
     
    488456EFIAPI
    489457InternalShellExecuteDevicePath(
    490   IN CONST EFI_HANDLE *ParentImageHandle,
     458  IN CONST EFI_HANDLE               *ParentImageHandle,
    491459  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
    492   IN CONST CHAR16 *CommandLine OPTIONAL,
    493   IN CONST CHAR16 **Environment OPTIONAL,
    494   OUT EFI_STATUS *StatusCode OPTIONAL
     460  IN CONST CHAR16                   *CommandLine OPTIONAL,
     461  IN CONST CHAR16                   **Environment OPTIONAL,
     462  OUT EFI_STATUS                    *StartImageStatus OPTIONAL
    495463  );
    496464
     
    589557  @param[in] BasePath         the Path to prepend onto filename for FullPath
    590558  @param[in] Status           Status member initial value.
    591   @param[in] FullName         FullName member initial value.
    592559  @param[in] FileName         FileName member initial value.
    593560  @param[in] Handle           Handle member initial value.
     
    600567  IN CONST CHAR16 *BasePath,
    601568  IN CONST EFI_STATUS Status,
    602   IN CONST CHAR16 *FullName,
    603569  IN CONST CHAR16 *FileName,
    604570  IN CONST SHELL_FILE_HANDLE Handle,
     
    689655  @param Name                   A pointer to the environment variable name
    690656
    691   @return !=NULL                The environment variable's value. The returned
     657  @retval !=NULL                The environment variable's value. The returned
    692658                                pointer does not need to be freed by the caller.
    693659  @retval NULL                  The environment variable doesn't exist.
Note: See TracChangeset for help on using the changeset viewer.

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