summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ShellPkg/Application/ShellLibTestApp/sa3.c19
-rw-r--r--ShellPkg/Include/Guid/ShellEnvironment2Ext.h25
-rw-r--r--ShellPkg/Include/Guid/ShellPkgTokenSpace.h25
-rw-r--r--ShellPkg/Include/Library/FileHandleLib.h331
-rw-r--r--ShellPkg/Include/Library/ShellLib.h29
-rw-r--r--ShellPkg/Include/Protocol/EfiShell.h24
-rw-r--r--ShellPkg/Include/Protocol/EfiShellEnvironment2.h16
-rw-r--r--ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c623
-rw-r--r--ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf49
-rw-r--r--ShellPkg/Library/BaseShellLib/BaseShellLib.c662
-rw-r--r--ShellPkg/Library/BaseShellLib/BaseShellLib.h26
-rw-r--r--ShellPkg/Library/BaseShellLib/BaseShellLib.inf4
-rw-r--r--ShellPkg/ShellPkg.dec20
-rw-r--r--ShellPkg/ShellPkg.dsc12
14 files changed, 1406 insertions, 459 deletions
diff --git a/ShellPkg/Application/ShellLibTestApp/sa3.c b/ShellPkg/Application/ShellLibTestApp/sa3.c
index ae677b4..135590b 100644
--- a/ShellPkg/Application/ShellLibTestApp/sa3.c
+++ b/ShellPkg/Application/ShellLibTestApp/sa3.c
@@ -52,7 +52,7 @@ UefiMain (
EFI_FILE_INFO *pFileInfo;
UINT64 Size;
BOOLEAN NoFile;
- EFI_SHELL_FILE_INFO *pShellFileInfo, *pShellFileInfo2;
+ EFI_SHELL_FILE_INFO *pShellFileInfo;
LIST_ENTRY *List;
FileHandle = NULL;
@@ -97,7 +97,6 @@ UefiMain (
FreePool(pFileInfo);
pFileInfo = NULL;
Status = ShellCloseFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
Print(L"read, write, create, getinfo - pass\r\n");
@@ -125,7 +124,6 @@ UefiMain (
ASSERT(Size == 0x20);
ASSERT_EFI_ERROR(Status);
Status = ShellCloseFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
Print(L"setinfo and change size, getsize - pass\r\n");
@@ -145,7 +143,6 @@ UefiMain (
FreePool(pFileInfo);
pFileInfo = NULL;
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
Print(L"reopen file - pass\r\n");
@@ -163,7 +160,6 @@ UefiMain (
ASSERT((pFileInfo->Attribute&EFI_FILE_DIRECTORY)==0);
FreePool(pFileInfo);
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
Print(L"size of empty - pass\r\n");
@@ -183,7 +179,6 @@ UefiMain (
ASSERT(StrCmp(pFileInfo->FileName, FileName) == 0);
ASSERT(pFileInfo->Attribute&EFI_FILE_DIRECTORY);
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
Print(L"Directory create - pass\r\n");
@@ -206,7 +201,7 @@ UefiMain (
0
);
ASSERT_EFI_ERROR(Status);
- Status = ShellFindFirstFile(FileHandle, pFileInfo);
+ Status = ShellFindFirstFile(FileHandle, &pFileInfo);
ASSERT_EFI_ERROR(Status);
Status = ShellFindNextFile(FileHandle, pFileInfo, &NoFile);
ASSERT_EFI_ERROR(Status);
@@ -218,7 +213,6 @@ UefiMain (
ASSERT_EFI_ERROR(Status);
/// @todo - why is NoFile never set? limitation of NT32 file system?
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT(Status == RETURN_WARN_DELETE_FAILURE);
Print(L"FindFirst - pass\r\n");
Print(L"FindNext - Verify with real EFI system. Cant verify NoFile under NT32\r\n");
@@ -233,10 +227,7 @@ UefiMain (
ASSERT(pShellFileInfo->Info->FileSize == 0);
ASSERT(StrCmp(pShellFileInfo->Info->FileName, L"File.txt") == 0);
ASSERT(pShellFileInfo->Info->Attribute == 0);
- pShellFileInfo2 = (EFI_SHELL_FILE_INFO*)0x12345678;
- Status = ShellOpenFileMetaArg(L"testDir\\*.*", EFI_FILE_MODE_READ, &pShellFileInfo2);
- ASSERT(pShellFileInfo2 == NULL);
- ASSERT(Status == EFI_UNSUPPORTED);
+
Status = ShellCloseFileMetaArg(&pShellFileInfo);
ASSERT_EFI_ERROR(Status);
Print(L"Open/Close Meta Arg - pass\r\n");
@@ -250,7 +241,6 @@ UefiMain (
);
ASSERT_EFI_ERROR(Status);
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
StrCpy(FileName, L"testDir");
ASSERT_EFI_ERROR(Status);
Status = ShellOpenFileByName(FileName,
@@ -259,7 +249,6 @@ UefiMain (
0
);
Status = ShellDeleteFile(&FileHandle);
- ASSERT(FileHandle == NULL);
ASSERT_EFI_ERROR(Status);
// get environment variable
@@ -286,7 +275,7 @@ UefiMain (
ASSERT(ShellCommandLineGetFlag(List, L"/Param5") == FALSE);
ASSERT(ShellCommandLineGetFlag(List, L"/Param1") != FALSE);
ASSERT(StrCmp(ShellCommandLineGetValue(List, L"/Param2"), L"Val1")==0);
- ASSERT(StrCmp(ShellCommandLineGetRawValue(List, 0), L"SimpleApplication")==0);
+ ASSERT(StrCmp(ShellCommandLineGetRawValue(List, 0), L"SimpleApplication.efi")==0);
ShellCommandLineFreeVarList(List);
} else {
diff --git a/ShellPkg/Include/Guid/ShellEnvironment2Ext.h b/ShellPkg/Include/Guid/ShellEnvironment2Ext.h
new file mode 100644
index 0000000..4977005
--- /dev/null
+++ b/ShellPkg/Include/Guid/ShellEnvironment2Ext.h
@@ -0,0 +1,25 @@
+/** @file
+ GUID for EFI shell Environment2 Extension
+
+ Copyright (c) 2009, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SHELLPKG_SHELL_ENV2_EXT_GUID_H
+#define _SHELLPKG_SHELL_ENV2_EXT_GUID_H
+
+#define SHELLPKG_SHELL_ENV2_EXT_GUID \
+{ \
+ 0xd2c18636, 0x40e5, 0x4eb5, {0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87} \
+};
+
+extern EFI_GUID gEfiShellEnvironment2ExtGuid;
+
+#endif
diff --git a/ShellPkg/Include/Guid/ShellPkgTokenSpace.h b/ShellPkg/Include/Guid/ShellPkgTokenSpace.h
new file mode 100644
index 0000000..9803e9c
--- /dev/null
+++ b/ShellPkg/Include/Guid/ShellPkgTokenSpace.h
@@ -0,0 +1,25 @@
+/** @file
+ GUID for ShellPkg PCD Token Space
+
+ Copyright (c) 2009, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SHELLPKG_TOKEN_SPACE_GUID_H_
+#define _SHELLPKG_TOKEN_SPACE_GUID_H_
+
+#define SHELLPKG_TOKEN_SPACE_GUID \
+{ \
+ 0x171e9188, 0x31d3, 0x40f5, { 0xb1, 0xc, 0x53, 0x9b, 0x2d, 0xb9, 0x40, 0xcd } \
+};
+
+extern EFI_GUID gEfiShellPkgTokenSpaceGuid;
+
+#endif
diff --git a/ShellPkg/Include/Library/FileHandleLib.h b/ShellPkg/Include/Library/FileHandleLib.h
new file mode 100644
index 0000000..8140dae
--- /dev/null
+++ b/ShellPkg/Include/Library/FileHandleLib.h
@@ -0,0 +1,331 @@
+/** @file
+ Provides interface to EFI_FILE_HANDLE functionality.
+
+Copyright (c) 2006 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+ This function will retrieve the information about the file for the handle
+ specified and store it in allocated pool memory.
+
+ This function allocates a buffer to store the file’s information. It is the
+ caller’s responsibility to free the buffer
+
+ @param FileHandle The file handle of the file for which information is
+ being requested.
+
+ @retval NULL information could not be retrieved.
+
+ @return the information about the file
+**/
+EFI_FILE_INFO*
+EFIAPI
+FileHandleGetInfo (
+ IN EFI_FILE_HANDLE FileHandle
+ );
+
+/**
+ This function will set the information about the file for the opened handle
+ specified.
+
+ @param FileHandle The file handle of the file for which information
+ is being set
+
+ @param FileInfo The infotmation to set.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetInfo (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN CONST EFI_FILE_INFO *FileInfo
+ );
+
+/**
+ This function reads information from an opened file.
+
+ If FileHandle is not a directory, the function reads the requested number of
+ bytes from the file at the file’s current position and returns them in Buffer.
+ If the read goes beyond the end of the file, the read length is truncated to the
+ end of the file. The file’s current position is increased by the number of bytes
+ returned. If FileHandle is a directory, the function reads the directory entry
+ at the file’s current position and returns the entry in Buffer. If the Buffer
+ is not large enough to hold the current directory entry, then
+ EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.
+ BufferSize is set to be the size of the buffer needed to read the entry. On
+ success, the current position is updated to the next directory entry. If there
+ are no more directory entries, the read returns a zero-length buffer.
+ EFI_FILE_INFO is the structure returned as the directory entry.
+
+ @param FileHandle the opened file handle
+ @param BufferSize on input the size of buffer in bytes. on return
+ the number of bytes written.
+ @param Buffer the buffer to put read data into.
+
+ @retval EFI_SUCCESS Data was read.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_BUFFER_TO_SMALL Buffer is too small. ReadSize contains required
+ size.
+
+**/
+EFI_STATUS
+EFIAPI
+FileHandleRead(
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Write data to a file.
+
+ This function writes the specified number of bytes to the file at the current
+ file position. The current file position is advanced the actual number of bytes
+ written, which is returned in BufferSize. Partial writes only occur when there
+ has been a data error during the write attempt (such as “volume space full”).
+ The file is automatically grown to hold the data if required. Direct writes to
+ opened directories are not supported.
+
+ @param FileHandle The opened file for writing
+ @param BufferSize on input the number of bytes in Buffer. On output
+ the number of bytes written.
+ @param Buffer the buffer containing data to write is stored.
+
+ @retval EFI_SUCCESS Data was written.
+ @retval EFI_UNSUPPORTED Writes to an open directory are not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write-protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleWrite(
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Close an open file handle.
+
+ This function closes a specified file handle. All “dirty” cached file data is
+ flushed to the device, and the file is closed. In all cases the handle is
+ closed.
+
+@param FileHandle the file handle to close.
+
+@retval EFI_SUCCESS the file handle was closed sucessfully.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleClose (
+ IN EFI_FILE_HANDLE FileHandle
+ );
+
+/**
+ Delete a file and close the handle
+
+ This function closes and deletes a file. In all cases the file handle is closed.
+ If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is
+ returned, but the handle is still closed.
+
+ @param FileHandle the file handle to delete
+
+ @retval EFI_SUCCESS the file was closed sucessfully
+ @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not
+ deleted
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleDelete (
+ IN EFI_FILE_HANDLE FileHandle
+ );
+
+/**
+ Set the current position in a file.
+
+ This function sets the current file position for the handle to the position
+ supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only
+ absolute positioning is supported, and seeking past the end of the file is
+ allowed (a subsequent write would grow the file). Seeking to position
+ 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.
+ If FileHandle is a directory, the only position that may be set is zero. This
+ has the effect of starting the read process of the directory entries over.
+
+ @param FileHandle The file handle on which the position is being set
+ @param Position Byte position from begining of file
+
+ @retval EFI_SUCCESS Operation completed sucessfully.
+ @retval EFI_UNSUPPORTED the seek request for non-zero is not valid on
+ directories.
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetPosition (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN UINT64 Position
+ );
+
+/**
+ Gets a file's current position
+
+ This function retrieves the current file position for the file handle. For
+ directories, the current file position has no meaning outside of the file
+ system driver and as such the operation is not supported. An error is returned
+ if FileHandle is a directory.
+
+ @param FileHandle The open file handle on which to get the position.
+ @param Position Byte position from begining of file.
+
+ @retval EFI_SUCCESS the operation completed sucessfully.
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED the request is not valid on directories.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetPosition (
+ IN EFI_FILE_HANDLE FileHandle,
+ OUT UINT64 *Position
+ );
+/**
+ Flushes data on a file
+
+ This function flushes all modified data associated with a file to a device.
+
+ @param FileHandle The file handle on which to flush data
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened for read only.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFlush (
+ IN EFI_FILE_HANDLE FileHandle
+ );
+
+/**
+ function to determine if a given handle is a directory handle
+
+ if DirHandle is NULL then ASSERT()
+
+ open the file information on the DirHandle and verify that the Attribute
+ includes EFI_FILE_DIRECTORY bit set.
+
+ @param DirHandle Handle to open file
+
+ @retval EFI_SUCCESS DirHandle is a directory
+ @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available
+ @retval EFI_NOT_FOUND DirHandle is not a directory
+**/
+EFI_STATUS
+EFIAPI
+FileHandleIsDirectory (
+ IN EFI_FILE_HANDLE DirHandle
+ );
+
+/**
+ Retrieves the first file from a directory
+
+ This function opens a directory and gets the first file’s info in the
+ directory. Caller can use FileHandleFindNextFile() to get other files. When
+ complete the caller is responsible for calling FreePool() on *Buffer.
+
+ @param DirHandle The file handle of the directory to search
+ @param Buffer Pointer to pointer to buffer for file's information
+
+ @retval EFI_SUCCESS Found the first file.
+ @retval EFI_NOT_FOUND Cannot find the directory.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @return Others status of FileHandleGetInfo, FileHandleSetPosition,
+ or FileHandleRead
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindFirstFile (
+ IN EFI_FILE_HANDLE DirHandle,
+ OUT EFI_FILE_INFO **Buffer
+ );
+/**
+ Retrieves the next file in a directory.
+
+ To use this function, caller must call the FileHandleFindFirstFile() to get the
+ first file, and then use this function get other files. This function can be
+ called for several times to get each file's information in the directory. If
+ the call of FileHandleFindNextFile() got the last file in the directory, the next
+ call of this function has no file to get. *NoFile will be set to TRUE and the
+ Buffer memory will be automatically freed.
+
+ @param DirHandle the file handle of the directory
+ @param Buffer pointer to buffer for file's information
+ @param NoFile pointer to boolean when last file is found
+
+ @retval EFI_SUCCESS Found the next file, or reached last file
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindNextFile(
+ IN EFI_FILE_HANDLE DirHandle,
+ OUT EFI_FILE_INFO *Buffer,
+ OUT BOOLEAN *NoFile
+ );
+
+/**
+ Retrieve the size of a file.
+
+ if FileHandle is NULL then ASSERT()
+ if Size is NULL then ASSERT()
+
+ This function extracts the file size info from the FileHandle’s EFI_FILE_INFO
+ data.
+
+ @param FileHandle file handle from which size is retrieved
+ @param Size pointer to size
+
+ @retval EFI_SUCCESS operation was completed sucessfully
+ @retval EFI_DEVICE_ERROR cannot access the file
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetSize (
+ IN EFI_FILE_HANDLE FileHandle,
+ OUT UINT64 *Size
+ ); \ No newline at end of file
diff --git a/ShellPkg/Include/Library/ShellLib.h b/ShellPkg/Include/Library/ShellLib.h
index f5e5ba6..5614d71 100644
--- a/ShellPkg/Include/Library/ShellLib.h
+++ b/ShellPkg/Include/Library/ShellLib.h
@@ -16,7 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define __SHELL_LIB__
#include <Protocol/SimpleFileSystem.h>
-#include <Guid/FileInfo.h>
#include <Protocol/EfiShell.h>
/**
@@ -363,8 +362,10 @@ ShellFlushFile (
in the directory's info. Caller can use ShellFindNextFile() to get
subsequent files.
+ Caller must use FreePool on *Buffer opon completion of all file searching.
+
@param DirHandle The file handle of the directory to search
- @param Buffer Pointer to buffer for file's information
+ @param Buffer Pointer to pointer to buffer for file's information
@retval EFI_SUCCESS Found the first file.
@retval EFI_NOT_FOUND Cannot find the directory.
@@ -377,7 +378,7 @@ EFI_STATUS
EFIAPI
ShellFindFirstFile (
IN EFI_FILE_HANDLE DirHandle,
- OUT EFI_FILE_INFO *Buffer
+ OUT EFI_FILE_INFO **Buffer
);
/**
@@ -613,6 +614,10 @@ typedef struct {
ParamType Type;
} SHELL_PARAM_ITEM;
+
+/// Helper structure for no parameters (besides -? and -b)
+extern SHELL_PARAM_ITEM EmptyParamList[];
+
/**
Checks the command line arguments passed against the list of valid ones.
Optionally removes NULL values first.
@@ -726,4 +731,22 @@ ShellCommandLineGetRawValue (
IN UINT32 Position
);
+/**
+ This function causes the shell library to initialize itself. If the shell library
+ is already initialized it will de-initialize all the current protocol poitners and
+ re-populate them again.
+
+ When the library is used with PcdShellLibAutoInitialize set to true this function
+ will return EFI_SUCCESS and perform no actions.
+
+ This function is intended for internal access for shell commands only.
+
+ @retval EFI_SUCCESS the initialization was complete sucessfully
+
+**/
+EFI_STATUS
+EFIAPI
+ShellInitialize (
+ );
+
#endif // __SHELL_LIB__ \ No newline at end of file
diff --git a/ShellPkg/Include/Protocol/EfiShell.h b/ShellPkg/Include/Protocol/EfiShell.h
index 8421056..bd0aebe 100644
--- a/ShellPkg/Include/Protocol/EfiShell.h
+++ b/ShellPkg/Include/Protocol/EfiShell.h
@@ -23,13 +23,10 @@
0x6302d008, 0x7f9b, 0x4f30, { 0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e } \
}
-typedef struct _EFI_LIST_ENTRY {
- struct _EFI_LIST_ENTRY *Flink;
- struct _EFI_LIST_ENTRY *Blink;
-} EFI_LIST_ENTRY;
-
+// replaced EFI_LIST_ENTRY with LIST_ENTRY for simplicity.
+// they are identical outside of the name.
typedef struct {
- EFI_LIST_ENTRY Link;
+ LIST_ENTRY Link;
EFI_STATUS Status;
CONST CHAR16 *FullName;
CONST CHAR16 *FileName;
@@ -317,6 +314,16 @@ typedef UINT32 EFI_SHELL_DEVICE_NAME_FLAGS;
handle. If no user-readable name could be generated, then *BestDeviceName will be
NULL and EFI_NOT_FOUND will be returned.
+ If EFI_DEVICE_NAME_USE_COMPONENT_NAME is set, then the function will return the
+ device’s name using the EFI_COMPONENT_NAME2_PROTOCOL, if present on
+ DeviceHandle.
+
+ If EFI_DEVICE_NAME_USE_DEVICE_PATH is set, then the function will return the
+ device’s name using the EFI_DEVICE_PATH_PROTOCOL, if present on DeviceHandle.
+ If both EFI_DEVICE_NAME_USE_COMPONENT_NAME and
+ EFI_DEVICE_NAME_USE_DEVICE_PATH are set, then
+ EFI_DEVICE_NAME_USE_COMPONENT_NAME will have higher priority.
+
@param DeviceHandle The handle of the device.
@param Flags Determines the possible sources of component names.
@param Language A pointer to the language specified for the device
@@ -946,4 +953,9 @@ typedef struct _EFI_SHELL_PROTOCOL {
extern EFI_GUID gEfiShellProtocolGuid;
+enum ShellVersion {
+ SHELL_MAJOR_VERSION = 2,
+ SHELL_MINOR_VERSION = 0
+};
+
#endif
diff --git a/ShellPkg/Include/Protocol/EfiShellEnvironment2.h b/ShellPkg/Include/Protocol/EfiShellEnvironment2.h
index 537b916..cafecb0 100644
--- a/ShellPkg/Include/Protocol/EfiShellEnvironment2.h
+++ b/ShellPkg/Include/Protocol/EfiShellEnvironment2.h
@@ -82,7 +82,7 @@ EFI_STATUS
**/
typedef struct {
UINT32 Signature; ///< SHELL_FILE_ARG_SIGNATURE
- EFI_LIST_ENTRY Link; ///< linked list helper
+ LIST_ENTRY Link; ///< linked list helper
EFI_STATUS Status; ///< File's status
EFI_FILE_HANDLE Parent; ///< what is the Parent file of this file
@@ -270,7 +270,7 @@ CHAR16*
support for wildcard characters ('?' and '*') in the Arg path. if there are
any wildcard characters in the path this function will find any and all files
that match the wildcards. the return is a double linked list based on the
- EFI_LIST_ENTRY linked list structure. use this in conjunction with the
+ LIST_ENTRY linked list structure. use this in conjunction with the
SHELL_FILE_ARG_SIGNATURE to get the SHELL_FILE_ARG structures that are returned.
The memory allocated by the callee for this list is freed by making a call to
SHELLENV_FREE_FILE_LIST.
@@ -288,7 +288,7 @@ CHAR16*
EFI_STATUS
(EFIAPI *SHELLENV_FILE_META_ARG) (
IN CHAR16 *Arg,
- IN OUT EFI_LIST_ENTRY *ListHead
+ IN OUT LIST_ENTRY *ListHead
);
/**
@@ -301,7 +301,7 @@ EFI_STATUS
typedef
EFI_STATUS
(EFIAPI *SHELLENV_FREE_FILE_LIST) (
- IN OUT EFI_LIST_ENTRY *ListHead
+ IN OUT LIST_ENTRY *ListHead
);
/**
@@ -618,7 +618,7 @@ typedef struct {
**/
typedef struct {
UINTN Signature; ///< PROTOCOL_INFO_SIGNATURE
- EFI_LIST_ENTRY Link; ///< standard lined list helper member
+ LIST_ENTRY Link; ///< standard lined list helper member
//
// parsing info for the protocol
//
@@ -845,7 +845,7 @@ EFI_STATUS
support the wildcard characters ('?' and '*') in the Arg path. if there are
any wildcard characters in the path this function will return
EFI_INVALID_PARAMETER. the return is a double linked list based on the
- EFI_LIST_ENTRY linked list structure. use this in conjunction with the
+ LIST_ENTRY linked list structure. use this in conjunction with the
SHELL_FILE_ARG_SIGNATURE to get the SHELL_FILE_ARG structures that are returned.
The memory allocated by the callee for this list is freed by making a call to
SHELLENV_FREE_FILE_LIST.
@@ -864,7 +864,7 @@ typedef
EFI_STATUS
(EFIAPI *SHELLENV_FILE_META_ARG_NO_WILDCARD) (
IN CHAR16 *Arg,
- IN OUT EFI_LIST_ENTRY *ListHead
+ IN OUT LIST_ENTRY *ListHead
);
/**
@@ -885,7 +885,7 @@ EFI_STATUS
typedef
EFI_STATUS
(EFIAPI *SHELLENV_DEL_DUP_FILE) (
- IN EFI_LIST_ENTRY * ListHead
+ IN LIST_ENTRY * ListHead
);
/**
diff --git a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
new file mode 100644
index 0000000..6822b74
--- /dev/null
+++ b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
@@ -0,0 +1,623 @@
+/** @file
+ Provides interface to EFI_FILE_HANDLE functionality.
+
+Copyright (c) 2006 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/ShellLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Protocol/SimpleFileSystem.h>
+
+#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)
+#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)
+
+/**
+ This function will retrieve the information about the file for the handle
+ specified and store it in allocated pool memory.
+
+ This function allocates a buffer to store the file’s information. It is the
+ caller’s responsibility to free the buffer
+
+ @param FileHandle The file handle of the file for which information is
+ being requested.
+
+ @retval NULL information could not be retrieved.
+
+ @return the information about the file
+**/
+EFI_FILE_INFO*
+EFIAPI
+FileHandleGetInfo (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_GUID FileInfoGuid;
+ EFI_FILE_INFO *pFileInfo;
+ UINTN FileInfoSize;
+ EFI_STATUS Status;
+
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+
+ //
+ // Get the required size to allocate
+ //
+ FileInfoGuid = gEfiFileInfoGuid;
+ FileInfoSize = 0;
+ pFileInfo = NULL;
+ Status = FileHandle->GetInfo(FileHandle,
+ &FileInfoGuid,
+ &FileInfoSize,
+ pFileInfo);
+ //
+ // error is expected. getting size to allocate
+ //
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ pFileInfo = AllocateZeroPool(FileInfoSize);
+ ASSERT (pFileInfo != NULL);
+ //
+ // now get the information
+ //
+ Status = FileHandle->GetInfo(FileHandle,
+ &FileInfoGuid,
+ &FileInfoSize,
+ pFileInfo);
+ //
+ // if we got an error free the memory and return NULL
+ //
+ if (EFI_ERROR(Status)) {
+ FreePool(pFileInfo);
+ return NULL;
+ }
+ return (pFileInfo);
+}
+
+/**
+ This function will set the information about the file for the opened handle
+ specified.
+
+ @param FileHandle The file handle of the file for which information
+ is being set
+
+ @param FileInfo The infotmation to set.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetInfo (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN CONST EFI_FILE_INFO *FileInfo
+ )
+{
+ EFI_GUID FileInfoGuid;
+
+ //
+ // ASSERT if the FileHandle or FileInfo is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ ASSERT (FileInfo != NULL);
+
+ FileInfoGuid = gEfiFileInfoGuid;
+ //
+ // Set the info
+ //
+ return (FileHandle->SetInfo(FileHandle,
+ &FileInfoGuid,
+ (UINTN)FileInfo->Size,
+ (EFI_FILE_INFO*)FileInfo));
+}
+
+/**
+ This function reads information from an opened file.
+
+ If FileHandle is not a directory, the function reads the requested number of
+ bytes from the file at the file’s current position and returns them in Buffer.
+ If the read goes beyond the end of the file, the read length is truncated to the
+ end of the file. The file’s current position is increased by the number of bytes
+ returned. If FileHandle is a directory, the function reads the directory entry
+ at the file’s current position and returns the entry in Buffer. If the Buffer
+ is not large enough to hold the current directory entry, then
+ EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.
+ BufferSize is set to be the size of the buffer needed to read the entry. On
+ success, the current position is updated to the next directory entry. If there
+ are no more directory entries, the read returns a zero-length buffer.
+ EFI_FILE_INFO is the structure returned as the directory entry.
+
+ @param FileHandle the opened file handle
+ @param BufferSize on input the size of buffer in bytes. on return
+ the number of bytes written.
+ @param Buffer the buffer to put read data into.
+
+ @retval EFI_SUCCESS Data was read.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_BUFFER_TO_SMALL Buffer is too small. ReadSize contains required
+ size.
+
+**/
+EFI_STATUS
+EFIAPI
+FileHandleRead(
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+
+ //
+ // Perform the read based on EFI_FILE_PROTOCOL
+ //
+ return (FileHandle->Read(FileHandle, BufferSize, Buffer));
+}
+
+
+/**
+ Write data to a file.
+
+ This function writes the specified number of bytes to the file at the current
+ file position. The current file position is advanced the actual number of bytes
+ written, which is returned in BufferSize. Partial writes only occur when there
+ has been a data error during the write attempt (such as “volume space full”).
+ The file is automatically grown to hold the data if required. Direct writes to
+ opened directories are not supported.
+
+ @param FileHandle The opened file for writing
+ @param BufferSize on input the number of bytes in Buffer. On output
+ the number of bytes written.
+ @param Buffer the buffer containing data to write is stored.
+
+ @retval EFI_SUCCESS Data was written.
+ @retval EFI_UNSUPPORTED Writes to an open directory are not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write-protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleWrite(
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the write based on EFI_FILE_PROTOCOL
+ //
+ return (FileHandle->Write(FileHandle, BufferSize, Buffer));
+}
+
+/**
+ Close an open file handle.
+
+ This function closes a specified file handle. All “dirty” cached file data is
+ flushed to the device, and the file is closed. In all cases the handle is
+ closed.
+
+@param FileHandle the file handle to close.
+
+@retval EFI_SUCCESS the file handle was closed sucessfully.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleClose (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the Close based on EFI_FILE_PROTOCOL
+ //
+ Status = FileHandle->Close(FileHandle);
+ return Status;
+}
+
+/**
+ Delete a file and close the handle
+
+ This function closes and deletes a file. In all cases the file handle is closed.
+ If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is
+ returned, but the handle is still closed.
+
+ @param FileHandle the file handle to delete
+
+ @retval EFI_SUCCESS the file was closed sucessfully
+ @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not
+ deleted
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleDelete (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the Delete based on EFI_FILE_PROTOCOL
+ //
+ Status = FileHandle->Delete(FileHandle);
+ return Status;
+}
+
+/**
+ Set the current position in a file.
+
+ This function sets the current file position for the handle to the position
+ supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only
+ absolute positioning is supported, and seeking past the end of the file is
+ allowed (a subsequent write would grow the file). Seeking to position
+ 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.
+ If FileHandle is a directory, the only position that may be set is zero. This
+ has the effect of starting the read process of the directory entries over.
+
+ @param FileHandle The file handle on which the position is being set
+ @param Position Byte position from begining of file
+
+ @retval EFI_SUCCESS Operation completed sucessfully.
+ @retval EFI_UNSUPPORTED the seek request for non-zero is not valid on
+ directories.
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetPosition (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN UINT64 Position
+ )
+{
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the SetPosition based on EFI_FILE_PROTOCOL
+ //
+ return (FileHandle->SetPosition(FileHandle, Position));
+}
+
+/**
+ Gets a file's current position
+
+ This function retrieves the current file position for the file handle. For
+ directories, the current file position has no meaning outside of the file
+ system driver and as such the operation is not supported. An error is returned
+ if FileHandle is a directory.
+
+ @param FileHandle The open file handle on which to get the position.
+ @param Position Byte position from begining of file.
+
+ @retval EFI_SUCCESS the operation completed sucessfully.
+ @retval INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED the request is not valid on directories.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetPosition (
+ IN EFI_FILE_HANDLE FileHandle,
+ OUT UINT64 *Position
+ )
+{
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the GetPosition based on EFI_FILE_PROTOCOL
+ //
+ return (FileHandle->GetPosition(FileHandle, Position));
+}
+/**
+ Flushes data on a file
+
+ This function flushes all modified data associated with a file to a device.
+
+ @param FileHandle The file handle on which to flush data
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened for read only.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFlush (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ //
+ // ASSERT if FileHandle is NULL
+ //
+ ASSERT (FileHandle != NULL);
+ //
+ // Perform the Flush based on EFI_FILE_PROTOCOL
+ //
+ return (FileHandle->Flush(FileHandle));
+}
+
+/**
+ function to determine if a given handle is a directory handle
+
+ if DirHandle is NULL then ASSERT()
+
+ open the file information on the DirHandle and verify that the Attribute
+ includes EFI_FILE_DIRECTORY bit set.
+
+ @param DirHandle Handle to open file
+
+ @retval EFI_SUCCESS DirHandle is a directory
+ @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available
+ @retval EFI_NOT_FOUND DirHandle is not a directory
+**/
+EFI_STATUS
+EFIAPI
+FileHandleIsDirectory (
+ IN EFI_FILE_HANDLE DirHandle
+ )
+{
+ EFI_FILE_INFO *DirInfo;
+
+ //
+ // ASSERT if DirHandle is NULL
+ //
+ ASSERT(DirHandle != NULL);
+
+ //
+ // get the file information for DirHandle
+ //
+ DirInfo = FileHandleGetInfo (DirHandle);
+
+ //
+ // Parse DirInfo
+ //
+ if (DirInfo == NULL) {
+ //
+ // We got nothing...
+ //
+ return (EFI_INVALID_PARAMETER);
+ }
+ if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
+ //
+ // Attributes say this is not a directory
+ //
+ FreePool (DirInfo);
+ return (EFI_NOT_FOUND);
+ }
+ //
+ // all good...
+ //
+ FreePool (DirInfo);
+ return (EFI_SUCCESS);
+}
+
+/**
+ Retrieves the first file from a directory
+
+ This function opens a directory and gets the first file’s info in the
+ directory. Caller can use FileHandleFindNextFile() to get other files. When
+ complete the caller is responsible for calling FreePool() on Buffer.
+
+ @param DirHandle The file handle of the directory to search
+ @param Buffer Pointer to buffer for file's information
+
+ @retval EFI_SUCCESS Found the first file.
+ @retval EFI_NOT_FOUND Cannot find the directory.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @return Others status of FileHandleGetInfo, FileHandleSetPosition,
+ or FileHandleRead
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindFirstFile (
+ IN EFI_FILE_HANDLE DirHandle,
+ OUT EFI_FILE_INFO **Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ //
+ // ASSERTs
+ //
+ ASSERT (DirHandle != NULL);
+ ASSERT (Buffer != NULL);
+
+ //
+ // verify that DirHandle is a directory
+ //
+ Status = FileHandleIsDirectory(DirHandle);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // reset to the begining of the directory
+ //
+ Status = FileHandleSetPosition(DirHandle, 0);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // Allocate a buffer sized to struct size + enough for the string at the end
+ //
+ BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
+ *Buffer = AllocateZeroPool(BufferSize);
+ ASSERT (*Buffer != NULL);
+
+ //
+ // read in the info about the first file
+ //
+ Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);
+ ASSERT(Status != EFI_BUFFER_TOO_SMALL);
+ if (EFI_ERROR(Status)) {
+ FreePool(*Buffer);
+ *Buffer = NULL;
+ return (Status);
+ }
+ return (EFI_SUCCESS);
+}
+/**
+ Retrieves the next file in a directory.
+
+ To use this function, caller must call the FileHandleFindFirstFile() to get the
+ first file, and then use this function get other files. This function can be
+ called for several times to get each file's information in the directory. If
+ the call of FileHandleFindNextFile() got the last file in the directory, the next
+ call of this function has no file to get. *NoFile will be set to TRUE and the
+ Buffer memory will be automatically freed.
+
+ @param DirHandle the file handle of the directory
+ @param Buffer pointer to buffer for file's information
+ @param NoFile pointer to boolean when last file is found
+
+ @retval EFI_SUCCESS Found the next file, or reached last file
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindNextFile(
+ IN EFI_FILE_HANDLE DirHandle,
+ OUT EFI_FILE_INFO *Buffer,
+ OUT BOOLEAN *NoFile
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ //
+ // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL
+ //
+ ASSERT (DirHandle != NULL);
+ ASSERT (Buffer != NULL);
+ ASSERT (NoFile != NULL);
+
+ //
+ // verify that DirHandle is a directory
+ //
+ Status = FileHandleIsDirectory(DirHandle);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile
+ //
+ BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
+
+ //
+ // read in the info about the next file
+ //
+ Status = FileHandleRead (DirHandle, &BufferSize, Buffer);
+ ASSERT(Status != EFI_BUFFER_TOO_SMALL);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // If we read 0 bytes (but did not have erros) we already read in the last file.
+ //
+ if (BufferSize == 0) {
+ FreePool(Buffer);
+ *NoFile = TRUE;
+ }
+
+ return (EFI_SUCCESS);
+}
+/**
+ Retrieve the size of a file.
+
+ if FileHandle is NULL then ASSERT()
+ if Size is NULL then ASSERT()
+
+ This function extracts the file size info from the FileHandle’s EFI_FILE_INFO
+ data.
+
+ @param FileHandle file handle from which size is retrieved
+ @param Size pointer to size
+
+ @retval EFI_SUCCESS operation was completed sucessfully
+ @retval EFI_DEVICE_ERROR cannot access the file
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetSize (
+ IN EFI_FILE_HANDLE FileHandle,
+ OUT UINT64 *Size
+ )
+{
+ EFI_FILE_INFO *FileInfo;
+
+ //
+ // ASSERT for FileHandle or Size being NULL
+ //
+ ASSERT (FileHandle != NULL);
+ ASSERT (Size != NULL);
+
+ //
+ // get the FileInfo structure
+ //
+ FileInfo = FileHandleGetInfo(FileHandle);
+ if (FileInfo == NULL) {
+ return (EFI_DEVICE_ERROR);
+ }
+
+ //
+ // Assign the Size pointer to the correct value
+ //
+ *Size = FileInfo->FileSize;
+
+ //
+ // free the FileInfo memory
+ //
+ FreePool(FileInfo);
+
+ return (EFI_SUCCESS);
+} \ No newline at end of file
diff --git a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
new file mode 100644
index 0000000..48489b4
--- /dev/null
+++ b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
@@ -0,0 +1,49 @@
+#/** @file
+# Provides interface to shell functionality for shell commands and applications.
+#
+# Copyright (c) 2006 - 2009, Intel Corporation.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = BaseFileHandleLib
+ FILE_GUID = 9495D344-9D8A-41f3-8D17-E2FD238C4E71
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FileHandleLib|UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ BaseFileHandleLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ DevicePathLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+
+[Protocols]
+
+[Guids]
+ gEfiFileInfoGuid # ALWAYS_CONSUMED
+
+[Pcd.common]
+
diff --git a/ShellPkg/Library/BaseShellLib/BaseShellLib.c b/ShellPkg/Library/BaseShellLib/BaseShellLib.c
index 205974d..a0e2e49 100644
--- a/ShellPkg/Library/BaseShellLib/BaseShellLib.c
+++ b/ShellPkg/Library/BaseShellLib/BaseShellLib.c
@@ -20,21 +20,35 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FileHandleLib.h>
#include <Protocol/EfiShellEnvironment2.h>
#include <Protocol/EfiShellInterface.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/SimpleFileSystem.h>
+#include "BaseShellLib.h"
+
#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)
#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)
-EFI_SHELL_ENVIRONMENT2 *mEfiShellEnvironment2;
-EFI_SHELL_INTERFACE *mEfiShellInterface;
-EFI_SHELL_PROTOCOL *mEfiShellProtocol;
-EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;
-EFI_HANDLE mEfiShellEnvironment2Handle;
-EFI_LIST_ENTRY *mOldStyleFileList;
+//
+// This is not static since it's extern in the .h file
+//
+SHELL_PARAM_ITEM EmptyParamList[] = {
+ {NULL, TypeMax}
+ };
+
+//
+// Static file globals for the shell library
+//
+STATIC EFI_SHELL_ENVIRONMENT2 *mEfiShellEnvironment2;
+STATIC EFI_SHELL_INTERFACE *mEfiShellInterface;
+STATIC EFI_SHELL_PROTOCOL *mEfiShellProtocol;
+STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;
+STATIC EFI_HANDLE mEfiShellEnvironment2Handle;
+STATIC FILE_HANDLE_FUNCTION_MAP FileFunctionMap;
/**
helper function to find ShellEnvironment2 for constructor
@@ -112,36 +126,14 @@ ShellFindSE2 (
return (Status);
}
-/**
- Constructor for the Shell library.
-
- Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.
-
- @param ImageHandle the image handle of the process
- @param SystemTable the EFI System Table pointer
-
- @retval EFI_SUCCESS the initialization was complete sucessfully
- @return others an error ocurred during initialization
-**/
EFI_STATUS
EFIAPI
-ShellLibConstructor (
+ShellLibConstructorWorker (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
+){
EFI_STATUS Status;
- ASSERT(SystemTable != NULL);
- ASSERT(gBS != NULL);
-
- mEfiShellEnvironment2 = NULL;
- mEfiShellProtocol = NULL;
- mEfiShellParametersProtocol = NULL;
- mEfiShellInterface = NULL;
- mEfiShellEnvironment2Handle = NULL;
- mOldStyleFileList = NULL;
-
//
// UEFI 2.0 shell interfaces (used preferentially)
//
@@ -192,10 +184,69 @@ ShellLibConstructor (
//
if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) ||
(mEfiShellProtocol != NULL && mEfiShellParametersProtocol != NULL) ) {
+ if (mEfiShellProtocol != NULL) {
+ FileFunctionMap.GetFileInfo = mEfiShellProtocol->GetFileInfo;
+ FileFunctionMap.SetFileInfo = mEfiShellProtocol->SetFileInfo;
+ FileFunctionMap.ReadFile = mEfiShellProtocol->ReadFile;
+ FileFunctionMap.WriteFile = mEfiShellProtocol->WriteFile;
+ FileFunctionMap.CloseFile = mEfiShellProtocol->CloseFile;
+ FileFunctionMap.DeleteFile = mEfiShellProtocol->DeleteFile;
+ FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;
+ FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;
+ FileFunctionMap.FlushFile = mEfiShellProtocol->FlushFile;
+ FileFunctionMap.GetFileSize = mEfiShellProtocol->GetFileSize;
+ } else {
+ FileFunctionMap.GetFileInfo = FileHandleGetInfo;
+ FileFunctionMap.SetFileInfo = FileHandleSetInfo;
+ FileFunctionMap.ReadFile = FileHandleRead;
+ FileFunctionMap.WriteFile = FileHandleWrite;
+ FileFunctionMap.CloseFile = FileHandleClose;
+ FileFunctionMap.DeleteFile = FileHandleDelete;
+ FileFunctionMap.GetFilePosition = FileHandleGetPosition;
+ FileFunctionMap.SetFilePosition = FileHandleSetPosition;
+ FileFunctionMap.FlushFile = FileHandleFlush;
+ FileFunctionMap.GetFileSize = FileHandleGetSize;
+ }
return (EFI_SUCCESS);
}
return (EFI_NOT_FOUND);
}
+/**
+ Constructor for the Shell library.
+
+ Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.
+
+ @param ImageHandle the image handle of the process
+ @param SystemTable the EFI System Table pointer
+
+ @retval EFI_SUCCESS the initialization was complete sucessfully
+ @return others an error ocurred during initialization
+**/
+EFI_STATUS
+EFIAPI
+ShellLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+
+ mEfiShellEnvironment2 = NULL;
+ mEfiShellProtocol = NULL;
+ mEfiShellParametersProtocol = NULL;
+ mEfiShellInterface = NULL;
+ mEfiShellEnvironment2Handle = NULL;
+
+ ///@todo make a worker constructor so initialize function works
+ //
+ // verify that auto initialize is not set false
+ //
+ if (PcdGetBool(PcdShellLibAutoInitialize) == 0) {
+ return (EFI_SUCCESS);
+ }
+
+ return (ShellLibConstructorWorker(ImageHandle, SystemTable));
+}
/**
Destructory for the library. free any resources.
@@ -212,27 +263,68 @@ ShellLibDestructor (
&gEfiShellEnvironment2Guid,
ImageHandle,
NULL);
+ mEfiShellEnvironment2 = NULL;
}
if (mEfiShellInterface != NULL) {
gBS->CloseProtocol(ImageHandle,
&gEfiShellInterfaceGuid,
ImageHandle,
NULL);
+ mEfiShellInterface = NULL;
}
if (mEfiShellProtocol != NULL) {
gBS->CloseProtocol(ImageHandle,
&gEfiShellProtocolGuid,
ImageHandle,
- NULL);
+ NULL);
+ mEfiShellProtocol = NULL;
}
if (mEfiShellParametersProtocol != NULL) {
gBS->CloseProtocol(ImageHandle,
&gEfiShellParametersProtocolGuid,
ImageHandle,
NULL);
+ mEfiShellParametersProtocol = NULL;
}
+ mEfiShellEnvironment2Handle = NULL;
return (EFI_SUCCESS);
}
+
+/**
+ This function causes the shell library to initialize itself. If the shell library
+ is already initialized it will de-initialize all the current protocol poitners and
+ re-populate them again.
+
+ When the library is used with PcdShellLibAutoInitialize set to true this function
+ will return EFI_SUCCESS and perform no actions.
+
+ This function is intended for internal access for shell commands only.
+
+ @retval EFI_SUCCESS the initialization was complete sucessfully
+
+**/
+EFI_STATUS
+EFIAPI
+ShellInitialize (
+ ) {
+ //
+ // if auto initialize is not false then skip
+ //
+ if (PcdGetBool(PcdShellLibAutoInitialize) != 0) {
+ return (EFI_SUCCESS);
+ }
+
+ //
+ // deinit the current stuff
+ //
+ ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));
+
+ //
+ // init the new stuff
+ //
+ return (ShellLibConstructorWorker(gImageHandle, gST));
+}
+
/**
This function will retrieve the information about the file for the handle
specified and store it in allocated pool memory.
@@ -253,47 +345,7 @@ ShellGetFileInfo (
IN EFI_FILE_HANDLE FileHandle
)
{
- EFI_GUID FileInfoGuid;
- EFI_FILE_INFO *pFileInfo;
- UINTN FileInfoSize;
- EFI_STATUS Status;
-
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
-
- //
- // Get the required size to allocate
- //
- FileInfoGuid = gEfiFileInfoGuid;
- FileInfoSize = 0;
- pFileInfo = NULL;
- Status = FileHandle->GetInfo(FileHandle,
- &FileInfoGuid,
- &FileInfoSize,
- pFileInfo);
- //
- // error is expected. getting size to allocate
- //
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- pFileInfo = AllocateZeroPool(FileInfoSize);
- ASSERT (pFileInfo != NULL);
- //
- // now get the information
- //
- Status = FileHandle->GetInfo(FileHandle,
- &FileInfoGuid,
- &FileInfoSize,
- pFileInfo);
- //
- // if we got an error free the memory and return NULL
- //
- if (EFI_ERROR(Status)) {
- FreePool(pFileInfo);
- return NULL;
- }
- return (pFileInfo);
+ return (FileFunctionMap.GetFileInfo(FileHandle));
}
/**
@@ -321,22 +373,7 @@ ShellSetFileInfo (
IN EFI_FILE_INFO *FileInfo
)
{
- EFI_GUID FileInfoGuid;
-
- //
- // ASSERT if the FileHandle or FileInfo is NULL
- //
- ASSERT (FileHandle != NULL);
- ASSERT (FileInfo != NULL);
-
- FileInfoGuid = gEfiFileInfoGuid;
- //
- // Set the info
- //
- return (FileHandle->SetInfo(FileHandle,
- &FileInfoGuid,
- (UINTN)FileInfo->Size,
- FileInfo));
+ return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));
}
/**
@@ -404,89 +441,90 @@ ShellOpenFileByDevicePath(
Status = ShellOpenFileByName(FileName, FileHandle, OpenMode, Attributes);
FreePool(FileName);
return (Status);
- } else {
+ }
+
+
+ //
+ // use old shell method.
+ //
+ Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid,
+ FilePath,
+ DeviceHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = gBS->OpenProtocol(*DeviceHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &EfiSimpleFileSystemProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);
+ if (EFI_ERROR (Status)) {
+ FileHandle = NULL;
+ return Status;
+ }
+
+ //
+ // go down directories one node at a time.
+ //
+ while (!IsDevicePathEnd (*FilePath)) {
//
- // use old shell method.
+ // For file system access each node should be a file path component
//
- Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid,
- FilePath,
- DeviceHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = gBS->OpenProtocol(*DeviceHandle,
- &gEfiSimpleFileSystemProtocolGuid,
- &EfiSimpleFileSystemProtocol,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);
- if (EFI_ERROR (Status)) {
+ if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
+ ) {
FileHandle = NULL;
- return Status;
+ return (EFI_INVALID_PARAMETER);
}
+ //
+ // Open this file path node
+ //
+ LastHandle = *FileHandle;
+ *FileHandle = NULL;
//
- // go down directories one node at a time.
+ // Try to test opening an existing file
//
- while (!IsDevicePathEnd (*FilePath)) {
- //
- // For file system access each node should be a file path component
- //
- if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
- DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
- ) {
- FileHandle = NULL;
- return (EFI_INVALID_PARAMETER);
- }
- //
- // Open this file path node
- //
- LastHandle = *FileHandle;
- *FileHandle = NULL;
+ Status = LastHandle->Open (
+ LastHandle,
+ FileHandle,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode &~EFI_FILE_MODE_CREATE,
+ 0
+ );
- //
- // Try to test opening an existing file
- //
+ //
+ // see if the error was that it needs to be created
+ //
+ if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
Status = LastHandle->Open (
LastHandle,
FileHandle,
((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
- OpenMode &~EFI_FILE_MODE_CREATE,
- 0
+ OpenMode,
+ Attributes
);
+ }
+ //
+ // Close the last node
+ //
+ LastHandle->Close (LastHandle);
- //
- // see if the error was that it needs to be created
- //
- if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
- Status = LastHandle->Open (
- LastHandle,
- FileHandle,
- ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
- OpenMode,
- Attributes
- );
- }
- //
- // Close the last node
- //
- LastHandle->Close (LastHandle);
-
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- //
- // Get the next node
- //
- *FilePath = NextDevicePathNode (*FilePath);
+ if (EFI_ERROR(Status)) {
+ return (Status);
}
- return (EFI_SUCCESS);
+
+ //
+ // Get the next node
+ //
+ *FilePath = NextDevicePathNode (*FilePath);
}
+ return (EFI_SUCCESS);
}
/**
@@ -544,6 +582,8 @@ ShellOpenFileByName(
return (mEfiShellProtocol->OpenFileByName(FileName,
FileHandle,
OpenMode));
+
+ ///@todo add the attributes
}
//
// Using EFI Shell version
@@ -643,15 +683,7 @@ ShellReadFile(
OUT VOID *Buffer
)
{
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
-
- //
- // Perform the read based on EFI_FILE_PROTOCOL
- //
- return (FileHandle->Read(FileHandle, BufferSize, Buffer));
+ return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));
}
@@ -687,14 +719,7 @@ ShellWriteFile(
IN VOID *Buffer
)
{
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- //
- // Perform the write based on EFI_FILE_PROTOCOL
- //
- return (FileHandle->Write(FileHandle, BufferSize, Buffer));
+ return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));
}
/**
@@ -714,18 +739,7 @@ ShellCloseFile (
IN EFI_FILE_HANDLE *FileHandle
)
{
- EFI_STATUS Status;
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- ASSERT (*FileHandle != NULL);
- //
- // Perform the Close based on EFI_FILE_PROTOCOL
- //
- Status = (*FileHandle)->Close(*FileHandle);
- *FileHandle = NULL;
- return Status;
+ return (FileFunctionMap.CloseFile(*FileHandle));
}
/**
@@ -748,18 +762,7 @@ ShellDeleteFile (
IN EFI_FILE_HANDLE *FileHandle
)
{
- EFI_STATUS Status;
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- ASSERT (*FileHandle != NULL);
- //
- // Perform the Delete based on EFI_FILE_PROTOCOL
- //
- Status = (*FileHandle)->Delete(*FileHandle);
- *FileHandle = NULL;
- return Status;
+ return (FileFunctionMap.DeleteFile(*FileHandle));
}
/**
@@ -788,14 +791,7 @@ ShellSetFilePosition (
IN UINT64 Position
)
{
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- //
- // Perform the SetPosition based on EFI_FILE_PROTOCOL
- //
- return (FileHandle->SetPosition(FileHandle, Position));
+ return (FileFunctionMap.SetFilePosition(FileHandle, Position));
}
/**
@@ -820,14 +816,7 @@ ShellGetFilePosition (
OUT UINT64 *Position
)
{
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- //
- // Perform the GetPosition based on EFI_FILE_PROTOCOL
- //
- return (FileHandle->GetPosition(FileHandle, Position));
+ return (FileFunctionMap.GetFilePosition(FileHandle, Position));
}
/**
Flushes data on a file
@@ -849,69 +838,7 @@ ShellFlushFile (
IN EFI_FILE_HANDLE FileHandle
)
{
- //
- // ASSERT if FileHandle is NULL
- //
- ASSERT (FileHandle != NULL);
- //
- // Perform the Flush based on EFI_FILE_PROTOCOL
- //
- return (FileHandle->Flush(FileHandle));
-}
-
-/**
- function to determine if a given handle is a directory handle
-
- if DirHandle is NULL then ASSERT()
-
- open the file information on the DirHandle and verify that the Attribute
- includes EFI_FILE_DIRECTORY bit set.
-
- @param DirHandle Handle to open file
-
- @retval EFI_SUCCESS DirHandle is a directory
- @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available
- @retval EFI_NOT_FOUND DirHandle is not a directory
-**/
-EFI_STATUS
-EFIAPI
-InternalShellIsDirectory (
- IN EFI_FILE_HANDLE DirHandle
- )
-{
- EFI_FILE_INFO *DirInfo;
-
- //
- // ASSERT if DirHandle is NULL
- //
- ASSERT(DirHandle != NULL);
-
- //
- // get the file information for DirHandle
- //
- DirInfo = ShellGetFileInfo (DirHandle);
-
- //
- // Parse DirInfo
- //
- if (DirInfo == NULL) {
- //
- // We got nothing...
- //
- return (EFI_INVALID_PARAMETER);
- }
- if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
- //
- // Attributes say this is not a directory
- //
- FreePool (DirInfo);
- return (EFI_NOT_FOUND);
- }
- //
- // all good...
- //
- FreePool (DirInfo);
- return (EFI_SUCCESS);
+ return (FileFunctionMap.FlushFile(FileHandle));
}
/**
@@ -936,49 +863,13 @@ EFI_STATUS
EFIAPI
ShellFindFirstFile (
IN EFI_FILE_HANDLE DirHandle,
- OUT EFI_FILE_INFO *Buffer
+ OUT EFI_FILE_INFO **Buffer
)
{
- EFI_STATUS Status;
- UINTN BufferSize;
-
- //
- // ASSERT if DirHandle is NULL
- //
- ASSERT (DirHandle != NULL);
-
- //
- // verify that DirHandle is a directory
- //
- Status = InternalShellIsDirectory(DirHandle);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- //
- // reset to the begining of the directory
- //
- Status = ShellSetFilePosition (DirHandle, 0);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
//
- // Allocate a buffer sized to struct size + enough for the string at the end
+ // pass to file handle lib
//
- BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
- Buffer = AllocateZeroPool(BufferSize);
- ASSERT (Buffer != NULL);
-
- //
- // read in the info about the first file
- //
- Status = ShellReadFile (DirHandle, &BufferSize, Buffer);
- ASSERT(Status != EFI_BUFFER_TOO_SMALL);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
- return (EFI_SUCCESS);
+ return (FileHandleFindFirstFile(DirHandle, Buffer));
}
/**
Retrieves the next file in a directory.
@@ -1007,47 +898,10 @@ ShellFindNextFile(
OUT BOOLEAN *NoFile
)
{
- EFI_STATUS Status;
- UINTN BufferSize;
-
//
- // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL
+ // pass to file handle lib
//
- ASSERT (DirHandle != NULL);
- ASSERT (Buffer != NULL);
- ASSERT (NoFile != NULL);
-
- //
- // verify that DirHandle is a directory
- //
- Status = InternalShellIsDirectory(DirHandle);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- //
- // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile
- //
- BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
-
- //
- // read in the info about the next file
- //
- Status = ShellReadFile (DirHandle, &BufferSize, Buffer);
- ASSERT(Status != EFI_BUFFER_TOO_SMALL);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- //
- // If we read 0 bytes (but did not have erros) we already read in the last file.
- //
- if (BufferSize == 0) {
- FreePool(Buffer);
- *NoFile = TRUE;
- }
-
- return (EFI_SUCCESS);
+ return (FileHandleFindNextFile(DirHandle, Buffer, NoFile));
}
/**
Retrieve the size of a file.
@@ -1071,33 +925,7 @@ ShellGetFileSize (
OUT UINT64 *Size
)
{
- EFI_FILE_INFO *FileInfo;
-
- //
- // ASSERT for FileHandle or Size being NULL
- //
- ASSERT (FileHandle != NULL);
- ASSERT (Size != NULL);
-
- //
- // get the FileInfo structure
- //
- FileInfo = ShellGetFileInfo(FileHandle);
- if (FileInfo == NULL) {
- return (EFI_DEVICE_ERROR);
- }
-
- //
- // Assign the Size pointer to the correct value
- //
- *Size = FileInfo->FileSize;
-
- //
- // free the FileInfo memory
- //
- FreePool(FileInfo);
-
- return (EFI_SUCCESS);
+ return (FileFunctionMap.GetFileSize(FileHandle, Size));
}
/**
Retrieves the status of the break execution flag
@@ -1366,7 +1194,7 @@ ShellSetPageBreakMode (
/// This allows for the struct to be populated.
///
typedef struct {
- EFI_LIST_ENTRY Link;
+ LIST_ENTRY Link;
EFI_STATUS Status;
CHAR16 *FullName;
CHAR16 *FileName;
@@ -1390,12 +1218,12 @@ typedef struct {
LIST_ENTRY*
EFIAPI
InternalShellConvertFileListType (
- EFI_LIST_ENTRY *FileList
+ LIST_ENTRY *FileList
)
{
LIST_ENTRY *ListHead;
SHELL_FILE_ARG *OldInfo;
- EFI_LIST_ENTRY *Link;
+ LIST_ENTRY *Link;
EFI_SHELL_FILE_INFO_NO_CONST *NewInfo;
//
@@ -1406,14 +1234,14 @@ InternalShellConvertFileListType (
//
// Allocate our list head and initialize the list
//
- ListHead = AllocateZeroPool(sizeof(EFI_LIST_ENTRY));
+ ListHead = AllocateZeroPool(sizeof(LIST_ENTRY));
ASSERT (ListHead != NULL);
ListHead = InitializeListHead (ListHead);
//
// enumerate through each member of the old list and copy
//
- for (Link = FileList->Flink; Link != FileList; Link = Link->Flink) {
+ for (Link = FileList->ForwardLink; Link != FileList; Link = Link->ForwardLink) {
OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
//
@@ -1435,6 +1263,9 @@ InternalShellConvertFileListType (
NewInfo->Handle = OldInfo->Handle;
NewInfo->Status = OldInfo->Status;
+ // old shell checks for 0 not NULL
+ OldInfo->Handle = 0;
+
//
// allocate new space to copy strings and structure
//
@@ -1497,15 +1328,8 @@ ShellOpenFileMetaArg (
{
EFI_STATUS Status;
LIST_ENTRY *EmptyNode;
-
- //
- // make sure we have no outstanding list
- //
- if (mOldStyleFileList != NULL) {
- *ListHead = NULL;
- return (EFI_UNSUPPORTED);
- }
-
+ LIST_ENTRY *mOldStyleFileList;
+
//
// ASSERT that Arg and ListHead are not NULL
//
@@ -1529,7 +1353,7 @@ ShellOpenFileMetaArg (
//
// allocate memory for old list head
//
- mOldStyleFileList = (EFI_LIST_ENTRY*)AllocatePool(sizeof(EFI_LIST_ENTRY));
+ mOldStyleFileList = (LIST_ENTRY*)AllocatePool(sizeof(LIST_ENTRY));
ASSERT(mOldStyleFileList != NULL);
//
@@ -1552,6 +1376,13 @@ ShellOpenFileMetaArg (
EmptyNode = InternalShellConvertFileListType(mOldStyleFileList);
//
+ // Free the EFI Shell version that was converted.
+ //
+ ASSERT_EFI_ERROR(mEfiShellEnvironment2->FreeFileList(mOldStyleFileList));
+ FreePool(mOldStyleFileList);
+ mOldStyleFileList = NULL;
+
+ //
// remove the empty head of the list
//
*ListHead = (EFI_SHELL_FILE_INFO*)RemoveEntryList(EmptyNode);
@@ -1588,18 +1419,12 @@ ShellCloseFileMetaArg (
return (mEfiShellProtocol->FreeFileList(ListHead));
} else {
//
- // Free the EFI Shell version that was converted.
- //
- ASSERT_EFI_ERROR(mEfiShellEnvironment2->FreeFileList(mOldStyleFileList));
- FreePool(mOldStyleFileList);
- mOldStyleFileList = NULL;
-
- //
// Since this is EFI Shell version we need to free our internally made copy
// of the list
//
for (Node = GetFirstNode((LIST_ENTRY*)*ListHead) ; IsListEmpty((LIST_ENTRY*)*ListHead) == FALSE ; Node = GetFirstNode((LIST_ENTRY*)*ListHead)) {
RemoveEntryList(Node);
+ ((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle->Close(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Handle);
FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FullName);
FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->FileName);
FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Info);
@@ -1610,7 +1435,7 @@ ShellCloseFileMetaArg (
}
typedef struct {
- EFI_LIST_ENTRY List;
+ LIST_ENTRY List;
CHAR16 *Name;
ParamType Type;
CHAR16 *Value;
@@ -1634,7 +1459,7 @@ typedef struct {
**/
BOOLEAN
EFIAPI
-IsCheckList (
+InternalIsOnCheckList (
IN CONST CHAR16 *Name,
IN CONST SHELL_PARAM_ITEM *CheckList,
OUT ParamType *Type
@@ -1650,6 +1475,15 @@ IsCheckList (
ASSERT(Name != NULL);
//
+ // question mark and page break mode are always supported
+ //
+ if ((StrCmp(Name, L"-?") == 0) ||
+ (StrCmp(Name, L"-b") == 0)
+ ) {
+ return (TRUE);
+ }
+
+ //
// Enumerate through the list
//
for (TempListItem = (SHELL_PARAM_ITEM*)CheckList ; TempListItem->Name != NULL ; TempListItem++) {
@@ -1664,7 +1498,7 @@ IsCheckList (
return (FALSE);
}
/**
- Checks the string for indicators of "flag" status. this is a leading '/' or '-'
+ Checks the string for indicators of "flag" status. this is a leading '/', '-', or '+'
@param Name pointer to Name of parameter found
@@ -1673,7 +1507,7 @@ IsCheckList (
**/
BOOLEAN
EFIAPI
-IsFlag (
+InternalIsFlag (
IN CONST CHAR16 *Name
)
{
@@ -1685,7 +1519,10 @@ IsFlag (
//
// If the Name has a / or - as the first character return TRUE
//
- if ((Name[0] == L'/') || (Name[0] == L'-') ) {
+ if ((Name[0] == L'/') ||
+ (Name[0] == L'-') ||
+ (Name[0] == L'+')
+ ) {
return (TRUE);
}
return (FALSE);
@@ -1699,7 +1536,8 @@ IsFlag (
@param CheckList pointer to list of parameters to check
@param CheckPackage pointer to pointer to list checked values
@param ProblemParam optional pointer to pointer to unicode string for
- the paramater that caused failure.
+ the paramater that caused failure. If used then the
+ caller is responsible for freeing the memory.
@param AutoPageBreak will automatically set PageBreakEnabled for "b" parameter
@param Argc Count of parameters in Argv
@param Argv pointer to array of parameters
@@ -1774,7 +1612,7 @@ InternalCommandLineParse (
ASSERT(CurrentItemPackage->Value != NULL);
StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);
InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);
- } else if (IsFlag(Argv[LoopCounter]) == FALSE) {
+ } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {
//
// add this one as a non-flag
//
@@ -1787,7 +1625,7 @@ InternalCommandLineParse (
StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);
CurrentItemPackage->OriginalPosition = Count++;
InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage);
- } else if (IsCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {
+ } else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {
//
// this is a flag
//
@@ -1818,7 +1656,9 @@ InternalCommandLineParse (
//
// this was a non-recognised flag... error!
//
- *ProblemParam = (CHAR16*)Argv[LoopCounter];
+ *ProblemParam = AllocatePool(StrSize(Argv[LoopCounter]));
+ ASSERT(*ProblemParam != NULL);
+ StrCpy(*ProblemParam, Argv[LoopCounter]);
ShellCommandLineFreeVarList(*CheckPackage);
*CheckPackage = NULL;
return (EFI_VOLUME_CORRUPTED);
diff --git a/ShellPkg/Library/BaseShellLib/BaseShellLib.h b/ShellPkg/Library/BaseShellLib/BaseShellLib.h
new file mode 100644
index 0000000..1620641
--- /dev/null
+++ b/ShellPkg/Library/BaseShellLib/BaseShellLib.h
@@ -0,0 +1,26 @@
+/** @file
+ Provides interface to shell functionality for shell commands and applications.
+
+Copyright (c) 2006 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+typedef struct {
+ EFI_SHELL_GET_FILE_INFO GetFileInfo;
+ EFI_SHELL_SET_FILE_INFO SetFileInfo;
+ EFI_SHELL_READ_FILE ReadFile;
+ EFI_SHELL_WRITE_FILE WriteFile;
+ EFI_SHELL_CLOSE_FILE CloseFile;
+ EFI_SHELL_DELETE_FILE DeleteFile;
+ EFI_SHELL_GET_FILE_POSITION GetFilePosition;
+ EFI_SHELL_SET_FILE_POSITION SetFilePosition;
+ EFI_SHELL_FLUSH_FILE FlushFile;
+ EFI_SHELL_GET_FILE_SIZE GetFileSize;
+} FILE_HANDLE_FUNCTION_MAP;
diff --git a/ShellPkg/Library/BaseShellLib/BaseShellLib.inf b/ShellPkg/Library/BaseShellLib/BaseShellLib.inf
index 8a2c33b..71c68cb 100644
--- a/ShellPkg/Library/BaseShellLib/BaseShellLib.inf
+++ b/ShellPkg/Library/BaseShellLib/BaseShellLib.inf
@@ -29,6 +29,7 @@
[Sources.common]
BaseShellLib.c
+ BaseShellLib.h
[Packages]
MdePkg/MdePkg.dec
@@ -41,6 +42,7 @@
BaseLib
BaseMemoryLib
DebugLib
+ FileHandleLib
[Protocols]
gEfiSimpleFileSystemProtocolGuid # ALWAYS_CONSUMED
@@ -58,4 +60,4 @@
gEfiShellEnvironment2ExtGuid # ALWAYS_CONSUMED
[Pcd.common]
-
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize # ALWAYS_CONSUMED
diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec
index 922ad5e..65b62a0 100644
--- a/ShellPkg/ShellPkg.dec
+++ b/ShellPkg/ShellPkg.dec
@@ -20,7 +20,7 @@
DEC_SPECIFICATION = 0x00010005
PACKAGE_NAME = ShellPkg
PACKAGE_GUID = 9FB7587C-93F7-40a7-9C04-FD7BA94EE646
- PACKAGE_VERSION = 0.1
+ PACKAGE_VERSION = 0.2
[Includes.common]
@@ -32,8 +32,15 @@
##
ShellLib|Include/Library/ShellLib.h
+ ## @libraryclass provides EFI_FILE_HANDLE services
+ ## used by Shell and ShellLib
+ ##
+ FileHandleLib|Include/Library/FileHandleLib.h
+
+
[Guids.common]
gEfiShellEnvironment2ExtGuid = {0xd2c18636, 0x40e5, 0x4eb5, {0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87}}
+ gEfiShellPkgTokenSpaceGuid = {0x171e9188, 0x31d3, 0x40f5, {0xb1, 0x0c, 0x53, 0x9b, 0x2d, 0xb9, 0x40, 0xcd}}
[Protocols.common]
gEfiShellProtocolGuid = {0x6302d008, 0x7f9b, 0x4f30, {0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}}
@@ -41,10 +48,7 @@
gEfiShellEnvironment2Guid = {0x47c7b221, 0xc42a, 0x11d2, {0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
gEfiShellInterfaceGuid = {0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
-[PcdsFeatureFlag.common]
-
-[PcdsFixedAtBuild.common]
-
-[PcdsPatchableInModule.common]
-
-[PcdsDynamic.common] \ No newline at end of file
+[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
+ ## This flag is used to control initialization of the shell library
+ ## This should be FALSE for compiling the shell application itself onlty.
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|TRUE|BOOLEAN|0x00000005 \ No newline at end of file
diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc
index ebe872a..787c374 100644
--- a/ShellPkg/ShellPkg.dsc
+++ b/ShellPkg/ShellPkg.dsc
@@ -1,8 +1,5 @@
#/** @file
# Shell Package
-# This is the first release of the Shell package. Please be aware that there will
-# probably be higher than usual numbers of changes as the package gets used and issues,
-# enhancements, and bugs are found and fixed.
#
# Copyright (c) 2007 - 2008, Intel Corporation
#
@@ -19,8 +16,8 @@
[Defines]
PLATFORM_NAME = Shell
PLATFORM_GUID = E1DC9BF8-7013-4c99-9437-795DAA45F3BD
- PLATFORM_VERSION = 0.1
- DSC_SPECIFICATION = 0x00010005
+ PLATFORM_VERSION = 0.2
+ DSC_SPECIFICATION = 0x00010006
OUTPUT_DIRECTORY = Build/Shell
SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC
BUILD_TARGETS = DEBUG|RELEASE
@@ -35,14 +32,15 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
- BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
PrintLib|MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
ShellLib|ShellPkg/Library/BaseShellLib/BaseShellLib.inf
+ FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
[PcdsFixedAtBuild.common]
[Components.common]
- ShellPkg/Library/BaseShellLib/BaseShellLib.inf
ShellPkg/Application/ShellExecTestApp/SA.inf
ShellPkg/Application/ShellLibTestApp/SA3.inf \ No newline at end of file