]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
udk2010.up2.shell initial release.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index d3cc59e9be5e8e5d1ae433f907b277f354cc8041..1694f463789a7b11b0ed0cb5220023ff2678e72e 100644 (file)
 **/\r
 \r
 #include "UefiShellLib.h"\r
+#include <ShellBase.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
+// globals...\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
-STATIC UINTN                         mTotalParameterCount;\r
-STATIC CHAR16                        *mPostReplaceFormat;\r
-STATIC CHAR16                        *mPostReplaceFormat2;\r
+SHELL_PARAM_ITEM SfoParamList[] = {\r
+  {L"-sfo", TypeFlag},\r
+  {NULL, TypeMax}\r
+  };\r
+EFI_SHELL_ENVIRONMENT2        *mEfiShellEnvironment2;\r
+EFI_SHELL_INTERFACE           *mEfiShellInterface;\r
+EFI_SHELL_PROTOCOL            *mEfiShellProtocol;\r
+EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
+EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
+FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
+CHAR16                        *mPostReplaceFormat;\r
+CHAR16                        *mPostReplaceFormat2;\r
 \r
 /**\r
   Check if a Unicode character is a hexadecimal character.\r
 \r
   This internal function checks if a Unicode character is a\r
-  decimal character.  The valid hexadecimal character is\r
+  numeric character.  The valid hexadecimal characters are\r
   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
 \r
-\r
   @param  Char  The character to check against.\r
 \r
   @retval TRUE  If the Char is a hexadecmial character.\r
@@ -55,18 +53,45 @@ BOOLEAN
 EFIAPI\r
 ShellIsHexaDecimalDigitCharacter (\r
   IN      CHAR16                    Char\r
-  ) {\r
+  )\r
+{\r
   return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));\r
 }\r
 \r
 /**\r
-  helper function to find ShellEnvironment2 for constructor\r
+  Check if a Unicode character is a decimal character.\r
+\r
+  This internal function checks if a Unicode character is a\r
+  decimal character.  The valid characters are\r
+  L'0' to L'9'.\r
+\r
+\r
+  @param  Char  The character to check against.\r
+\r
+  @retval TRUE  If the Char is a hexadecmial character.\r
+  @retval FALSE If the Char is not a hexadecmial character.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellIsDecimalDigitCharacter (\r
+  IN      CHAR16                    Char\r
+  )\r
+{\r
+  return (BOOLEAN) (Char >= L'0' && Char <= L'9');\r
+}\r
+\r
+/**\r
+  Helper function to find ShellEnvironment2 for constructor.\r
+\r
+  @param[in] ImageHandle    A copy of the calling image's handle.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 ShellFindSE2 (\r
   IN EFI_HANDLE        ImageHandle\r
-  ) {\r
+  )\r
+{\r
   EFI_STATUS  Status;\r
   EFI_HANDLE  *Buffer;\r
   UINTN       BufferSize;\r
@@ -80,11 +105,11 @@ ShellFindSE2 (
                              ImageHandle,\r
                              NULL,\r
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                             );\r
+                            );\r
   //\r
   // look for the mEfiShellEnvironment2 protocol at a higher level\r
   //\r
-  if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE)){\r
+  if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid))){\r
     //\r
     // figure out how big of a buffer we need.\r
     //\r
@@ -93,7 +118,7 @@ ShellFindSE2 (
                                 NULL, // ignored for ByProtocol\r
                                 &BufferSize,\r
                                 Buffer\r
-                                );\r
+                               );\r
     //\r
     // maybe it's not there???\r
     //\r
@@ -105,7 +130,7 @@ ShellFindSE2 (
                                   NULL, // ignored for ByProtocol\r
                                   &BufferSize,\r
                                   Buffer\r
-                                  );\r
+                                 );\r
     }\r
     if (!EFI_ERROR (Status) && Buffer != NULL) {\r
       //\r
@@ -119,8 +144,8 @@ ShellFindSE2 (
                                    ImageHandle,\r
                                    NULL,\r
                                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                                   );\r
-         if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE) {\r
+                                  );\r
+         if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid)) {\r
           mEfiShellEnvironment2Handle = Buffer[HandleIndex];\r
           Status = EFI_SUCCESS;\r
           break;\r
@@ -134,44 +159,58 @@ ShellFindSE2 (
   return (Status);\r
 }\r
 \r
+/*/\r
+  Function to do most of the work of the constructor.  Allows for calling \r
+  multiple times without complete re-initialization.\r
+\r
+  @param[in] ImageHandle  A copy of the ImageHandle.\r
+  @param[in] SystemTable  A pointer to the SystemTable for the application.\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
+{\r
+  EFI_STATUS  Status;\r
   mPostReplaceFormat = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
   ASSERT (mPostReplaceFormat != NULL);\r
   mPostReplaceFormat2 = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
   ASSERT (mPostReplaceFormat2 != NULL);\r
 \r
-  //\r
-  // Set the parameter count to an invalid number\r
-  //\r
-  mTotalParameterCount = (UINTN)(-1);\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
+  Status = gBS->OpenProtocol(\r
+    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
+    // Search for the shell protocol\r
+    //\r
+    Status = gBS->LocateProtocol(\r
+      &gEfiShellProtocolGuid,\r
+      NULL,\r
+      (VOID **)&mEfiShellProtocol\r
+     );\r
+    if (EFI_ERROR(Status)) {\r
+      mEfiShellProtocol = NULL;\r
+    }\r
   }\r
-  Status = gBS->OpenProtocol(ImageHandle,\r
-                             &gEfiShellParametersProtocolGuid,\r
-                             (VOID **)&mEfiShellParametersProtocol,\r
-                             ImageHandle,\r
-                             NULL,\r
-                             EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                             );\r
+  Status = gBS->OpenProtocol(\r
+    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
@@ -192,7 +231,7 @@ ShellLibConstructorWorker (
                                ImageHandle,\r
                                NULL,\r
                                EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                               );\r
+                              );\r
     if (EFI_ERROR(Status)) {\r
       mEfiShellInterface = NULL;\r
     }\r
@@ -202,7 +241,7 @@ ShellLibConstructorWorker (
   // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
   //\r
   if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) ||\r
-      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)    ) {\r
+      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)   ) {\r
     if (mEfiShellProtocol != NULL) {\r
       FileFunctionMap.GetFileInfo     = mEfiShellProtocol->GetFileInfo;\r
       FileFunctionMap.SetFileInfo     = mEfiShellProtocol->SetFileInfo;\r
@@ -215,16 +254,16 @@ ShellLibConstructorWorker (
       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
+      FileFunctionMap.GetFileInfo     = (EFI_SHELL_GET_FILE_INFO)FileHandleGetInfo;\r
+      FileFunctionMap.SetFileInfo     = (EFI_SHELL_SET_FILE_INFO)FileHandleSetInfo;\r
+      FileFunctionMap.ReadFile        = (EFI_SHELL_READ_FILE)FileHandleRead;\r
+      FileFunctionMap.WriteFile       = (EFI_SHELL_WRITE_FILE)FileHandleWrite;\r
+      FileFunctionMap.CloseFile       = (EFI_SHELL_CLOSE_FILE)FileHandleClose;\r
+      FileFunctionMap.DeleteFile      = (EFI_SHELL_DELETE_FILE)FileHandleDelete;\r
+      FileFunctionMap.GetFilePosition = (EFI_SHELL_GET_FILE_POSITION)FileHandleGetPosition;\r
+      FileFunctionMap.SetFilePosition = (EFI_SHELL_SET_FILE_POSITION)FileHandleSetPosition;\r
+      FileFunctionMap.FlushFile       = (EFI_SHELL_FLUSH_FILE)FileHandleFlush;\r
+      FileFunctionMap.GetFileSize     = (EFI_SHELL_GET_FILE_SIZE)FileHandleGetSize;\r
     }\r
     return (EFI_SUCCESS);\r
   }\r
@@ -246,8 +285,8 @@ EFIAPI
 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
@@ -267,14 +306,21 @@ ShellLibConstructor (
 }\r
 \r
 /**\r
-  Destructory for the library.  free any resources.\r
+  Destructor for the library.  free any resources.\r
+\r
+  @param[in] ImageHandle  A copy of the ImageHandle.\r
+  @param[in] SystemTable  A pointer to the SystemTable for the application.\r
+\r
+  @retval EFI_SUCCESS   The operation was successful.\r
+  @return               An error from the CloseProtocol function.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 ShellLibDestructor (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
-  ) {\r
+  )\r
+{\r
   if (mEfiShellEnvironment2 != NULL) {\r
     gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
                        &gEfiShellEnvironment2Guid,\r
@@ -333,7 +379,8 @@ ShellLibDestructor (
 EFI_STATUS\r
 EFIAPI\r
 ShellInitialize (\r
-  ) {\r
+  )\r
+{\r
   //\r
   // if auto initialize is not false then skip\r
   //\r
@@ -369,35 +416,38 @@ ShellInitialize (
 EFI_FILE_INFO*\r
 EFIAPI\r
 ShellGetFileInfo (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  ) {\r
+  IN SHELL_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
+  This function sets 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
+  @param[in]  FileHandle        The file handle of the file for which information\r
+                                is being set.\r
 \r
-  @param  FileInfo              The infotmation to set.\r
+  @param[in]  FileInfo          The information 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_SUCCESS                  The information was set.\r
+  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.\r
+  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.\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
+  @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 SHELL_FILE_HANDLE                         FileHandle,\r
   IN EFI_FILE_INFO              *FileInfo\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
 }\r
 \r
@@ -426,7 +476,7 @@ ShellSetFileInfo (
   @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_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
@@ -436,14 +486,16 @@ EFIAPI
 ShellOpenFileByDevicePath(\r
   IN OUT EFI_DEVICE_PATH_PROTOCOL        **FilePath,\r
   OUT EFI_HANDLE                       *DeviceHandle,\r
-  OUT EFI_FILE_HANDLE                  *FileHandle,\r
+  OUT SHELL_FILE_HANDLE               *FileHandle,\r
   IN UINT64                            OpenMode,\r
   IN UINT64                            Attributes\r
-  ) {\r
-  CHAR16      *FileName;\r
-  EFI_STATUS  Status;\r
+  )\r
+{\r
+  CHAR16                          *FileName;\r
+  EFI_STATUS                      Status;\r
   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
-  EFI_FILE_HANDLE LastHandle;\r
+  EFI_FILE_PROTOCOL               *Handle1;\r
+  EFI_FILE_PROTOCOL               *Handle2;\r
 \r
   //\r
   // ASERT for FileHandle, FilePath, and DeviceHandle being NULL\r
@@ -486,7 +538,7 @@ ShellOpenFileByDevicePath(
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);\r
+  Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);\r
   if (EFI_ERROR (Status)) {\r
     FileHandle = NULL;\r
     return Status;\r
@@ -501,43 +553,43 @@ ShellOpenFileByDevicePath(
     //\r
     if (DevicePathType    (*FilePath) != MEDIA_DEVICE_PATH ||\r
         DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP\r
-        ) {\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
+    Handle2  = Handle1;\r
+    Handle1 = NULL;\r
 \r
     //\r
     // Try to test opening an existing file\r
     //\r
-    Status = LastHandle->Open (\r
-                          LastHandle,\r
-                          FileHandle,\r
+    Status = Handle2->Open (\r
+                          Handle2,\r
+                          &Handle1,\r
                           ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
                           OpenMode &~EFI_FILE_MODE_CREATE,\r
                           0\r
-                          );\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
+      Status = Handle2->Open (\r
+                            Handle2,\r
+                            &Handle1,\r
                             ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
                             OpenMode,\r
                             Attributes\r
-                            );\r
+                           );\r
     }\r
     //\r
     // Close the last node\r
     //\r
-    LastHandle->Close (LastHandle);\r
+    Handle2->Close (Handle2);\r
 \r
     if (EFI_ERROR(Status)) {\r
       return (Status);\r
@@ -548,6 +600,11 @@ ShellOpenFileByDevicePath(
     //\r
     *FilePath = NextDevicePathNode (*FilePath);\r
   }\r
+\r
+  //\r
+  // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!\r
+  //\r
+  *FileHandle = (VOID*)Handle1;\r
   return (EFI_SUCCESS);\r
 }\r
 \r
@@ -586,10 +643,11 @@ EFI_STATUS
 EFIAPI\r
 ShellOpenFileByName(\r
   IN CONST CHAR16                          *FileName,\r
-  OUT EFI_FILE_HANDLE           *FileHandle,\r
+  OUT SHELL_FILE_HANDLE         *FileHandle,\r
   IN UINT64                     OpenMode,\r
   IN UINT64                            Attributes\r
-  ) {\r
+  )\r
+{\r
   EFI_HANDLE                    DeviceHandle;\r
   EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
   EFI_STATUS                    Status;\r
@@ -600,14 +658,21 @@ ShellOpenFileByName(
   //\r
   ASSERT(FileName != NULL);\r
 \r
+  if (FileName == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
   if (mEfiShellProtocol != NULL) {\r
+    if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE && (Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
+      return ShellCreateDirectory(FileName, FileHandle);\r
+    }\r
     //\r
     // Use UEFI Shell 2.0 method\r
     //\r
     Status = mEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
-    if (!EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
+    if (StrCmp(FileName, L"NUL") != 0 && !EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
       FileInfo = FileFunctionMap.GetFileInfo(*FileHandle);\r
       ASSERT(FileInfo != NULL);\r
       FileInfo->Attribute = Attributes;\r
@@ -628,7 +693,7 @@ ShellOpenFileByName(
                                       &DeviceHandle,\r
                                       FileHandle,\r
                                       OpenMode,\r
-                                      Attributes ));\r
+                                      Attributes));\r
   }\r
   return (EFI_DEVICE_ERROR);\r
 }\r
@@ -664,8 +729,9 @@ EFI_STATUS
 EFIAPI\r
 ShellCreateDirectory(\r
   IN CONST CHAR16             *DirectoryName,\r
-  OUT EFI_FILE_HANDLE         *FileHandle\r
-  ) {\r
+  OUT SHELL_FILE_HANDLE                  *FileHandle\r
+  )\r
+{\r
   if (mEfiShellProtocol != NULL) {\r
     //\r
     // Use UEFI Shell 2.0 method\r
@@ -673,13 +739,13 @@ ShellCreateDirectory(
     return (mEfiShellProtocol->CreateFile(DirectoryName,\r
                           EFI_FILE_DIRECTORY,\r
                           FileHandle\r
-                          ));\r
+                         ));\r
   } else {\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
 \r
@@ -715,10 +781,11 @@ ShellCreateDirectory(
 EFI_STATUS\r
 EFIAPI\r
 ShellReadFile(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN SHELL_FILE_HANDLE                     FileHandle,\r
   IN OUT UINTN                  *BufferSize,\r
   OUT VOID                      *Buffer\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));\r
 }\r
 \r
@@ -750,10 +817,11 @@ ShellReadFile(
 EFI_STATUS\r
 EFIAPI\r
 ShellWriteFile(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN SHELL_FILE_HANDLE                     FileHandle,\r
   IN OUT UINTN                  *BufferSize,\r
   IN VOID                       *Buffer\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));\r
 }\r
 \r
@@ -771,8 +839,9 @@ ShellWriteFile(
 EFI_STATUS\r
 EFIAPI\r
 ShellCloseFile (\r
-  IN EFI_FILE_HANDLE            *FileHandle\r
-  ) {\r
+  IN SHELL_FILE_HANDLE                     *FileHandle\r
+  )\r
+{\r
   return (FileFunctionMap.CloseFile(*FileHandle));\r
 }\r
 \r
@@ -793,8 +862,9 @@ ShellCloseFile (
 EFI_STATUS\r
 EFIAPI\r
 ShellDeleteFile (\r
-  IN EFI_FILE_HANDLE           *FileHandle\r
-  ) {\r
+  IN SHELL_FILE_HANDLE                         *FileHandle\r
+  )\r
+{\r
   return (FileFunctionMap.DeleteFile(*FileHandle));\r
 }\r
 \r
@@ -820,9 +890,10 @@ ShellDeleteFile (
 EFI_STATUS\r
 EFIAPI\r
 ShellSetFilePosition (\r
-  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN SHELL_FILE_HANDLE                 FileHandle,\r
   IN UINT64            Position\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
 }\r
 \r
@@ -844,9 +915,10 @@ ShellSetFilePosition (
 EFI_STATUS\r
 EFIAPI\r
 ShellGetFilePosition (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN SHELL_FILE_HANDLE                     FileHandle,\r
   OUT UINT64                    *Position\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
 }\r
 /**\r
@@ -866,8 +938,9 @@ ShellGetFilePosition (
 EFI_STATUS\r
 EFIAPI\r
 ShellFlushFile (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  ) {\r
+  IN SHELL_FILE_HANDLE                     FileHandle\r
+  )\r
+{\r
   return (FileFunctionMap.FlushFile(FileHandle));\r
 }\r
 \r
@@ -892,9 +965,10 @@ ShellFlushFile (
 EFI_STATUS\r
 EFIAPI\r
 ShellFindFirstFile (\r
-  IN EFI_FILE_HANDLE            DirHandle,\r
+  IN SHELL_FILE_HANDLE                     DirHandle,\r
   OUT EFI_FILE_INFO             **Buffer\r
-  ) {\r
+  )\r
+{\r
   //\r
   // pass to file handle lib\r
   //\r
@@ -903,7 +977,7 @@ ShellFindFirstFile (
 /**\r
   Retrieves the next file in a directory.\r
 \r
-  To use this function, caller must call the LibFindFirstFile() to get the\r
+  To use this function, caller must call the ShellFindFirstFile() 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
@@ -922,10 +996,11 @@ ShellFindFirstFile (
 EFI_STATUS\r
 EFIAPI\r
 ShellFindNextFile(\r
-  IN EFI_FILE_HANDLE             DirHandle,\r
+  IN SHELL_FILE_HANDLE                      DirHandle,\r
   OUT EFI_FILE_INFO              *Buffer,\r
   OUT BOOLEAN                    *NoFile\r
-  ) {\r
+  )\r
+{\r
   //\r
   // pass to file handle lib\r
   //\r
@@ -949,9 +1024,10 @@ ShellFindNextFile(
 EFI_STATUS\r
 EFIAPI\r
 ShellGetFileSize (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN SHELL_FILE_HANDLE                     FileHandle,\r
   OUT UINT64                    *Size\r
-  ) {\r
+  )\r
+{\r
   return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
 }\r
 /**\r
@@ -1062,34 +1138,38 @@ ShellSetEnvironmentVariable (
   //\r
   return (EFI_UNSUPPORTED);\r
 }\r
+\r
 /**\r
-  cause the shell to parse and execute a command line.\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
+  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
+  The EnvironmentVariables and Status parameters are ignored in a pre-UEFI Shell 2.0\r
+  environment.  The values pointed to by the parameters will be unchanged by the\r
+  ShellExecute() function.  The Output parameter has no effect in a\r
+  UEFI Shell 2.0 environment.\r
+\r
+  @param[in] ParentHandle         The parent image starting the operation.\r
+  @param[in] CommandLine          The pointer to a NULL terminated command line.\r
+  @param[in] Output               True to display debug output.  False to hide it.\r
+  @param[in] EnvironmentVariables Optional pointer to array of environment variables\r
+                                  in the form "x=y".  If NULL, the current set is used.\r
+  @param[out] 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
+\r
 EFI_STATUS\r
 EFIAPI\r
 ShellExecute (\r
@@ -1139,7 +1219,7 @@ ShellExecute (
 CONST CHAR16*\r
 EFIAPI\r
 ShellGetCurrentDir (\r
-  IN CHAR16                     *DeviceName OPTIONAL\r
+  IN CHAR16                     * CONST DeviceName OPTIONAL\r
   )\r
 {\r
   //\r
@@ -1225,7 +1305,7 @@ typedef struct {
   EFI_STATUS Status;\r
   CHAR16 *FullName;\r
   CHAR16 *FileName;\r
-  EFI_FILE_HANDLE Handle;\r
+  SHELL_FILE_HANDLE          Handle;\r
   EFI_FILE_INFO *Info;\r
 } EFI_SHELL_FILE_INFO_NO_CONST;\r
 \r
@@ -1238,7 +1318,7 @@ typedef struct {
   EFI_SHELL_FILE_INFO based list.  it is up to the caller to free the memory via\r
   the ShellCloseFileMetaArg function.\r
 \r
-  @param[in] FileList           the EFI shell list type\r
+  @param[in] FileList          the EFI shell list type\r
   @param[in,out] ListHead      the list to add to\r
 \r
   @retval the resultant head of the double linked new format list;\r
@@ -1265,11 +1345,18 @@ InternalShellConvertFileListType (
   //\r
   for (Link = FileList->ForwardLink; Link != FileList; Link = Link->ForwardLink) {\r
     OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);\r
+    ASSERT(OldInfo           != NULL);\r
+\r
+    //\r
+    // Skip ones that failed to open...\r
+    //\r
+    if (OldInfo->Status != EFI_SUCCESS) {\r
+      continue;\r
+    }\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
@@ -1339,8 +1426,6 @@ InternalShellConvertFileListType (
 \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
@@ -1381,6 +1466,11 @@ ShellOpenFileMetaArg (
     } else {\r
       Status = mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
     }\r
+    if (*ListHead != NULL && IsListEmpty(&(*ListHead)->Link)) {\r
+      FreePool(*ListHead);\r
+      *ListHead = NULL;\r
+      return (EFI_NOT_FOUND);\r
+    }\r
     return (Status);\r
   }\r
 \r
@@ -1408,6 +1498,7 @@ ShellOpenFileMetaArg (
     if (*ListHead == NULL) {\r
       return (EFI_OUT_OF_RESOURCES);\r
     }\r
+    InitializeListHead(&((*ListHead)->Link));\r
   }\r
 \r
   //\r
@@ -1420,16 +1511,22 @@ ShellOpenFileMetaArg (
   //\r
   mEfiShellEnvironment2->FreeFileList(&mOldStyleFileList);\r
 \r
+  if ((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink && (*ListHead)->Link.BackLink == &((*ListHead)->Link)) {\r
+    FreePool(*ListHead);\r
+    *ListHead = NULL;\r
+    Status = EFI_NOT_FOUND;\r
+  }\r
+\r
   return (Status);\r
 }\r
 /**\r
-  Free the linked list returned from ShellOpenFileMetaArg\r
+  Free the linked list returned from ShellOpenFileMetaArg.\r
 \r
-  if ListHead is NULL then ASSERT()\r
+  if ListHead is NULL then ASSERT().\r
 \r
-  @param ListHead               the pointer to free\r
+  @param ListHead               the pointer to free.\r
 \r
-  @retval EFI_SUCCESS           the operation was sucessful\r
+  @retval EFI_SUCCESS           the operation was sucessful.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1455,10 +1552,10 @@ ShellCloseFileMetaArg (
     // of the list\r
     //\r
     for ( Node = GetFirstNode(&(*ListHead)->Link)\r
-        ; IsListEmpty(&(*ListHead)->Link) == FALSE\r
+        ; *ListHead != NULL && !IsListEmpty(&(*ListHead)->Link)\r
         ; Node = GetFirstNode(&(*ListHead)->Link)) {\r
       RemoveEntryList(Node);\r
-      ((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle->Close(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle);\r
+      ((EFI_FILE_PROTOCOL*)((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
@@ -1487,7 +1584,7 @@ ShellFindFilePath (
   )\r
 {\r
   CONST CHAR16      *Path;\r
-  EFI_FILE_HANDLE   Handle;\r
+  SHELL_FILE_HANDLE Handle;\r
   EFI_STATUS        Status;\r
   CHAR16            *RetVal;\r
   CHAR16            *TestPath;\r
@@ -1497,6 +1594,21 @@ ShellFindFilePath (
 \r
   RetVal = NULL;\r
 \r
+  //\r
+  // First make sure its not an absolute path.\r
+  //\r
+  Status = ShellOpenFileByName(FileName, &Handle, EFI_FILE_MODE_READ, 0);\r
+  if (!EFI_ERROR(Status)){\r
+    if (FileHandleIsDirectory(Handle) != EFI_SUCCESS) {\r
+      ASSERT(RetVal == NULL);\r
+      RetVal = StrnCatGrow(&RetVal, NULL, FileName, 0);\r
+      ShellCloseFile(&Handle);\r
+      return (RetVal);\r
+    } else {\r
+      ShellCloseFile(&Handle);\r
+    }\r
+  }\r
+\r
   Path = ShellGetEnvironmentVariable(L"cwd");\r
   if (Path != NULL) {\r
     Size = StrSize(Path);\r
@@ -1510,22 +1622,23 @@ ShellFindFilePath (
     StrCat(TestPath, FileName);\r
     Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);\r
     if (!EFI_ERROR(Status)){\r
-      RetVal = StrnCatGrow(&RetVal, NULL, TestPath, 0);\r
-      ShellCloseFile(&Handle);\r
-      FreePool(TestPath);\r
-      return (RetVal);\r
+      if (FileHandleIsDirectory(Handle) != EFI_SUCCESS) {\r
+        ASSERT(RetVal == NULL);\r
+        RetVal = StrnCatGrow(&RetVal, NULL, TestPath, 0);\r
+        ShellCloseFile(&Handle);\r
+        FreePool(TestPath);\r
+        return (RetVal);\r
+      } else {\r
+        ShellCloseFile(&Handle);\r
+      }\r
     }\r
     FreePool(TestPath);\r
   }\r
   Path = ShellGetEnvironmentVariable(L"path");\r
   if (Path != NULL) {\r
-    Size = StrSize(Path);\r
+    Size = StrSize(Path)+sizeof(CHAR16);\r
     Size += StrSize(FileName);\r
     TestPath = AllocateZeroPool(Size);\r
-    ASSERT(TestPath != NULL);\r
-    if (TestPath == NULL) {\r
-      return (NULL);\r
-    }\r
     Walker = (CHAR16*)Path;\r
     do {\r
       CopyMem(TestPath, Walker, StrSize(Walker));\r
@@ -1533,6 +1646,9 @@ ShellFindFilePath (
       if (TempChar != NULL) {\r
         *TempChar = CHAR_NULL;\r
       }\r
+      if (TestPath[StrLen(TestPath)-1] != L'\\') {\r
+        StrCat(TestPath, L"\\");\r
+      }\r
       StrCat(TestPath, FileName);\r
       if (StrStr(Walker, L";") != NULL) {\r
         Walker = StrStr(Walker, L";") + 1;\r
@@ -1541,9 +1657,14 @@ ShellFindFilePath (
       }\r
       Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);\r
       if (!EFI_ERROR(Status)){\r
-        RetVal = StrnCatGrow(&RetVal, NULL, TestPath, 0);\r
-        ShellCloseFile(&Handle);\r
-        break;\r
+        if (FileHandleIsDirectory(Handle) != EFI_SUCCESS) {\r
+          ASSERT(RetVal == NULL);\r
+          RetVal = StrnCatGrow(&RetVal, NULL, TestPath, 0);\r
+          ShellCloseFile(&Handle);\r
+          break;\r
+        } else {\r
+          ShellCloseFile(&Handle);\r
+        }\r
       }\r
     } while (Walker != NULL && Walker[0] != CHAR_NULL);\r
     FreePool(TestPath);\r
@@ -1596,9 +1717,11 @@ ShellFindFilePathEx (
   if (TestPath == NULL) {\r
     return (NULL);\r
   }\r
-  for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16*)FileExtension;  TempChar2 != NULL ; ExtensionWalker = TempChar2 + 1 ){\r
+  for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16*)FileExtension;  TempChar2 != NULL ; ExtensionWalker = TempChar2 + 1){\r
     StrCpy(TestPath, FileName);\r
-    StrCat(TestPath, ExtensionWalker);\r
+    if (ExtensionWalker != NULL) {\r
+      StrCat(TestPath, ExtensionWalker);\r
+    }\r
     TempChar = StrStr(TestPath, L";");\r
     if (TempChar != NULL) {\r
       *TempChar = CHAR_NULL;\r
@@ -1607,6 +1730,7 @@ ShellFindFilePathEx (
     if (RetVal != NULL) {\r
       break;\r
     }\r
+    ASSERT(ExtensionWalker != NULL);\r
     TempChar2 = StrStr(ExtensionWalker, L";");\r
   }\r
   FreePool(TestPath);\r
@@ -1616,7 +1740,7 @@ ShellFindFilePathEx (
 typedef struct {\r
   LIST_ENTRY     Link;\r
   CHAR16         *Name;\r
-  ParamType      Type;\r
+  SHELL_PARAM_TYPE      Type;\r
   CHAR16         *Value;\r
   UINTN          OriginalPosition;\r
 } SHELL_PARAM_PACKAGE;\r
@@ -1629,9 +1753,9 @@ typedef struct {
   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
+  @param Type                   pointer to type of parameter if it was found\r
 \r
   @retval TRUE                  the Parameter was found.  Type is valid.\r
   @retval FALSE                 the Parameter was not found.  Type is not valid.\r
@@ -1641,8 +1765,9 @@ EFIAPI
 InternalIsOnCheckList (\r
   IN CONST CHAR16               *Name,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
-  OUT ParamType                 *Type\r
-  ) {\r
+  OUT SHELL_PARAM_TYPE                 *Type\r
+  )\r
+{\r
   SHELL_PARAM_ITEM              *TempListItem;\r
 \r
   //\r
@@ -1657,7 +1782,7 @@ InternalIsOnCheckList (
   //\r
   if ((StrCmp(Name, L"-?") == 0) ||\r
       (StrCmp(Name, L"-b") == 0)\r
-      ) {\r
+     ) {\r
      return (TRUE);\r
   }\r
 \r
@@ -1683,10 +1808,11 @@ InternalIsOnCheckList (
 /**\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
+  @param[in] Name               pointer to Name of parameter found\r
+  @param[in] AlwaysAllowNumbers TRUE to allow numbers, FALSE to not.\r
 \r
   @retval TRUE                  the Parameter is a flag.\r
-  @retval FALSE                 the Parameter not a flag\r
+  @retval FALSE                 the Parameter not a flag.\r
 **/\r
 BOOLEAN\r
 EFIAPI\r
@@ -1703,17 +1829,17 @@ InternalIsFlag (
   //\r
   // If we accept numbers then dont return TRUE. (they will be values)\r
   //\r
-  if (((Name[0] == L'-' || Name[0] == L'+') && ShellIsHexaDecimalDigitCharacter(Name[1])) && AlwaysAllowNumbers != FALSE) {\r
+  if (((Name[0] == L'-' || Name[0] == L'+') && ShellIsHexaDecimalDigitCharacter(Name[1])) && AlwaysAllowNumbers) {\r
     return (FALSE);\r
   }\r
 \r
   //\r
-  // If the Name has a / or - as the first character return TRUE\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
+     ) {\r
       return (TRUE);\r
   }\r
   return (FALSE);\r
@@ -1724,14 +1850,15 @@ InternalIsFlag (
 \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
+  @param[in] CheckList          pointer to list of parameters to check\r
+  @param[out] CheckPackage      pointer to pointer to list checked values\r
+  @param[out] 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
+  @param[in] AutoPageBreak      will automatically set PageBreakEnabled for "b" parameter\r
+  @param[in] Argv               pointer to array of parameters\r
+  @param[in] Argc               Count of parameters in Argv\r
+  @param[in] AlwaysAllowNumbers TRUE to allow numbers always, FALSE otherwise.\r
 \r
   @retval EFI_SUCCESS           The operation completed sucessfully.\r
   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed\r
@@ -1743,7 +1870,6 @@ InternalIsFlag (
                                 the invalid command line argument was returned in\r
                                 ProblemParam if provided.\r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 InternalCommandLineParse (\r
@@ -1754,22 +1880,24 @@ InternalCommandLineParse (
   IN CONST CHAR16               **Argv,\r
   IN UINTN                      Argc,\r
   IN BOOLEAN                    AlwaysAllowNumbers\r
-  ) {\r
+  )\r
+{\r
   UINTN                         LoopCounter;\r
-  ParamType                     CurrentItemType;\r
+  SHELL_PARAM_TYPE                     CurrentItemType;\r
   SHELL_PARAM_PACKAGE           *CurrentItemPackage;\r
   UINTN                         GetItemValue;\r
   UINTN                         ValueSize;\r
+  UINTN                         Count;\r
 \r
   CurrentItemPackage = NULL;\r
-  mTotalParameterCount = 0;\r
   GetItemValue = 0;\r
   ValueSize = 0;\r
+  Count = 0;\r
 \r
   //\r
   // If there is only 1 item we dont need to do anything\r
   //\r
-  if (Argc <= 1) {\r
+  if (Argc < 1) {\r
     *CheckPackage = NULL;\r
     return (EFI_SUCCESS);\r
   }\r
@@ -1794,7 +1922,7 @@ InternalCommandLineParse (
       //\r
       // do nothing for NULL argv\r
       //\r
-    } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) != FALSE) {\r
+    } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType)) {\r
       //\r
       // We might have leftover if last parameter didnt have optional value\r
       //\r
@@ -1841,7 +1969,7 @@ InternalCommandLineParse (
           ASSERT(GetItemValue == 0);\r
           break;\r
       }\r
-    } else if (GetItemValue != 0 && InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
+    } else if (GetItemValue != 0 && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers)) {\r
       ASSERT(CurrentItemPackage != NULL);\r
       //\r
       // get the item VALUE for a previous flag\r
@@ -1859,7 +1987,7 @@ InternalCommandLineParse (
       if (GetItemValue == 0) {\r
         InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
       }\r
-    } else if (InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
+    } else if (!InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) ){ //|| ProblemParam == NULL) {\r
       //\r
       // add this one as a non-flag\r
       //\r
@@ -1870,9 +1998,9 @@ InternalCommandLineParse (
       CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
       ASSERT(CurrentItemPackage->Value != NULL);\r
       StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
-      CurrentItemPackage->OriginalPosition = mTotalParameterCount++;\r
+      CurrentItemPackage->OriginalPosition = Count++;\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
-    } else if (ProblemParam) {\r
+    } else if (ProblemParam != NULL) {\r
       //\r
       // this was a non-recognised flag... error!\r
       //\r
@@ -1883,9 +2011,7 @@ InternalCommandLineParse (
       *CheckPackage = NULL;\r
       return (EFI_VOLUME_CORRUPTED);\r
     } else {\r
-      ShellCommandLineFreeVarList(*CheckPackage);\r
-      *CheckPackage = NULL;\r
-      return (EFI_VOLUME_CORRUPTED);\r
+      //ASSERT(FALSE);\r
     }\r
   }\r
   if (GetItemValue != 0) {\r
@@ -1907,23 +2033,22 @@ InternalCommandLineParse (
 \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
+  @param[in] CheckList          The pointer to list of parameters to check.\r
+  @param[out] CheckPackage      The package of checked values.\r
+  @param[out] 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
+  @param[in] AutoPageBreak      Will automatically set PageBreakEnabled.\r
+  @param[in] AlwaysAllowNumbers Will never fail for number based flags.\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
+  @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.\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
+  @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
@@ -1934,7 +2059,8 @@ ShellCommandLineParseEx (
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
   IN BOOLEAN                    AutoPageBreak,\r
   IN BOOLEAN                    AlwaysAllowNumbers\r
-  ) {\r
+  )\r
+{\r
   //\r
   // ASSERT that CheckList and CheckPackage aren't NULL\r
   //\r
@@ -1983,7 +2109,8 @@ VOID
 EFIAPI\r
 ShellCommandLineFreeVarList (\r
   IN LIST_ENTRY                 *CheckPackage\r
-  ) {\r
+  )\r
+{\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -1997,9 +2124,9 @@ ShellCommandLineFreeVarList (
   // for each node in the list\r
   //\r
   for ( Node = GetFirstNode(CheckPackage)\r
-      ; IsListEmpty(CheckPackage) == FALSE\r
+      ; !IsListEmpty(CheckPackage)\r
       ; Node = GetFirstNode(CheckPackage)\r
-      ){\r
+     ){\r
     //\r
     // Remove it from the list\r
     //\r
@@ -2046,9 +2173,10 @@ ShellCommandLineFreeVarList (
 BOOLEAN\r
 EFIAPI\r
 ShellCommandLineGetFlag (\r
-  IN CONST LIST_ENTRY           *CheckPackage,\r
-  IN CHAR16                     *KeyString\r
-  ) {\r
+  IN CONST LIST_ENTRY         * CONST CheckPackage,\r
+  IN CONST CHAR16             * CONST KeyString\r
+  )\r
+{\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -2069,7 +2197,7 @@ ShellCommandLineGetFlag (
   for ( Node = GetFirstNode(CheckPackage)\r
       ; !IsNull (CheckPackage, Node)\r
       ; Node = GetNextNode(CheckPackage, Node)\r
-      ){\r
+     ){\r
     //\r
     // If the Name matches, return TRUE (and there may be NULL name)\r
     //\r
@@ -2079,7 +2207,7 @@ ShellCommandLineGetFlag (
       //\r
       if ( ((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart\r
         && StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0\r
-        ){\r
+       ){\r
         return (TRUE);\r
       } else if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {\r
         return (TRUE);\r
@@ -2089,24 +2217,25 @@ ShellCommandLineGetFlag (
   return (FALSE);\r
 }\r
 /**\r
-  returns value from command line argument\r
+  Returns value from command line argument.\r
 \r
-  value parameters are in the form of "-<Key> value" or "/<Key> value"\r
+  Value parameters are in the form of "-<Key> value" or "/<Key> value".\r
 \r
-  if CheckPackage is NULL, then return NULL;\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
+  @param[in] CheckPackage       The package of parsed command line arguments.\r
+  @param[in] 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
+  @retval NULL                  The flag is not on the command line.\r
+  @retval !=NULL                The 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
+{\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -2122,7 +2251,7 @@ ShellCommandLineGetValue (
   for ( Node = GetFirstNode(CheckPackage)\r
       ; !IsNull (CheckPackage, Node)\r
       ; Node = GetNextNode(CheckPackage, Node)\r
-      ){\r
+     ){\r
     //\r
     // If the Name matches, return the value (name can be NULL)\r
     //\r
@@ -2132,7 +2261,7 @@ ShellCommandLineGetValue (
       //\r
       if ( ((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart\r
         && StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0\r
-        ){\r
+       ){\r
         //\r
         // return the string part after the flag\r
         //\r
@@ -2147,25 +2276,27 @@ ShellCommandLineGetValue (
   }\r
   return (NULL);\r
 }\r
+\r
 /**\r
-  returns raw value from command line argument\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
+  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
+  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
+  @param[in] CheckPackage       The package of parsed command line arguments.\r
+  @param[in] 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
+  @retval NULL                  The flag is not on the command line.\r
+  @retval !=NULL                The 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
+  IN CONST LIST_ENTRY           * CONST CheckPackage,\r
+  IN UINTN                      Position\r
+  )\r
+{\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -2181,7 +2312,7 @@ ShellCommandLineGetRawValue (
   for ( Node = GetFirstNode(CheckPackage)\r
       ; !IsNull (CheckPackage, Node)\r
       ; Node = GetNextNode(CheckPackage, Node)\r
-      ){\r
+     ){\r
     //\r
     // If the position matches, return the value\r
     //\r
@@ -2197,16 +2328,32 @@ ShellCommandLineGetRawValue (
 \r
   this will not include flags.\r
 \r
+  @param[in] CheckPackage       The package of parsed command line arguments.\r
+\r
   @retval (UINTN)-1     No parsing has ocurred\r
   @return other         The number of value parameters found\r
 **/\r
 UINTN\r
 EFIAPI\r
 ShellCommandLineGetCount(\r
-  VOID\r
+  IN CONST LIST_ENTRY              *CheckPackage\r
   )\r
 {\r
-  return (mTotalParameterCount);\r
+  LIST_ENTRY  *Node1;\r
+  UINTN       Count;\r
+\r
+  if (CheckPackage == NULL) {\r
+    return (0);\r
+  }\r
+  for ( Node1 = GetFirstNode(CheckPackage), Count = 0\r
+      ; !IsNull (CheckPackage, Node1)\r
+      ; Node1 = GetNextNode(CheckPackage, Node1)\r
+     ){\r
+    if (((SHELL_PARAM_PACKAGE*)Node1)->Name == NULL) {\r
+      Count++;\r
+    }\r
+  }\r
+  return (Count);\r
 }\r
 \r
 /**\r
@@ -2238,12 +2385,12 @@ ShellCommandLineCheckDuplicate (
   for ( Node1 = GetFirstNode(CheckPackage)\r
       ; !IsNull (CheckPackage, Node1)\r
       ; Node1 = GetNextNode(CheckPackage, Node1)\r
-      ){\r
+     ){\r
     for ( Node2 = GetNextNode(CheckPackage, Node1)\r
         ; !IsNull (CheckPackage, Node2)\r
         ; Node2 = GetNextNode(CheckPackage, Node2)\r
-        ){\r
-      if (StrCmp(((SHELL_PARAM_PACKAGE*)Node1)->Name, ((SHELL_PARAM_PACKAGE*)Node2)->Name) == 0) {\r
+       ){\r
+      if ((((SHELL_PARAM_PACKAGE*)Node1)->Name != NULL) && (((SHELL_PARAM_PACKAGE*)Node2)->Name != NULL) && StrCmp(((SHELL_PARAM_PACKAGE*)Node1)->Name, ((SHELL_PARAM_PACKAGE*)Node2)->Name) == 0) {\r
         if (Param != NULL) {\r
           *Param = NULL;\r
           *Param = StrnCatGrow(Param, NULL, ((SHELL_PARAM_PACKAGE*)Node1)->Name, 0);\r
@@ -2263,13 +2410,14 @@ ShellCommandLineCheckDuplicate (
 \r
   If the string would grow bigger than NewSize it will halt and return error.\r
 \r
-  @param[in] SourceString             String with source buffer\r
-  @param[in,out] NewString           String with resultant buffer\r
-  @param[in] NewSize                  Size in bytes of NewString\r
-  @param[in] FindTarget               String to look for\r
-  @param[in[ ReplaceWith              String to replace FindTarget with\r
+  @param[in] SourceString             The string with source buffer.\r
+  @param[in,out] NewString            The string with resultant buffer.\r
+  @param[in] NewSize                  The size in bytes of NewString.\r
+  @param[in] FindTarget               The string to look for.\r
+  @param[in] ReplaceWith              The string to replace FindTarget with.\r
   @param[in] SkipPreCarrot            If TRUE will skip a FindTarget that has a '^'\r
                                       immediately before it.\r
+  @param[in] ParameterReplacing       If TRUE will add "" around items with spaces.\r
 \r
   @retval EFI_INVALID_PARAMETER       SourceString was NULL.\r
   @retval EFI_INVALID_PARAMETER       NewString was NULL.\r
@@ -2279,54 +2427,66 @@ ShellCommandLineCheckDuplicate (
   @retval EFI_INVALID_PARAMETER       SourceString had length < 1.\r
   @retval EFI_BUFFER_TOO_SMALL        NewSize was less than the minimum size to hold\r
                                       the new string (truncation occurred).\r
-  @retval EFI_SUCCESS                 the string was sucessfully copied with replacement.\r
+  @retval EFI_SUCCESS                 The string was successfully copied with replacement.\r
 **/\r
-\r
 EFI_STATUS\r
 EFIAPI\r
-ShellCopySearchAndReplace2(\r
+ShellCopySearchAndReplace(\r
   IN CHAR16 CONST                     *SourceString,\r
-  IN CHAR16                           *NewString,\r
+  IN OUT CHAR16                       *NewString,\r
   IN UINTN                            NewSize,\r
   IN CONST CHAR16                     *FindTarget,\r
   IN CONST CHAR16                     *ReplaceWith,\r
-  IN CONST BOOLEAN                    SkipPreCarrot\r
+  IN CONST BOOLEAN                    SkipPreCarrot,\r
+  IN CONST BOOLEAN                    ParameterReplacing\r
   )\r
 {\r
   UINTN Size;\r
+  CHAR16 *Replace;\r
+\r
   if ( (SourceString == NULL)\r
     || (NewString    == NULL)\r
     || (FindTarget   == NULL)\r
     || (ReplaceWith  == NULL)\r
     || (StrLen(FindTarget) < 1)\r
     || (StrLen(SourceString) < 1)\r
-    ){\r
+   ){\r
     return (EFI_INVALID_PARAMETER);\r
   }\r
+  Replace = NULL;\r
+  if (StrStr(ReplaceWith, L" ") == NULL || !ParameterReplacing) {\r
+    Replace = StrnCatGrow(&Replace, NULL, ReplaceWith, 0);\r
+  } else {\r
+    Replace = AllocateZeroPool(StrSize(ReplaceWith) + 2*sizeof(CHAR16));\r
+    UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith);\r
+  }\r
   NewString = SetMem16(NewString, NewSize, CHAR_NULL);\r
   while (*SourceString != CHAR_NULL) {\r
     //\r
-    // if we find the FindTarget and either Skip == FALSE or Skip == TRUE and we\r
+    // if we find the FindTarget and either Skip == FALSE or Skip  and we\r
     // dont have a carrot do a replace...\r
     //\r
     if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0\r
-      && ((SkipPreCarrot && *(SourceString-1) != L'^') || SkipPreCarrot == FALSE)\r
-      ){\r
+      && ((SkipPreCarrot && *(SourceString-1) != L'^') || !SkipPreCarrot)\r
+     ){\r
       SourceString += StrLen(FindTarget);\r
       Size = StrSize(NewString);\r
-      if ((Size + (StrLen(ReplaceWith)*sizeof(CHAR16))) > NewSize) {\r
+      if ((Size + (StrLen(Replace)*sizeof(CHAR16))) > NewSize) {\r
+        FreePool(Replace);\r
         return (EFI_BUFFER_TOO_SMALL);\r
       }\r
-      StrCat(NewString, ReplaceWith);\r
+      StrCat(NewString, Replace);\r
     } else {\r
       Size = StrSize(NewString);\r
       if (Size + sizeof(CHAR16) > NewSize) {\r
+        FreePool(Replace);\r
         return (EFI_BUFFER_TOO_SMALL);\r
       }\r
       StrnCat(NewString, SourceString, 1);\r
       SourceString++;\r
     }\r
   }\r
+  FreePool(Replace);\r
   return (EFI_SUCCESS);\r
 }\r
 \r
@@ -2348,15 +2508,18 @@ InternalPrintTo (
 {\r
   UINTN Size;\r
   Size = StrSize(String) - sizeof(CHAR16);\r
+  if (Size == 0) {\r
+    return (EFI_SUCCESS);\r
+  }\r
   if (mEfiShellParametersProtocol != NULL) {\r
-    return (mEfiShellParametersProtocol->StdOut->Write(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));\r
+    return (mEfiShellProtocol->WriteFile(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));\r
   }\r
   if (mEfiShellInterface          != NULL) {\r
     //\r
     // Divide in half for old shell.  Must be string length not size.\r
     //\r
     Size /= 2;\r
-    return (         mEfiShellInterface->StdOut->Write(mEfiShellInterface->StdOut,          &Size, (VOID*)String));\r
+    return (mEfiShellInterface->StdOut->Write(mEfiShellInterface->StdOut,          &Size, (VOID*)String));\r
   }\r
   ASSERT(FALSE);\r
   return (EFI_UNSUPPORTED);\r
@@ -2388,10 +2551,10 @@ InternalPrintTo (
   @param[in] Format     the format string\r
   @param[in] Marker     the marker for the variable argument list\r
 \r
-  @return the number of characters printed to the screen\r
+  @return EFI_SUCCESS           The operation was successful.\r
+  @return EFI_DEVICE_ERROR      The console device reported an error.\r
 **/\r
-\r
-UINTN\r
+EFI_STATUS\r
 EFIAPI\r
 InternalShellPrintWorker(\r
   IN INT32                Col OPTIONAL,\r
@@ -2400,37 +2563,38 @@ InternalShellPrintWorker(
   VA_LIST                 Marker\r
   )\r
 {\r
-  UINTN             Return;\r
   EFI_STATUS        Status;\r
-  UINTN             NormalAttribute;\r
   CHAR16            *ResumeLocation;\r
   CHAR16            *FormatWalker;\r
+  UINTN             OriginalAttribute;\r
+\r
+  Status            = EFI_SUCCESS;\r
+  OriginalAttribute = gST->ConOut->Mode->Attribute;\r
 \r
   //\r
   // Back and forth each time fixing up 1 of our flags...\r
   //\r
-  Status = ShellLibCopySearchAndReplace(Format,             mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%N", L"%%N");\r
+  Status = ShellCopySearchAndReplace(Format,             mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%N", L"%%N", FALSE, FALSE);\r
   ASSERT_EFI_ERROR(Status);\r
-  Status = ShellLibCopySearchAndReplace(mPostReplaceFormat,  mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%E", L"%%E");\r
+  Status = ShellCopySearchAndReplace(mPostReplaceFormat,  mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%E", L"%%E", FALSE, FALSE);\r
   ASSERT_EFI_ERROR(Status);\r
-  Status = ShellLibCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%H", L"%%H");\r
+  Status = ShellCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%H", L"%%H", FALSE, FALSE);\r
   ASSERT_EFI_ERROR(Status);\r
-  Status = ShellLibCopySearchAndReplace(mPostReplaceFormat,  mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%B", L"%%B");\r
+  Status = ShellCopySearchAndReplace(mPostReplaceFormat,  mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%B", L"%%B", FALSE, FALSE);\r
   ASSERT_EFI_ERROR(Status);\r
-  Status = ShellLibCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%V", L"%%V");\r
+  Status = ShellCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat,  PcdGet16 (PcdShellPrintBufferSize), L"%V", L"%%V", FALSE, FALSE);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
   //\r
   // Use the last buffer from replacing to print from...\r
   //\r
-  Return = UnicodeVSPrint (mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), mPostReplaceFormat, Marker);\r
+  UnicodeVSPrint (mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), mPostReplaceFormat, Marker);\r
 \r
   if (Col != -1 && Row != -1) {\r
     Status = gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);\r
     ASSERT_EFI_ERROR(Status);\r
   }\r
 \r
-  NormalAttribute = gST->ConOut->Mode->Attribute;\r
   FormatWalker = mPostReplaceFormat2;\r
   while (*FormatWalker != CHAR_NULL) {\r
     //\r
@@ -2443,34 +2607,41 @@ InternalShellPrintWorker(
     //\r
     // print the current FormatWalker string\r
     //\r
-    Status = InternalPrintTo(FormatWalker);\r
-    ASSERT_EFI_ERROR(Status);\r
+    if (StrLen(FormatWalker)>0) {\r
+      Status = InternalPrintTo(FormatWalker);\r
+      if (EFI_ERROR(Status)) {\r
+        break;\r
+      }\r
+    }\r
+\r
     //\r
     // update the attribute\r
     //\r
     if (ResumeLocation != NULL) {\r
       switch (*(ResumeLocation+1)) {\r
         case (L'N'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, NormalAttribute);\r
+          gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);\r
           break;\r
         case (L'E'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
           break;\r
         case (L'H'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
           break;\r
         case (L'B'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
           break;\r
         case (L'V'):\r
-          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
           break;\r
         default:\r
           //\r
           // Print a simple '%' symbol\r
           //\r
           Status = InternalPrintTo(L"%");\r
-          ASSERT_EFI_ERROR(Status);\r
+          if (EFI_ERROR(Status)) {\r
+            break;\r
+          }\r
           ResumeLocation = ResumeLocation - 1;\r
           break;\r
       }\r
@@ -2478,7 +2649,6 @@ InternalShellPrintWorker(
       //\r
       // reset to normal now...\r
       //\r
-      gST->ConOut->SetAttribute(gST->ConOut, NormalAttribute);\r
       break;\r
     }\r
 \r
@@ -2488,7 +2658,8 @@ InternalShellPrintWorker(
     FormatWalker = ResumeLocation + 2;\r
   }\r
 \r
-  return (Return);\r
+  gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);\r
+  return (Status);\r
 }\r
 \r
 /**\r
@@ -2512,14 +2683,15 @@ InternalShellPrintWorker(
 \r
   Note: The background color is controlled by the shell command cls.\r
 \r
-  @param[in] Row        the row to print at\r
   @param[in] Col        the column to print at\r
+  @param[in] Row        the row to print at\r
   @param[in] Format     the format string\r
+  @param[in] ...        The variable argument list.\r
 \r
-  @return the number of characters printed to the screen\r
+  @return EFI_SUCCESS           The printing was successful.\r
+  @return EFI_DEVICE_ERROR      The console device reported an error.\r
 **/\r
-\r
-UINTN\r
+EFI_STATUS\r
 EFIAPI\r
 ShellPrintEx(\r
   IN INT32                Col OPTIONAL,\r
@@ -2529,11 +2701,11 @@ ShellPrintEx(
   )\r
 {\r
   VA_LIST           Marker;\r
-  EFI_STATUS        Status;\r
+  EFI_STATUS        RetVal;\r
   VA_START (Marker, Format);\r
-  Status = InternalShellPrintWorker(Col, Row, Format, Marker);\r
+  RetVal = InternalShellPrintWorker(Col, Row, Format, Marker);\r
   VA_END(Marker);\r
-  return(Status);\r
+  return(RetVal);\r
 }\r
 \r
 /**\r
@@ -2557,16 +2729,18 @@ ShellPrintEx(
 \r
   Note: The background color is controlled by the shell command cls.\r
 \r
-  @param[in] Row                The row to print at.\r
   @param[in] Col                The column to print at.\r
+  @param[in] Row                The row to print at.\r
   @param[in] Language           The language of the string to retrieve.  If this parameter\r
                                 is NULL, then the current platform language is used.\r
   @param[in] HiiFormatStringId  The format string Id for getting from Hii.\r
   @param[in] HiiFormatHandle    The format string Handle for getting from Hii.\r
+  @param[in] ...                The variable argument list.\r
 \r
-  @return the number of characters printed to the screen.\r
+  @return EFI_SUCCESS           The printing was successful.\r
+  @return EFI_DEVICE_ERROR      The console device reported an error.\r
 **/\r
-UINTN\r
+EFI_STATUS\r
 EFIAPI\r
 ShellPrintHiiEx(\r
   IN INT32                Col OPTIONAL,\r
@@ -2579,7 +2753,7 @@ ShellPrintHiiEx(
 {\r
   VA_LIST           Marker;\r
   CHAR16            *HiiFormatString;\r
-  UINTN             RetVal;\r
+  EFI_STATUS        RetVal;\r
 \r
   VA_START (Marker, HiiFormatHandle);\r
   HiiFormatString = HiiGetString(HiiFormatHandle, HiiFormatStringId, Language);\r
@@ -2587,7 +2761,7 @@ ShellPrintHiiEx(
 \r
   RetVal = InternalShellPrintWorker(Col, Row, HiiFormatString, Marker);\r
 \r
-  FreePool(HiiFormatString);\r
+  SHELL_FREE_NON_NULL(HiiFormatString);\r
   VA_END(Marker);\r
 \r
   return (RetVal);\r
@@ -2609,14 +2783,38 @@ ShellIsDirectory(
   )\r
 {\r
   EFI_STATUS        Status;\r
-  EFI_FILE_HANDLE   Handle;\r
+  SHELL_FILE_HANDLE Handle;\r
+        CHAR16      *TempLocation;\r
 \r
   ASSERT(DirName != NULL);\r
 \r
-  Handle = NULL;\r
+  Handle        = NULL;\r
+  TempLocation  = NULL;\r
 \r
   Status = ShellOpenFileByName(DirName, &Handle, EFI_FILE_MODE_READ, 0);\r
   if (EFI_ERROR(Status)) {\r
+    //\r
+    // try good logic first.\r
+    //\r
+    if (mEfiShellProtocol != NULL) {\r
+      TempLocation = StrnCatGrow(&TempLocation, NULL, DirName, 0);\r
+      if (StrStr(TempLocation, L":") != NULL && StrLen(StrStr(TempLocation, L":")) == 2) {\r
+        *(StrStr(TempLocation, L":")+1) = CHAR_NULL;\r
+      }\r
+      if (mEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) {\r
+        FreePool(TempLocation);\r
+        return (EFI_SUCCESS);\r
+      }\r
+      FreePool(TempLocation);\r
+    } else {\r
+      //\r
+      // probably a map name?!?!!?\r
+      //\r
+      TempLocation = StrStr(DirName, L"\\");\r
+      if (TempLocation != NULL && *(TempLocation+1) == CHAR_NULL) {\r
+        return (EFI_SUCCESS);\r
+      }\r
+    }\r
     return (Status);\r
   }\r
 \r
@@ -2644,7 +2842,7 @@ ShellIsFile(
   )\r
 {\r
   EFI_STATUS        Status;\r
-  EFI_FILE_HANDLE   Handle;\r
+  SHELL_FILE_HANDLE            Handle;\r
 \r
   ASSERT(Name != NULL);\r
 \r
@@ -2680,12 +2878,13 @@ EFI_STATUS
 EFIAPI\r
 ShellIsFileInPath(\r
   IN CONST CHAR16 *Name\r
-  ) {\r
+  )\r
+{\r
   CHAR16      *NewName;\r
   EFI_STATUS  Status;\r
 \r
   if (!EFI_ERROR(ShellIsFile(Name))) {\r
-    return (TRUE);\r
+    return (EFI_SUCCESS);\r
   }\r
 \r
   NewName = ShellFindFilePath(Name);\r
@@ -2836,10 +3035,10 @@ StrnCatGrow (
   This function will display the requested question on the shell prompt and then\r
   wait for an apropriate answer to be input from the console.\r
 \r
-  if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, SHELL_PROMPT_REQUEST_TYPE_QUIT_CONTINUE\r
+  if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, ShellPromptResponseTypeQuitContinue\r
   or SHELL_PROMPT_REQUEST_TYPE_YESNOCANCEL then *Response is of type SHELL_PROMPT_RESPONSE.\r
 \r
-  if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_FREEFORM then *Response is of type\r
+  if the SHELL_PROMPT_REQUEST_TYPE is ShellPromptResponseTypeFreeform then *Response is of type\r
   CHAR16*.\r
 \r
   In either case *Response must be callee freed if Response was not NULL;\r
@@ -2852,7 +3051,6 @@ StrnCatGrow (
   @retval EFI_SUCCESS             The operation was sucessful.\r
   @retval EFI_UNSUPPORTED         The operation is not supported as requested.\r
   @retval EFI_INVALID_PARAMETER   A parameter was invalid.\r
-  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.\r
   @return other                   The operation failed.\r
 **/\r
 EFI_STATUS\r
@@ -2867,15 +3065,19 @@ ShellPromptForResponse (
   EFI_INPUT_KEY     Key;\r
   UINTN             EventIndex;\r
   SHELL_PROMPT_RESPONSE          *Resp;\r
+  UINTN             Size;\r
+  CHAR16            *Buffer;\r
 \r
-  Status = EFI_SUCCESS;\r
-  Resp = (SHELL_PROMPT_RESPONSE*)AllocatePool(sizeof(SHELL_PROMPT_RESPONSE));\r
-  if (Resp == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  Status  = EFI_UNSUPPORTED;\r
+  Resp    = NULL;\r
+  Buffer  = NULL;\r
+  Size    = 0;\r
+  if (Type != ShellPromptResponseTypeFreeform) {\r
+    Resp = (SHELL_PROMPT_RESPONSE*)AllocatePool(sizeof(SHELL_PROMPT_RESPONSE));\r
   }\r
 \r
   switch(Type) {\r
-    case SHELL_PROMPT_REQUEST_TYPE_QUIT_CONTINUE:\r
+    case ShellPromptResponseTypeQuitContinue:\r
       if (Prompt != NULL) {\r
         ShellPrintEx(-1, -1, L"%s", Prompt);\r
       }\r
@@ -2887,20 +3089,20 @@ ShellPromptForResponse (
       ASSERT_EFI_ERROR(Status);\r
       ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
       if (Key.UnicodeChar == L'Q' || Key.UnicodeChar ==L'q') {\r
-        *Resp = SHELL_PROMPT_RESPONSE_QUIT;\r
+        *Resp = ShellPromptResponseQuit;\r
       } else {\r
-        *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;\r
+        *Resp = ShellPromptResponseContinue;\r
       }\r
       break;\r
-    case SHELL_PROMPT_REQUEST_TYPE_YES_NO_ALL_CANCEL:\r
+    case ShellPromptResponseTypeYesNoCancel:\r
        if (Prompt != NULL) {\r
         ShellPrintEx(-1, -1, L"%s", Prompt);\r
       }\r
       //\r
       // wait for valid response\r
       //\r
-      *Resp = SHELL_PROMPT_RESPONSE_MAX;\r
-      while (*Resp == SHELL_PROMPT_RESPONSE_MAX) {\r
+      *Resp = ShellPromptResponseMax;\r
+      while (*Resp == ShellPromptResponseMax) {\r
         gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
         Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
         ASSERT_EFI_ERROR(Status);\r
@@ -2908,60 +3110,143 @@ ShellPromptForResponse (
         switch (Key.UnicodeChar) {\r
           case L'Y':\r
           case L'y':\r
-            *Resp = SHELL_PROMPT_RESPONSE_YES;\r
+            *Resp = ShellPromptResponseYes;\r
             break;\r
           case L'N':\r
           case L'n':\r
-            *Resp = SHELL_PROMPT_RESPONSE_NO;\r
+            *Resp = ShellPromptResponseNo;\r
+            break;\r
+          case L'C':\r
+          case L'c':\r
+            *Resp = ShellPromptResponseCancel;\r
+            break;\r
+        }\r
+      }\r
+      break;    case ShellPromptResponseTypeYesNoAllCancel:\r
+       if (Prompt != NULL) {\r
+        ShellPrintEx(-1, -1, L"%s", Prompt);\r
+      }\r
+      //\r
+      // wait for valid response\r
+      //\r
+      *Resp = ShellPromptResponseMax;\r
+      while (*Resp == ShellPromptResponseMax) {\r
+        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+        ASSERT_EFI_ERROR(Status);\r
+        ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+        switch (Key.UnicodeChar) {\r
+          case L'Y':\r
+          case L'y':\r
+            *Resp = ShellPromptResponseYes;\r
+            break;\r
+          case L'N':\r
+          case L'n':\r
+            *Resp = ShellPromptResponseNo;\r
             break;\r
           case L'A':\r
           case L'a':\r
-            *Resp = SHELL_PROMPT_RESPONSE_ALL;\r
+            *Resp = ShellPromptResponseAll;\r
             break;\r
           case L'C':\r
           case L'c':\r
-            *Resp = SHELL_PROMPT_RESPONSE_CANCEL;\r
+            *Resp = ShellPromptResponseCancel;\r
             break;\r
         }\r
       }\r
       break;\r
-    case SHELL_PROMPT_REQUEST_TYPE_ENTER_TO_COMTINUE:\r
-    case SHELL_PROMPT_REQUEST_TYPE_ANYKEY_TO_COMTINUE:\r
+    case ShellPromptResponseTypeEnterContinue:\r
+    case ShellPromptResponseTypeAnyKeyContinue:\r
       if (Prompt != NULL) {\r
         ShellPrintEx(-1, -1, L"%s", Prompt);\r
       }\r
       //\r
       // wait for valid response\r
       //\r
-      *Resp = SHELL_PROMPT_RESPONSE_MAX;\r
-      while (*Resp == SHELL_PROMPT_RESPONSE_MAX) {\r
+      *Resp = ShellPromptResponseMax;\r
+      while (*Resp == ShellPromptResponseMax) {\r
         gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
-        if (Type == SHELL_PROMPT_REQUEST_TYPE_ENTER_TO_COMTINUE) {\r
+        if (Type == ShellPromptResponseTypeEnterContinue) {\r
           Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
           ASSERT_EFI_ERROR(Status);\r
           ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
           if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
-            *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;\r
+            *Resp = ShellPromptResponseContinue;\r
             break;\r
           }\r
         }\r
-        if (Type == SHELL_PROMPT_REQUEST_TYPE_ANYKEY_TO_COMTINUE) {\r
-          *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;\r
+        if (Type == ShellPromptResponseTypeAnyKeyContinue) {\r
+          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+          ASSERT_EFI_ERROR(Status);\r
+          *Resp = ShellPromptResponseContinue;\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+    case ShellPromptResponseTypeYesNo:\r
+       if (Prompt != NULL) {\r
+        ShellPrintEx(-1, -1, L"%s", Prompt);\r
+      }\r
+      //\r
+      // wait for valid response\r
+      //\r
+      *Resp = ShellPromptResponseMax;\r
+      while (*Resp == ShellPromptResponseMax) {\r
+        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+        ASSERT_EFI_ERROR(Status);\r
+        ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+        switch (Key.UnicodeChar) {\r
+          case L'Y':\r
+          case L'y':\r
+            *Resp = ShellPromptResponseYes;\r
+            break;\r
+          case L'N':\r
+          case L'n':\r
+            *Resp = ShellPromptResponseNo;\r
+            break;\r
+        }\r
+      }\r
+      break;\r
+    case ShellPromptResponseTypeFreeform:\r
+      if (Prompt != NULL) {\r
+        ShellPrintEx(-1, -1, L"%s", Prompt);\r
+      }\r
+      while(1) {\r
+        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+        ASSERT_EFI_ERROR(Status);\r
+        ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+        if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
           break;\r
         }\r
+        ASSERT((Buffer == NULL && Size == 0) || (Buffer != NULL));\r
+        StrnCatGrow(&Buffer, &Size, &Key.UnicodeChar, 1);\r
       }\r
       break;\r
-    ///@todo add more request types here!\r
+    //\r
+    // This is the location to add new prompt types.\r
+    //\r
     default:\r
-      Status = EFI_UNSUPPORTED;\r
+      ASSERT(FALSE);\r
   }\r
 \r
   if (Response != NULL) {\r
-    *Response = Resp;\r
+    if (Resp != NULL) {\r
+      *Response = Resp;\r
+    } else if (Buffer != NULL) {\r
+      *Response = Buffer;\r
+    }\r
   } else {\r
-    FreePool(Resp);\r
+    if (Resp != NULL) {\r
+      FreePool(Resp);\r
+    }\r
+    if (Buffer != NULL) {\r
+      FreePool(Buffer);\r
+    }\r
   }\r
 \r
+  ShellPrintEx(-1, -1, L"\r\n");\r
   return (Status);\r
 }\r
 \r
@@ -2973,8 +3258,9 @@ ShellPromptForResponse (
 \r
   @param Type     What type of question is asked.  This is used to filter the input\r
                   to prevent invalid answers to question.\r
-  @param Prompt   Pointer to string prompt to use to request input.\r
-  @param Response Pointer to Response which will be populated upon return.\r
+  @param[in] HiiFormatStringId  The format string Id for getting from Hii.\r
+  @param[in] HiiFormatHandle    The format string Handle for getting from Hii.\r
+  @param Response               Pointer to Response which will be populated upon return.\r
 \r
   @retval EFI_SUCCESS the operation was sucessful.\r
   @return other       the operation failed.\r
@@ -2999,4 +3285,107 @@ ShellPromptForResponseHii (
   return (Status);\r
 }\r
 \r
+/**\r
+  Function to determin if an entire string is a valid number.\r
+\r
+  If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.\r
 \r
+  @param[in] String       The string to evaluate.\r
+  @param[in] ForceHex     TRUE - always assume hex.\r
+  @param[in] StopAtSpace  TRUE to halt upon finding a space, FALSE to keep going.\r
+\r
+  @retval TRUE        It is all numeric (dec/hex) characters.\r
+  @retval FALSE       There is a non-numeric character.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellIsHexOrDecimalNumber (\r
+  IN CONST CHAR16   *String,\r
+  IN CONST BOOLEAN  ForceHex,\r
+  IN CONST BOOLEAN  StopAtSpace\r
+  )\r
+{\r
+  BOOLEAN Hex;\r
+\r
+  //\r
+  // chop off a single negative sign\r
+  //\r
+  if (String != NULL && *String == L'-') {\r
+    String++;\r
+  }\r
+  \r
+  if (String == NULL) {\r
+    return (FALSE);\r
+  }\r
+\r
+  //\r
+  // chop leading zeroes\r
+  //\r
+  while(String != NULL && *String == L'0'){\r
+    String++;\r
+  }\r
+  //\r
+  // allow '0x' or '0X', but not 'x' or 'X'\r
+  //\r
+  if (String != NULL && (*String == L'x' || *String == L'X')) {\r
+    if (*(String-1) != L'0') {\r
+      //\r
+      // we got an x without a preceeding 0\r
+      //\r
+      return (FALSE);\r
+    }\r
+    String++;\r
+    Hex = TRUE;\r
+  } else if (ForceHex) {\r
+    Hex = TRUE;\r
+  } else {\r
+    Hex = FALSE;\r
+  }\r
+\r
+  //\r
+  // loop through the remaining characters and use the lib function\r
+  //\r
+  for ( ; String != NULL && *String != CHAR_NULL && !(StopAtSpace && *String == L' ') ; String++){\r
+    if (Hex) {\r
+      if (!ShellIsHexaDecimalDigitCharacter(*String)) {\r
+        return (FALSE);\r
+      }\r
+    } else {\r
+      if (!ShellIsDecimalDigitCharacter(*String)) {\r
+        return (FALSE);\r
+      }\r
+    }\r
+  }\r
+  return (TRUE);\r
+}\r
+\r
+/**\r
+  Function to determine if a given filename exists.\r
+\r
+  @param[in] Name         Path to test.\r
+\r
+  @retval EFI_SUCCESS     The Path represents a file.\r
+  @retval EFI_NOT_FOUND   The Path does not represent a file.\r
+  @retval other           The path failed to open.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFileExists(\r
+  IN CONST CHAR16 *Name\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_SHELL_FILE_INFO *List;\r
+\r
+  ASSERT(Name != NULL);\r
+\r
+  List = NULL;\r
+  Status = ShellOpenFileMetaArg((CHAR16*)Name, EFI_FILE_MODE_READ, &List);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  ShellCloseFileMetaArg(&List);\r
+\r
+  return (EFI_SUCCESS);\r
+}\r