]> git.proxmox.com Git - mirror_edk2.git/commitdiff
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8563 6f19259b...
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Jun 2009 23:45:12 +0000 (23:45 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Jun 2009 23:45:12 +0000 (23:45 +0000)
ShellPkg/Library/UefiShellLib/BaseShellLib.c [deleted file]
ShellPkg/Library/UefiShellLib/BaseShellLib.h [deleted file]
ShellPkg/Library/UefiShellLib/BaseShellLib.inf [deleted file]
ShellPkg/Library/UefiShellLib/UefiShellLib.c [new file with mode: 0644]
ShellPkg/Library/UefiShellLib/UefiShellLib.h [new file with mode: 0644]
ShellPkg/Library/UefiShellLib/UefiShellLib.inf [new file with mode: 0644]
ShellPkg/ShellPkg.dsc

diff --git a/ShellPkg/Library/UefiShellLib/BaseShellLib.c b/ShellPkg/Library/UefiShellLib/BaseShellLib.c
deleted file mode 100644 (file)
index 1ddff9a..0000000
+++ /dev/null
@@ -1,1939 +0,0 @@
-/** @file\r
-  Provides interface to shell functionality for shell commands and applications.\r
-\r
-Copyright (c) 2006 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-#include <Library/ShellLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/FileHandleLib.h>\r
-#include <Protocol/EfiShellEnvironment2.h>\r
-#include <Protocol/EfiShellInterface.h>\r
-#include <Protocol/EfiShell.h>\r
-#include <Protocol/EfiShellParameters.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
-\r
-#include "BaseShellLib.h"\r
-\r
-#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
-#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
-\r
-//\r
-// This is not static since it's extern in the .h file\r
-//\r
-SHELL_PARAM_ITEM EmptyParamList[] = {\r
-  {NULL, TypeMax}\r
-  };\r
-\r
-//\r
-// Static file globals for the shell library\r
-//\r
-STATIC EFI_SHELL_ENVIRONMENT2        *mEfiShellEnvironment2;\r
-STATIC EFI_SHELL_INTERFACE           *mEfiShellInterface;\r
-STATIC EFI_SHELL_PROTOCOL            *mEfiShellProtocol;\r
-STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
-STATIC EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
-STATIC FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
-\r
-/**\r
-  helper function to find ShellEnvironment2 for constructor\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellFindSE2 (\r
-  IN EFI_HANDLE        ImageHandle\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_HANDLE  *Buffer;\r
-  UINTN       BufferSize;\r
-  UINTN       HandleIndex;\r
-\r
-  BufferSize = 0;\r
-  Buffer = NULL;\r
-  Status = gBS->OpenProtocol(ImageHandle, \r
-                             &gEfiShellEnvironment2Guid,\r
-                             (VOID **)&mEfiShellEnvironment2,\r
-                             ImageHandle,\r
-                             NULL,\r
-                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                             );\r
-  //\r
-  // look for the mEfiShellEnvironment2 protocol at a higher level\r
-  //\r
-  if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
-     (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
-     (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER)))) {\r
-    //\r
-    // figure out how big of a buffer we need.\r
-    //\r
-    Status = gBS->LocateHandle (ByProtocol,\r
-                                &gEfiShellEnvironment2Guid,\r
-                                NULL, // ignored for ByProtocol\r
-                                &BufferSize,\r
-                                Buffer\r
-                                );\r
-    ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
-    Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
-    ASSERT(Buffer != NULL);\r
-    Status = gBS->LocateHandle (ByProtocol,\r
-                                &gEfiShellEnvironment2Guid,\r
-                                NULL, // ignored for ByProtocol\r
-                                &BufferSize,\r
-                                Buffer\r
-                                );\r
-    if (!EFI_ERROR (Status)) {\r
-      //\r
-      // now parse the list of returned handles\r
-      //\r
-      Status = EFI_NOT_FOUND;\r
-      for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof(Buffer[0])); HandleIndex++) {\r
-        Status = gBS->OpenProtocol(Buffer[HandleIndex], \r
-                                   &gEfiShellEnvironment2Guid,\r
-                                   (VOID **)&mEfiShellEnvironment2,\r
-                                   ImageHandle,\r
-                                   NULL,\r
-                                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                                   );\r
-         if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
-          (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
-          (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER))) {\r
-          mEfiShellEnvironment2Handle = Buffer[HandleIndex];\r
-          Status = EFI_SUCCESS;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  if (Buffer != NULL) {\r
-    FreePool (Buffer);\r
-  }\r
-  return (Status);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ShellLibConstructorWorker (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-){\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // UEFI 2.0 shell interfaces (used preferentially)\r
-  //\r
-  Status = gBS->OpenProtocol(ImageHandle, \r
-                             &gEfiShellProtocolGuid,\r
-                             (VOID **)&mEfiShellProtocol,\r
-                             ImageHandle,\r
-                             NULL,\r
-                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                             );\r
-  if (EFI_ERROR(Status)) {\r
-    mEfiShellProtocol = NULL;\r
-  }\r
-  Status = gBS->OpenProtocol(ImageHandle, \r
-                             &gEfiShellParametersProtocolGuid,\r
-                             (VOID **)&mEfiShellParametersProtocol,\r
-                             ImageHandle,\r
-                             NULL,\r
-                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                             );\r
-  if (EFI_ERROR(Status)) {\r
-    mEfiShellParametersProtocol = NULL;\r
-  }\r
-\r
-  if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) {\r
-    //\r
-    // Moved to seperate function due to complexity\r
-    //\r
-    Status = ShellFindSE2(ImageHandle);\r
-\r
-    if (EFI_ERROR(Status)) {\r
-      DEBUG((DEBUG_ERROR, "Status: 0x%08x\r\n", Status));\r
-      mEfiShellEnvironment2 = NULL;\r
-    }\r
-    Status = gBS->OpenProtocol(ImageHandle, \r
-                               &gEfiShellInterfaceGuid,\r
-                               (VOID **)&mEfiShellInterface,\r
-                               ImageHandle,\r
-                               NULL,\r
-                               EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                               );\r
-    if (EFI_ERROR(Status)) {\r
-      mEfiShellInterface = NULL;\r
-    }\r
-  }\r
-  //\r
-  // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
-  //\r
-  if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) || \r
-      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)    ) {\r
-    if (mEfiShellProtocol != NULL) {\r
-      FileFunctionMap.GetFileInfo     = mEfiShellProtocol->GetFileInfo;\r
-      FileFunctionMap.SetFileInfo     = mEfiShellProtocol->SetFileInfo;\r
-      FileFunctionMap.ReadFile        = mEfiShellProtocol->ReadFile;\r
-      FileFunctionMap.WriteFile       = mEfiShellProtocol->WriteFile;\r
-      FileFunctionMap.CloseFile       = mEfiShellProtocol->CloseFile;\r
-      FileFunctionMap.DeleteFile      = mEfiShellProtocol->DeleteFile;\r
-      FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;\r
-      FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;\r
-      FileFunctionMap.FlushFile       = mEfiShellProtocol->FlushFile;\r
-      FileFunctionMap.GetFileSize     = mEfiShellProtocol->GetFileSize;\r
-    } else {\r
-      FileFunctionMap.GetFileInfo     = FileHandleGetInfo;\r
-      FileFunctionMap.SetFileInfo     = FileHandleSetInfo;\r
-      FileFunctionMap.ReadFile        = FileHandleRead;\r
-      FileFunctionMap.WriteFile       = FileHandleWrite;\r
-      FileFunctionMap.CloseFile       = FileHandleClose;\r
-      FileFunctionMap.DeleteFile      = FileHandleDelete;\r
-      FileFunctionMap.GetFilePosition = FileHandleGetPosition;\r
-      FileFunctionMap.SetFilePosition = FileHandleSetPosition;\r
-      FileFunctionMap.FlushFile       = FileHandleFlush;\r
-      FileFunctionMap.GetFileSize     = FileHandleGetSize;\r
-    }\r
-    return (EFI_SUCCESS);\r
-  }\r
-  return (EFI_NOT_FOUND);\r
-}\r
-/**\r
-  Constructor for the Shell library.\r
-\r
-  Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.\r
-\r
-  @param ImageHandle    the image handle of the process\r
-  @param SystemTable    the EFI System Table pointer\r
-\r
-  @retval EFI_SUCCESS   the initialization was complete sucessfully\r
-  @return others        an error ocurred during initialization\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellLibConstructor (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-\r
-\r
-  mEfiShellEnvironment2       = NULL;\r
-  mEfiShellProtocol           = NULL;\r
-  mEfiShellParametersProtocol = NULL;\r
-  mEfiShellInterface          = NULL;\r
-  mEfiShellEnvironment2Handle = NULL;\r
-\r
-  ///@todo make a worker constructor so initialize function works\r
-  //\r
-  // verify that auto initialize is not set false\r
-  // \r
-  if (PcdGetBool(PcdShellLibAutoInitialize) == 0) {\r
-    return (EFI_SUCCESS);\r
-  }\r
-  \r
-  return (ShellLibConstructorWorker(ImageHandle, SystemTable));\r
-}\r
-\r
-/**\r
-  Destructory for the library.  free any resources.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellLibDestructor (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  if (mEfiShellEnvironment2 != NULL) {\r
-    gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
-                       &gEfiShellEnvironment2Guid,\r
-                       ImageHandle,\r
-                       NULL);\r
-    mEfiShellEnvironment2 = NULL;\r
-  }\r
-  if (mEfiShellInterface != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
-                       &gEfiShellInterfaceGuid,\r
-                       ImageHandle,\r
-                       NULL);  \r
-    mEfiShellInterface = NULL;\r
-  }\r
-  if (mEfiShellProtocol != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
-                       &gEfiShellProtocolGuid,\r
-                       ImageHandle,\r
-                       NULL);  \r
-    mEfiShellProtocol = NULL;\r
-  }\r
-  if (mEfiShellParametersProtocol != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
-                       &gEfiShellParametersProtocolGuid,\r
-                       ImageHandle,\r
-                       NULL);    \r
-    mEfiShellParametersProtocol = NULL;\r
-  }\r
-  mEfiShellEnvironment2Handle = NULL;\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  This function causes the shell library to initialize itself.  If the shell library\r
-  is already initialized it will de-initialize all the current protocol poitners and\r
-  re-populate them again.\r
-\r
-  When the library is used with PcdShellLibAutoInitialize set to true this function\r
-  will return EFI_SUCCESS and perform no actions.\r
-\r
-  This function is intended for internal access for shell commands only.\r
-\r
-  @retval EFI_SUCCESS   the initialization was complete sucessfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellInitialize (\r
-  ) {\r
-  //\r
-  // if auto initialize is not false then skip\r
-  //\r
-  if (PcdGetBool(PcdShellLibAutoInitialize) != 0) {\r
-    return (EFI_SUCCESS);\r
-  }\r
-\r
-  //\r
-  // deinit the current stuff\r
-  //\r
-  ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));\r
-\r
-  //\r
-  // init the new stuff\r
-  //\r
-  return (ShellLibConstructorWorker(gImageHandle, gST));\r
-}\r
-\r
-/**\r
-  This function will retrieve the information about the file for the handle \r
-  specified and store it in allocated pool memory.\r
-\r
-  This function allocates a buffer to store the file's information. It is the \r
-  caller's responsibility to free the buffer\r
-\r
-  @param  FileHandle  The file handle of the file for which information is \r
-  being requested.\r
-\r
-  @retval NULL information could not be retrieved.\r
-\r
-  @return the information about the file\r
-**/\r
-EFI_FILE_INFO*\r
-EFIAPI\r
-ShellGetFileInfo (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
-  return (FileFunctionMap.GetFileInfo(FileHandle));\r
-}\r
-\r
-/**\r
-  This function will set the information about the file for the opened handle \r
-  specified.\r
-\r
-  @param  FileHandle            The file handle of the file for which information \r
-  is being set\r
-\r
-  @param  FileInfo              The infotmation to set.\r
-\r
-  @retval EFI_SUCCESS          The information was set.\r
-  @retval EFI_UNSUPPORTED The InformationType is not known.\r
-  @retval EFI_NO_MEDIA         The device has no medium.\r
-  @retval EFI_DEVICE_ERROR     The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED  The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
-  @retval EFI_VOLUME_FULL      The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellSetFileInfo (\r
-  IN EFI_FILE_HANDLE           FileHandle,\r
-  IN EFI_FILE_INFO              *FileInfo\r
-  )\r
-{\r
-  return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
-}  \r
-  \r
-  /**\r
-  This function will open a file or directory referenced by DevicePath.\r
-\r
-  This function opens a file with the open mode according to the file path. The \r
-  Attributes is valid only for EFI_FILE_MODE_CREATE.\r
-\r
-  @param  FilePath                 on input the device path to the file.  On output \r
-                          the remaining device path.\r
-  @param  DeviceHandle         pointer to the system device handle.\r
-  @param  FileHandle             pointer to the file handle.\r
-  @param  OpenMode                 the mode to open the file with.\r
-  @param  Attributes             the file's file attributes.\r
-\r
-  @retval EFI_SUCCESS                  The information was set.\r
-  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
-  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
-  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
-                                device or the file system could not be found on \r
-                                the device.\r
-  @retval EFI_NO_MEDIA               The device has no medium.\r
-  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
-                                medium is no longer supported.\r
-  @retval EFI_DEVICE_ERROR         The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
-  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
-                                file.\r
-  @retval EFI_VOLUME_FULL            The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellOpenFileByDevicePath(\r
-  IN OUT EFI_DEVICE_PATH_PROTOCOL        **FilePath,\r
-  OUT EFI_HANDLE                       *DeviceHandle,\r
-  OUT EFI_FILE_HANDLE                  *FileHandle,\r
-  IN UINT64                            OpenMode,\r
-  IN UINT64                            Attributes\r
-  )\r
-{\r
-  CHAR16      *FileName;\r
-  EFI_STATUS  Status;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
-  EFI_FILE_HANDLE LastHandle;\r
-\r
-  //\r
-  // ASERT for FileHandle, FilePath, and DeviceHandle being NULL\r
-  //\r
-  ASSERT(FilePath != NULL);\r
-  ASSERT(FileHandle != NULL);\r
-  ASSERT(DeviceHandle != NULL);\r
-  // \r
-  // which shell interface should we use\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    //\r
-    // use UEFI Shell 2.0 method.\r
-    //\r
-    FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath);\r
-    if (FileName == NULL) {\r
-      return (EFI_INVALID_PARAMETER);\r
-    }\r
-    Status = ShellOpenFileByName(FileName, FileHandle, OpenMode, Attributes);\r
-    FreePool(FileName);\r
-    return (Status);\r
-  } \r
-\r
-\r
-  //\r
-  // use old shell method.\r
-  //\r
-  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, \r
-                                  FilePath, \r
-                                  DeviceHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  Status = gBS->OpenProtocol(*DeviceHandle,\r
-                             &gEfiSimpleFileSystemProtocolGuid,\r
-                             (VOID**) &EfiSimpleFileSystemProtocol,\r
-                             gImageHandle,\r
-                             NULL,\r
-                             EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    FileHandle = NULL;\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // go down directories one node at a time.\r
-  //\r
-  while (!IsDevicePathEnd (*FilePath)) {\r
-    //\r
-    // For file system access each node should be a file path component\r
-    //\r
-    if (DevicePathType    (*FilePath) != MEDIA_DEVICE_PATH ||\r
-        DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP\r
-        ) {\r
-      FileHandle = NULL;\r
-      return (EFI_INVALID_PARAMETER);\r
-    }\r
-    //\r
-    // Open this file path node\r
-    //\r
-    LastHandle  = *FileHandle;\r
-    *FileHandle = NULL;\r
-\r
-    //\r
-    // Try to test opening an existing file\r
-    //\r
-    Status = LastHandle->Open (\r
-                          LastHandle,\r
-                          FileHandle,\r
-                          ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
-                          OpenMode &~EFI_FILE_MODE_CREATE,\r
-                          0\r
-                          );\r
-\r
-    //\r
-    // see if the error was that it needs to be created\r
-    //\r
-    if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {\r
-      Status = LastHandle->Open (\r
-                            LastHandle,\r
-                            FileHandle,\r
-                            ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
-                            OpenMode,\r
-                            Attributes\r
-                            );\r
-    }\r
-    //\r
-    // Close the last node\r
-    //\r
-    LastHandle->Close (LastHandle);\r
-\r
-    if (EFI_ERROR(Status)) {\r
-      return (Status);\r
-    }\r
-\r
-    //\r
-    // Get the next node\r
-    //\r
-    *FilePath = NextDevicePathNode (*FilePath);\r
-  }\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  This function will open a file or directory referenced by filename.\r
-\r
-  If return is EFI_SUCCESS, the Filehandle is the opened file's handle; \r
-  otherwise, the Filehandle is NULL. The Attributes is valid only for \r
-  EFI_FILE_MODE_CREATE.\r
-\r
-  if FileNAme is NULL then ASSERT()\r
-\r
-  @param  FileName               pointer to file name\r
-  @param  FileHandle           pointer to the file handle.\r
-  @param  OpenMode               the mode to open the file with.\r
-  @param  Attributes           the file's file attributes.\r
-\r
-  @retval EFI_SUCCESS                  The information was set.\r
-  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
-  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
-  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
-                                device or the file system could not be found \r
-                                on the device.\r
-  @retval EFI_NO_MEDIA               The device has no medium.\r
-  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
-                                medium is no longer supported.\r
-  @retval EFI_DEVICE_ERROR         The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED        The file was opened read only.\r
-  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
-                                file.\r
-  @retval EFI_VOLUME_FULL            The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellOpenFileByName(\r
-  IN CHAR16                              *FileName,\r
-  OUT EFI_FILE_HANDLE           *FileHandle,\r
-  IN UINT64                     OpenMode,\r
-  IN UINT64                            Attributes\r
-  )\r
-{\r
-  EFI_HANDLE                    DeviceHandle;\r
-  EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
-\r
-  //\r
-  // ASSERT if FileName is NULL\r
-  //\r
-  ASSERT(FileName != NULL);\r
-\r
-  if (mEfiShellProtocol != NULL) {\r
-    //\r
-    // Use UEFI Shell 2.0 method\r
-    //\r
-    return (mEfiShellProtocol->OpenFileByName(FileName,\r
-                                             FileHandle,\r
-                                             OpenMode));\r
-\r
-    ///@todo add the attributes\r
-  } \r
-  //\r
-  // Using EFI Shell version\r
-  // this means convert name to path and call that function\r
-  // since this will use EFI method again that will open it.\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  FilePath = mEfiShellEnvironment2->NameToPath (FileName);\r
-  if (FileDevicePath != NULL) {\r
-    return (ShellOpenFileByDevicePath(&FilePath,\r
-                                      &DeviceHandle,\r
-                                      FileHandle,\r
-                                      OpenMode,\r
-                                      Attributes ));\r
-  }\r
-  return (EFI_DEVICE_ERROR);\r
-}\r
-/**\r
-  This function create a directory\r
-\r
-  If return is EFI_SUCCESS, the Filehandle is the opened directory's handle; \r
-  otherwise, the Filehandle is NULL. If the directory already existed, this \r
-  function opens the existing directory.\r
-\r
-  @param  DirectoryName                pointer to directory name\r
-  @param  FileHandle             pointer to the file handle.\r
-\r
-  @retval EFI_SUCCESS                  The information was set.\r
-  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
-  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
-  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
-                                device or the file system could not be found \r
-                                on the device.\r
-  @retval EFI_NO_MEDIA               The device has no medium.\r
-  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
-                                medium is no longer supported.\r
-  @retval EFI_DEVICE_ERROR         The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED        The file was opened read only.\r
-  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
-                                file.\r
-  @retval EFI_VOLUME_FULL            The volume is full.\r
-  @sa ShellOpenFileByName\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellCreateDirectory(\r
-  IN CHAR16                   *DirectoryName,\r
-  OUT EFI_FILE_HANDLE         *FileHandle\r
-  )\r
-{\r
-  //\r
-  // this is a pass thru to the open file function with sepcific open mode and attributes\r
-  //\r
-  return (ShellOpenFileByName(DirectoryName,\r
-                              FileHandle,\r
-                              EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
-                              EFI_FILE_DIRECTORY\r
-                              ));\r
-}\r
-\r
-/**\r
-  This function reads information from an opened file.\r
-\r
-  If FileHandle is not a directory, the function reads the requested number of \r
-  bytes from the file at the file's current position and returns them in Buffer. \r
-  If the read goes beyond the end of the file, the read length is truncated to the\r
-  end of the file. The file's current position is increased by the number of bytes \r
-  returned.  If FileHandle is a directory, the function reads the directory entry \r
-  at the file's current position and returns the entry in Buffer. If the Buffer \r
-  is not large enough to hold the current directory entry, then \r
-  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated. \r
-  BufferSize is set to be the size of the buffer needed to read the entry. On \r
-  success, the current position is updated to the next directory entry. If there \r
-  are no more directory entries, the read returns a zero-length buffer. \r
-  EFI_FILE_INFO is the structure returned as the directory entry.\r
-\r
-  @param FileHandle             the opened file handle\r
-  @param BufferSize             on input the size of buffer in bytes.  on return \r
-                                the number of bytes written.\r
-  @param Buffer                 the buffer to put read data into.\r
-\r
-  @retval EFI_SUCCESS            Data was read.\r
-  @retval EFI_NO_MEDIA         The device has no media.\r
-  @retval EFI_DEVICE_ERROR     The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_BUFFER_TO_SMALL  Buffer is too small. ReadSize contains required \r
-                                size.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellReadFile(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  IN OUT UINTN                  *BufferSize,\r
-  OUT VOID                      *Buffer\r
-  )\r
-{\r
-  return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));\r
-}\r
-\r
-\r
-/**\r
-  Write data to a file.\r
-\r
-  This function writes the specified number of bytes to the file at the current \r
-  file position. The current file position is advanced the actual number of bytes \r
-  written, which is returned in BufferSize. Partial writes only occur when there \r
-  has been a data error during the write attempt (such as "volume space full"). \r
-  The file is automatically grown to hold the data if required. Direct writes to \r
-  opened directories are not supported.\r
-\r
-  @param FileHandle           The opened file for writing\r
-  @param BufferSize           on input the number of bytes in Buffer.  On output\r
-                              the number of bytes written.\r
-  @param Buffer               the buffer containing data to write is stored.\r
-\r
- @retval EFI_SUCCESS           Data was written.\r
- @retval EFI_UNSUPPORTED           Writes to an open directory are not supported.\r
- @retval EFI_NO_MEDIA          The device has no media.\r
- @retval EFI_DEVICE_ERROR          The device reported an error.\r
- @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
- @retval EFI_WRITE_PROTECTED   The device is write-protected.\r
- @retval EFI_ACCESS_DENIED       The file was open for read only.\r
- @retval EFI_VOLUME_FULL           The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellWriteFile(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  IN OUT UINTN                  *BufferSize,\r
-  IN VOID                       *Buffer\r
-  )\r
-{\r
-  return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));\r
-}\r
-\r
-/** \r
-  Close an open file handle.\r
-\r
-  This function closes a specified file handle. All "dirty" cached file data is \r
-  flushed to the device, and the file is closed. In all cases the handle is \r
-  closed.\r
-\r
-@param FileHandle               the file handle to close.\r
-\r
-@retval EFI_SUCCESS             the file handle was closed sucessfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellCloseFile (\r
-  IN EFI_FILE_HANDLE            *FileHandle\r
-  )\r
-{\r
-  return (FileFunctionMap.CloseFile(*FileHandle));\r
-}\r
-\r
-/**\r
-  Delete a file and close the handle\r
-\r
-  This function closes and deletes a file. In all cases the file handle is closed.\r
-  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is \r
-  returned, but the handle is still closed.\r
-\r
-  @param FileHandle             the file handle to delete\r
-\r
-  @retval EFI_SUCCESS           the file was closed sucessfully\r
-  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not \r
-                                deleted\r
-  @retval INVALID_PARAMETER            One of the parameters has an invalid value.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellDeleteFile (\r
-  IN EFI_FILE_HANDLE           *FileHandle\r
-  )\r
-{\r
-  return (FileFunctionMap.DeleteFile(*FileHandle));\r
-}\r
-\r
-/**\r
-  Set the current position in a file.\r
-\r
-  This function sets the current file position for the handle to the position \r
-  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only\r
-  absolute positioning is supported, and seeking past the end of the file is \r
-  allowed (a subsequent write would grow the file). Seeking to position \r
-  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.\r
-  If FileHandle is a directory, the only position that may be set is zero. This \r
-  has the effect of starting the read process of the directory entries over.\r
-\r
-  @param FileHandle             The file handle on which the position is being set\r
-  @param Position               Byte position from begining of file\r
-\r
-  @retval EFI_SUCCESS           Operation completed sucessfully.\r
-  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on \r
-                                directories.\r
-  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellSetFilePosition (\r
-  IN EFI_FILE_HANDLE           FileHandle,\r
-  IN UINT64            Position\r
-  )\r
-{\r
-  return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
-}\r
-\r
-/** \r
-  Gets a file's current position\r
-\r
-  This function retrieves the current file position for the file handle. For \r
-  directories, the current file position has no meaning outside of the file \r
-  system driver and as such the operation is not supported. An error is returned\r
-  if FileHandle is a directory.\r
-\r
-  @param FileHandle             The open file handle on which to get the position.\r
-  @param Position               Byte position from begining of file.\r
-\r
-  @retval EFI_SUCCESS           the operation completed sucessfully.\r
-  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
-  @retval EFI_UNSUPPORTED       the request is not valid on directories.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellGetFilePosition (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  OUT UINT64                    *Position\r
-  )\r
-{\r
-  return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
-}\r
-/**\r
-  Flushes data on a file\r
-  \r
-  This function flushes all modified data associated with a file to a device.\r
-\r
-  @param FileHandle             The file handle on which to flush data\r
-\r
-  @retval EFI_SUCCESS           The data was flushed.\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED     The file was opened for read only.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellFlushFile (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
-  return (FileFunctionMap.FlushFile(FileHandle));\r
-}\r
-\r
-/**\r
-  Retrieves the first file from a directory\r
-\r
-  This function opens a directory and gets the first file's info in the \r
-  directory. Caller can use ShellFindNextFile() to get other files.  When \r
-  complete the caller is responsible for calling FreePool() on Buffer.\r
-\r
-  @param DirHandle              The file handle of the directory to search\r
-  @param Buffer                 Pointer to buffer for file's information\r
-\r
-  @retval EFI_SUCCESS           Found the first file.\r
-  @retval EFI_NOT_FOUND         Cannot find the directory.\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-  @return Others                status of ShellGetFileInfo, ShellSetFilePosition,\r
-                                or ShellReadFile\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellFindFirstFile (\r
-  IN EFI_FILE_HANDLE            DirHandle,\r
-  OUT EFI_FILE_INFO             **Buffer\r
-  )\r
-{\r
-  //\r
-  // pass to file handle lib\r
-  //\r
-  return (FileHandleFindFirstFile(DirHandle, Buffer));\r
-}\r
-/**\r
-  Retrieves the next file in a directory.\r
-\r
-  To use this function, caller must call the LibFindFirstFile() to get the \r
-  first file, and then use this function get other files. This function can be \r
-  called for several times to get each file's information in the directory. If \r
-  the call of ShellFindNextFile() got the last file in the directory, the next \r
-  call of this function has no file to get. *NoFile will be set to TRUE and the \r
-  Buffer memory will be automatically freed. \r
-\r
-  @param DirHandle              the file handle of the directory\r
-  @param Buffer                                    pointer to buffer for file's information\r
-  @param NoFile                                    pointer to boolean when last file is found\r
-\r
-  @retval EFI_SUCCESS           Found the next file, or reached last file\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellFindNextFile(\r
-  IN EFI_FILE_HANDLE             DirHandle,\r
-  OUT EFI_FILE_INFO              *Buffer,\r
-  OUT BOOLEAN                    *NoFile\r
-  )\r
-{\r
-  //\r
-  // pass to file handle lib\r
-  //\r
-  return (FileHandleFindNextFile(DirHandle, Buffer, NoFile));\r
-}\r
-/**\r
-  Retrieve the size of a file.\r
-\r
-  if FileHandle is NULL then ASSERT()\r
-  if Size is NULL then ASSERT()\r
-\r
-  This function extracts the file size info from the FileHandle's EFI_FILE_INFO \r
-  data.\r
-\r
-  @param FileHandle             file handle from which size is retrieved\r
-  @param Size                   pointer to size\r
-\r
-  @retval EFI_SUCCESS           operation was completed sucessfully\r
-  @retval EFI_DEVICE_ERROR      cannot access the file\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellGetFileSize (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  OUT UINT64                    *Size\r
-  )\r
-{\r
-  return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
-}\r
-/**\r
-  Retrieves the status of the break execution flag\r
-\r
-  this function is useful to check whether the application is being asked to halt by the shell.\r
-\r
-  @retval TRUE                  the execution break is enabled\r
-  @retval FALSE                 the execution break is not enabled\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-ShellGetExecutionBreakFlag(\r
-  VOID\r
-  )\r
-{\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-\r
-    //\r
-    // We are using UEFI Shell 2.0; see if the event has been triggered\r
-    //\r
-    if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {\r
-      return (FALSE);\r
-    }\r
-    return (TRUE);\r
-  } \r
-\r
-  //\r
-  // using EFI Shell; call the function to check\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  return (mEfiShellEnvironment2->GetExecutionBreak());\r
-}\r
-/**\r
-  return the value of an environment variable\r
-\r
-  this function gets the value of the environment variable set by the \r
-  ShellSetEnvironmentVariable function\r
-\r
-  @param EnvKey                 The key name of the environment variable.\r
-\r
-  @retval NULL                  the named environment variable does not exist.\r
-  @return != NULL               pointer to the value of the environment variable\r
-**/\r
-CONST CHAR16*\r
-EFIAPI\r
-ShellGetEnvironmentVariable (\r
-  IN CHAR16                     *EnvKey\r
-  )\r
-{\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->GetEnv(EnvKey));\r
-  }\r
-\r
-  //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-\r
-  //\r
-  // using EFI Shell\r
-  //\r
-  return (mEfiShellEnvironment2->GetEnv(EnvKey));\r
-}\r
-/**\r
-  set the value of an environment variable\r
-\r
-This function changes the current value of the specified environment variable. If the\r
-environment variable exists and the Value is an empty string, then the environment\r
-variable is deleted. If the environment variable exists and the Value is not an empty\r
-string, then the value of the environment variable is changed. If the environment\r
-variable does not exist and the Value is an empty string, there is no action. If the\r
-environment variable does not exist and the Value is a non-empty string, then the\r
-environment variable is created and assigned the specified value.\r
-\r
-  This is not supported pre-UEFI Shell 2.0.\r
-\r
-  @param EnvKey                 The key name of the environment variable.\r
-  @param EnvVal                 The Value of the environment variable\r
-  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).\r
-\r
-  @retval EFI_SUCCESS           the operation was completed sucessfully\r
-  @retval EFI_UNSUPPORTED       This operation is not allowed in pre UEFI 2.0 Shell environments\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellSetEnvironmentVariable (\r
-  IN CONST CHAR16               *EnvKey,\r
-  IN CONST CHAR16               *EnvVal,\r
-  IN BOOLEAN                    Volatile\r
-  )\r
-{\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile));\r
-  } \r
-\r
-  //\r
-  // This feature does not exist under EFI shell\r
-  //\r
-  return (EFI_UNSUPPORTED);\r
-}\r
-/**\r
-  cause the shell to parse and execute a command line.\r
-\r
-  This function creates a nested instance of the shell and executes the specified\r
-command (CommandLine) with the specified environment (Environment). Upon return,\r
-the status code returned by the specified command is placed in StatusCode.\r
-If Environment is NULL, then the current environment is used and all changes made\r
-by the commands executed will be reflected in the current environment. If the\r
-Environment is non-NULL, then the changes made will be discarded.\r
-The CommandLine is executed from the current working directory on the current\r
-device.\r
-\r
-EnvironmentVariables and Status are only supported for UEFI Shell 2.0.\r
-Output is only supported for pre-UEFI Shell 2.0\r
-\r
-  @param ImageHandle            Parent image that is starting the operation\r
-  @param CommandLine            pointer to null terminated command line.\r
-  @param Output                 true to display debug output.  false to hide it.\r
-  @param EnvironmentVariables   optional pointer to array of environment variables\r
-                                in the form "x=y".  if NULL current set is used.\r
-  @param Status                 the status of the run command line.\r
-\r
-  @retval EFI_SUCCESS           the operation completed sucessfully.  Status\r
-                                contains the status code returned.\r
-  @retval EFI_INVALID_PARAMETER a parameter contains an invalid value\r
-  @retval EFI_OUT_OF_RESOURCES  out of resources\r
-  @retval EFI_UNSUPPORTED       the operation is not allowed.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellExecute (\r
-  IN EFI_HANDLE                 *ParentHandle,\r
-  IN CHAR16                     *CommandLine OPTIONAL,\r
-  IN BOOLEAN                    Output OPTIONAL,\r
-  IN CHAR16                     **EnvironmentVariables OPTIONAL,\r
-  OUT EFI_STATUS                *Status OPTIONAL\r
-  )\r
-{\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    //\r
-    // Call UEFI Shell 2.0 version (not using Output parameter)\r
-    //\r
-    return (mEfiShellProtocol->Execute(ParentHandle,\r
-                                      CommandLine,\r
-                                      EnvironmentVariables,\r
-                                      Status));\r
-  } \r
-  //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  //\r
-  // Call EFI Shell version (not using EnvironmentVariables or Status parameters)\r
-  // Due to oddity in the EFI shell we want to dereference the ParentHandle here\r
-  //\r
-  return (mEfiShellEnvironment2->Execute(*ParentHandle, \r
-                                        CommandLine, \r
-                                        Output));\r
-}\r
-/**\r
-  Retreives the current directory path\r
-\r
-  If the DeviceName is NULL, it returns the current device's current directory \r
-  name. If the DeviceName is not NULL, it returns the current directory name \r
-  on specified drive.\r
-\r
-  @param DeviceName             the name of the drive to get directory on\r
-\r
-  @retval NULL                  the directory does not exist\r
-  @return != NULL               the directory\r
-**/\r
-CONST CHAR16*\r
-EFIAPI\r
-ShellGetCurrentDir (\r
-  IN CHAR16                     *DeviceName OPTIONAL\r
-  )\r
-{\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->GetCurDir(DeviceName));\r
-  } \r
-  //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-  return (mEfiShellEnvironment2->CurDir(DeviceName));\r
-}\r
-/**\r
-  sets (enabled or disabled) the page break mode\r
-\r
-  when page break mode is enabled the screen will stop scrolling \r
-  and wait for operator input before scrolling a subsequent screen.\r
-\r
-  @param CurrentState           TRUE to enable and FALSE to disable\r
-**/\r
-VOID \r
-EFIAPI\r
-ShellSetPageBreakMode (\r
-  IN BOOLEAN                    CurrentState\r
-  )\r
-{\r
-  //\r
-  // check for enabling\r
-  //\r
-  if (CurrentState != 0x00) {\r
-    // \r
-    // check for UEFI Shell 2.0\r
-    //\r
-    if (mEfiShellProtocol != NULL) {\r
-      //\r
-      // Enable with UEFI 2.0 Shell\r
-      //\r
-      mEfiShellProtocol->EnablePageBreak();\r
-      return;\r
-    } else {\r
-      // \r
-      // ASSERT that must have EFI Shell\r
-      //\r
-      ASSERT(mEfiShellEnvironment2 != NULL);\r
-      //\r
-      // Enable with EFI Shell\r
-      //\r
-      mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);\r
-      return;\r
-    }\r
-  } else {\r
-    // \r
-    // check for UEFI Shell 2.0\r
-    //\r
-    if (mEfiShellProtocol != NULL) {\r
-      //\r
-      // Disable with UEFI 2.0 Shell\r
-      //\r
-      mEfiShellProtocol->DisablePageBreak();\r
-      return;\r
-    } else {\r
-      // \r
-      // ASSERT that must have EFI Shell\r
-      //\r
-      ASSERT(mEfiShellEnvironment2 != NULL);\r
-      //\r
-      // Disable with EFI Shell\r
-      //\r
-      mEfiShellEnvironment2->DisablePageBreak ();\r
-      return;\r
-    }\r
-  }\r
-}\r
-\r
-///\r
-/// version of EFI_SHELL_FILE_INFO struct, except has no CONST pointers.\r
-/// This allows for the struct to be populated.\r
-///\r
-typedef struct {\r
-  LIST_ENTRY Link;\r
-  EFI_STATUS Status;\r
-  CHAR16 *FullName;\r
-  CHAR16 *FileName;\r
-  EFI_FILE_HANDLE Handle;\r
-  EFI_FILE_INFO *Info;\r
-} EFI_SHELL_FILE_INFO_NO_CONST;\r
-\r
-/**\r
-  Converts a EFI shell list of structures to the coresponding UEFI Shell 2.0 type of list.\r
-\r
-  if OldStyleFileList is NULL then ASSERT()\r
-\r
-  this function will convert a SHELL_FILE_ARG based list into a callee allocated \r
-  EFI_SHELL_FILE_INFO based list.  it is up to the caller to free the memory via\r
-  the ShellCloseFileMetaArg function.\r
-\r
-  @param FileList               the EFI shell list type\r
-\r
-  @retval the resultant head of the double linked new format list;\r
-**/\r
-LIST_ENTRY*\r
-EFIAPI\r
-InternalShellConvertFileListType (\r
-  LIST_ENTRY                *FileList\r
-  )\r
-{\r
-  LIST_ENTRY                    *ListHead;\r
-  SHELL_FILE_ARG                *OldInfo;\r
-  LIST_ENTRY                *Link;\r
-  EFI_SHELL_FILE_INFO_NO_CONST  *NewInfo;\r
-\r
-  //\r
-  // ASSERT that FileList is not NULL\r
-  //\r
-  ASSERT(FileList != NULL);\r
-\r
-  //\r
-  // Allocate our list head and initialize the list\r
-  //\r
-  ListHead = AllocateZeroPool(sizeof(LIST_ENTRY));\r
-  ASSERT (ListHead != NULL);\r
-  ListHead = InitializeListHead (ListHead);\r
-\r
-  //\r
-  // enumerate through each member of the old list and copy\r
-  //\r
-  for (Link = FileList->ForwardLink; Link != FileList; Link = Link->ForwardLink) {\r
-    OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);\r
-\r
-    //\r
-    // make sure the old list was valid\r
-    //\r
-    ASSERT(OldInfo           != NULL); \r
-    ASSERT(OldInfo->Info     != NULL);\r
-    ASSERT(OldInfo->FullName != NULL);\r
-    ASSERT(OldInfo->FileName != NULL);\r
-\r
-    //\r
-    // allocate a new EFI_SHELL_FILE_INFO object\r
-    //\r
-    NewInfo               = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
-    \r
-    // \r
-    // copy the simple items\r
-    //\r
-    NewInfo->Handle       = OldInfo->Handle;\r
-    NewInfo->Status       = OldInfo->Status;\r
-\r
-    // old shell checks for 0 not NULL\r
-    OldInfo->Handle = 0;\r
-\r
-    //\r
-    // allocate new space to copy strings and structure\r
-    //\r
-    NewInfo->FullName     = AllocateZeroPool(StrSize(OldInfo->FullName));\r
-    NewInfo->FileName     = AllocateZeroPool(StrSize(OldInfo->FileName));\r
-    NewInfo->Info         = AllocateZeroPool((UINTN)OldInfo->Info->Size);\r
-    \r
-    //\r
-    // make sure all the memory allocations were sucessful\r
-    //\r
-    ASSERT(NewInfo->FullName != NULL);\r
-    ASSERT(NewInfo->FileName != NULL);\r
-    ASSERT(NewInfo->Info     != NULL);\r
-\r
-    //\r
-    // Copt the strings and structure\r
-    //\r
-    StrCpy(NewInfo->FullName, OldInfo->FullName);\r
-    StrCpy(NewInfo->FileName, OldInfo->FileName);\r
-    gBS->CopyMem (NewInfo->Info, OldInfo->Info, (UINTN)OldInfo->Info->Size);\r
-\r
-    //\r
-    // add that to the list\r
-    //\r
-    InsertTailList(ListHead, (LIST_ENTRY*)NewInfo);\r
-  }\r
-  return (ListHead);\r
-}\r
-/**\r
-  Opens a group of files based on a path.\r
-\r
-  This function uses the Arg to open all the matching files. Each matched \r
-  file has a SHELL_FILE_ARG structure to record the file information. These \r
-  structures are placed on the list ListHead. Users can get the SHELL_FILE_ARG \r
-  structures from ListHead to access each file. This function supports wildcards\r
-  and will process '?' and '*' as such.  the list must be freed with a call to \r
-  ShellCloseFileMetaArg().\r
-\r
-  This function will fail if called sequentially without freeing the list in the middle.\r
-\r
-  @param Arg                    pointer to path string\r
-  @param OpenMode               mode to open files with\r
-  @param ListHead               head of linked list of results\r
-\r
-  @retval EFI_SUCCESS           the operation was sucessful and the list head \r
-                                contains the list of opened files\r
-  #retval EFI_UNSUPPORTED       a previous ShellOpenFileMetaArg must be closed first.\r
-                                *ListHead is set to NULL.\r
-  @return != EFI_SUCCESS        the operation failed\r
-\r
-  @sa InternalShellConvertFileListType\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellOpenFileMetaArg (\r
-  IN CHAR16                     *Arg,\r
-  IN UINT64                     OpenMode,\r
-  IN OUT EFI_SHELL_FILE_INFO    **ListHead\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  LIST_ENTRY                    *EmptyNode;\r
-  LIST_ENTRY                    *mOldStyleFileList;\r
-  \r
-  //\r
-  // ASSERT that Arg and ListHead are not NULL\r
-  //\r
-  ASSERT(Arg      != NULL);\r
-  ASSERT(ListHead != NULL);\r
-\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->OpenFileList(Arg, \r
-                                           OpenMode, \r
-                                           ListHead));\r
-  } \r
-\r
-  //\r
-  // ASSERT that we must have EFI shell\r
-  //\r
-  ASSERT(mEfiShellEnvironment2 != NULL);\r
-\r
-  //\r
-  // allocate memory for old list head\r
-  //\r
-  mOldStyleFileList = (LIST_ENTRY*)AllocatePool(sizeof(LIST_ENTRY));\r
-  ASSERT(mOldStyleFileList != NULL);\r
-\r
-  //\r
-  // make sure the list head is initialized\r
-  //\r
-  InitializeListHead((LIST_ENTRY*)mOldStyleFileList);\r
-\r
-  //\r
-  // Get the EFI Shell list of files\r
-  //\r
-  Status = mEfiShellEnvironment2->FileMetaArg(Arg, mOldStyleFileList);\r
-  if (EFI_ERROR(Status)) {\r
-    *ListHead = NULL;\r
-    return (Status);\r
-  }\r
-\r
-  //\r
-  // Convert that to equivalent of UEFI Shell 2.0 structure\r
-  //\r
-  EmptyNode = InternalShellConvertFileListType(mOldStyleFileList);\r
-\r
-  //\r
-  // Free the EFI Shell version that was converted.\r
-  //\r
-  ASSERT_EFI_ERROR(mEfiShellEnvironment2->FreeFileList(mOldStyleFileList));\r
-  FreePool(mOldStyleFileList);\r
-  mOldStyleFileList = NULL;\r
-\r
-  //\r
-  // remove the empty head of the list\r
-  //\r
-  *ListHead = (EFI_SHELL_FILE_INFO*)RemoveEntryList(EmptyNode);\r
-  FreePool(EmptyNode);  \r
-\r
-  return (Status);\r
-}\r
-/**\r
-  Free the linked list returned from ShellOpenFileMetaArg\r
-\r
-  if ListHead is NULL then ASSERT()\r
-\r
-  @param ListHead               the pointer to free\r
-\r
-  @retval EFI_SUCCESS           the operation was sucessful\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellCloseFileMetaArg (\r
-  IN OUT EFI_SHELL_FILE_INFO    **ListHead\r
-  )\r
-{\r
-  LIST_ENTRY                    *Node;\r
-\r
-  //\r
-  // ASSERT that ListHead is not NULL\r
-  //\r
-  ASSERT(ListHead != NULL);\r
-\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellProtocol != NULL) {\r
-    return (mEfiShellProtocol->FreeFileList(ListHead));\r
-  } else {\r
-    //\r
-    // Since this is EFI Shell version we need to free our internally made copy \r
-    // of the list\r
-    //\r
-    for (Node = GetFirstNode((LIST_ENTRY*)*ListHead) ; IsListEmpty((LIST_ENTRY*)*ListHead) == FALSE ; Node = GetFirstNode((LIST_ENTRY*)*ListHead)) {\r
-      RemoveEntryList(Node);\r
-      ((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle->Close(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle);\r
-      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FullName);\r
-      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FileName);\r
-      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Info);\r
-      FreePool((EFI_SHELL_FILE_INFO_NO_CONST*)Node);\r
-    }\r
-    return EFI_SUCCESS;\r
-  }\r
-}\r
-\r
-typedef struct {\r
-  LIST_ENTRY List;\r
-  CHAR16         *Name;\r
-  ParamType      Type;\r
-  CHAR16         *Value;\r
-  UINTN          OriginalPosition;\r
-} SHELL_PARAM_PACKAGE;\r
-\r
-/**\r
-  Checks the list of valid arguments and returns TRUE if the item was found.  If the \r
-  return value is TRUE then the type parameter is set also.\r
-  \r
-  if CheckList is NULL then ASSERT();\r
-  if Name is NULL then ASSERT();\r
-  if Type is NULL then ASSERT();\r
-\r
-  @param Type                   pointer to type of parameter if it was found\r
-  @param Name                   pointer to Name of parameter found\r
-  @param CheckList              List to check against\r
-\r
-  @retval TRUE                  the Parameter was found.  Type is valid.\r
-  @retval FALSE                 the Parameter was not found.  Type is not valid.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-InternalIsOnCheckList (\r
-  IN CONST CHAR16               *Name,\r
-  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
-  OUT ParamType                 *Type\r
-  )\r
-{\r
-  SHELL_PARAM_ITEM              *TempListItem;\r
-\r
-  //\r
-  // ASSERT that all 3 pointer parameters aren't NULL\r
-  //\r
-  ASSERT(CheckList  != NULL);\r
-  ASSERT(Type       != NULL);\r
-  ASSERT(Name       != NULL);\r
-\r
-  //\r
-  // question mark and page break mode are always supported\r
-  //\r
-  if ((StrCmp(Name, L"-?") == 0) ||\r
-      (StrCmp(Name, L"-b") == 0)\r
-      ) {\r
-     return (TRUE);\r
-  }\r
-\r
-  //\r
-  // Enumerate through the list\r
-  //\r
-  for (TempListItem = (SHELL_PARAM_ITEM*)CheckList ; TempListItem->Name != NULL ; TempListItem++) {\r
-    //\r
-    // If the Name matches set the type and return TRUE\r
-    //\r
-    if (StrCmp(Name, TempListItem->Name) == 0) {\r
-      *Type = TempListItem->Type;\r
-      return (TRUE);\r
-    }\r
-  }\r
-  return (FALSE);\r
-}\r
-/**\r
-  Checks the string for indicators of "flag" status.  this is a leading '/', '-', or '+'\r
-\r
-  @param Name                   pointer to Name of parameter found\r
-\r
-  @retval TRUE                  the Parameter is a flag.\r
-  @retval FALSE                 the Parameter not a flag\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-InternalIsFlag (\r
-  IN CONST CHAR16               *Name\r
-  )\r
-{\r
-  //\r
-  // ASSERT that Name isn't NULL\r
-  //\r
-  ASSERT(Name != NULL);\r
-\r
-  //\r
-  // If the Name has a / or - as the first character return TRUE\r
-  //\r
-  if ((Name[0] == L'/') || \r
-      (Name[0] == L'-') ||\r
-      (Name[0] == L'+')\r
-      ) {\r
-      return (TRUE);\r
-  }\r
-  return (FALSE);\r
-}\r
-\r
-/**\r
-  Checks the command line arguments passed against the list of valid ones.  \r
-\r
-  If no initialization is required, then return RETURN_SUCCESS.\r
-  \r
-  @param CheckList              pointer to list of parameters to check\r
-  @param CheckPackage           pointer to pointer to list checked values\r
-  @param ProblemParam           optional pointer to pointer to unicode string for \r
-                                the paramater that caused failure.  If used then the\r
-                                caller is responsible for freeing the memory.\r
-  @param AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter\r
-  @param Argc                   Count of parameters in Argv\r
-  @param Argv                   pointer to array of parameters\r
-\r
-  @retval EFI_SUCCESS           The operation completed sucessfully.\r
-  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed\r
-  @retval EFI_INVALID_PARAMETER A parameter was invalid\r
-  @retval EFI_VOLUME_CORRUPTED  the command line was corrupt.  an argument was \r
-                                duplicated.  the duplicated command line argument \r
-                                was returned in ProblemParam if provided.\r
-  @retval EFI_NOT_FOUND         a argument required a value that was missing.  \r
-                                the invalid command line argument was returned in\r
-                                ProblemParam if provided.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InternalCommandLineParse (\r
-  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
-  OUT LIST_ENTRY                **CheckPackage,\r
-  OUT CHAR16                    **ProblemParam OPTIONAL,\r
-  IN BOOLEAN                    AutoPageBreak,\r
-  IN CONST CHAR16               **Argv,\r
-  IN UINTN                      Argc\r
-  )\r
-{\r
-  UINTN                         LoopCounter;\r
-  UINTN                         Count;\r
-  ParamType                     CurrentItemType;\r
-  SHELL_PARAM_PACKAGE           *CurrentItemPackage;\r
-  BOOLEAN                       GetItemValue;\r
-\r
-  CurrentItemPackage = NULL;\r
-\r
-  //\r
-  // ASSERTs\r
-  //\r
-  ASSERT(CheckList  != NULL);\r
-  ASSERT(Argv       != NULL);\r
-\r
-  Count = 0;\r
-  GetItemValue = FALSE;\r
-\r
-  //\r
-  // If there is only 1 item we dont need to do anything\r
-  //\r
-  if (Argc <= 1) {\r
-    *CheckPackage = NULL;\r
-    return (EFI_SUCCESS);\r
-  }\r
-\r
-  //\r
-  // initialize the linked list\r
-  //\r
-  *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY));\r
-  InitializeListHead(*CheckPackage);\r
-\r
-  //\r
-  // loop through each of the arguments\r
-  //\r
-  for (LoopCounter = 0 ; LoopCounter < Argc ; ++LoopCounter) {\r
-    if (Argv[LoopCounter] == NULL) {\r
-      //\r
-      // do nothing for NULL argv\r
-      //\r
-    } else if (GetItemValue == TRUE) {\r
-      ASSERT(CurrentItemPackage != NULL);\r
-      //\r
-      // get the item VALUE for the previous flag\r
-      //\r
-      GetItemValue = FALSE;\r
-      CurrentItemPackage->Value = AllocateZeroPool(StrSize(Argv[LoopCounter]));\r
-      ASSERT(CurrentItemPackage->Value != NULL);\r
-      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
-      InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
-    } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
-      //\r
-      // add this one as a non-flag\r
-      //\r
-      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));\r
-      ASSERT(CurrentItemPackage != NULL);\r
-      CurrentItemPackage->Name  = NULL;\r
-      CurrentItemPackage->Type  = TypePosition;\r
-      CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
-      ASSERT(CurrentItemPackage->Value != NULL);\r
-      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
-      CurrentItemPackage->OriginalPosition = Count++;\r
-      InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
-    } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {\r
-      //\r
-      // this is a flag\r
-      //\r
-      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));\r
-      ASSERT(CurrentItemPackage != NULL);\r
-      CurrentItemPackage->Name  = AllocatePool(StrSize(Argv[LoopCounter]));\r
-      ASSERT(CurrentItemPackage->Name != NULL);\r
-      StrCpy(CurrentItemPackage->Name,  Argv[LoopCounter]);\r
-      CurrentItemPackage->Type  = CurrentItemType;\r
-      CurrentItemPackage->OriginalPosition = (UINTN)(-1);\r
-\r
-      //\r
-      // Does this flag require a value\r
-      //\r
-      if (CurrentItemPackage->Type == TypeValue) {\r
-        //\r
-        // trigger the next loop to populate the value of this item\r
-        //\r
-        GetItemValue = TRUE; \r
-      } else {\r
-        //\r
-        // this item has no value expected; we are done\r
-        //\r
-        CurrentItemPackage->Value = NULL;\r
-        InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
-      }\r
-    } else if (ProblemParam) {\r
-      //\r
-      // this was a non-recognised flag... error!\r
-      //\r
-      *ProblemParam = AllocatePool(StrSize(Argv[LoopCounter]));\r
-      ASSERT(*ProblemParam != NULL);\r
-      StrCpy(*ProblemParam, Argv[LoopCounter]);\r
-      ShellCommandLineFreeVarList(*CheckPackage);\r
-      *CheckPackage = NULL;\r
-      return (EFI_VOLUME_CORRUPTED);\r
-    } else {\r
-      ShellCommandLineFreeVarList(*CheckPackage);\r
-      *CheckPackage = NULL;\r
-      return (EFI_VOLUME_CORRUPTED);\r
-    }\r
-  }\r
-  //\r
-  // support for AutoPageBreak\r
-  //\r
-  if (AutoPageBreak && ShellCommandLineGetFlag(*CheckPackage, L"-b")) {\r
-    ShellSetPageBreakMode(TRUE);\r
-  }\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  Checks the command line arguments passed against the list of valid ones.  \r
-  Optionally removes NULL values first.\r
-  \r
-  If no initialization is required, then return RETURN_SUCCESS.\r
-  \r
-  @param CheckList              pointer to list of parameters to check\r
-  @param CheckPackage           pointer to pointer to list checked values\r
-  @param ProblemParam           optional pointer to pointer to unicode string for \r
-                                the paramater that caused failure.\r
-  @param AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter\r
-\r
-  @retval EFI_SUCCESS           The operation completed sucessfully.\r
-  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed\r
-  @retval EFI_INVALID_PARAMETER A parameter was invalid\r
-  @retval EFI_VOLUME_CORRUPTED  the command line was corrupt.  an argument was \r
-                                duplicated.  the duplicated command line argument \r
-                                was returned in ProblemParam if provided.\r
-  @retval EFI_DEVICE_ERROR      the commands contained 2 opposing arguments.  one\r
-                                of the command line arguments was returned in \r
-                                ProblemParam if provided.\r
-  @retval EFI_NOT_FOUND         a argument required a value that was missing.  \r
-                                the invalid command line argument was returned in\r
-                                ProblemParam if provided.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellCommandLineParse (\r
-  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
-  OUT LIST_ENTRY                **CheckPackage,\r
-  OUT CHAR16                    **ProblemParam OPTIONAL,\r
-  IN BOOLEAN                    AutoPageBreak\r
-  )\r
-{\r
-  // \r
-  // ASSERT that CheckList and CheckPackage aren't NULL\r
-  //\r
-  ASSERT(CheckList    != NULL);\r
-  ASSERT(CheckPackage != NULL);\r
-\r
-  // \r
-  // Check for UEFI Shell 2.0 protocols\r
-  //\r
-  if (mEfiShellParametersProtocol != NULL) {\r
-    return (InternalCommandLineParse(CheckList, \r
-                                     CheckPackage, \r
-                                     ProblemParam, \r
-                                     AutoPageBreak, \r
-                                     (CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
-                                     mEfiShellParametersProtocol->Argc ));\r
-  }\r
-\r
-  // \r
-  // ASSERT That EFI Shell is not required\r
-  //\r
-  ASSERT (mEfiShellInterface != NULL);\r
-  return (InternalCommandLineParse(CheckList, \r
-                                   CheckPackage, \r
-                                   ProblemParam, \r
-                                   AutoPageBreak, \r
-                                   (CONST CHAR16**) mEfiShellInterface->Argv,\r
-                                   mEfiShellInterface->Argc ));\r
-}\r
-\r
-/**\r
-  Frees shell variable list that was returned from ShellCommandLineParse.\r
-\r
-  This function will free all the memory that was used for the CheckPackage\r
-  list of postprocessed shell arguments.\r
-\r
-  this function has no return value.\r
-\r
-  if CheckPackage is NULL, then return\r
-\r
-  @param CheckPackage           the list to de-allocate\r
-  **/\r
-VOID\r
-EFIAPI\r
-ShellCommandLineFreeVarList (\r
-  IN LIST_ENTRY                 *CheckPackage\r
-  )\r
-{\r
-  LIST_ENTRY                    *Node;\r
-\r
-  //\r
-  // check for CheckPackage == NULL\r
-  //\r
-  if (CheckPackage == NULL) {\r
-    return;\r
-  }\r
-\r
-  //\r
-  // for each node in the list\r
-  //\r
-  for (Node = GetFirstNode(CheckPackage); Node != CheckPackage ; Node = GetFirstNode(CheckPackage)) {\r
-    //\r
-    // Remove it from the list\r
-    //\r
-    RemoveEntryList(Node);\r
-\r
-    //\r
-    // if it has a name free the name\r
-    //\r
-    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
-      FreePool(((SHELL_PARAM_PACKAGE*)Node)->Name);\r
-    }\r
-\r
-    //\r
-    // if it has a value free the value\r
-    //\r
-    if (((SHELL_PARAM_PACKAGE*)Node)->Value != NULL) {\r
-      FreePool(((SHELL_PARAM_PACKAGE*)Node)->Value);\r
-    }\r
-    \r
-    //\r
-    // free the node structure\r
-    //\r
-    FreePool((SHELL_PARAM_PACKAGE*)Node);\r
-  }\r
-  //\r
-  // free the list head node\r
-  //\r
-  FreePool(CheckPackage);\r
-}\r
-/**\r
-  Checks for presence of a flag parameter\r
-\r
-  flag arguments are in the form of "-<Key>" or "/<Key>", but do not have a value following the key\r
-\r
-  if CheckPackage is NULL then return FALSE.\r
-  if KeyString is NULL then ASSERT()\r
-  \r
-  @param CheckPackage           The package of parsed command line arguments\r
-  @param KeyString              the Key of the command line argument to check for\r
-\r
-  @retval TRUE                  the flag is on the command line\r
-  @retval FALSE                 the flag is not on the command line\r
-  **/\r
-BOOLEAN\r
-EFIAPI\r
-ShellCommandLineGetFlag (\r
-  IN CONST LIST_ENTRY           *CheckPackage,\r
-  IN CHAR16                     *KeyString\r
-  )\r
-{\r
-  LIST_ENTRY                    *Node;\r
-\r
-  //\r
-  // ASSERT that both CheckPackage and KeyString aren't NULL\r
-  //\r
-  ASSERT(KeyString != NULL);\r
-\r
-  //\r
-  // return FALSE for no package\r
-  //\r
-  if (CheckPackage == NULL) {\r
-    return (FALSE);\r
-  }\r
-\r
-  //\r
-  // enumerate through the list of parametrs\r
-  //\r
-  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
-    //\r
-    // If the Name matches, return TRUE (and there may be NULL name)\r
-    //\r
-    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
-      if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {\r
-        return (TRUE);\r
-      }\r
-    }\r
-  }\r
-  return (FALSE);\r
-}\r
-/**\r
-  returns value from command line argument\r
-\r
-  value parameters are in the form of "-<Key> value" or "/<Key> value"\r
-  \r
-  if CheckPackage is NULL, then return NULL;\r
-\r
-  @param CheckPackage           The package of parsed command line arguments\r
-  @param KeyString              the Key of the command line argument to check for\r
-\r
-  @retval NULL                  the flag is not on the command line\r
-  @return !=NULL                pointer to unicode string of the value\r
-  **/\r
-CONST CHAR16*\r
-EFIAPI\r
-ShellCommandLineGetValue (\r
-  IN CONST LIST_ENTRY           *CheckPackage,\r
-  IN CHAR16                     *KeyString\r
-  )\r
-{\r
-  LIST_ENTRY                    *Node;\r
-\r
-  //\r
-  // check for CheckPackage == NULL\r
-  //\r
-  if (CheckPackage == NULL) {\r
-    return (NULL);\r
-  }\r
-\r
-  //\r
-  // enumerate through the list of parametrs\r
-  //\r
-  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
-    //\r
-    // If the Name matches, return the value (name can be NULL)\r
-    //\r
-    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
-      if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {\r
-        return (((SHELL_PARAM_PACKAGE*)Node)->Value);\r
-      }\r
-    }\r
-  }\r
-  return (NULL);\r
-}\r
-/**\r
-  returns raw value from command line argument\r
-\r
-  raw value parameters are in the form of "value" in a specific position in the list\r
-  \r
-  if CheckPackage is NULL, then return NULL;\r
-\r
-  @param CheckPackage           The package of parsed command line arguments\r
-  @param Position               the position of the value \r
-\r
-  @retval NULL                  the flag is not on the command line\r
-  @return !=NULL                pointer to unicode string of the value\r
-  **/\r
-CONST CHAR16*\r
-EFIAPI\r
-ShellCommandLineGetRawValue (\r
-  IN CONST LIST_ENTRY           *CheckPackage,\r
-  IN UINT32                     Position\r
-  )\r
-{\r
-  LIST_ENTRY                    *Node;\r
-\r
-  //\r
-  // check for CheckPackage == NULL\r
-  //\r
-  if (CheckPackage == NULL) {\r
-    return (NULL);\r
-  }\r
-\r
-  //\r
-  // enumerate through the list of parametrs\r
-  //\r
-  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
-    //\r
-    // If the position matches, return the value\r
-    //\r
-    if (((SHELL_PARAM_PACKAGE*)Node)->OriginalPosition == Position) {\r
-      return (((SHELL_PARAM_PACKAGE*)Node)->Value);\r
-    }\r
-  }\r
-  return (NULL);\r
-}
\ No newline at end of file
diff --git a/ShellPkg/Library/UefiShellLib/BaseShellLib.h b/ShellPkg/Library/UefiShellLib/BaseShellLib.h
deleted file mode 100644 (file)
index 1620641..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/** @file\r
-  Provides interface to shell functionality for shell commands and applications.\r
-\r
-Copyright (c) 2006 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-typedef struct  {\r
-  EFI_SHELL_GET_FILE_INFO                   GetFileInfo;\r
-  EFI_SHELL_SET_FILE_INFO                   SetFileInfo;\r
-  EFI_SHELL_READ_FILE                       ReadFile;\r
-  EFI_SHELL_WRITE_FILE                      WriteFile;\r
-  EFI_SHELL_CLOSE_FILE                      CloseFile;\r
-  EFI_SHELL_DELETE_FILE                     DeleteFile;\r
-  EFI_SHELL_GET_FILE_POSITION               GetFilePosition;\r
-  EFI_SHELL_SET_FILE_POSITION               SetFilePosition;\r
-  EFI_SHELL_FLUSH_FILE                      FlushFile;\r
-  EFI_SHELL_GET_FILE_SIZE                   GetFileSize;\r
-} FILE_HANDLE_FUNCTION_MAP;\r
diff --git a/ShellPkg/Library/UefiShellLib/BaseShellLib.inf b/ShellPkg/Library/UefiShellLib/BaseShellLib.inf
deleted file mode 100644 (file)
index 71c68cb..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#/** @file\r
-# Provides interface to shell functionality for shell commands and applications.\r
-#\r
-# Copyright (c) 2006 - 2009, Intel Corporation.\r
-#\r
-#  All rights reserved. This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution. The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010006\r
-  BASE_NAME                      = BaseShellLib\r
-  FILE_GUID                      = 449D0F00-2148-4a43-9836-F10B3980ECF5\r
-  MODULE_TYPE                    = UEFI_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = ShellLib|UEFI_APPLICATION UEFI_DRIVER\r
-  CONSTRUCTOR                    = ShellLibConstructor\r
-  DESTRUCTOR                     = ShellLibDestructor\r
-\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources.common]\r
-  BaseShellLib.c\r
-  BaseShellLib.h\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  ShellPkg/ShellPkg.dec\r
-\r
-[LibraryClasses]\r
-  UefiBootServicesTableLib\r
-  MemoryAllocationLib\r
-  DevicePathLib\r
-  BaseLib\r
-  BaseMemoryLib\r
-  DebugLib\r
-  FileHandleLib\r
-\r
-[Protocols]\r
-  gEfiSimpleFileSystemProtocolGuid              # ALWAYS_CONSUMED\r
-  \r
-  # shell 2.0 \r
-  gEfiShellProtocolGuid                         # SOMETIMES_CONSUMED\r
-  gEfiShellParametersProtocolGuid               # SOMETIMES_CONSUMED\r
-\r
-  # 'old' shell\r
-  gEfiShellEnvironment2Guid                     # SOMETIMES_CONSUMED\r
-  gEfiShellInterfaceGuid                        # SOMETIMES_CONSUMED\r
-\r
-[Guids]\r
-  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
-  gEfiShellEnvironment2ExtGuid                  # ALWAYS_CONSUMED\r
-\r
-[Pcd.common]\r
-  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize  # ALWAYS_CONSUMED\r
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
new file mode 100644 (file)
index 0000000..1ddff9a
--- /dev/null
@@ -0,0 +1,1939 @@
+/** @file\r
+  Provides interface to shell functionality for shell commands and applications.\r
+\r
+Copyright (c) 2006 - 2009, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/ShellLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/FileHandleLib.h>\r
+#include <Protocol/EfiShellEnvironment2.h>\r
+#include <Protocol/EfiShellInterface.h>\r
+#include <Protocol/EfiShell.h>\r
+#include <Protocol/EfiShellParameters.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+\r
+#include "BaseShellLib.h"\r
+\r
+#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
+#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
+\r
+//\r
+// This is not static since it's extern in the .h file\r
+//\r
+SHELL_PARAM_ITEM EmptyParamList[] = {\r
+  {NULL, TypeMax}\r
+  };\r
+\r
+//\r
+// Static file globals for the shell library\r
+//\r
+STATIC EFI_SHELL_ENVIRONMENT2        *mEfiShellEnvironment2;\r
+STATIC EFI_SHELL_INTERFACE           *mEfiShellInterface;\r
+STATIC EFI_SHELL_PROTOCOL            *mEfiShellProtocol;\r
+STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
+STATIC EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
+STATIC FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
+\r
+/**\r
+  helper function to find ShellEnvironment2 for constructor\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFindSE2 (\r
+  IN EFI_HANDLE        ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_HANDLE  *Buffer;\r
+  UINTN       BufferSize;\r
+  UINTN       HandleIndex;\r
+\r
+  BufferSize = 0;\r
+  Buffer = NULL;\r
+  Status = gBS->OpenProtocol(ImageHandle, \r
+                             &gEfiShellEnvironment2Guid,\r
+                             (VOID **)&mEfiShellEnvironment2,\r
+                             ImageHandle,\r
+                             NULL,\r
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                             );\r
+  //\r
+  // look for the mEfiShellEnvironment2 protocol at a higher level\r
+  //\r
+  if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
+     (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
+     (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER)))) {\r
+    //\r
+    // figure out how big of a buffer we need.\r
+    //\r
+    Status = gBS->LocateHandle (ByProtocol,\r
+                                &gEfiShellEnvironment2Guid,\r
+                                NULL, // ignored for ByProtocol\r
+                                &BufferSize,\r
+                                Buffer\r
+                                );\r
+    ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
+    Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
+    ASSERT(Buffer != NULL);\r
+    Status = gBS->LocateHandle (ByProtocol,\r
+                                &gEfiShellEnvironment2Guid,\r
+                                NULL, // ignored for ByProtocol\r
+                                &BufferSize,\r
+                                Buffer\r
+                                );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // now parse the list of returned handles\r
+      //\r
+      Status = EFI_NOT_FOUND;\r
+      for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof(Buffer[0])); HandleIndex++) {\r
+        Status = gBS->OpenProtocol(Buffer[HandleIndex], \r
+                                   &gEfiShellEnvironment2Guid,\r
+                                   (VOID **)&mEfiShellEnvironment2,\r
+                                   ImageHandle,\r
+                                   NULL,\r
+                                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                                   );\r
+         if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE &&\r
+          (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER ||\r
+          (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER))) {\r
+          mEfiShellEnvironment2Handle = Buffer[HandleIndex];\r
+          Status = EFI_SUCCESS;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if (Buffer != NULL) {\r
+    FreePool (Buffer);\r
+  }\r
+  return (Status);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ShellLibConstructorWorker (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+){\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  // UEFI 2.0 shell interfaces (used preferentially)\r
+  //\r
+  Status = gBS->OpenProtocol(ImageHandle, \r
+                             &gEfiShellProtocolGuid,\r
+                             (VOID **)&mEfiShellProtocol,\r
+                             ImageHandle,\r
+                             NULL,\r
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                             );\r
+  if (EFI_ERROR(Status)) {\r
+    mEfiShellProtocol = NULL;\r
+  }\r
+  Status = gBS->OpenProtocol(ImageHandle, \r
+                             &gEfiShellParametersProtocolGuid,\r
+                             (VOID **)&mEfiShellParametersProtocol,\r
+                             ImageHandle,\r
+                             NULL,\r
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                             );\r
+  if (EFI_ERROR(Status)) {\r
+    mEfiShellParametersProtocol = NULL;\r
+  }\r
+\r
+  if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) {\r
+    //\r
+    // Moved to seperate function due to complexity\r
+    //\r
+    Status = ShellFindSE2(ImageHandle);\r
+\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG((DEBUG_ERROR, "Status: 0x%08x\r\n", Status));\r
+      mEfiShellEnvironment2 = NULL;\r
+    }\r
+    Status = gBS->OpenProtocol(ImageHandle, \r
+                               &gEfiShellInterfaceGuid,\r
+                               (VOID **)&mEfiShellInterface,\r
+                               ImageHandle,\r
+                               NULL,\r
+                               EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                               );\r
+    if (EFI_ERROR(Status)) {\r
+      mEfiShellInterface = NULL;\r
+    }\r
+  }\r
+  //\r
+  // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
+  //\r
+  if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) || \r
+      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)    ) {\r
+    if (mEfiShellProtocol != NULL) {\r
+      FileFunctionMap.GetFileInfo     = mEfiShellProtocol->GetFileInfo;\r
+      FileFunctionMap.SetFileInfo     = mEfiShellProtocol->SetFileInfo;\r
+      FileFunctionMap.ReadFile        = mEfiShellProtocol->ReadFile;\r
+      FileFunctionMap.WriteFile       = mEfiShellProtocol->WriteFile;\r
+      FileFunctionMap.CloseFile       = mEfiShellProtocol->CloseFile;\r
+      FileFunctionMap.DeleteFile      = mEfiShellProtocol->DeleteFile;\r
+      FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;\r
+      FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;\r
+      FileFunctionMap.FlushFile       = mEfiShellProtocol->FlushFile;\r
+      FileFunctionMap.GetFileSize     = mEfiShellProtocol->GetFileSize;\r
+    } else {\r
+      FileFunctionMap.GetFileInfo     = FileHandleGetInfo;\r
+      FileFunctionMap.SetFileInfo     = FileHandleSetInfo;\r
+      FileFunctionMap.ReadFile        = FileHandleRead;\r
+      FileFunctionMap.WriteFile       = FileHandleWrite;\r
+      FileFunctionMap.CloseFile       = FileHandleClose;\r
+      FileFunctionMap.DeleteFile      = FileHandleDelete;\r
+      FileFunctionMap.GetFilePosition = FileHandleGetPosition;\r
+      FileFunctionMap.SetFilePosition = FileHandleSetPosition;\r
+      FileFunctionMap.FlushFile       = FileHandleFlush;\r
+      FileFunctionMap.GetFileSize     = FileHandleGetSize;\r
+    }\r
+    return (EFI_SUCCESS);\r
+  }\r
+  return (EFI_NOT_FOUND);\r
+}\r
+/**\r
+  Constructor for the Shell library.\r
+\r
+  Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.\r
+\r
+  @param ImageHandle    the image handle of the process\r
+  @param SystemTable    the EFI System Table pointer\r
+\r
+  @retval EFI_SUCCESS   the initialization was complete sucessfully\r
+  @return others        an error ocurred during initialization\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+\r
+\r
+  mEfiShellEnvironment2       = NULL;\r
+  mEfiShellProtocol           = NULL;\r
+  mEfiShellParametersProtocol = NULL;\r
+  mEfiShellInterface          = NULL;\r
+  mEfiShellEnvironment2Handle = NULL;\r
+\r
+  ///@todo make a worker constructor so initialize function works\r
+  //\r
+  // verify that auto initialize is not set false\r
+  // \r
+  if (PcdGetBool(PcdShellLibAutoInitialize) == 0) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+  \r
+  return (ShellLibConstructorWorker(ImageHandle, SystemTable));\r
+}\r
+\r
+/**\r
+  Destructory for the library.  free any resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  if (mEfiShellEnvironment2 != NULL) {\r
+    gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
+                       &gEfiShellEnvironment2Guid,\r
+                       ImageHandle,\r
+                       NULL);\r
+    mEfiShellEnvironment2 = NULL;\r
+  }\r
+  if (mEfiShellInterface != NULL) {\r
+    gBS->CloseProtocol(ImageHandle,\r
+                       &gEfiShellInterfaceGuid,\r
+                       ImageHandle,\r
+                       NULL);  \r
+    mEfiShellInterface = NULL;\r
+  }\r
+  if (mEfiShellProtocol != NULL) {\r
+    gBS->CloseProtocol(ImageHandle,\r
+                       &gEfiShellProtocolGuid,\r
+                       ImageHandle,\r
+                       NULL);  \r
+    mEfiShellProtocol = NULL;\r
+  }\r
+  if (mEfiShellParametersProtocol != NULL) {\r
+    gBS->CloseProtocol(ImageHandle,\r
+                       &gEfiShellParametersProtocolGuid,\r
+                       ImageHandle,\r
+                       NULL);    \r
+    mEfiShellParametersProtocol = NULL;\r
+  }\r
+  mEfiShellEnvironment2Handle = NULL;\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  This function causes the shell library to initialize itself.  If the shell library\r
+  is already initialized it will de-initialize all the current protocol poitners and\r
+  re-populate them again.\r
+\r
+  When the library is used with PcdShellLibAutoInitialize set to true this function\r
+  will return EFI_SUCCESS and perform no actions.\r
+\r
+  This function is intended for internal access for shell commands only.\r
+\r
+  @retval EFI_SUCCESS   the initialization was complete sucessfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellInitialize (\r
+  ) {\r
+  //\r
+  // if auto initialize is not false then skip\r
+  //\r
+  if (PcdGetBool(PcdShellLibAutoInitialize) != 0) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  //\r
+  // deinit the current stuff\r
+  //\r
+  ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));\r
+\r
+  //\r
+  // init the new stuff\r
+  //\r
+  return (ShellLibConstructorWorker(gImageHandle, gST));\r
+}\r
+\r
+/**\r
+  This function will retrieve the information about the file for the handle \r
+  specified and store it in allocated pool memory.\r
+\r
+  This function allocates a buffer to store the file's information. It is the \r
+  caller's responsibility to free the buffer\r
+\r
+  @param  FileHandle  The file handle of the file for which information is \r
+  being requested.\r
+\r
+  @retval NULL information could not be retrieved.\r
+\r
+  @return the information about the file\r
+**/\r
+EFI_FILE_INFO*\r
+EFIAPI\r
+ShellGetFileInfo (\r
+  IN EFI_FILE_HANDLE            FileHandle\r
+  )\r
+{\r
+  return (FileFunctionMap.GetFileInfo(FileHandle));\r
+}\r
+\r
+/**\r
+  This function will set the information about the file for the opened handle \r
+  specified.\r
+\r
+  @param  FileHandle            The file handle of the file for which information \r
+  is being set\r
+\r
+  @param  FileInfo              The infotmation to set.\r
+\r
+  @retval EFI_SUCCESS          The information was set.\r
+  @retval EFI_UNSUPPORTED The InformationType is not known.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellSetFileInfo (\r
+  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN EFI_FILE_INFO              *FileInfo\r
+  )\r
+{\r
+  return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
+}  \r
+  \r
+  /**\r
+  This function will open a file or directory referenced by DevicePath.\r
+\r
+  This function opens a file with the open mode according to the file path. The \r
+  Attributes is valid only for EFI_FILE_MODE_CREATE.\r
+\r
+  @param  FilePath                 on input the device path to the file.  On output \r
+                          the remaining device path.\r
+  @param  DeviceHandle         pointer to the system device handle.\r
+  @param  FileHandle             pointer to the file handle.\r
+  @param  OpenMode                 the mode to open the file with.\r
+  @param  Attributes             the file's file attributes.\r
+\r
+  @retval EFI_SUCCESS                  The information was set.\r
+  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
+  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
+                                device or the file system could not be found on \r
+                                the device.\r
+  @retval EFI_NO_MEDIA               The device has no medium.\r
+  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
+                                medium is no longer supported.\r
+  @retval EFI_DEVICE_ERROR         The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
+                                file.\r
+  @retval EFI_VOLUME_FULL            The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellOpenFileByDevicePath(\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL        **FilePath,\r
+  OUT EFI_HANDLE                       *DeviceHandle,\r
+  OUT EFI_FILE_HANDLE                  *FileHandle,\r
+  IN UINT64                            OpenMode,\r
+  IN UINT64                            Attributes\r
+  )\r
+{\r
+  CHAR16      *FileName;\r
+  EFI_STATUS  Status;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
+  EFI_FILE_HANDLE LastHandle;\r
+\r
+  //\r
+  // ASERT for FileHandle, FilePath, and DeviceHandle being NULL\r
+  //\r
+  ASSERT(FilePath != NULL);\r
+  ASSERT(FileHandle != NULL);\r
+  ASSERT(DeviceHandle != NULL);\r
+  // \r
+  // which shell interface should we use\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    //\r
+    // use UEFI Shell 2.0 method.\r
+    //\r
+    FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath);\r
+    if (FileName == NULL) {\r
+      return (EFI_INVALID_PARAMETER);\r
+    }\r
+    Status = ShellOpenFileByName(FileName, FileHandle, OpenMode, Attributes);\r
+    FreePool(FileName);\r
+    return (Status);\r
+  } \r
+\r
+\r
+  //\r
+  // use old shell method.\r
+  //\r
+  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, \r
+                                  FilePath, \r
+                                  DeviceHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = gBS->OpenProtocol(*DeviceHandle,\r
+                             &gEfiSimpleFileSystemProtocolGuid,\r
+                             (VOID**) &EfiSimpleFileSystemProtocol,\r
+                             gImageHandle,\r
+                             NULL,\r
+                             EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    FileHandle = NULL;\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // go down directories one node at a time.\r
+  //\r
+  while (!IsDevicePathEnd (*FilePath)) {\r
+    //\r
+    // For file system access each node should be a file path component\r
+    //\r
+    if (DevicePathType    (*FilePath) != MEDIA_DEVICE_PATH ||\r
+        DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP\r
+        ) {\r
+      FileHandle = NULL;\r
+      return (EFI_INVALID_PARAMETER);\r
+    }\r
+    //\r
+    // Open this file path node\r
+    //\r
+    LastHandle  = *FileHandle;\r
+    *FileHandle = NULL;\r
+\r
+    //\r
+    // Try to test opening an existing file\r
+    //\r
+    Status = LastHandle->Open (\r
+                          LastHandle,\r
+                          FileHandle,\r
+                          ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
+                          OpenMode &~EFI_FILE_MODE_CREATE,\r
+                          0\r
+                          );\r
+\r
+    //\r
+    // see if the error was that it needs to be created\r
+    //\r
+    if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {\r
+      Status = LastHandle->Open (\r
+                            LastHandle,\r
+                            FileHandle,\r
+                            ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
+                            OpenMode,\r
+                            Attributes\r
+                            );\r
+    }\r
+    //\r
+    // Close the last node\r
+    //\r
+    LastHandle->Close (LastHandle);\r
+\r
+    if (EFI_ERROR(Status)) {\r
+      return (Status);\r
+    }\r
+\r
+    //\r
+    // Get the next node\r
+    //\r
+    *FilePath = NextDevicePathNode (*FilePath);\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  This function will open a file or directory referenced by filename.\r
+\r
+  If return is EFI_SUCCESS, the Filehandle is the opened file's handle; \r
+  otherwise, the Filehandle is NULL. The Attributes is valid only for \r
+  EFI_FILE_MODE_CREATE.\r
+\r
+  if FileNAme is NULL then ASSERT()\r
+\r
+  @param  FileName               pointer to file name\r
+  @param  FileHandle           pointer to the file handle.\r
+  @param  OpenMode               the mode to open the file with.\r
+  @param  Attributes           the file's file attributes.\r
+\r
+  @retval EFI_SUCCESS                  The information was set.\r
+  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
+  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
+                                device or the file system could not be found \r
+                                on the device.\r
+  @retval EFI_NO_MEDIA               The device has no medium.\r
+  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
+                                medium is no longer supported.\r
+  @retval EFI_DEVICE_ERROR         The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED        The file was opened read only.\r
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
+                                file.\r
+  @retval EFI_VOLUME_FULL            The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellOpenFileByName(\r
+  IN CHAR16                              *FileName,\r
+  OUT EFI_FILE_HANDLE           *FileHandle,\r
+  IN UINT64                     OpenMode,\r
+  IN UINT64                            Attributes\r
+  )\r
+{\r
+  EFI_HANDLE                    DeviceHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
+\r
+  //\r
+  // ASSERT if FileName is NULL\r
+  //\r
+  ASSERT(FileName != NULL);\r
+\r
+  if (mEfiShellProtocol != NULL) {\r
+    //\r
+    // Use UEFI Shell 2.0 method\r
+    //\r
+    return (mEfiShellProtocol->OpenFileByName(FileName,\r
+                                             FileHandle,\r
+                                             OpenMode));\r
+\r
+    ///@todo add the attributes\r
+  } \r
+  //\r
+  // Using EFI Shell version\r
+  // this means convert name to path and call that function\r
+  // since this will use EFI method again that will open it.\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+  FilePath = mEfiShellEnvironment2->NameToPath (FileName);\r
+  if (FileDevicePath != NULL) {\r
+    return (ShellOpenFileByDevicePath(&FilePath,\r
+                                      &DeviceHandle,\r
+                                      FileHandle,\r
+                                      OpenMode,\r
+                                      Attributes ));\r
+  }\r
+  return (EFI_DEVICE_ERROR);\r
+}\r
+/**\r
+  This function create a directory\r
+\r
+  If return is EFI_SUCCESS, the Filehandle is the opened directory's handle; \r
+  otherwise, the Filehandle is NULL. If the directory already existed, this \r
+  function opens the existing directory.\r
+\r
+  @param  DirectoryName                pointer to directory name\r
+  @param  FileHandle             pointer to the file handle.\r
+\r
+  @retval EFI_SUCCESS                  The information was set.\r
+  @retval EFI_INVALID_PARAMETER        One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED            Could not open the file path.     \r
+  @retval EFI_NOT_FOUND                The specified file could not be found on the \r
+                                device or the file system could not be found \r
+                                on the device.\r
+  @retval EFI_NO_MEDIA               The device has no medium.\r
+  @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the \r
+                                medium is no longer supported.\r
+  @retval EFI_DEVICE_ERROR         The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED        The file was opened read only.\r
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the \r
+                                file.\r
+  @retval EFI_VOLUME_FULL            The volume is full.\r
+  @sa ShellOpenFileByName\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellCreateDirectory(\r
+  IN CHAR16                   *DirectoryName,\r
+  OUT EFI_FILE_HANDLE         *FileHandle\r
+  )\r
+{\r
+  //\r
+  // this is a pass thru to the open file function with sepcific open mode and attributes\r
+  //\r
+  return (ShellOpenFileByName(DirectoryName,\r
+                              FileHandle,\r
+                              EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
+                              EFI_FILE_DIRECTORY\r
+                              ));\r
+}\r
+\r
+/**\r
+  This function reads information from an opened file.\r
+\r
+  If FileHandle is not a directory, the function reads the requested number of \r
+  bytes from the file at the file's current position and returns them in Buffer. \r
+  If the read goes beyond the end of the file, the read length is truncated to the\r
+  end of the file. The file's current position is increased by the number of bytes \r
+  returned.  If FileHandle is a directory, the function reads the directory entry \r
+  at the file's current position and returns the entry in Buffer. If the Buffer \r
+  is not large enough to hold the current directory entry, then \r
+  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated. \r
+  BufferSize is set to be the size of the buffer needed to read the entry. On \r
+  success, the current position is updated to the next directory entry. If there \r
+  are no more directory entries, the read returns a zero-length buffer. \r
+  EFI_FILE_INFO is the structure returned as the directory entry.\r
+\r
+  @param FileHandle             the opened file handle\r
+  @param BufferSize             on input the size of buffer in bytes.  on return \r
+                                the number of bytes written.\r
+  @param Buffer                 the buffer to put read data into.\r
+\r
+  @retval EFI_SUCCESS            Data was read.\r
+  @retval EFI_NO_MEDIA         The device has no media.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TO_SMALL  Buffer is too small. ReadSize contains required \r
+                                size.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellReadFile(\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN OUT UINTN                  *BufferSize,\r
+  OUT VOID                      *Buffer\r
+  )\r
+{\r
+  return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));\r
+}\r
+\r
+\r
+/**\r
+  Write data to a file.\r
+\r
+  This function writes the specified number of bytes to the file at the current \r
+  file position. The current file position is advanced the actual number of bytes \r
+  written, which is returned in BufferSize. Partial writes only occur when there \r
+  has been a data error during the write attempt (such as "volume space full"). \r
+  The file is automatically grown to hold the data if required. Direct writes to \r
+  opened directories are not supported.\r
+\r
+  @param FileHandle           The opened file for writing\r
+  @param BufferSize           on input the number of bytes in Buffer.  On output\r
+                              the number of bytes written.\r
+  @param Buffer               the buffer containing data to write is stored.\r
+\r
+ @retval EFI_SUCCESS           Data was written.\r
+ @retval EFI_UNSUPPORTED           Writes to an open directory are not supported.\r
+ @retval EFI_NO_MEDIA          The device has no media.\r
+ @retval EFI_DEVICE_ERROR          The device reported an error.\r
+ @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+ @retval EFI_WRITE_PROTECTED   The device is write-protected.\r
+ @retval EFI_ACCESS_DENIED       The file was open for read only.\r
+ @retval EFI_VOLUME_FULL           The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellWriteFile(\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN OUT UINTN                  *BufferSize,\r
+  IN VOID                       *Buffer\r
+  )\r
+{\r
+  return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));\r
+}\r
+\r
+/** \r
+  Close an open file handle.\r
+\r
+  This function closes a specified file handle. All "dirty" cached file data is \r
+  flushed to the device, and the file is closed. In all cases the handle is \r
+  closed.\r
+\r
+@param FileHandle               the file handle to close.\r
+\r
+@retval EFI_SUCCESS             the file handle was closed sucessfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellCloseFile (\r
+  IN EFI_FILE_HANDLE            *FileHandle\r
+  )\r
+{\r
+  return (FileFunctionMap.CloseFile(*FileHandle));\r
+}\r
+\r
+/**\r
+  Delete a file and close the handle\r
+\r
+  This function closes and deletes a file. In all cases the file handle is closed.\r
+  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is \r
+  returned, but the handle is still closed.\r
+\r
+  @param FileHandle             the file handle to delete\r
+\r
+  @retval EFI_SUCCESS           the file was closed sucessfully\r
+  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not \r
+                                deleted\r
+  @retval INVALID_PARAMETER            One of the parameters has an invalid value.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellDeleteFile (\r
+  IN EFI_FILE_HANDLE           *FileHandle\r
+  )\r
+{\r
+  return (FileFunctionMap.DeleteFile(*FileHandle));\r
+}\r
+\r
+/**\r
+  Set the current position in a file.\r
+\r
+  This function sets the current file position for the handle to the position \r
+  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only\r
+  absolute positioning is supported, and seeking past the end of the file is \r
+  allowed (a subsequent write would grow the file). Seeking to position \r
+  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.\r
+  If FileHandle is a directory, the only position that may be set is zero. This \r
+  has the effect of starting the read process of the directory entries over.\r
+\r
+  @param FileHandle             The file handle on which the position is being set\r
+  @param Position               Byte position from begining of file\r
+\r
+  @retval EFI_SUCCESS           Operation completed sucessfully.\r
+  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on \r
+                                directories.\r
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellSetFilePosition (\r
+  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN UINT64            Position\r
+  )\r
+{\r
+  return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
+}\r
+\r
+/** \r
+  Gets a file's current position\r
+\r
+  This function retrieves the current file position for the file handle. For \r
+  directories, the current file position has no meaning outside of the file \r
+  system driver and as such the operation is not supported. An error is returned\r
+  if FileHandle is a directory.\r
+\r
+  @param FileHandle             The open file handle on which to get the position.\r
+  @param Position               Byte position from begining of file.\r
+\r
+  @retval EFI_SUCCESS           the operation completed sucessfully.\r
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED       the request is not valid on directories.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellGetFilePosition (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  OUT UINT64                    *Position\r
+  )\r
+{\r
+  return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
+}\r
+/**\r
+  Flushes data on a file\r
+  \r
+  This function flushes all modified data associated with a file to a device.\r
+\r
+  @param FileHandle             The file handle on which to flush data\r
+\r
+  @retval EFI_SUCCESS           The data was flushed.\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED     The file was opened for read only.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFlushFile (\r
+  IN EFI_FILE_HANDLE            FileHandle\r
+  )\r
+{\r
+  return (FileFunctionMap.FlushFile(FileHandle));\r
+}\r
+\r
+/**\r
+  Retrieves the first file from a directory\r
+\r
+  This function opens a directory and gets the first file's info in the \r
+  directory. Caller can use ShellFindNextFile() to get other files.  When \r
+  complete the caller is responsible for calling FreePool() on Buffer.\r
+\r
+  @param DirHandle              The file handle of the directory to search\r
+  @param Buffer                 Pointer to buffer for file's information\r
+\r
+  @retval EFI_SUCCESS           Found the first file.\r
+  @retval EFI_NOT_FOUND         Cannot find the directory.\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @return Others                status of ShellGetFileInfo, ShellSetFilePosition,\r
+                                or ShellReadFile\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFindFirstFile (\r
+  IN EFI_FILE_HANDLE            DirHandle,\r
+  OUT EFI_FILE_INFO             **Buffer\r
+  )\r
+{\r
+  //\r
+  // pass to file handle lib\r
+  //\r
+  return (FileHandleFindFirstFile(DirHandle, Buffer));\r
+}\r
+/**\r
+  Retrieves the next file in a directory.\r
+\r
+  To use this function, caller must call the LibFindFirstFile() to get the \r
+  first file, and then use this function get other files. This function can be \r
+  called for several times to get each file's information in the directory. If \r
+  the call of ShellFindNextFile() got the last file in the directory, the next \r
+  call of this function has no file to get. *NoFile will be set to TRUE and the \r
+  Buffer memory will be automatically freed. \r
+\r
+  @param DirHandle              the file handle of the directory\r
+  @param Buffer                                    pointer to buffer for file's information\r
+  @param NoFile                                    pointer to boolean when last file is found\r
+\r
+  @retval EFI_SUCCESS           Found the next file, or reached last file\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFindNextFile(\r
+  IN EFI_FILE_HANDLE             DirHandle,\r
+  OUT EFI_FILE_INFO              *Buffer,\r
+  OUT BOOLEAN                    *NoFile\r
+  )\r
+{\r
+  //\r
+  // pass to file handle lib\r
+  //\r
+  return (FileHandleFindNextFile(DirHandle, Buffer, NoFile));\r
+}\r
+/**\r
+  Retrieve the size of a file.\r
+\r
+  if FileHandle is NULL then ASSERT()\r
+  if Size is NULL then ASSERT()\r
+\r
+  This function extracts the file size info from the FileHandle's EFI_FILE_INFO \r
+  data.\r
+\r
+  @param FileHandle             file handle from which size is retrieved\r
+  @param Size                   pointer to size\r
+\r
+  @retval EFI_SUCCESS           operation was completed sucessfully\r
+  @retval EFI_DEVICE_ERROR      cannot access the file\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellGetFileSize (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  OUT UINT64                    *Size\r
+  )\r
+{\r
+  return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
+}\r
+/**\r
+  Retrieves the status of the break execution flag\r
+\r
+  this function is useful to check whether the application is being asked to halt by the shell.\r
+\r
+  @retval TRUE                  the execution break is enabled\r
+  @retval FALSE                 the execution break is not enabled\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellGetExecutionBreakFlag(\r
+  VOID\r
+  )\r
+{\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+\r
+    //\r
+    // We are using UEFI Shell 2.0; see if the event has been triggered\r
+    //\r
+    if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {\r
+      return (FALSE);\r
+    }\r
+    return (TRUE);\r
+  } \r
+\r
+  //\r
+  // using EFI Shell; call the function to check\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+  return (mEfiShellEnvironment2->GetExecutionBreak());\r
+}\r
+/**\r
+  return the value of an environment variable\r
+\r
+  this function gets the value of the environment variable set by the \r
+  ShellSetEnvironmentVariable function\r
+\r
+  @param EnvKey                 The key name of the environment variable.\r
+\r
+  @retval NULL                  the named environment variable does not exist.\r
+  @return != NULL               pointer to the value of the environment variable\r
+**/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellGetEnvironmentVariable (\r
+  IN CHAR16                     *EnvKey\r
+  )\r
+{\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    return (mEfiShellProtocol->GetEnv(EnvKey));\r
+  }\r
+\r
+  //\r
+  // ASSERT that we must have EFI shell\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+\r
+  //\r
+  // using EFI Shell\r
+  //\r
+  return (mEfiShellEnvironment2->GetEnv(EnvKey));\r
+}\r
+/**\r
+  set the value of an environment variable\r
+\r
+This function changes the current value of the specified environment variable. If the\r
+environment variable exists and the Value is an empty string, then the environment\r
+variable is deleted. If the environment variable exists and the Value is not an empty\r
+string, then the value of the environment variable is changed. If the environment\r
+variable does not exist and the Value is an empty string, there is no action. If the\r
+environment variable does not exist and the Value is a non-empty string, then the\r
+environment variable is created and assigned the specified value.\r
+\r
+  This is not supported pre-UEFI Shell 2.0.\r
+\r
+  @param EnvKey                 The key name of the environment variable.\r
+  @param EnvVal                 The Value of the environment variable\r
+  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).\r
+\r
+  @retval EFI_SUCCESS           the operation was completed sucessfully\r
+  @retval EFI_UNSUPPORTED       This operation is not allowed in pre UEFI 2.0 Shell environments\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellSetEnvironmentVariable (\r
+  IN CONST CHAR16               *EnvKey,\r
+  IN CONST CHAR16               *EnvVal,\r
+  IN BOOLEAN                    Volatile\r
+  )\r
+{\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    return (mEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile));\r
+  } \r
+\r
+  //\r
+  // This feature does not exist under EFI shell\r
+  //\r
+  return (EFI_UNSUPPORTED);\r
+}\r
+/**\r
+  cause the shell to parse and execute a command line.\r
+\r
+  This function creates a nested instance of the shell and executes the specified\r
+command (CommandLine) with the specified environment (Environment). Upon return,\r
+the status code returned by the specified command is placed in StatusCode.\r
+If Environment is NULL, then the current environment is used and all changes made\r
+by the commands executed will be reflected in the current environment. If the\r
+Environment is non-NULL, then the changes made will be discarded.\r
+The CommandLine is executed from the current working directory on the current\r
+device.\r
+\r
+EnvironmentVariables and Status are only supported for UEFI Shell 2.0.\r
+Output is only supported for pre-UEFI Shell 2.0\r
+\r
+  @param ImageHandle            Parent image that is starting the operation\r
+  @param CommandLine            pointer to null terminated command line.\r
+  @param Output                 true to display debug output.  false to hide it.\r
+  @param EnvironmentVariables   optional pointer to array of environment variables\r
+                                in the form "x=y".  if NULL current set is used.\r
+  @param Status                 the status of the run command line.\r
+\r
+  @retval EFI_SUCCESS           the operation completed sucessfully.  Status\r
+                                contains the status code returned.\r
+  @retval EFI_INVALID_PARAMETER a parameter contains an invalid value\r
+  @retval EFI_OUT_OF_RESOURCES  out of resources\r
+  @retval EFI_UNSUPPORTED       the operation is not allowed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellExecute (\r
+  IN EFI_HANDLE                 *ParentHandle,\r
+  IN CHAR16                     *CommandLine OPTIONAL,\r
+  IN BOOLEAN                    Output OPTIONAL,\r
+  IN CHAR16                     **EnvironmentVariables OPTIONAL,\r
+  OUT EFI_STATUS                *Status OPTIONAL\r
+  )\r
+{\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    //\r
+    // Call UEFI Shell 2.0 version (not using Output parameter)\r
+    //\r
+    return (mEfiShellProtocol->Execute(ParentHandle,\r
+                                      CommandLine,\r
+                                      EnvironmentVariables,\r
+                                      Status));\r
+  } \r
+  //\r
+  // ASSERT that we must have EFI shell\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+  //\r
+  // Call EFI Shell version (not using EnvironmentVariables or Status parameters)\r
+  // Due to oddity in the EFI shell we want to dereference the ParentHandle here\r
+  //\r
+  return (mEfiShellEnvironment2->Execute(*ParentHandle, \r
+                                        CommandLine, \r
+                                        Output));\r
+}\r
+/**\r
+  Retreives the current directory path\r
+\r
+  If the DeviceName is NULL, it returns the current device's current directory \r
+  name. If the DeviceName is not NULL, it returns the current directory name \r
+  on specified drive.\r
+\r
+  @param DeviceName             the name of the drive to get directory on\r
+\r
+  @retval NULL                  the directory does not exist\r
+  @return != NULL               the directory\r
+**/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellGetCurrentDir (\r
+  IN CHAR16                     *DeviceName OPTIONAL\r
+  )\r
+{\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    return (mEfiShellProtocol->GetCurDir(DeviceName));\r
+  } \r
+  //\r
+  // ASSERT that we must have EFI shell\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+  return (mEfiShellEnvironment2->CurDir(DeviceName));\r
+}\r
+/**\r
+  sets (enabled or disabled) the page break mode\r
+\r
+  when page break mode is enabled the screen will stop scrolling \r
+  and wait for operator input before scrolling a subsequent screen.\r
+\r
+  @param CurrentState           TRUE to enable and FALSE to disable\r
+**/\r
+VOID \r
+EFIAPI\r
+ShellSetPageBreakMode (\r
+  IN BOOLEAN                    CurrentState\r
+  )\r
+{\r
+  //\r
+  // check for enabling\r
+  //\r
+  if (CurrentState != 0x00) {\r
+    // \r
+    // check for UEFI Shell 2.0\r
+    //\r
+    if (mEfiShellProtocol != NULL) {\r
+      //\r
+      // Enable with UEFI 2.0 Shell\r
+      //\r
+      mEfiShellProtocol->EnablePageBreak();\r
+      return;\r
+    } else {\r
+      // \r
+      // ASSERT that must have EFI Shell\r
+      //\r
+      ASSERT(mEfiShellEnvironment2 != NULL);\r
+      //\r
+      // Enable with EFI Shell\r
+      //\r
+      mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);\r
+      return;\r
+    }\r
+  } else {\r
+    // \r
+    // check for UEFI Shell 2.0\r
+    //\r
+    if (mEfiShellProtocol != NULL) {\r
+      //\r
+      // Disable with UEFI 2.0 Shell\r
+      //\r
+      mEfiShellProtocol->DisablePageBreak();\r
+      return;\r
+    } else {\r
+      // \r
+      // ASSERT that must have EFI Shell\r
+      //\r
+      ASSERT(mEfiShellEnvironment2 != NULL);\r
+      //\r
+      // Disable with EFI Shell\r
+      //\r
+      mEfiShellEnvironment2->DisablePageBreak ();\r
+      return;\r
+    }\r
+  }\r
+}\r
+\r
+///\r
+/// version of EFI_SHELL_FILE_INFO struct, except has no CONST pointers.\r
+/// This allows for the struct to be populated.\r
+///\r
+typedef struct {\r
+  LIST_ENTRY Link;\r
+  EFI_STATUS Status;\r
+  CHAR16 *FullName;\r
+  CHAR16 *FileName;\r
+  EFI_FILE_HANDLE Handle;\r
+  EFI_FILE_INFO *Info;\r
+} EFI_SHELL_FILE_INFO_NO_CONST;\r
+\r
+/**\r
+  Converts a EFI shell list of structures to the coresponding UEFI Shell 2.0 type of list.\r
+\r
+  if OldStyleFileList is NULL then ASSERT()\r
+\r
+  this function will convert a SHELL_FILE_ARG based list into a callee allocated \r
+  EFI_SHELL_FILE_INFO based list.  it is up to the caller to free the memory via\r
+  the ShellCloseFileMetaArg function.\r
+\r
+  @param FileList               the EFI shell list type\r
+\r
+  @retval the resultant head of the double linked new format list;\r
+**/\r
+LIST_ENTRY*\r
+EFIAPI\r
+InternalShellConvertFileListType (\r
+  LIST_ENTRY                *FileList\r
+  )\r
+{\r
+  LIST_ENTRY                    *ListHead;\r
+  SHELL_FILE_ARG                *OldInfo;\r
+  LIST_ENTRY                *Link;\r
+  EFI_SHELL_FILE_INFO_NO_CONST  *NewInfo;\r
+\r
+  //\r
+  // ASSERT that FileList is not NULL\r
+  //\r
+  ASSERT(FileList != NULL);\r
+\r
+  //\r
+  // Allocate our list head and initialize the list\r
+  //\r
+  ListHead = AllocateZeroPool(sizeof(LIST_ENTRY));\r
+  ASSERT (ListHead != NULL);\r
+  ListHead = InitializeListHead (ListHead);\r
+\r
+  //\r
+  // enumerate through each member of the old list and copy\r
+  //\r
+  for (Link = FileList->ForwardLink; Link != FileList; Link = Link->ForwardLink) {\r
+    OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);\r
+\r
+    //\r
+    // make sure the old list was valid\r
+    //\r
+    ASSERT(OldInfo           != NULL); \r
+    ASSERT(OldInfo->Info     != NULL);\r
+    ASSERT(OldInfo->FullName != NULL);\r
+    ASSERT(OldInfo->FileName != NULL);\r
+\r
+    //\r
+    // allocate a new EFI_SHELL_FILE_INFO object\r
+    //\r
+    NewInfo               = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));\r
+    \r
+    // \r
+    // copy the simple items\r
+    //\r
+    NewInfo->Handle       = OldInfo->Handle;\r
+    NewInfo->Status       = OldInfo->Status;\r
+\r
+    // old shell checks for 0 not NULL\r
+    OldInfo->Handle = 0;\r
+\r
+    //\r
+    // allocate new space to copy strings and structure\r
+    //\r
+    NewInfo->FullName     = AllocateZeroPool(StrSize(OldInfo->FullName));\r
+    NewInfo->FileName     = AllocateZeroPool(StrSize(OldInfo->FileName));\r
+    NewInfo->Info         = AllocateZeroPool((UINTN)OldInfo->Info->Size);\r
+    \r
+    //\r
+    // make sure all the memory allocations were sucessful\r
+    //\r
+    ASSERT(NewInfo->FullName != NULL);\r
+    ASSERT(NewInfo->FileName != NULL);\r
+    ASSERT(NewInfo->Info     != NULL);\r
+\r
+    //\r
+    // Copt the strings and structure\r
+    //\r
+    StrCpy(NewInfo->FullName, OldInfo->FullName);\r
+    StrCpy(NewInfo->FileName, OldInfo->FileName);\r
+    gBS->CopyMem (NewInfo->Info, OldInfo->Info, (UINTN)OldInfo->Info->Size);\r
+\r
+    //\r
+    // add that to the list\r
+    //\r
+    InsertTailList(ListHead, (LIST_ENTRY*)NewInfo);\r
+  }\r
+  return (ListHead);\r
+}\r
+/**\r
+  Opens a group of files based on a path.\r
+\r
+  This function uses the Arg to open all the matching files. Each matched \r
+  file has a SHELL_FILE_ARG structure to record the file information. These \r
+  structures are placed on the list ListHead. Users can get the SHELL_FILE_ARG \r
+  structures from ListHead to access each file. This function supports wildcards\r
+  and will process '?' and '*' as such.  the list must be freed with a call to \r
+  ShellCloseFileMetaArg().\r
+\r
+  This function will fail if called sequentially without freeing the list in the middle.\r
+\r
+  @param Arg                    pointer to path string\r
+  @param OpenMode               mode to open files with\r
+  @param ListHead               head of linked list of results\r
+\r
+  @retval EFI_SUCCESS           the operation was sucessful and the list head \r
+                                contains the list of opened files\r
+  #retval EFI_UNSUPPORTED       a previous ShellOpenFileMetaArg must be closed first.\r
+                                *ListHead is set to NULL.\r
+  @return != EFI_SUCCESS        the operation failed\r
+\r
+  @sa InternalShellConvertFileListType\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellOpenFileMetaArg (\r
+  IN CHAR16                     *Arg,\r
+  IN UINT64                     OpenMode,\r
+  IN OUT EFI_SHELL_FILE_INFO    **ListHead\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  LIST_ENTRY                    *EmptyNode;\r
+  LIST_ENTRY                    *mOldStyleFileList;\r
+  \r
+  //\r
+  // ASSERT that Arg and ListHead are not NULL\r
+  //\r
+  ASSERT(Arg      != NULL);\r
+  ASSERT(ListHead != NULL);\r
+\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    return (mEfiShellProtocol->OpenFileList(Arg, \r
+                                           OpenMode, \r
+                                           ListHead));\r
+  } \r
+\r
+  //\r
+  // ASSERT that we must have EFI shell\r
+  //\r
+  ASSERT(mEfiShellEnvironment2 != NULL);\r
+\r
+  //\r
+  // allocate memory for old list head\r
+  //\r
+  mOldStyleFileList = (LIST_ENTRY*)AllocatePool(sizeof(LIST_ENTRY));\r
+  ASSERT(mOldStyleFileList != NULL);\r
+\r
+  //\r
+  // make sure the list head is initialized\r
+  //\r
+  InitializeListHead((LIST_ENTRY*)mOldStyleFileList);\r
+\r
+  //\r
+  // Get the EFI Shell list of files\r
+  //\r
+  Status = mEfiShellEnvironment2->FileMetaArg(Arg, mOldStyleFileList);\r
+  if (EFI_ERROR(Status)) {\r
+    *ListHead = NULL;\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // Convert that to equivalent of UEFI Shell 2.0 structure\r
+  //\r
+  EmptyNode = InternalShellConvertFileListType(mOldStyleFileList);\r
+\r
+  //\r
+  // Free the EFI Shell version that was converted.\r
+  //\r
+  ASSERT_EFI_ERROR(mEfiShellEnvironment2->FreeFileList(mOldStyleFileList));\r
+  FreePool(mOldStyleFileList);\r
+  mOldStyleFileList = NULL;\r
+\r
+  //\r
+  // remove the empty head of the list\r
+  //\r
+  *ListHead = (EFI_SHELL_FILE_INFO*)RemoveEntryList(EmptyNode);\r
+  FreePool(EmptyNode);  \r
+\r
+  return (Status);\r
+}\r
+/**\r
+  Free the linked list returned from ShellOpenFileMetaArg\r
+\r
+  if ListHead is NULL then ASSERT()\r
+\r
+  @param ListHead               the pointer to free\r
+\r
+  @retval EFI_SUCCESS           the operation was sucessful\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellCloseFileMetaArg (\r
+  IN OUT EFI_SHELL_FILE_INFO    **ListHead\r
+  )\r
+{\r
+  LIST_ENTRY                    *Node;\r
+\r
+  //\r
+  // ASSERT that ListHead is not NULL\r
+  //\r
+  ASSERT(ListHead != NULL);\r
+\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellProtocol != NULL) {\r
+    return (mEfiShellProtocol->FreeFileList(ListHead));\r
+  } else {\r
+    //\r
+    // Since this is EFI Shell version we need to free our internally made copy \r
+    // of the list\r
+    //\r
+    for (Node = GetFirstNode((LIST_ENTRY*)*ListHead) ; IsListEmpty((LIST_ENTRY*)*ListHead) == FALSE ; Node = GetFirstNode((LIST_ENTRY*)*ListHead)) {\r
+      RemoveEntryList(Node);\r
+      ((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle->Close(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle);\r
+      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FullName);\r
+      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FileName);\r
+      FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Info);\r
+      FreePool((EFI_SHELL_FILE_INFO_NO_CONST*)Node);\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+typedef struct {\r
+  LIST_ENTRY List;\r
+  CHAR16         *Name;\r
+  ParamType      Type;\r
+  CHAR16         *Value;\r
+  UINTN          OriginalPosition;\r
+} SHELL_PARAM_PACKAGE;\r
+\r
+/**\r
+  Checks the list of valid arguments and returns TRUE if the item was found.  If the \r
+  return value is TRUE then the type parameter is set also.\r
+  \r
+  if CheckList is NULL then ASSERT();\r
+  if Name is NULL then ASSERT();\r
+  if Type is NULL then ASSERT();\r
+\r
+  @param Type                   pointer to type of parameter if it was found\r
+  @param Name                   pointer to Name of parameter found\r
+  @param CheckList              List to check against\r
+\r
+  @retval TRUE                  the Parameter was found.  Type is valid.\r
+  @retval FALSE                 the Parameter was not found.  Type is not valid.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalIsOnCheckList (\r
+  IN CONST CHAR16               *Name,\r
+  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
+  OUT ParamType                 *Type\r
+  )\r
+{\r
+  SHELL_PARAM_ITEM              *TempListItem;\r
+\r
+  //\r
+  // ASSERT that all 3 pointer parameters aren't NULL\r
+  //\r
+  ASSERT(CheckList  != NULL);\r
+  ASSERT(Type       != NULL);\r
+  ASSERT(Name       != NULL);\r
+\r
+  //\r
+  // question mark and page break mode are always supported\r
+  //\r
+  if ((StrCmp(Name, L"-?") == 0) ||\r
+      (StrCmp(Name, L"-b") == 0)\r
+      ) {\r
+     return (TRUE);\r
+  }\r
+\r
+  //\r
+  // Enumerate through the list\r
+  //\r
+  for (TempListItem = (SHELL_PARAM_ITEM*)CheckList ; TempListItem->Name != NULL ; TempListItem++) {\r
+    //\r
+    // If the Name matches set the type and return TRUE\r
+    //\r
+    if (StrCmp(Name, TempListItem->Name) == 0) {\r
+      *Type = TempListItem->Type;\r
+      return (TRUE);\r
+    }\r
+  }\r
+  return (FALSE);\r
+}\r
+/**\r
+  Checks the string for indicators of "flag" status.  this is a leading '/', '-', or '+'\r
+\r
+  @param Name                   pointer to Name of parameter found\r
+\r
+  @retval TRUE                  the Parameter is a flag.\r
+  @retval FALSE                 the Parameter not a flag\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalIsFlag (\r
+  IN CONST CHAR16               *Name\r
+  )\r
+{\r
+  //\r
+  // ASSERT that Name isn't NULL\r
+  //\r
+  ASSERT(Name != NULL);\r
+\r
+  //\r
+  // If the Name has a / or - as the first character return TRUE\r
+  //\r
+  if ((Name[0] == L'/') || \r
+      (Name[0] == L'-') ||\r
+      (Name[0] == L'+')\r
+      ) {\r
+      return (TRUE);\r
+  }\r
+  return (FALSE);\r
+}\r
+\r
+/**\r
+  Checks the command line arguments passed against the list of valid ones.  \r
+\r
+  If no initialization is required, then return RETURN_SUCCESS.\r
+  \r
+  @param CheckList              pointer to list of parameters to check\r
+  @param CheckPackage           pointer to pointer to list checked values\r
+  @param ProblemParam           optional pointer to pointer to unicode string for \r
+                                the paramater that caused failure.  If used then the\r
+                                caller is responsible for freeing the memory.\r
+  @param AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter\r
+  @param Argc                   Count of parameters in Argv\r
+  @param Argv                   pointer to array of parameters\r
+\r
+  @retval EFI_SUCCESS           The operation completed sucessfully.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed\r
+  @retval EFI_INVALID_PARAMETER A parameter was invalid\r
+  @retval EFI_VOLUME_CORRUPTED  the command line was corrupt.  an argument was \r
+                                duplicated.  the duplicated command line argument \r
+                                was returned in ProblemParam if provided.\r
+  @retval EFI_NOT_FOUND         a argument required a value that was missing.  \r
+                                the invalid command line argument was returned in\r
+                                ProblemParam if provided.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalCommandLineParse (\r
+  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
+  OUT LIST_ENTRY                **CheckPackage,\r
+  OUT CHAR16                    **ProblemParam OPTIONAL,\r
+  IN BOOLEAN                    AutoPageBreak,\r
+  IN CONST CHAR16               **Argv,\r
+  IN UINTN                      Argc\r
+  )\r
+{\r
+  UINTN                         LoopCounter;\r
+  UINTN                         Count;\r
+  ParamType                     CurrentItemType;\r
+  SHELL_PARAM_PACKAGE           *CurrentItemPackage;\r
+  BOOLEAN                       GetItemValue;\r
+\r
+  CurrentItemPackage = NULL;\r
+\r
+  //\r
+  // ASSERTs\r
+  //\r
+  ASSERT(CheckList  != NULL);\r
+  ASSERT(Argv       != NULL);\r
+\r
+  Count = 0;\r
+  GetItemValue = FALSE;\r
+\r
+  //\r
+  // If there is only 1 item we dont need to do anything\r
+  //\r
+  if (Argc <= 1) {\r
+    *CheckPackage = NULL;\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  //\r
+  // initialize the linked list\r
+  //\r
+  *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY));\r
+  InitializeListHead(*CheckPackage);\r
+\r
+  //\r
+  // loop through each of the arguments\r
+  //\r
+  for (LoopCounter = 0 ; LoopCounter < Argc ; ++LoopCounter) {\r
+    if (Argv[LoopCounter] == NULL) {\r
+      //\r
+      // do nothing for NULL argv\r
+      //\r
+    } else if (GetItemValue == TRUE) {\r
+      ASSERT(CurrentItemPackage != NULL);\r
+      //\r
+      // get the item VALUE for the previous flag\r
+      //\r
+      GetItemValue = FALSE;\r
+      CurrentItemPackage->Value = AllocateZeroPool(StrSize(Argv[LoopCounter]));\r
+      ASSERT(CurrentItemPackage->Value != NULL);\r
+      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
+      InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
+    } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
+      //\r
+      // add this one as a non-flag\r
+      //\r
+      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));\r
+      ASSERT(CurrentItemPackage != NULL);\r
+      CurrentItemPackage->Name  = NULL;\r
+      CurrentItemPackage->Type  = TypePosition;\r
+      CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
+      ASSERT(CurrentItemPackage->Value != NULL);\r
+      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
+      CurrentItemPackage->OriginalPosition = Count++;\r
+      InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
+    } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {\r
+      //\r
+      // this is a flag\r
+      //\r
+      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));\r
+      ASSERT(CurrentItemPackage != NULL);\r
+      CurrentItemPackage->Name  = AllocatePool(StrSize(Argv[LoopCounter]));\r
+      ASSERT(CurrentItemPackage->Name != NULL);\r
+      StrCpy(CurrentItemPackage->Name,  Argv[LoopCounter]);\r
+      CurrentItemPackage->Type  = CurrentItemType;\r
+      CurrentItemPackage->OriginalPosition = (UINTN)(-1);\r
+\r
+      //\r
+      // Does this flag require a value\r
+      //\r
+      if (CurrentItemPackage->Type == TypeValue) {\r
+        //\r
+        // trigger the next loop to populate the value of this item\r
+        //\r
+        GetItemValue = TRUE; \r
+      } else {\r
+        //\r
+        // this item has no value expected; we are done\r
+        //\r
+        CurrentItemPackage->Value = NULL;\r
+        InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);\r
+      }\r
+    } else if (ProblemParam) {\r
+      //\r
+      // this was a non-recognised flag... error!\r
+      //\r
+      *ProblemParam = AllocatePool(StrSize(Argv[LoopCounter]));\r
+      ASSERT(*ProblemParam != NULL);\r
+      StrCpy(*ProblemParam, Argv[LoopCounter]);\r
+      ShellCommandLineFreeVarList(*CheckPackage);\r
+      *CheckPackage = NULL;\r
+      return (EFI_VOLUME_CORRUPTED);\r
+    } else {\r
+      ShellCommandLineFreeVarList(*CheckPackage);\r
+      *CheckPackage = NULL;\r
+      return (EFI_VOLUME_CORRUPTED);\r
+    }\r
+  }\r
+  //\r
+  // support for AutoPageBreak\r
+  //\r
+  if (AutoPageBreak && ShellCommandLineGetFlag(*CheckPackage, L"-b")) {\r
+    ShellSetPageBreakMode(TRUE);\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Checks the command line arguments passed against the list of valid ones.  \r
+  Optionally removes NULL values first.\r
+  \r
+  If no initialization is required, then return RETURN_SUCCESS.\r
+  \r
+  @param CheckList              pointer to list of parameters to check\r
+  @param CheckPackage           pointer to pointer to list checked values\r
+  @param ProblemParam           optional pointer to pointer to unicode string for \r
+                                the paramater that caused failure.\r
+  @param AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter\r
+\r
+  @retval EFI_SUCCESS           The operation completed sucessfully.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed\r
+  @retval EFI_INVALID_PARAMETER A parameter was invalid\r
+  @retval EFI_VOLUME_CORRUPTED  the command line was corrupt.  an argument was \r
+                                duplicated.  the duplicated command line argument \r
+                                was returned in ProblemParam if provided.\r
+  @retval EFI_DEVICE_ERROR      the commands contained 2 opposing arguments.  one\r
+                                of the command line arguments was returned in \r
+                                ProblemParam if provided.\r
+  @retval EFI_NOT_FOUND         a argument required a value that was missing.  \r
+                                the invalid command line argument was returned in\r
+                                ProblemParam if provided.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellCommandLineParse (\r
+  IN CONST SHELL_PARAM_ITEM     *CheckList,\r
+  OUT LIST_ENTRY                **CheckPackage,\r
+  OUT CHAR16                    **ProblemParam OPTIONAL,\r
+  IN BOOLEAN                    AutoPageBreak\r
+  )\r
+{\r
+  // \r
+  // ASSERT that CheckList and CheckPackage aren't NULL\r
+  //\r
+  ASSERT(CheckList    != NULL);\r
+  ASSERT(CheckPackage != NULL);\r
+\r
+  // \r
+  // Check for UEFI Shell 2.0 protocols\r
+  //\r
+  if (mEfiShellParametersProtocol != NULL) {\r
+    return (InternalCommandLineParse(CheckList, \r
+                                     CheckPackage, \r
+                                     ProblemParam, \r
+                                     AutoPageBreak, \r
+                                     (CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
+                                     mEfiShellParametersProtocol->Argc ));\r
+  }\r
+\r
+  // \r
+  // ASSERT That EFI Shell is not required\r
+  //\r
+  ASSERT (mEfiShellInterface != NULL);\r
+  return (InternalCommandLineParse(CheckList, \r
+                                   CheckPackage, \r
+                                   ProblemParam, \r
+                                   AutoPageBreak, \r
+                                   (CONST CHAR16**) mEfiShellInterface->Argv,\r
+                                   mEfiShellInterface->Argc ));\r
+}\r
+\r
+/**\r
+  Frees shell variable list that was returned from ShellCommandLineParse.\r
+\r
+  This function will free all the memory that was used for the CheckPackage\r
+  list of postprocessed shell arguments.\r
+\r
+  this function has no return value.\r
+\r
+  if CheckPackage is NULL, then return\r
+\r
+  @param CheckPackage           the list to de-allocate\r
+  **/\r
+VOID\r
+EFIAPI\r
+ShellCommandLineFreeVarList (\r
+  IN LIST_ENTRY                 *CheckPackage\r
+  )\r
+{\r
+  LIST_ENTRY                    *Node;\r
+\r
+  //\r
+  // check for CheckPackage == NULL\r
+  //\r
+  if (CheckPackage == NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // for each node in the list\r
+  //\r
+  for (Node = GetFirstNode(CheckPackage); Node != CheckPackage ; Node = GetFirstNode(CheckPackage)) {\r
+    //\r
+    // Remove it from the list\r
+    //\r
+    RemoveEntryList(Node);\r
+\r
+    //\r
+    // if it has a name free the name\r
+    //\r
+    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
+      FreePool(((SHELL_PARAM_PACKAGE*)Node)->Name);\r
+    }\r
+\r
+    //\r
+    // if it has a value free the value\r
+    //\r
+    if (((SHELL_PARAM_PACKAGE*)Node)->Value != NULL) {\r
+      FreePool(((SHELL_PARAM_PACKAGE*)Node)->Value);\r
+    }\r
+    \r
+    //\r
+    // free the node structure\r
+    //\r
+    FreePool((SHELL_PARAM_PACKAGE*)Node);\r
+  }\r
+  //\r
+  // free the list head node\r
+  //\r
+  FreePool(CheckPackage);\r
+}\r
+/**\r
+  Checks for presence of a flag parameter\r
+\r
+  flag arguments are in the form of "-<Key>" or "/<Key>", but do not have a value following the key\r
+\r
+  if CheckPackage is NULL then return FALSE.\r
+  if KeyString is NULL then ASSERT()\r
+  \r
+  @param CheckPackage           The package of parsed command line arguments\r
+  @param KeyString              the Key of the command line argument to check for\r
+\r
+  @retval TRUE                  the flag is on the command line\r
+  @retval FALSE                 the flag is not on the command line\r
+  **/\r
+BOOLEAN\r
+EFIAPI\r
+ShellCommandLineGetFlag (\r
+  IN CONST LIST_ENTRY           *CheckPackage,\r
+  IN CHAR16                     *KeyString\r
+  )\r
+{\r
+  LIST_ENTRY                    *Node;\r
+\r
+  //\r
+  // ASSERT that both CheckPackage and KeyString aren't NULL\r
+  //\r
+  ASSERT(KeyString != NULL);\r
+\r
+  //\r
+  // return FALSE for no package\r
+  //\r
+  if (CheckPackage == NULL) {\r
+    return (FALSE);\r
+  }\r
+\r
+  //\r
+  // enumerate through the list of parametrs\r
+  //\r
+  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
+    //\r
+    // If the Name matches, return TRUE (and there may be NULL name)\r
+    //\r
+    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
+      if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {\r
+        return (TRUE);\r
+      }\r
+    }\r
+  }\r
+  return (FALSE);\r
+}\r
+/**\r
+  returns value from command line argument\r
+\r
+  value parameters are in the form of "-<Key> value" or "/<Key> value"\r
+  \r
+  if CheckPackage is NULL, then return NULL;\r
+\r
+  @param CheckPackage           The package of parsed command line arguments\r
+  @param KeyString              the Key of the command line argument to check for\r
+\r
+  @retval NULL                  the flag is not on the command line\r
+  @return !=NULL                pointer to unicode string of the value\r
+  **/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellCommandLineGetValue (\r
+  IN CONST LIST_ENTRY           *CheckPackage,\r
+  IN CHAR16                     *KeyString\r
+  )\r
+{\r
+  LIST_ENTRY                    *Node;\r
+\r
+  //\r
+  // check for CheckPackage == NULL\r
+  //\r
+  if (CheckPackage == NULL) {\r
+    return (NULL);\r
+  }\r
+\r
+  //\r
+  // enumerate through the list of parametrs\r
+  //\r
+  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
+    //\r
+    // If the Name matches, return the value (name can be NULL)\r
+    //\r
+    if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {\r
+      if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {\r
+        return (((SHELL_PARAM_PACKAGE*)Node)->Value);\r
+      }\r
+    }\r
+  }\r
+  return (NULL);\r
+}\r
+/**\r
+  returns raw value from command line argument\r
+\r
+  raw value parameters are in the form of "value" in a specific position in the list\r
+  \r
+  if CheckPackage is NULL, then return NULL;\r
+\r
+  @param CheckPackage           The package of parsed command line arguments\r
+  @param Position               the position of the value \r
+\r
+  @retval NULL                  the flag is not on the command line\r
+  @return !=NULL                pointer to unicode string of the value\r
+  **/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellCommandLineGetRawValue (\r
+  IN CONST LIST_ENTRY           *CheckPackage,\r
+  IN UINT32                     Position\r
+  )\r
+{\r
+  LIST_ENTRY                    *Node;\r
+\r
+  //\r
+  // check for CheckPackage == NULL\r
+  //\r
+  if (CheckPackage == NULL) {\r
+    return (NULL);\r
+  }\r
+\r
+  //\r
+  // enumerate through the list of parametrs\r
+  //\r
+  for (Node = GetFirstNode(CheckPackage) ; !IsNull (CheckPackage, Node) ; Node = GetNextNode(CheckPackage, Node) ) {\r
+    //\r
+    // If the position matches, return the value\r
+    //\r
+    if (((SHELL_PARAM_PACKAGE*)Node)->OriginalPosition == Position) {\r
+      return (((SHELL_PARAM_PACKAGE*)Node)->Value);\r
+    }\r
+  }\r
+  return (NULL);\r
+}
\ No newline at end of file
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.h b/ShellPkg/Library/UefiShellLib/UefiShellLib.h
new file mode 100644 (file)
index 0000000..1620641
--- /dev/null
@@ -0,0 +1,26 @@
+/** @file\r
+  Provides interface to shell functionality for shell commands and applications.\r
+\r
+Copyright (c) 2006 - 2009, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+typedef struct  {\r
+  EFI_SHELL_GET_FILE_INFO                   GetFileInfo;\r
+  EFI_SHELL_SET_FILE_INFO                   SetFileInfo;\r
+  EFI_SHELL_READ_FILE                       ReadFile;\r
+  EFI_SHELL_WRITE_FILE                      WriteFile;\r
+  EFI_SHELL_CLOSE_FILE                      CloseFile;\r
+  EFI_SHELL_DELETE_FILE                     DeleteFile;\r
+  EFI_SHELL_GET_FILE_POSITION               GetFilePosition;\r
+  EFI_SHELL_SET_FILE_POSITION               SetFilePosition;\r
+  EFI_SHELL_FLUSH_FILE                      FlushFile;\r
+  EFI_SHELL_GET_FILE_SIZE                   GetFileSize;\r
+} FILE_HANDLE_FUNCTION_MAP;\r
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.inf b/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
new file mode 100644 (file)
index 0000000..5ed4259
--- /dev/null
@@ -0,0 +1,63 @@
+#/** @file\r
+# Provides interface to shell functionality for shell commands and applications.\r
+#\r
+# Copyright (c) 2006 - 2009, Intel Corporation.\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = UefiShellLib\r
+  FILE_GUID                      = 449D0F00-2148-4a43-9836-F10B3980ECF5\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ShellLib|UEFI_APPLICATION UEFI_DRIVER\r
+  CONSTRUCTOR                    = ShellLibConstructor\r
+  DESTRUCTOR                     = ShellLibDestructor\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  UefiShellLib.c\r
+  UefiShellLib.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  DevicePathLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  FileHandleLib\r
+\r
+[Protocols]\r
+  gEfiSimpleFileSystemProtocolGuid              # ALWAYS_CONSUMED\r
+  \r
+  # shell 2.0 \r
+  gEfiShellProtocolGuid                         # SOMETIMES_CONSUMED\r
+  gEfiShellParametersProtocolGuid               # SOMETIMES_CONSUMED\r
+\r
+  # 'old' shell\r
+  gEfiShellEnvironment2Guid                     # SOMETIMES_CONSUMED\r
+  gEfiShellInterfaceGuid                        # SOMETIMES_CONSUMED\r
+\r
+[Guids]\r
+  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
+  gEfiShellEnvironment2ExtGuid                  # ALWAYS_CONSUMED\r
+\r
+[Pcd.common]\r
+  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize  # ALWAYS_CONSUMED\r
index 787c37427056c4913e59bed9947593516b02d78b..ed7d46d9cad42d0a7ffef18c42030f2370d786b2 100644 (file)
@@ -36,7 +36,7 @@
   PrintLib|MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf\r
   UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
   \r
   PrintLib|MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf\r
   UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
   \r
-  ShellLib|ShellPkg/Library/BaseShellLib/BaseShellLib.inf\r
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf\r
   FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf\r
 \r
 [PcdsFixedAtBuild.common]\r
   FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf\r
 \r
 [PcdsFixedAtBuild.common]\r