]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Upgrade ShellLib and fix bug with param parsing
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 9 Nov 2009 18:08:58 +0000 (18:08 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 9 Nov 2009 18:08:58 +0000 (18:08 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9398 6f19259b-4bc3-4df7-8a09-765794883524

ShellPkg/Include/Library/ShellLib.h
ShellPkg/Library/UefiShellLib/UefiShellLib.c
ShellPkg/Library/UefiShellLib/UefiShellLib.inf

index e08cc884524354fb14a6adf0b4e5ad8c7736eb2c..6211343f1690f5aa0e5a0d0e00fd83f61cd3243e 100644 (file)
@@ -647,13 +647,17 @@ extern SHELL_PARAM_ITEM EmptyParamList[];
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ShellCommandLineParse (\r
+ShellCommandLineParseEx (\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT LIST_ENTRY                **CheckPackage,\r
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT LIST_ENTRY                **CheckPackage,\r
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
-  IN BOOLEAN                    AutoPageBreak\r
+  IN BOOLEAN                    AutoPageBreak,\r
+  IN BOOLEAN                    AlwaysAllowNumbers\r
   );\r
 \r
   );\r
 \r
+// make it easy to upgrade from older versions of the shell library.\r
+#define ShellCommandLineParse(CheckList,CheckPackage,ProblemParam,AutoPageBreak) ShellCommandLineParseEx(CheckList,CheckPackage,ProblemParam,AutoPageBreak,FALSE)\r
+\r
 /**\r
   Frees shell variable list that was returned from ShellCommandLineParse.\r
 \r
 /**\r
   Frees shell variable list that was returned from ShellCommandLineParse.\r
 \r
@@ -733,6 +737,20 @@ ShellCommandLineGetRawValue (
   IN UINT32                        Position\r
   );\r
 \r
   IN UINT32                        Position\r
   );\r
 \r
+/**\r
+  returns the number of command line value parameters that were parsed.  \r
+  \r
+  this will not include flags.\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
+  );\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
 /**\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
@@ -789,4 +807,59 @@ ShellPrintEx(
   ...\r
   );\r
 \r
   ...\r
   );\r
 \r
+/**\r
+  Print at a specific location on the screen.\r
+\r
+  This function will move the cursor to a given screen location, print the specified string, \r
+  and return the cursor to the original locaiton.  \r
+  \r
+  If -1 is specified for either the Row or Col the current screen location for BOTH \r
+  will be used and the cursor's position will not be moved back to an original location.\r
+\r
+  if either Row or Col is out of range for the current console, then ASSERT\r
+  if Format is NULL, then ASSERT\r
+\r
+  In addition to the standard %-based flags as supported by UefiLib Print() this supports \r
+  the following additional flags:\r
+    %N       -   Set output attribute to normal\r
+    %H       -   Set output attribute to highlight\r
+    %E       -   Set output attribute to error\r
+    %B       -   Set output attribute to blue color\r
+    %V       -   Set output attribute to green color\r
+\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] HiiFormatStringId  the format string Id for getting from Hii\r
+  @param[in] HiiFormatHandle    the format string Handle for getting from Hii\r
+\r
+  @return the number of characters printed to the screen\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellPrintHiiEx(\r
+  IN INT32                Col OPTIONAL,\r
+  IN INT32                Row OPTIONAL,\r
+  IN CONST EFI_STRING_ID  HiiFormatStringId,\r
+  IN CONST EFI_HANDLE     HiiFormatHandle,\r
+  ...\r
+  );\r
+\r
+/**\r
+  Function to determine if a given filename represents a file or a directory.\r
+\r
+  @param[in] DirName      Path to directory to test.\r
+\r
+  @retval EFI_SUCCESS     The Path represents a directory\r
+  @retval EFI_NOT_FOUND   The Path does not represent a directory\r
+  @return other           The path failed to open\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellIsDirectory(\r
+  IN CONST CHAR16 *DirName\r
+  );\r
+\r
+\r
 #endif // __SHELL_LIB__\r
 #endif // __SHELL_LIB__\r
index 66fcc9f89d33947ca60260a0eddea00df566cc11..0d79880dffb026b71f7d0d84e969e0a63562d447 100644 (file)
@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/FileHandleLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/FileHandleLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/UefiLib.h>\r
+#include <Library/HiiLib.h>\r
 \r
 #include <Protocol/EfiShellEnvironment2.h>\r
 #include <Protocol/EfiShellInterface.h>\r
 \r
 #include <Protocol/EfiShellEnvironment2.h>\r
 #include <Protocol/EfiShellInterface.h>\r
@@ -52,6 +53,29 @@ STATIC EFI_SHELL_PROTOCOL            *mEfiShellProtocol;
 STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
 STATIC EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
 STATIC FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
 STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
 STATIC EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
 STATIC FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
+STATIC UINTN                         mTotalParameterCount;\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
+  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
+  @retval FALSE If the Char is not a hexadecmial character.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellInternalIsHexaDecimalDigitCharacter (\r
+  IN      CHAR16                    Char\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
 \r
 /**\r
   helper function to find ShellEnvironment2 for constructor\r
@@ -60,8 +84,7 @@ EFI_STATUS
 EFIAPI\r
 ShellFindSE2 (\r
   IN EFI_HANDLE        ImageHandle\r
 EFIAPI\r
 ShellFindSE2 (\r
   IN EFI_HANDLE        ImageHandle\r
-  )\r
-{\r
+  ) {\r
   EFI_STATUS  Status;\r
   EFI_HANDLE  *Buffer;\r
   UINTN       BufferSize;\r
   EFI_STATUS  Status;\r
   EFI_HANDLE  *Buffer;\r
   UINTN       BufferSize;\r
@@ -89,15 +112,19 @@ ShellFindSE2 (
                                 &BufferSize,\r
                                 Buffer\r
                                 );\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
+    //\r
+    // maybe it's not there???\r
+    //\r
+    if (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
+    }\r
     if (!EFI_ERROR (Status)) {\r
       //\r
       // now parse the list of returned handles\r
     if (!EFI_ERROR (Status)) {\r
       //\r
       // now parse the list of returned handles\r
@@ -130,9 +157,14 @@ EFIAPI
 ShellLibConstructorWorker (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
 ShellLibConstructorWorker (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
-){\r
+  ) {\r
   EFI_STATUS Status;\r
 \r
   EFI_STATUS Status;\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
   //\r
   // UEFI 2.0 shell interfaces (used preferentially)\r
   //\r
@@ -226,8 +258,7 @@ EFIAPI
 ShellLibConstructor (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
 ShellLibConstructor (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
+  ) {\r
 \r
 \r
   mEfiShellEnvironment2       = NULL;\r
 \r
 \r
   mEfiShellEnvironment2       = NULL;\r
@@ -254,7 +285,7 @@ EFIAPI
 ShellLibDestructor (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\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
   if (mEfiShellEnvironment2 != NULL) {\r
     gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
                        &gEfiShellEnvironment2Guid,\r
@@ -340,8 +371,7 @@ EFI_FILE_INFO*
 EFIAPI\r
 ShellGetFileInfo (\r
   IN EFI_FILE_HANDLE            FileHandle\r
 EFIAPI\r
 ShellGetFileInfo (\r
   IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.GetFileInfo(FileHandle));\r
 }\r
 \r
   return (FileFunctionMap.GetFileInfo(FileHandle));\r
 }\r
 \r
@@ -368,8 +398,7 @@ EFIAPI
 ShellSetFileInfo (\r
   IN EFI_FILE_HANDLE           FileHandle,\r
   IN EFI_FILE_INFO              *FileInfo\r
 ShellSetFileInfo (\r
   IN EFI_FILE_HANDLE           FileHandle,\r
   IN EFI_FILE_INFO              *FileInfo\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
 }  \r
   \r
   return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
 }  \r
   \r
@@ -411,8 +440,7 @@ ShellOpenFileByDevicePath(
   OUT EFI_FILE_HANDLE                  *FileHandle,\r
   IN UINT64                            OpenMode,\r
   IN UINT64                            Attributes\r
   OUT EFI_FILE_HANDLE                  *FileHandle,\r
   IN UINT64                            OpenMode,\r
   IN UINT64                            Attributes\r
-  )\r
-{\r
+  ) {\r
   CHAR16      *FileName;\r
   EFI_STATUS  Status;\r
   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
   CHAR16      *FileName;\r
   EFI_STATUS  Status;\r
   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
@@ -562,8 +590,7 @@ ShellOpenFileByName(
   OUT EFI_FILE_HANDLE           *FileHandle,\r
   IN UINT64                     OpenMode,\r
   IN UINT64                            Attributes\r
   OUT EFI_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
   EFI_HANDLE                    DeviceHandle;\r
   EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
   EFI_STATUS                    Status;\r
@@ -581,11 +608,12 @@ ShellOpenFileByName(
     Status = mEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
     Status = mEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
-    if (!EFI_ERROR(Status)){\r
-      FileInfo = FileHandleGetInfo(*FileHandle);\r
+    if (!EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
+      FileInfo = FileFunctionMap.GetFileInfo(*FileHandle);\r
       ASSERT(FileInfo != NULL);\r
       FileInfo->Attribute = Attributes;\r
       ASSERT(FileInfo != NULL);\r
       FileInfo->Attribute = Attributes;\r
-      Status = FileHandleSetInfo(*FileHandle, FileInfo);\r
+      Status = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
+      FreePool(FileInfo);\r
     }\r
     return (Status);\r
   } \r
     }\r
     return (Status);\r
   } \r
@@ -638,16 +666,22 @@ EFIAPI
 ShellCreateDirectory(\r
   IN CONST CHAR16             *DirectoryName,\r
   OUT EFI_FILE_HANDLE         *FileHandle\r
 ShellCreateDirectory(\r
   IN CONST 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
+  if (mEfiShellProtocol != NULL) {\r
+    //\r
+    // Use UEFI Shell 2.0 method\r
+    //\r
+    return (mEfiShellProtocol->CreateFile(DirectoryName,\r
+                          EFI_FILE_DIRECTORY,\r
+                          FileHandle\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
 }\r
 \r
 /**\r
@@ -685,8 +719,7 @@ ShellReadFile(
   IN EFI_FILE_HANDLE            FileHandle,\r
   IN OUT UINTN                  *BufferSize,\r
   OUT VOID                      *Buffer\r
   IN EFI_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
   return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));\r
 }\r
 \r
@@ -721,8 +754,7 @@ ShellWriteFile(
   IN EFI_FILE_HANDLE            FileHandle,\r
   IN OUT UINTN                  *BufferSize,\r
   IN VOID                       *Buffer\r
   IN EFI_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
   return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));\r
 }\r
 \r
@@ -741,8 +773,7 @@ EFI_STATUS
 EFIAPI\r
 ShellCloseFile (\r
   IN EFI_FILE_HANDLE            *FileHandle\r
 EFIAPI\r
 ShellCloseFile (\r
   IN EFI_FILE_HANDLE            *FileHandle\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.CloseFile(*FileHandle));\r
 }\r
 \r
   return (FileFunctionMap.CloseFile(*FileHandle));\r
 }\r
 \r
@@ -764,8 +795,7 @@ EFI_STATUS
 EFIAPI\r
 ShellDeleteFile (\r
   IN EFI_FILE_HANDLE           *FileHandle\r
 EFIAPI\r
 ShellDeleteFile (\r
   IN EFI_FILE_HANDLE           *FileHandle\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.DeleteFile(*FileHandle));\r
 }\r
 \r
   return (FileFunctionMap.DeleteFile(*FileHandle));\r
 }\r
 \r
@@ -793,8 +823,7 @@ EFIAPI
 ShellSetFilePosition (\r
   IN EFI_FILE_HANDLE           FileHandle,\r
   IN UINT64            Position\r
 ShellSetFilePosition (\r
   IN EFI_FILE_HANDLE           FileHandle,\r
   IN UINT64            Position\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
 }\r
 \r
   return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
 }\r
 \r
@@ -818,8 +847,7 @@ EFIAPI
 ShellGetFilePosition (\r
   IN EFI_FILE_HANDLE            FileHandle,\r
   OUT UINT64                    *Position\r
 ShellGetFilePosition (\r
   IN EFI_FILE_HANDLE            FileHandle,\r
   OUT UINT64                    *Position\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
 }\r
 /**\r
   return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
 }\r
 /**\r
@@ -840,8 +868,7 @@ EFI_STATUS
 EFIAPI\r
 ShellFlushFile (\r
   IN EFI_FILE_HANDLE            FileHandle\r
 EFIAPI\r
 ShellFlushFile (\r
   IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.FlushFile(FileHandle));\r
 }\r
 \r
   return (FileFunctionMap.FlushFile(FileHandle));\r
 }\r
 \r
@@ -868,8 +895,7 @@ EFIAPI
 ShellFindFirstFile (\r
   IN EFI_FILE_HANDLE            DirHandle,\r
   OUT EFI_FILE_INFO             **Buffer\r
 ShellFindFirstFile (\r
   IN EFI_FILE_HANDLE            DirHandle,\r
   OUT EFI_FILE_INFO             **Buffer\r
-  )\r
-{\r
+  ) {\r
   //\r
   // pass to file handle lib\r
   //\r
   //\r
   // pass to file handle lib\r
   //\r
@@ -900,8 +926,7 @@ ShellFindNextFile(
   IN EFI_FILE_HANDLE             DirHandle,\r
   OUT EFI_FILE_INFO              *Buffer,\r
   OUT BOOLEAN                    *NoFile\r
   IN EFI_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
   //\r
   // pass to file handle lib\r
   //\r
@@ -927,8 +952,7 @@ EFIAPI
 ShellGetFileSize (\r
   IN EFI_FILE_HANDLE            FileHandle,\r
   OUT UINT64                    *Size\r
 ShellGetFileSize (\r
   IN EFI_FILE_HANDLE            FileHandle,\r
   OUT UINT64                    *Size\r
-  )\r
-{\r
+  ) {\r
   return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
 }\r
 /**\r
   return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
 }\r
 /**\r
@@ -1345,9 +1369,15 @@ ShellOpenFileMetaArg (
       }\r
       InitializeListHead(&((*ListHead)->Link));\r
     }    \r
       }\r
       InitializeListHead(&((*ListHead)->Link));\r
     }    \r
-    return (mEfiShellProtocol->OpenFileList(Arg, \r
+    Status = mEfiShellProtocol->OpenFileList(Arg, \r
                                            OpenMode, \r
                                            OpenMode, \r
-                                           ListHead));\r
+                                           ListHead);\r
+    if (EFI_ERROR(Status)) {\r
+      mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+    } else {\r
+      Status = mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+    }\r
+    return (Status);\r
   } \r
 \r
   //\r
   } \r
 \r
   //\r
@@ -1463,8 +1493,7 @@ InternalIsOnCheckList (
   IN CONST CHAR16               *Name,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT ParamType                 *Type\r
   IN CONST CHAR16               *Name,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT ParamType                 *Type\r
-  )\r
-{\r
+  ) {\r
   SHELL_PARAM_ITEM              *TempListItem;\r
 \r
   //\r
   SHELL_PARAM_ITEM              *TempListItem;\r
 \r
   //\r
@@ -1499,6 +1528,7 @@ InternalIsOnCheckList (
       return (TRUE);\r
     }\r
   }\r
       return (TRUE);\r
     }\r
   }\r
+\r
   return (FALSE);\r
 }\r
 /**\r
   return (FALSE);\r
 }\r
 /**\r
@@ -1512,7 +1542,8 @@ InternalIsOnCheckList (
 BOOLEAN\r
 EFIAPI\r
 InternalIsFlag (\r
 BOOLEAN\r
 EFIAPI\r
 InternalIsFlag (\r
-  IN CONST CHAR16               *Name\r
+  IN CONST CHAR16               *Name,\r
+  IN BOOLEAN                    AlwaysAllowNumbers\r
   )\r
 {\r
   //\r
   )\r
 {\r
   //\r
@@ -1520,6 +1551,13 @@ InternalIsFlag (
   //\r
   ASSERT(Name != NULL);\r
 \r
   //\r
   ASSERT(Name != NULL);\r
 \r
+  //\r
+  // If we accept numbers then dont return TRUE. (they will be values)\r
+  //\r
+  if (((Name[0] == L'-' || Name[0] == L'+') && ShellInternalIsHexaDecimalDigitCharacter(Name[1])) && AlwaysAllowNumbers == TRUE) {\r
+    return (FALSE);\r
+  }\r
+\r
   //\r
   // If the Name has a / or - as the first character return TRUE\r
   //\r
   //\r
   // If the Name has a / or - as the first character return TRUE\r
   //\r
@@ -1556,6 +1594,7 @@ InternalIsFlag (
                                 the invalid command line argument was returned in\r
                                 ProblemParam if provided.\r
 **/\r
                                 the invalid command line argument was returned in\r
                                 ProblemParam if provided.\r
 **/\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 InternalCommandLineParse (\r
 EFI_STATUS\r
 EFIAPI\r
 InternalCommandLineParse (\r
@@ -1564,24 +1603,16 @@ InternalCommandLineParse (
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
   IN BOOLEAN                    AutoPageBreak,\r
   IN CONST CHAR16               **Argv,\r
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
   IN BOOLEAN                    AutoPageBreak,\r
   IN CONST CHAR16               **Argv,\r
-  IN UINTN                      Argc\r
-  )\r
-{\r
+  IN UINTN                      Argc,\r
+  IN BOOLEAN                    AlwaysAllowNumbers\r
+  ) {\r
   UINTN                         LoopCounter;\r
   UINTN                         LoopCounter;\r
-  UINTN                         Count;\r
   ParamType                     CurrentItemType;\r
   SHELL_PARAM_PACKAGE           *CurrentItemPackage;\r
   BOOLEAN                       GetItemValue;\r
 \r
   CurrentItemPackage = NULL;\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
+  mTotalParameterCount = 0;\r
   GetItemValue = FALSE;\r
 \r
   //\r
   GetItemValue = FALSE;\r
 \r
   //\r
@@ -1592,6 +1623,12 @@ InternalCommandLineParse (
     return (EFI_SUCCESS);\r
   }\r
 \r
     return (EFI_SUCCESS);\r
   }\r
 \r
+  //\r
+  // ASSERTs\r
+  //\r
+  ASSERT(CheckList  != NULL);\r
+  ASSERT(Argv       != NULL);\r
+\r
   //\r
   // initialize the linked list\r
   //\r
   //\r
   // initialize the linked list\r
   //\r
@@ -1607,6 +1644,13 @@ InternalCommandLineParse (
       // do nothing for NULL argv\r
       //\r
     } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {\r
       // do nothing for NULL argv\r
       //\r
     } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {\r
+      //\r
+      // We might have leftover if last parameter didnt have optional value\r
+      //\r
+      if (GetItemValue == TRUE) {\r
+        GetItemValue = FALSE;\r
+        InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
+      }\r
       //\r
       // this is a flag\r
       //\r
       //\r
       // this is a flag\r
       //\r
@@ -1633,7 +1677,7 @@ InternalCommandLineParse (
         //\r
         InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
       }\r
         //\r
         InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
       }\r
-    } else if (GetItemValue == TRUE && InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
+    } else if (GetItemValue == TRUE && InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
       ASSERT(CurrentItemPackage != NULL);\r
       //\r
       // get the item VALUE for the previous flag\r
       ASSERT(CurrentItemPackage != NULL);\r
       //\r
       // get the item VALUE for the previous flag\r
@@ -1643,7 +1687,7 @@ InternalCommandLineParse (
       ASSERT(CurrentItemPackage->Value != NULL);\r
       StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
       ASSERT(CurrentItemPackage->Value != NULL);\r
       StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
-    } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
+    } else if (InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
       //\r
       // add this one as a non-flag\r
       //\r
       //\r
       // add this one as a non-flag\r
       //\r
@@ -1654,7 +1698,7 @@ InternalCommandLineParse (
       CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
       ASSERT(CurrentItemPackage->Value != NULL);\r
       StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
       CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
       ASSERT(CurrentItemPackage->Value != NULL);\r
       StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
-      CurrentItemPackage->OriginalPosition = Count++;\r
+      CurrentItemPackage->OriginalPosition = mTotalParameterCount++;\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
     } else if (ProblemParam) {\r
       //\r
       InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
     } else if (ProblemParam) {\r
       //\r
@@ -1708,13 +1752,13 @@ InternalCommandLineParse (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ShellCommandLineParse (\r
+ShellCommandLineParseEx (\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT LIST_ENTRY                **CheckPackage,\r
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT LIST_ENTRY                **CheckPackage,\r
   OUT CHAR16                    **ProblemParam OPTIONAL,\r
-  IN BOOLEAN                    AutoPageBreak\r
-  )\r
-{\r
+  IN BOOLEAN                    AutoPageBreak,\r
+  IN BOOLEAN                    AlwaysAllowNumbers\r
+  ) {\r
   // \r
   // ASSERT that CheckList and CheckPackage aren't NULL\r
   //\r
   // \r
   // ASSERT that CheckList and CheckPackage aren't NULL\r
   //\r
@@ -1730,7 +1774,8 @@ ShellCommandLineParse (
                                      ProblemParam, \r
                                      AutoPageBreak, \r
                                      (CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
                                      ProblemParam, \r
                                      AutoPageBreak, \r
                                      (CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
-                                     mEfiShellParametersProtocol->Argc ));\r
+                                     mEfiShellParametersProtocol->Argc,\r
+                                     AlwaysAllowNumbers));\r
   }\r
 \r
   // \r
   }\r
 \r
   // \r
@@ -1742,7 +1787,8 @@ ShellCommandLineParse (
                                    ProblemParam, \r
                                    AutoPageBreak, \r
                                    (CONST CHAR16**) mEfiShellInterface->Argv,\r
                                    ProblemParam, \r
                                    AutoPageBreak, \r
                                    (CONST CHAR16**) mEfiShellInterface->Argv,\r
-                                   mEfiShellInterface->Argc ));\r
+                                   mEfiShellInterface->Argc,\r
+                                   AlwaysAllowNumbers));\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -1761,8 +1807,7 @@ VOID
 EFIAPI\r
 ShellCommandLineFreeVarList (\r
   IN LIST_ENTRY                 *CheckPackage\r
 EFIAPI\r
 ShellCommandLineFreeVarList (\r
   IN LIST_ENTRY                 *CheckPackage\r
-  )\r
-{\r
+  ) {\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -1776,7 +1821,7 @@ ShellCommandLineFreeVarList (
   // for each node in the list\r
   //\r
   for ( Node = GetFirstNode(CheckPackage)\r
   // for each node in the list\r
   //\r
   for ( Node = GetFirstNode(CheckPackage)\r
-      ; Node != CheckPackage \r
+      ; IsListEmpty(CheckPackage) == FALSE\r
       ; Node = GetFirstNode(CheckPackage)\r
       ){\r
     //\r
       ; Node = GetFirstNode(CheckPackage)\r
       ){\r
     //\r
@@ -1827,8 +1872,7 @@ EFIAPI
 ShellCommandLineGetFlag (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN CHAR16                     *KeyString\r
 ShellCommandLineGetFlag (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN CHAR16                     *KeyString\r
-  )\r
-{\r
+  ) {\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -1886,8 +1930,7 @@ EFIAPI
 ShellCommandLineGetValue (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN CHAR16                     *KeyString\r
 ShellCommandLineGetValue (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN CHAR16                     *KeyString\r
-  )\r
-{\r
+  ) {\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -1946,8 +1989,7 @@ EFIAPI
 ShellCommandLineGetRawValue (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN UINT32                     Position\r
 ShellCommandLineGetRawValue (\r
   IN CONST LIST_ENTRY           *CheckPackage,\r
   IN UINT32                     Position\r
-  )\r
-{\r
+  ) {\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
   LIST_ENTRY                    *Node;\r
 \r
   //\r
@@ -1973,6 +2015,23 @@ ShellCommandLineGetRawValue (
   }\r
   return (NULL);\r
 }\r
   }\r
   return (NULL);\r
 }\r
+\r
+/**\r
+  returns the number of command line value parameters that were parsed.  \r
+  \r
+  this will not include flags.\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
+  ){\r
+  return (mTotalParameterCount);\r
+}\r
+\r
 /**\r
   This is a find and replace function.  it will return the NewString as a copy of \r
   SourceString with each instance of FindTarget replaced with ReplaceWith.\r
 /**\r
   This is a find and replace function.  it will return the NewString as a copy of \r
   SourceString with each instance of FindTarget replaced with ReplaceWith.\r
@@ -2004,7 +2063,8 @@ CopyReplace(
   IN UINTN                            NewSize,\r
   IN CONST CHAR16                     *FindTarget,\r
   IN CONST CHAR16                     *ReplaceWith\r
   IN UINTN                            NewSize,\r
   IN CONST CHAR16                     *FindTarget,\r
   IN CONST CHAR16                     *ReplaceWith\r
-  ){\r
+  ) \r
+{\r
   UINTN Size;\r
   if ( (SourceString == NULL)\r
     || (NewString    == NULL)\r
   UINTN Size;\r
   if ( (SourceString == NULL)\r
     || (NewString    == NULL)\r
@@ -2015,8 +2075,8 @@ CopyReplace(
     ){\r
     return (EFI_INVALID_PARAMETER);\r
   }\r
     ){\r
     return (EFI_INVALID_PARAMETER);\r
   }\r
-  NewString = SetMem16(NewString, NewSize, L'\0');\r
-  while (*SourceString != L'\0') {\r
+  NewString = SetMem16(NewString, NewSize, CHAR_NULL);\r
+  while (*SourceString != CHAR_NULL) {\r
     if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0) {\r
       SourceString += StrLen(FindTarget);\r
       Size = StrSize(NewString);\r
     if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0) {\r
       SourceString += StrLen(FindTarget);\r
       Size = StrSize(NewString);\r
@@ -2060,30 +2120,28 @@ CopyReplace(
   @param[in] Row        the row to print at\r
   @param[in] Col        the column to print at\r
   @param[in] Format     the format string\r
   @param[in] Row        the row to print at\r
   @param[in] Col        the column to print at\r
   @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
 **/\r
 \r
 UINTN\r
 EFIAPI\r
 \r
   @return the number of characters printed to the screen\r
 **/\r
 \r
 UINTN\r
 EFIAPI\r
-ShellPrintEx(\r
+InternalShellPrintWorker(\r
   IN INT32                Col OPTIONAL,\r
   IN INT32                Row OPTIONAL,\r
   IN CONST CHAR16         *Format,\r
   IN INT32                Col OPTIONAL,\r
   IN INT32                Row OPTIONAL,\r
   IN CONST CHAR16         *Format,\r
-  ...\r
-  ){\r
-  VA_LIST           Marker;\r
+  VA_LIST                 Marker\r
+  ) \r
+{\r
   UINTN             BufferSize;\r
   CHAR16            *PostReplaceFormat;\r
   CHAR16            *PostReplaceFormat2;\r
   UINTN             Return;\r
   UINTN             BufferSize;\r
   CHAR16            *PostReplaceFormat;\r
   CHAR16            *PostReplaceFormat2;\r
   UINTN             Return;\r
-\r
   EFI_STATUS        Status;\r
   UINTN             NormalAttribute;\r
   CHAR16            *ResumeLocation;\r
   CHAR16            *FormatWalker;\r
   EFI_STATUS        Status;\r
   UINTN             NormalAttribute;\r
   CHAR16            *ResumeLocation;\r
   CHAR16            *FormatWalker;\r
-\r
-  VA_START (Marker, Format);\r
   \r
   BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
   PostReplaceFormat = AllocateZeroPool (BufferSize);\r
   \r
   BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
   PostReplaceFormat = AllocateZeroPool (BufferSize);\r
@@ -2119,13 +2177,13 @@ ShellPrintEx(
 \r
   NormalAttribute = gST->ConOut->Mode->Attribute;\r
   FormatWalker = PostReplaceFormat2;\r
 \r
   NormalAttribute = gST->ConOut->Mode->Attribute;\r
   FormatWalker = PostReplaceFormat2;\r
-  while (*FormatWalker != L'\0') {\r
+  while (*FormatWalker != CHAR_NULL) {\r
     //\r
     // Find the next attribute change request\r
     //\r
     ResumeLocation = StrStr(FormatWalker, L"%");\r
     if (ResumeLocation != NULL) {\r
     //\r
     // Find the next attribute change request\r
     //\r
     ResumeLocation = StrStr(FormatWalker, L"%");\r
     if (ResumeLocation != NULL) {\r
-      *ResumeLocation = L'\0';\r
+      *ResumeLocation = CHAR_NULL;\r
     }\r
     //\r
     // print the current FormatWalker string\r
     }\r
     //\r
     // print the current FormatWalker string\r
@@ -2174,3 +2232,133 @@ ShellPrintEx(
 \r
   return (Return);\r
 }\r
 \r
   return (Return);\r
 }\r
+\r
+/**\r
+  Print at a specific location on the screen.\r
+\r
+  This function will move the cursor to a given screen location and print the specified string\r
+  \r
+  If -1 is specified for either the Row or Col the current screen location for BOTH \r
+  will be used.\r
+\r
+  if either Row or Col is out of range for the current console, then ASSERT\r
+  if Format is NULL, then ASSERT\r
+\r
+  In addition to the standard %-based flags as supported by UefiLib Print() this supports \r
+  the following additional flags:\r
+    %N       -   Set output attribute to normal\r
+    %H       -   Set output attribute to highlight\r
+    %E       -   Set output attribute to error\r
+    %B       -   Set output attribute to blue color\r
+    %V       -   Set output attribute to green color\r
+\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] Format     the format string\r
+\r
+  @return the number of characters printed to the screen\r
+**/\r
+\r
+UINTN\r
+EFIAPI\r
+ShellPrintEx(\r
+  IN INT32                Col OPTIONAL,\r
+  IN INT32                Row OPTIONAL,\r
+  IN CONST CHAR16         *Format,\r
+  ...\r
+  ) \r
+{\r
+  VA_LIST           Marker;\r
+  VA_START (Marker, Format);\r
+  return (InternalShellPrintWorker(Col, Row, Format, Marker));\r
+}\r
+\r
+/**\r
+  Print at a specific location on the screen.\r
+\r
+  This function will move the cursor to a given screen location, print the specified string, \r
+  and return the cursor to the original locaiton.  \r
+  \r
+  If -1 is specified for either the Row or Col the current screen location for BOTH \r
+  will be used and the cursor's position will not be moved back to an original location.\r
+\r
+  if either Row or Col is out of range for the current console, then ASSERT\r
+  if Format is NULL, then ASSERT\r
+\r
+  In addition to the standard %-based flags as supported by UefiLib Print() this supports \r
+  the following additional flags:\r
+    %N       -   Set output attribute to normal\r
+    %H       -   Set output attribute to highlight\r
+    %E       -   Set output attribute to error\r
+    %B       -   Set output attribute to blue color\r
+    %V       -   Set output attribute to green color\r
+\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] HiiFormatStringId  the format string Id for getting from Hii\r
+  @param[in] HiiFormatHandle    the format string Handle for getting from Hii\r
+\r
+  @return the number of characters printed to the screen\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellPrintHiiEx(\r
+  IN INT32                Col OPTIONAL,\r
+  IN INT32                Row OPTIONAL,\r
+  IN CONST EFI_STRING_ID  HiiFormatStringId,\r
+  IN CONST EFI_HANDLE     HiiFormatHandle,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST           Marker;\r
+  CHAR16            *HiiFormatString;\r
+  UINTN             RetVal;\r
+\r
+  VA_START (Marker, HiiFormatHandle);\r
+  HiiFormatString = HiiGetString(HiiFormatHandle, HiiFormatStringId, NULL);\r
+  ASSERT(HiiFormatString != NULL);\r
+\r
+  RetVal = InternalShellPrintWorker(Col, Row, HiiFormatString, Marker);\r
+\r
+  FreePool(HiiFormatString);\r
+\r
+  return (RetVal);\r
+}\r
+\r
+/**\r
+  Function to determine if a given filename represents a file or a directory.\r
+\r
+  @param[in] DirName      Path to directory to test.\r
+\r
+  @retval EFI_SUCCESS     The Path represents a directory\r
+  @retval EFI_NOT_FOUND   The Path does not represent a directory\r
+  @return other           The path failed to open\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellIsDirectory(\r
+  IN CONST CHAR16 *DirName\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  EFI_FILE_HANDLE   Handle;\r
+\r
+  Handle = NULL;\r
+\r
+  Status = ShellOpenFileByName(DirName, &Handle, EFI_FILE_MODE_READ, 0);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  if (FileHandleIsDirectory(Handle) == EFI_SUCCESS) {\r
+    ShellCloseFile(&Handle);\r
+    return (EFI_SUCCESS);\r
+  }\r
+  ShellCloseFile(&Handle);\r
+  return (EFI_NOT_FOUND);\r
+}\r
+\r
index c2f26cd526110ec76f250661c42865df988f57aa..832028b73da4a9b630eb41c1e42f4d4cc6293f4f 100644 (file)
@@ -33,6 +33,7 @@
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
   ShellPkg/ShellPkg.dec\r
 \r
 [LibraryClasses]\r
   ShellPkg/ShellPkg.dec\r
 \r
 [LibraryClasses]\r
@@ -45,6 +46,7 @@
   FileHandleLib\r
   PrintLib\r
   UefiLib\r
   FileHandleLib\r
   PrintLib\r
   UefiLib\r
+  HiiLib\r
 \r
 [Protocols]\r
   gEfiSimpleFileSystemProtocolGuid              # ALWAYS_CONSUMED\r
 \r
 [Protocols]\r
   gEfiSimpleFileSystemProtocolGuid              # ALWAYS_CONSUMED\r