From: jcarsey Date: Thu, 7 May 2009 18:46:18 +0000 (+0000) Subject: First (Alpha) release of ShellPkg X-Git-Tag: edk2-stable201903~18011 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=94b17fa1b669e55482efc7a8faec8c95e05d86ec First (Alpha) release of ShellPkg git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8256 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/ShellPkg/Application/ShellExecTestApp/SA.C b/ShellPkg/Application/ShellExecTestApp/SA.C new file mode 100644 index 0000000000..7db28f64cb --- /dev/null +++ b/ShellPkg/Application/ShellExecTestApp/SA.C @@ -0,0 +1,38 @@ +/** @file + This is a simple shell application + + Copyright (c) 2008, 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 +#include +#include + +/** + as the real entry point for the application. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + Print(L"ShellExecute - Pass"); + return EFI_SUCCESS; +} \ No newline at end of file diff --git a/ShellPkg/Application/ShellExecTestApp/SA.inf b/ShellPkg/Application/ShellExecTestApp/SA.inf new file mode 100644 index 0000000000..0384eaa712 --- /dev/null +++ b/ShellPkg/Application/ShellExecTestApp/SA.inf @@ -0,0 +1,50 @@ +#/** @file +# Sample UEFI Application Reference EDKII Module +# +# This is a simple shell application +# +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmptyApplication + FILE_GUID = 8F7D7B1D-0E1C-4c98-B12E-4EC99C4081AC + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + SA.C + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] diff --git a/ShellPkg/Application/ShellLibTestApp/SA3.inf b/ShellPkg/Application/ShellLibTestApp/SA3.inf new file mode 100644 index 0000000000..dbfa783353 --- /dev/null +++ b/ShellPkg/Application/ShellLibTestApp/SA3.inf @@ -0,0 +1,54 @@ +#/** @file +# Sample UEFI Application Reference EDKII Module +# +# This is a simple shell application +# +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SimpleApplication + FILE_GUID = 10C75C00-3052-4467-9ED8-7196CAAF610F + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + sa3.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + ShellLib + MemoryAllocationLib + DebugLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] diff --git a/ShellPkg/Application/ShellLibTestApp/sa3.c b/ShellPkg/Application/ShellLibTestApp/sa3.c new file mode 100644 index 0000000000..ae677b4dfa --- /dev/null +++ b/ShellPkg/Application/ShellLibTestApp/sa3.c @@ -0,0 +1,336 @@ +/** @file + This is a simple shell application + + This should be executed with "/Param2 Val1" and "/Param1" as the 2 command line options! + + Copyright (c) 2008, 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 +#include +#include +#include +#include +#include + +SHELL_PARAM_ITEM ParamList[] = { + {L"/Param1", TypeFlag}, + {L"/Param2", TypeValue}, + {NULL, TypeMax}}; + +/** + as the real entry point for the application. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_FILE_HANDLE FileHandle; + EFI_STATUS Status; + CHAR16 FileName[100]; + UINTN BufferSize; + UINT64 Position; + UINT8 Buffer[200]; + EFI_FILE_INFO *pFileInfo; + UINT64 Size; + BOOLEAN NoFile; + EFI_SHELL_FILE_INFO *pShellFileInfo, *pShellFileInfo2; + LIST_ENTRY *List; + + FileHandle = NULL; + StrCpy(FileName, L"testfile.txt"); + Position = 0; + pFileInfo = NULL; + Size = 0; + NoFile = FALSE; + pShellFileInfo = NULL; + List = NULL; + + ASSERT(ShellGetExecutionBreakFlag() == FALSE); + ASSERT(StrCmp(ShellGetCurrentDir(NULL), L"f8:\\") == 0); + Print(L"execution break and get cur dir - pass\r\n"); + + ShellSetPageBreakMode(TRUE); + + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + + BufferSize = StrSize(FileName); + Status = ShellWriteFile(FileHandle, &BufferSize, FileName); + ASSERT_EFI_ERROR(Status); + Status = ShellGetFilePosition(FileHandle, &Position); + ASSERT_EFI_ERROR(Status); + ASSERT(Position == 0x1A); + Status = ShellSetFilePosition(FileHandle, 0); + ASSERT_EFI_ERROR(Status); + BufferSize = sizeof(Buffer) * sizeof(Buffer[0]); + Status = ShellReadFile(FileHandle, &BufferSize, Buffer); + ASSERT_EFI_ERROR(Status); + ASSERT(BufferSize == 0x1A); + ASSERT(StrCmp((CHAR16*)Buffer, FileName) == 0); + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + ASSERT(StrCmp(pFileInfo->FileName, FileName) == 0); + ASSERT(pFileInfo->FileSize == 0x1A); + FreePool(pFileInfo); + pFileInfo = NULL; + Status = ShellCloseFile(&FileHandle); + ASSERT(FileHandle == NULL); + ASSERT_EFI_ERROR(Status); + Print(L"read, write, create, getinfo - pass\r\n"); + + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + pFileInfo->FileSize = 0x20; + Status = ShellSetFileInfo(FileHandle, pFileInfo); + FreePool(pFileInfo); + pFileInfo = NULL; + ASSERT_EFI_ERROR(Status); + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + ASSERT(StrCmp(pFileInfo->FileName, FileName) == 0); + ASSERT(pFileInfo->PhysicalSize == 0x20); + ASSERT(pFileInfo->FileSize == 0x20); + ASSERT((pFileInfo->Attribute&EFI_FILE_DIRECTORY)==0); + FreePool(pFileInfo); + Status = ShellGetFileSize(FileHandle, &Size); + 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"); + + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + ASSERT(StrCmp(pFileInfo->FileName, FileName) == 0); + ASSERT(pFileInfo->PhysicalSize == 0x20); + ASSERT(pFileInfo->FileSize == 0x20); + ASSERT((pFileInfo->Attribute&EFI_FILE_DIRECTORY)==0); + FreePool(pFileInfo); + pFileInfo = NULL; + Status = ShellDeleteFile(&FileHandle); + ASSERT(FileHandle == NULL); + ASSERT_EFI_ERROR(Status); + Print(L"reopen file - pass\r\n"); + + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + ASSERT(StrCmp(pFileInfo->FileName, FileName) == 0); + ASSERT(pFileInfo->PhysicalSize == 0x0); + ASSERT(pFileInfo->FileSize == 0x0); + 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"); + + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT(Status == EFI_NOT_FOUND); + ASSERT(FileHandle == NULL); + + Status = ShellCreateDirectory(FileName, &FileHandle); + ASSERT_EFI_ERROR(Status); + ASSERT(FileHandle != NULL); + pFileInfo = ShellGetFileInfo(FileHandle); + ASSERT(pFileInfo != NULL); + 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"); + + // FindFirst and FindNext + StrCpy(FileName, L"testDir"); + Status = ShellCreateDirectory(FileName, &FileHandle); + Status = ShellCloseFile(&FileHandle); + StrCat(FileName, L"\\File.txt"); + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + Status = ShellCloseFile(&FileHandle); + StrCpy(FileName, L"testDir"); + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + Status = ShellFindFirstFile(FileHandle, pFileInfo); + ASSERT_EFI_ERROR(Status); + Status = ShellFindNextFile(FileHandle, pFileInfo, &NoFile); + ASSERT_EFI_ERROR(Status); + ASSERT(NoFile == FALSE); + Status = ShellFindNextFile(FileHandle, pFileInfo, &NoFile); + ASSERT_EFI_ERROR(Status); + ASSERT(NoFile == FALSE); + Status = ShellFindNextFile(FileHandle, pFileInfo, &NoFile); + 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"); + + // open and close meta arg + Status = ShellOpenFileMetaArg(L"testDir\\*.*", EFI_FILE_MODE_READ, &pShellFileInfo); + ASSERT_EFI_ERROR(Status); + ASSERT(pShellFileInfo->Status == 0); + ASSERT(StrCmp(pShellFileInfo->FileName, L"File.txt") == 0); + ASSERT(pShellFileInfo->Handle); + ASSERT(pShellFileInfo->Info); + 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"); + + // now delete that file and that directory + StrCat(FileName, L"\\File.txt"); + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + ASSERT_EFI_ERROR(Status); + Status = ShellDeleteFile(&FileHandle); + ASSERT(FileHandle == NULL); + StrCpy(FileName, L"testDir"); + ASSERT_EFI_ERROR(Status); + Status = ShellOpenFileByName(FileName, + &FileHandle, + EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, + 0 + ); + Status = ShellDeleteFile(&FileHandle); + ASSERT(FileHandle == NULL); + ASSERT_EFI_ERROR(Status); + + // get environment variable + // made for testing under nt32 + ASSERT(StrCmp(ShellGetEnvironmentVariable(L"path"), L".;f8:\\efi\\tools;f8:\\efi\\boot;f8:\\;f9:\\efi\\tools;f9:\\efi\\boot;f9:\\") == 0); + Print(L"ShellGetEnvironmentVariable - pass\r\n"); + + // set environment variable + Status = ShellSetEnvironmentVariable(L"", L"", FALSE); + ASSERT(Status == EFI_UNSUPPORTED); + Print(L"ShellSetEnvironmentVariable - pass\r\n"); + + // ShellExecute + Status = ShellExecute(&ImageHandle, L"EmptyApplication.efi", TRUE, NULL, NULL); + ASSERT_EFI_ERROR(Status); + // the pass printout for this is performed by EmptyApplication + Print(L"\r\n"); + + // command line param functions + Status = ShellCommandLineParse(ParamList, &List, NULL, FALSE); + // if you put an invalid parameter you SHOULD hit this assert. + ASSERT_EFI_ERROR(Status); + if (List) { + 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); + + ShellCommandLineFreeVarList(List); + } else { + Print(L"param checking skipped.\r\n"); + } + + // page break mode (done last so we can see the results) + // we set this true at the begining of the program + // this is enough lines to trigger the page... + Print(L"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n"); + ShellSetPageBreakMode(FALSE); + Print(L"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n"); + + return EFI_SUCCESS; +} + + +/* +done - ShellGetFileInfo +done - ShellSetFileInfo +done - ShellOpenFileByDevicePath +done - ShellOpenFileByName +done - ShellCreateDirectory +done - ShellReadFile +done - ShellWriteFile +done - ShellCloseFile +done - ShellDeleteFile +done - ShellSetFilePosition +done - ShellGetFilePosition +???? - ShellFlushFile +done - ShellFindFirstFile +done - ShellFindNextFile +done - ShellGetFileSize +done - ShellGetExecutionBreakFlag +done - ShellGetEnvironmentVariable +done - ShellSetEnvironmentVariable +done - ShellExecute +done - ShellGetCurrentDir +done - ShellSetPageBreakMode +done - ShellOpenFileMetaArg +done - ShellCloseFileMetaArg +done - ShellCommandLineParse +done - ShellCommandLineFreeVarList +done - ShellCommandLineGetFlag +done - ShellCommandLineGetValue +done - ShellCommandLineGetRawValue +*/ \ No newline at end of file diff --git a/ShellPkg/Include/Library/ShellLib.h b/ShellPkg/Include/Library/ShellLib.h new file mode 100644 index 0000000000..f5e5ba60de --- /dev/null +++ b/ShellPkg/Include/Library/ShellLib.h @@ -0,0 +1,729 @@ +/** @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. + +**/ + +#if !defined(__SHELL_LIB__) +#define __SHELL_LIB__ + +#include +#include +#include + +/** + 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 +ShellGetFileInfo ( + 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 +ShellSetFileInfo ( + IN EFI_FILE_HANDLE FileHandle, + IN EFI_FILE_INFO *FileInfo + ); + +/** + This function will open a file or directory referenced by DevicePath. + + This function opens a file with the open mode according to the file path. The + Attributes is valid only for EFI_FILE_MODE_CREATE. + + @param FilePath on input the device path to the file. On output + the remaining device path. + @param DeviceHandle pointer to the system device handle. + @param FileHandle pointer to the file handle. + @param OpenMode the mode to open the file with. + @param Attributes the file's file attributes. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found on + the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +ShellOpenFileByDevicePath( + IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, + OUT EFI_HANDLE *DeviceHandle, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + This function will open a file or directory referenced by filename. + + If return is EFI_SUCCESS, the Filehandle is the opened file’s handle; + otherwise, the Filehandle is NULL. The Attributes is valid only for + EFI_FILE_MODE_CREATE. + + @param FileName pointer to file name + @param FileHandle pointer to the file handle. + @param OpenMode the mode to open the file with. + @param Attributes the file's file attributes. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found + on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +ShellOpenFileByName( + IN CHAR16 *FilePath, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + This function create a directory + + If return is EFI_SUCCESS, the Filehandle is the opened directory's handle; + otherwise, the Filehandle is NULL. If the directory already existed, this + function opens the existing directory. + + @param DirectoryName pointer to Directory name + @param FileHandle pointer to the file handle. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found + on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +ShellCreateDirectory( + IN CHAR16 *DirectoryName, + OUT EFI_FILE_HANDLE *FileHandle + ); + +/** + 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 ReadSize 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 +ShellReadFile( + IN EFI_FILE_HANDLE FileHandle, + IN OUT UINTN *ReadSize, + 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 +ShellWriteFile( + IN EFI_FILE_HANDLE FileHandle, + IN OUT UINTN *BufferSize, + IN CONST 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. +@retval INVALID_PARAMETER One of the parameters has an invalid value. +**/ +EFI_STATUS +EFIAPI +ShellCloseFile ( + 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 +ShellDeleteFile ( + 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 +ShellSetFilePosition ( + 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 +ShellGetFilePosition ( + 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 +ShellFlushFile ( + IN EFI_FILE_HANDLE FileHandle + ); + +/** + Retrieves the first file from a directory + + This function takes an open directory handle and gets the first file + in the directory's info. Caller can use ShellFindNextFile() to get + subsequent files. + + @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 ShellReadFile +**/ +EFI_STATUS +EFIAPI +ShellFindFirstFile ( + 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 ShellFindFirstFile() 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 ShellFindNextFile() 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 + data in Buffer is meaningless. + + @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. + @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 +ShellFindNextFile( + IN EFI_FILE_HANDLE DirHandle, + OUT EFI_FILE_INFO *Buffer, + OUT BOOLEAN *NoFile + ); + +/** + Retrieve the size of a file. + + 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 +ShellGetFileSize ( + IN EFI_FILE_HANDLE FileHandle, + OUT UINT64 *Size + ); + +/** + Retrieves the status of the break execution flag + + this function is useful to check whether the application is being asked to halt by the shell. + + @retval TRUE the execution break is enabled + @retval FALSE the execution break is not enabled +**/ +BOOLEAN +EFIAPI +ShellGetExecutionBreakFlag( + VOID + ); + +/** + return the value of an environment variable + + this function gets the value of the environment variable set by the + ShellSetEnvironmentVariable function + + @param EnvKey The key name of the environment variable. + + @retval NULL the named environment variable does not exist. + @return != NULL pointer to the value of the environment variable +**/ +CONST CHAR16* +EFIAPI +ShellGetEnvironmentVariable ( + IN CHAR16 *EnvKey + ); + +/** + set the value of an environment variable + +This function changes the current value of the specified environment variable. If the +environment variable exists and the Value is an empty string, then the environment +variable is deleted. If the environment variable exists and the Value is not an empty +string, then the value of the environment variable is changed. If the environment +variable does not exist and the Value is an empty string, there is no action. If the +environment variable does not exist and the Value is a non-empty string, then the +environment variable is created and assigned the specified value. + + This is not supported pre-UEFI Shell 2.0. + + @param EnvKey The key name of the environment variable. + @param EnvVal The Value of the environment variable + @param Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE). + + @retval EFI_SUCCESS the operation was completed sucessfully + @retval EFI_UNSUPPORTED This operation is not allowed in pre UEFI 2.0 Shell environments +**/ +EFI_STATUS +EFIAPI +ShellSetEnvironmentVariable ( + IN CONST CHAR16 *EnvKey, + IN CONST CHAR16 *EnvVal, + IN BOOLEAN Volatile + ); + +/** + cause the shell to parse and execute a command line. + + This function creates a nested instance of the shell and executes the specified +command (CommandLine) with the specified environment (Environment). Upon return, +the status code returned by the specified command is placed in StatusCode. +If Environment is NULL, then the current environment is used and all changes made +by the commands executed will be reflected in the current environment. If the +Environment is non-NULL, then the changes made will be discarded. +The CommandLine is executed from the current working directory on the current +device. + +EnvironmentVariables and Status are only supported for UEFI Shell 2.0. +Output is only supported for pre-UEFI Shell 2.0 + + @param ImageHandle Parent image that is starting the operation + @param CommandLine pointer to null terminated command line. + @param Output true to display debug output. false to hide it. + @param EnvironmentVariables optional pointer to array of environment variables + in the form "x=y". if NULL current set is used. + @param Status the status of the run command line. + + @retval EFI_SUCCESS the operation completed sucessfully. Status + contains the status code returned. + @retval EFI_INVALID_PARAMETER a parameter contains an invalid value + @retval EFI_OUT_OF_RESOURCES out of resources + @retval EFI_UNSUPPORTED the operation is not allowed. +**/ +EFI_STATUS +EFIAPI +ShellExecute ( + IN EFI_HANDLE *ParentHandle, + IN CHAR16 *CommandLine, + IN BOOLEAN Output, + IN CHAR16 **EnvironmentVariables, + OUT EFI_STATUS *Status + ); + +/** + Retreives the current directory path + + If the DeviceName is NULL, it returns the current device’s current directory + name. If the DeviceName is not NULL, it returns the current directory name + on specified drive. + + @param DeviceName the name of the drive to get directory on + + @retval NULL the directory does not exist + @return != NULL the directory +**/ +CONST CHAR16* +EFIAPI +ShellGetCurrentDir ( + IN CHAR16 *DeviceName OPTIONAL + ); + +/** + sets (enabled or disabled) the page break mode + + when page break mode is enabled the screen will stop scrolling + and wait for operator input before scrolling a subsequent screen. + + @param CurrentState TRUE to enable and FALSE to disable +**/ +VOID +EFIAPI +ShellSetPageBreakMode ( + IN BOOLEAN CurrentState + ); + +/** + Opens a group of files based on a path. + + This function uses the Arg to open all the matching files. Each matched + file has a SHELL_FILE_ARG structure to record the file information. These + structures are placed on the list ListHead. Users can get the SHELL_FILE_ARG + structures from ListHead to access each file. This function supports wildcards + and will process '?' and '*' as such. the list must be freed with a call to + ShellCloseFileMetaArg(). + + This function will fail if called sequentially without freeing the list in the middle. + + @param Arg pointer to path string + @param OpenMode mode to open files with + @param ListHead head of linked list of results + + @retval EFI_SUCCESS the operation was sucessful and the list head + contains the list of opened files + #retval EFI_UNSUPPORTED a previous ShellOpenFileMetaArg must be closed first. + *ListHead is set to NULL. + @return != EFI_SUCCESS the operation failed + + @sa InternalShellConvertFileListType +**/ +EFI_STATUS +EFIAPI +ShellOpenFileMetaArg ( + IN CHAR16 *Arg, + IN UINT64 OpenMode, + IN OUT EFI_SHELL_FILE_INFO **ListHead + ); + +/** + Free the linked list returned from ShellOpenFileMetaArg + + @param ListHead the pointer to free + + @retval EFI_SUCCESS the operation was sucessful + @retval EFI_INVALID_PARAMETER A parameter was invalid +**/ +EFI_STATUS +EFIAPI +ShellCloseFileMetaArg ( + IN OUT EFI_SHELL_FILE_INFO **ListHead + ); + +typedef enum { + TypeFlag = 0, + TypeValue, + TypePosition, + TypeMax, +} ParamType; + +typedef struct { + CHAR16 *Name; + ParamType Type; +} SHELL_PARAM_ITEM; + +/** + Checks the command line arguments passed against the list of valid ones. + Optionally removes NULL values first. + + If no initialization is required, then return RETURN_SUCCESS. + + @param CheckList pointer to list of parameters to check + @param CheckPackage Package of checked values + @param ProblemParam optional pointer to pointer to unicode string for + the paramater that caused failure. + @param AutoPageBreak will automatically set PageBreakEnabled + + @retval EFI_SUCCESS The operation completed sucessfully. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed + @retval EFI_INVALID_PARAMETER A parameter was invalid + @retval EFI_VOLUME_CORRUPTED the command line was corrupt. an argument was + duplicated. the duplicated command line argument + was returned in ProblemParam if provided. + @retval EFI_DEVICE_ERROR the commands contained 2 opposing arguments. one + of the command line arguments was returned in + ProblemParam if provided. + @retval EFI_NOT_FOUND a argument required a value that was missing. + the invalid command line argument was returned in + ProblemParam if provided. +**/ +EFI_STATUS +EFIAPI +ShellCommandLineParse ( + IN CONST SHELL_PARAM_ITEM *CheckList, + OUT LIST_ENTRY **CheckPackage, + OUT CHAR16 **ProblemParam OPTIONAL, + IN BOOLEAN AutoPageBreak + ); + +/** + Frees shell variable list that was returned from ShellCommandLineParse. + + This function will free all the memory that was used for the CheckPackage + list of postprocessed shell arguments. + + this function has no return value. + + if CheckPackage is NULL, then return + + @param CheckPackage the list to de-allocate + **/ +VOID +EFIAPI +ShellCommandLineFreeVarList ( + IN LIST_ENTRY *CheckPackage + ); + +/** + Checks for presence of a flag parameter + + flag arguments are in the form of "-" or "/", but do not have a value following the key + + if CheckPackage is NULL then return FALSE. + if KeyString is NULL then ASSERT() + + @param CheckPackage The package of parsed command line arguments + @param KeyString the Key of the command line argument to check for + + @retval TRUE the flag is on the command line + @retval FALSE the flag is not on the command line + **/ +BOOLEAN +EFIAPI +ShellCommandLineGetFlag ( + IN CONST LIST_ENTRY *CheckPackage, + IN CHAR16 *KeyString + ); + +/** + returns value from command line argument + + value parameters are in the form of "- value" or "/ value" + + if CheckPackage is NULL, then return NULL; + + @param CheckPackage The package of parsed command line arguments + @param KeyString the Key of the command line argument to check for + + @retval NULL the flag is not on the command line + @return !=NULL pointer to unicode string of the value + **/ +CONST CHAR16* +EFIAPI +ShellCommandLineGetValue ( + IN CONST LIST_ENTRY *CheckPackage, + IN CHAR16 *KeyString + ); + +/** + returns raw value from command line argument + + raw value parameters are in the form of "value" in a specific position in the list + + if CheckPackage is NULL, then return NULL; + + @param CheckPackage The package of parsed command line arguments + @param Position the position of the value + + @retval NULL the flag is not on the command line + @return !=NULL pointer to unicode string of the value + **/ +CONST CHAR16* +EFIAPI +ShellCommandLineGetRawValue ( + IN CONST LIST_ENTRY *CheckPackage, + IN UINT32 Position + ); + +#endif // __SHELL_LIB__ \ No newline at end of file diff --git a/ShellPkg/Include/Protocol/EfiShell.h b/ShellPkg/Include/Protocol/EfiShell.h new file mode 100644 index 0000000000..8421056145 --- /dev/null +++ b/ShellPkg/Include/Protocol/EfiShell.h @@ -0,0 +1,949 @@ +/** @file + EFI Shell protocol as defined in the UEFI Shell 2.0 specification. + + 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. + +**/ + +#ifndef __EFI_SHELL_PROTOCOL__ +#define __EFI_SHELL_PROTOCOL__ + +#include +#include + +#define EFI_SHELL_PROTOCOL_GUID \ + { \ + 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; + +typedef struct { + EFI_LIST_ENTRY Link; + EFI_STATUS Status; + CONST CHAR16 *FullName; + CONST CHAR16 *FileName; + EFI_FILE_HANDLE Handle; + EFI_FILE_INFO *Info; +} EFI_SHELL_FILE_INFO; +/** + Returns whether any script files are currently being processed. + + @retval TRUE There is at least one script file active. + @retval FALSE No script files are active now. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_BATCH_IS_ACTIVE) ( + VOID + ); + +/** + Closes the 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 be closed + + @retval EFI_SUCCESS the file closed sucessfully +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_CLOSE_FILE)( + IN EFI_FILE_HANDLE FileHandle + ); + +/** + Creates a file or directory by name. + + This function creates an empty new file or directory with the specified attributes and + returns the new file's handle. If the file already exists and is read-only, then + EFI_INVALID_PARAMETER will be returned. + + If the file already existed, it is truncated and its attributes updated. If the file is + created successfully, the FileHandle is the file's handle, else, the FileHandle is NULL. + + If the file name begins with >v, then the file handle which is returned refers to the + shell environment variable with the specified name. If the shell environment variable + already exists and is non-volatile then EFI_INVALID_PARAMETER is returned. + + @param FileName Pointer to null-terminated file path + @param FileAttribs The new file's attrbiutes. the different attributes are + described in EFI_FILE_PROTOCOL.Open(). + @param FileHandle On return, points to the created file handle or directory's handle + + @retval EFI_SUCCESS The file was opened. FileHandle points to the new file's handle. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED could not open the file path + @retval EFI_NOT_FOUND the specified file could not be found on the devide, or could not + file the file system on the device. + @retval EFI_NO_MEDIA the device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according + the DirName. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_CREATE_FILE)( + IN CONST CHAR16 *FileName, + IN UINT64 FileAttribs, + OUT EFI_FILE_HANDLE *FileHandle + ); + +/** + Deletes the file specified by the file 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 and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_DELETE_FILE)( + IN EFI_FILE_HANDLE FileHandle + ); + +/** + Deletes the file specified by the file name. + + This function deletes a file. + + @param FileName Points to the null-terminated file name. + + @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_DELETE_FILE_BY_NAME)( + IN CONST CHAR16 *FileName + ); + +/** + Disables the page break output mode. +**/ +typedef +VOID +(EFIAPI *EFI_SHELL_DISABLE_PAGE_BREAK) ( +VOID +); + +/** + Enables the page break output mode. +**/ +typedef +VOID +(EFIAPI *EFI_SHELL_ENABLE_PAGE_BREAK) ( +VOID +); + +/** + Execute the command line. + + This function creates a nested instance of the shell and executes the specified + command (CommandLine) with the specified environment (Environment). Upon return, + the status code returned by the specified command is placed in StatusCode. + + If Environment is NULL, then the current environment is used and all changes made + by the commands executed will be reflected in the current environment. If the + Environment is non-NULL, then the changes made will be discarded. + + The CommandLine is executed from the current working directory on the current + device. + + @param ParentImageHandle A handle of the image that is executing the specified + command line. + @param CommandLine Points to the null-terminated UCS-2 encoded string + containing the command line. If NULL then the command- + line will be empty. + @param Environment Points to a null-terminated array of environment + variables with the format 'x=y', where x is the + environment variable name and y is the value. If this + is NULL, then the current shell environment is used. + @param ErrorCode Points to the status code returned by the command. + + @retval EFI_SUCCESS The command executed successfully. The status code + returned by the command is pointed to by StatusCode. + @retval EFI_INVALID_PARAMETER The parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Out of resources. + @retval EFI_UNSUPPORTED Nested shell invocations are not allowed. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_EXECUTE) ( + IN EFI_HANDLE *ParentImageHandle, + IN CHAR16 *CommandLine OPTIONAL, + IN CHAR16 **Environment OPTIONAL, + OUT EFI_STATUS *StatusCode OPTIONAL + ); + +/** + Find files that match a specified pattern. + + This function searches for all files and directories that match the specified + FilePattern. The FilePattern can contain wild-card characters. The resulting file + information is placed in the file list FileList. + + The files in the file list are not opened. The OpenMode field is set to 0 and the FileInfo + field is set to NULL. + + @param FilePattern Points to a null-terminated shell file path, including wildcards. + @param FileList On return, points to the start of a file list containing the names + of all matching files or else points to NULL if no matching files + were found. + + @retval EFI_SUCCESS Files found. + @retval EFI_NOT_FOUND No files found. + @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 +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FIND_FILES)( + IN CONST CHAR16 *FilePattern, + OUT EFI_SHELL_FILE_INFO **FileList + ); + +/** + Find all files in a specified directory. + + @param FileDirHandle Handle of the directory to search. + @param FileList On return, points to the list of files in the directory + or NULL if there are no files in the directory. + + @retval EFI_SUCCESS File information was returned successfully. + @retval EFI_VOLUME_CORRUPTED The file system structures have been corrupted. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_NO_MEDIA The device media is not present. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FIND_FILES_IN_DIR)( +IN EFI_FILE_HANDLE FileDirHandle, +OUT EFI_SHELL_FILE_INFO **FileList +); + +/** + Flushes data back to a device + + This function flushes all modified data associated with a file to a device. + + @param FileHandle The handle of the file to flush + + @retval EFI_SUCCESS The data was flushed. + @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. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FLUSH_FILE)( + IN EFI_FILE_HANDLE FileHandle + ); + +/** + Frees the file list. + + This function cleans up the file list and any related data structures. It has no + impact on the files themselves. + + @param FileList The file list to free. Type EFI_SHELL_FILE_INFO is + defined in OpenFileList() + + @retval EFI_SUCCESS Free the file list successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FREE_FILE_LIST) ( + IN EFI_SHELL_FILE_INFO **FileList + ); + +/** + Returns the current directory on the specified device. + + If FileSystemMapping is NULL, it returns the current working directory. If the + FileSystemMapping is not NULL, it returns the current directory associated with the + FileSystemMapping. In both cases, the returned name includes the file system + mapping (i.e. fs0:\current-dir). + + @param FileSystemMapping A pointer to the file system mapping. If NULL, + then the current working directory is returned. + + @retval !=NULL The current directory. + @retval NULL Current directory does not exist. +**/ +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_CUR_DIR) ( + IN CONST CHAR16 *FileSystemMapping OPTIONAL + ); + +typedef UINT32 EFI_SHELL_DEVICE_NAME_FLAGS; +#define EFI_DEVICE_NAME_USE_COMPONENT_NAME 0x00000001 +#define EFI_DEVICE_NAME_USE_DEVICE_PATH 0x00000002 +/** + Gets the name of the device specified by the device handle. + + This function gets the user-readable name of the device specified by the device + handle. If no user-readable name could be generated, then *BestDeviceName will be + NULL and EFI_NOT_FOUND will be returned. + + @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 + name, in the same format as described in the UEFI + specification, Appendix M + @param BestDeviceName On return, points to the callee-allocated null- + terminated name of the device. If no device name + could be found, points to NULL. The name must be + freed by the caller... + + @retval EFI_SUCCESS Get the name successfully. + @retval EFI_NOT_FOUND Fail to get the device name. +**/ +typedef +EFI_STATUS +(*EFI_SHELL_GET_DEVICE_NAME) ( + IN EFI_HANDLE DeviceHandle, + IN EFI_SHELL_DEVICE_NAME_FLAGS Flags, + IN CHAR8 *Language, + OUT CHAR16 **BestDeviceName + ); + +/** + Gets the device path from the mapping. + + This function gets the device path associated with a mapping. + + @param Mapping A pointer to the mapping + + @retval !=NULL Pointer to the device path that corresponds to the + device mapping. The returned pointer does not need + to be freed. + @retval NULL There is no device path associated with the + specified mapping. +**/ +typedef +CONST EFI_DEVICE_PATH_PROTOCOL * +(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_MAP) ( + IN CONST CHAR16 *Mapping + ); + +/** + Converts a file system style name to a device path. + + This function converts a file system style name to a device path, by replacing any + mapping references to the associated device path. + + @param Path the pointer to the path + + @return all The pointer of the file path. The file path is callee + allocated and should be freed by the caller. +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL * +(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH) ( + IN CONST CHAR16 *Path + ); + +/** + Gets the environment variable. + + This function returns the current value of the specified environment variable. + + @param Name A pointer to the environment variable name + + @return !=NULL The environment variable's value. The returned + pointer does not need to be freed by the caller. + @retval NULL The environment variable doesn't exist. +**/ +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_ENV) ( + IN CONST CHAR16 *Name + ); + +/** + Gets the file information from an open file handle. + + This function allocates a buffer to store the file's information. It's the caller's + responsibility to free the buffer. + + @param FileHandle A File Handle + + @return !=NULL Cannot get the file info. + @return NULL A pointer to a buffer with file information. +**/ +typedef +EFI_FILE_INFO * +(EFIAPI *EFI_SHELL_GET_FILE_INFO)( + IN EFI_FILE_HANDLE FileHandle + ); + +/** + Converts a device path to a file system-style path. + + This function converts a device path to a file system path by replacing part, or all, of + the device path with the file-system mapping. If there are more than one application + file system mappings, the one that most closely matches Path will be used. + + @param Path The pointer to the device path + + @return all The pointer of the null-terminated file path. The path + is callee-allocated and should be freed by the caller. +**/ +typedef +CHAR16 * +(EFIAPI *EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *Path + ); + +/** + Gets a file's current position + + This function returns 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. + + @param FileHandle The file handle on which to get the current position. + @param Position Byte position from the start of the file + + @retval EFI_SUCCESS Data was accessed. + @retval EFI_UNSUPPORTED The request is not valid on open directories. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_FILE_POSITION)( + IN EFI_FILE_HANDLE FileHandle, + OUT UINT64 *Position + ); + +/** + Gets the size of a file. + + This function returns the size of the file specified by FileHandle. + + @param FileHandle The handle of the file. + @param Size The size of this file. + + @retval EFI_SUCCESS Get the file's size. + @retval EFI_DEVICE_ERROR Can't access the file. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_FILE_SIZE)( + IN EFI_FILE_HANDLE FileHandle, + OUT UINT64 *Size + ); + +/** + Return help information about a specific command. + + This function returns the help information for the specified command. The help text + can be internal to the shell or can be from a UEFI Shell manual page. + + If Sections is specified, then each section name listed will be compared in a casesensitive + manner, to the section names described in Appendix B. If the section exists, + it will be appended to the returned help text. If the section does not exist, no + information will be returned. If Sections is NULL, then all help text information + available will be returned. + + @param Command Points to the null-terminated UEFI Shell command name. + @param Sections Points to the null-terminated comma-delimited + section names to return. If NULL, then all + sections will be returned. + @param HelpText On return, points to a callee-allocated buffer + containing all specified help text. + + @retval EFI_SUCCESS The help text was returned. + @retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the + returned help text. + @retval EFI_INVALID_PARAMETER HelpText is NULL + @retval EFI_NOT_FOUND There is no help text available for Command. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_HELP_TEXT) ( + IN CONST CHAR16 *Command, + IN CONST CHAR16 *Sections, + OUT CHAR16 **HelpText + ); + +/** + Gets the mapping that most closely matches the device path. + + This function gets the mapping which corresponds to the device path *DevicePath. If + there is no exact match, then the mapping which most closely matches *DevicePath + is returned, and *DevicePath is updated to point to the remaining portion of the + device path. If there is an exact match, the mapping is returned and *DevicePath + points to the end-of-device-path node. + + @param DevicePath On entry, points to a device path pointer. On + exit, updates the pointer to point to the + portion of the device path after the mapping. + + @retval NULL No mapping was found. + @return !=NULL Pointer to null-terminated mapping. The buffer + is callee allocated and should be freed by the caller. +**/ +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_MAP_FROM_DEVICE_PATH) ( + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ); + +/** + Gets the enable status of the page break output mode. + + User can use this function to determine current page break mode. + + @retval TRUE The page break output mode is enabled + @retval FALSE The page break output mode is disabled +**/ +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_GET_PAGE_BREAK) ( + VOID + ); + +/** + Judges whether the active shell is the root shell. + + This function makes the user to know that whether the active Shell is the root shell. + + @retval TRUE The active Shell is the root Shell. + @retval FALSE The active Shell is NOT the root Shell. +**/ +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_IS_ROOT_SHELL) ( +VOID +); + +/** + Opens a file or a directory by file name. + + This function opens the specified file in the specified OpenMode and returns a file + handle. + If the file name begins with >v, then the file handle which is returned refers to the + shell environment variable with the specified name. If the shell environment variable + exists, is non-volatile and the OpenMode indicates EFI_FILE_MODE_WRITE, then + EFI_INVALID_PARAMETER is returned. + + If the file name is >i, then the file handle which is returned refers to the standard + input. If the OpenMode indicates EFI_FILE_MODE_WRITE, then EFI_INVALID_PARAMETER + is returned. + + If the file name is >o, then the file handle which is returned refers to the standard + output. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER + is returned. + + If the file name is >e, then the file handle which is returned refers to the standard + error. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER + is returned. + + If the file name is NUL, then the file handle that is returned refers to the standard NUL + file. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER is + returned. + + If return EFI_SUCCESS, the FileHandle is the opened file's handle, else, the + FileHandle is NULL. + + @param FileName Points to the null-terminated UCS-2 encoded file name. + @param FileHandle On return, points to the file handle. + @param OpenMode File open mode. Either EFI_FILE_MODE_READ or + EFI_FILE_MODE_WRITE from section 12.4 of the UEFI + Specification. + @retval EFI_SUCCESS The file was opened. FileHandle has the opened file's handle. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. FileHandle is NULL. + @retval EFI_UNSUPPORTED Could not open the file path. FileHandle is NULL. + @retval EFI_NOT_FOUND The specified file could not be found on the device or the file + system could not be found on the device. FileHandle is NULL. + @retval EFI_NO_MEDIA The device has no medium. FileHandle is NULL. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. FileHandle is NULL. + @retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according + the FileName. FileHandle is NULL. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. FileHandle is NULL. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. FileHandle is NULL. + @retval EFI_ACCESS_DENIED The service denied access to the file. FileHandle is NULL. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. FileHandle + is NULL. + @retval EFI_VOLUME_FULL The volume is full. FileHandle is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_FILE_BY_NAME) ( + IN CONST CHAR16 *FileName, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode + ); + +/** + Opens the files that match the path specified. + + This function opens all of the files specified by Path. Wildcards are processed + according to the rules specified in UEFI Shell 2.0 spec section 3.7.1. Each + matching file has an EFI_SHELL_FILE_INFO structure created in a linked list. + + @param Path A pointer to the path string. + @param OpenMode Specifies the mode used to open each file, EFI_FILE_MODE_READ or + EFI_FILE_MODE_WRITE. + @param FileList Points to the start of a list of files opened. + + @retval EFI_SUCCESS Create the file list successfully. + @return Others Can't create the file list. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_FILE_LIST) ( + IN CHAR16 *Path, + IN UINT64 OpenMode, + IN OUT EFI_SHELL_FILE_INFO **FileList + ); + +/** + Opens the root directory of a device. + + This function opens the root directory of a device and returns a file handle to it. + + @param DevicePath Points to the device path corresponding to the device where the + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed. + @param FileHandle On exit, points to the file handle corresponding to the root directory on the + device. + + @retval EFI_SUCCESS Root opened successfully. + @retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory + could not be opened. + @retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted. + @retval EFI_DEVICE_ERROR The device had an error +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_ROOT)( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT EFI_FILE_HANDLE *FileHandle + ); + +/** + Opens the root directory of a device on a handle + + This function opens the root directory of a device and returns a file handle to it. + + @param DeviceHandle The handle of the device that contains the volume. + @param FileHandle On exit, points to the file handle corresponding to the root directory on the + device. + + @retval EFI_SUCCESS Root opened successfully. + @retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory + could not be opened. + @retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted. + @retval EFI_DEVICE_ERROR The device had an error +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_ROOT_BY_HANDLE)( + IN EFI_HANDLE DeviceHandle, + OUT EFI_FILE_HANDLE *FileHandle + ); + +/** + Reads data from the 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, then an error is returned. + + @param FileHandle The opened file handle for read + @param ReadSize On input, the size of Buffer, in bytes. On output, the amount of data read. + @param Buffer The buffer in which data is read. + + @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 +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_READ_FILE) ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ); + +/** + Deletes the duplicate file names files in the given file list. + + This function deletes the reduplicate files in the given file list. + + @param FileList A pointer to the first entry in the file list. + + @retval EFI_SUCCESS Always success. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_REMOVE_DUP_IN_FILE_LIST) ( + IN EFI_SHELL_FILE_INFO **FileList + ); + +/** + Changes a shell command alias. + + This function creates an alias for a shell command. + + @param Command Points to the null-terminated shell command or existing alias. + @param Alias Points to the null-terminated alias for the shell command. If this is NULL, and + Command refers to an alias, that alias will be deleted. + @param Replace If TRUE and the alias already exists, then the existing alias will be replaced. If + FALSE and the alias already exists, then the existing alias is unchanged and + EFI_ACCESS_DENIED is returned. + + @retval EFI_SUCCESS Alias created or deleted successfully. + @retval EFI_ACCESS_DENIED The alias is a built-in alias or already existed and Replace was set to + FALSE. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_ALIAS)( + IN CONST CHAR16 *Command, + IN CONST CHAR16 *Alias, + IN BOOLEAN Replace + ); + +/** + Changes the current directory on the specified device. + + If the FileSystem is NULL, and the directory Dir does not contain a file system's + mapped name, this function changes the current working directory. If FileSystem is + NULL and the directory Dir contains a mapped name, then the current file system and + the current directory on that file system are changed. + + If FileSystem is not NULL, and Dir is NULL, then this changes the current working file + system. + + If FileSystem is not NULL and Dir is not NULL, then this function changes the current + directory on the specified file system. + + If the current working directory or the current working file system is changed then the + %cwd% environment variable will be updated + + @param FileSystem A pointer to the file system's mapped name. If NULL, then the current working + directory is changed. + @param Dir Points to the null-terminated directory on the device specified by FileSystem. + + @return !=NULL The current directory. + @retval NULL Current directory does not exist. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_CUR_DIR) ( + IN CONST CHAR16 *FileSystem OPTIONAL, + IN CONST CHAR16 *Dir + ); + +/** + Sets the environment variable. + + This function changes the current value of the specified environment variable. If the + environment variable exists and the Value is an empty string, then the environment + variable is deleted. If the environment variable exists and the Value is not an empty + string, then the value of the environment variable is changed. If the environment + variable does not exist and the Value is an empty string, there is no action. If the + environment variable does not exist and the Value is a non-empty string, then the + environment variable is created and assigned the specified value. + + For a description of volatile and non-volatile environment variables, see UEFI Shell + 2.0 specification section 3.6.1. + + @param Name Points to the null-terminated environment variable name. + @param Value Points to the null-terminated environment variable value. If the value is an + empty string then the environment variable is deleted. + @param Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE). + + @retval EFI_SUCCESS The environment variable was successfully updated. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_ENV) ( + IN CONST CHAR16 *Name, + IN CONST CHAR16 *Value, + IN BOOLEAN Volatile + ); + +/** + Sets the file information to an opened file handle. + + This function changes file information. + + @param FileHandle A file handle + @param FileInfo Points to new file information. + + @retval EFI_SUCCESS The information was set. + @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. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of EFI_FILE_INFO. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_FILE_INFO)( + IN EFI_FILE_HANDLE FileHandle, + IN CONST EFI_FILE_INFO *FileInfo + ); + +/** + Sets a file's current position + + 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. + + @param FileHandle The file handle on which requested position will be set. + @param Position Byte position from the start of the file + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open directories. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_FILE_POSITION)( + IN EFI_FILE_HANDLE FileHandle, + IN UINT64 Position + ); + +/** + This function creates a mapping for a device path. + + @param DevicePath Points to the device path. If this is NULL and Mapping points to a valid mapping, + then the mapping will be deleted. + @param Mapping Points to the null-terminated mapping for the device path. + + @retval EFI_SUCCESS Mapping created or deleted successfully. + @retval EFI_NO_MAPPING There is no handle that corresponds exactly to DevicePath. See the + boot service function LocateDevicePath(). + @retval EFI_ACCESS_DENIED The mapping is a built-in alias. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_MAP)( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CONST CHAR16 *Mapping + ); + +/** + Writes data to the 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 automatically grows to + hold the data, if required. + + Direct writes to opened directories are not supported. + + @param FileHandle The opened file handle for writing. + @param BufferSize On input, size of Buffer. + @param Buffer The buffer in which data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to 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 +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_WRITE_FILE)( + IN EFI_FILE_HANDLE FileHandle, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef struct _EFI_SHELL_PROTOCOL { + EFI_SHELL_EXECUTE Execute; + EFI_SHELL_GET_ENV GetEnv; + EFI_SHELL_SET_ENV SetEnv; + EFI_SHELL_SET_ALIAS SetAlias; + EFI_SHELL_GET_HELP_TEXT GetHelpText; + EFI_SHELL_GET_DEVICE_PATH_FROM_MAP GetDevicePathFromMap; + EFI_SHELL_GET_MAP_FROM_DEVICE_PATH GetMapFromDevicePath; + EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH GetDevicePathFromFilePath; + EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH GetFilePathFromDevicePath; + EFI_SHELL_SET_MAP SetMap; + EFI_SHELL_GET_CUR_DIR GetCurDir; + EFI_SHELL_SET_CUR_DIR SetCurDir; + EFI_SHELL_OPEN_FILE_LIST OpenFileList; + EFI_SHELL_FREE_FILE_LIST FreeFileList; + EFI_SHELL_REMOVE_DUP_IN_FILE_LIST RemoveDupInFileList; + EFI_SHELL_BATCH_IS_ACTIVE BatchIsActive; + EFI_SHELL_IS_ROOT_SHELL IsRootShell; + EFI_SHELL_ENABLE_PAGE_BREAK EnablePageBreak; + EFI_SHELL_DISABLE_PAGE_BREAK DisablePageBreak; + EFI_SHELL_GET_PAGE_BREAK GetPageBreak; + EFI_SHELL_GET_DEVICE_NAME GetDeviceName; + EFI_SHELL_GET_FILE_INFO GetFileInfo; + EFI_SHELL_SET_FILE_INFO SetFileInfo; + EFI_SHELL_OPEN_FILE_BY_NAME OpenFileByName; + EFI_SHELL_CLOSE_FILE CloseFile; + EFI_SHELL_CREATE_FILE CreateFile; + EFI_SHELL_READ_FILE ReadFile; + EFI_SHELL_WRITE_FILE WriteFile; + EFI_SHELL_DELETE_FILE DeleteFile; + EFI_SHELL_DELETE_FILE_BY_NAME DeleteFileByName; + EFI_SHELL_GET_FILE_POSITION GetFilePosition; + EFI_SHELL_SET_FILE_POSITION SetFilePosition; + EFI_SHELL_FLUSH_FILE FlushFile; + EFI_SHELL_FIND_FILES FindFiles; + EFI_SHELL_FIND_FILES_IN_DIR FindFilesInDir; + EFI_SHELL_GET_FILE_SIZE GetFileSize; + EFI_SHELL_OPEN_ROOT OpenRoot; + EFI_SHELL_OPEN_ROOT_BY_HANDLE OpenRootByHandle; + EFI_EVENT ExecutionBreak; + UINT32 MajorVersion; + UINT32 MinorVersion; +} EFI_SHELL_PROTOCOL; + +extern EFI_GUID gEfiShellProtocolGuid; + +#endif diff --git a/ShellPkg/Include/Protocol/EfiShellEnvironment2.h b/ShellPkg/Include/Protocol/EfiShellEnvironment2.h new file mode 100644 index 0000000000..537b916071 --- /dev/null +++ b/ShellPkg/Include/Protocol/EfiShellEnvironment2.h @@ -0,0 +1,976 @@ +/** @file + Defines for EFI shell environment 2 ported to EDK II build environment. + +Copyright (c) 2005, 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 _SHELLENV2_H_ +#define _SHELLENV2_H_ + +#include +#include +#include + +#define DEFAULT_INIT_ROW 1 +#define DEFAULT_AUTO_LF FALSE + + +/** + this function is a prototype for a function that dumps information on a protocol + to a given location. the location is dependant on the implementation. This is + used when programatically adding shell commands. + + @param Handle the handle the protocol is on + @param Interface the interface to the protocol + +**/ +typedef +VOID +(EFIAPI *SHELLENV_DUMP_PROTOCOL_INFO) ( + IN EFI_HANDLE Handle, + IN VOID *Interface + ); + +/** + this function is a prototype foe each command internal to the EFI shell + implementation. the specific command depends on the implementation. This is + used when programatically adding shell commands. + + @param ImageHandle The handle to the binary shell + @param SystemTable pointer to the system table. + + @retval EFI_SUCCESS the command ran to completion + @return other an error ocurred. any error is possible + depending on the implementation of the shell + command. + +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_INTERNAL_COMMAND) ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + This function is a prototype for one that gets a help string for a given command. + This is used when programatically adding shell commands. Upon successful return + the memory allocated is up to the caller to free. + + @param Str pointer to pointer to string to display for help. + + @retval EFI_SUCCESS the help string is in the parameter Str. + +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLCMD_GET_LINE_HELP) ( + IN OUT CHAR16 **Str + ); + +/** +* Structure returned from functions that open multiple files +**/ +typedef struct { + UINT32 Signature; ///< SHELL_FILE_ARG_SIGNATURE + EFI_LIST_ENTRY Link; ///< linked list helper + EFI_STATUS Status; ///< File's status + + EFI_FILE_HANDLE Parent; ///< what is the Parent file of this file + UINT64 OpenMode; ///< how was the file opened + CHAR16 *ParentName; ///< string representation of parent + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; ///< DevicePath for Parent + + CHAR16 *FullName; ///< path and file name for this file + CHAR16 *FileName; ///< file name for this file + + EFI_FILE_HANDLE Handle; ///< handle to this file + EFI_FILE_INFO *Info; ///< pointer to file info for this file +} SHELL_FILE_ARG; + +/// signature for SHELL_FILE_ARG +#define SHELL_FILE_ARG_SIGNATURE SIGNATURE_32 ('g', 'r', 'a', 'f') + +/** +* GUID for the shell environment2 and shell environment +**/ +#define SHELL_ENVIRONMENT_PROTOCOL_GUID \ + { \ + 0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } + +/** +* GUID for the shell environment2 extension (main GUID same as shell environment) +**/ +#define EFI_SE_EXT_SIGNATURE_GUID \ + { \ + 0xd2c18636, 0x40e5, 0x4eb5, {0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87} \ + } + +#define EFI_SHELL_MAJOR_VER 0x00000001 ///< Major version of the EFI_SHELL_ENVIRONMENT2 +#define EFI_SHELL_MINOR_VER 0x00000000 ///< Minor version of the EFI_SHELL_ENVIRONMENT2 + +/** + execute a command line + + this function will run the CommandLine. This includes loading any required images, + parsing any requires scripts, and it DebugOutput is TRUE printing errors + encountered directly to the screen. + + @param ParentImageHandle Handle of image executing this operation + @param CommandLine string command line to execute + @param DebugOutput TRUE indicates that errors should be printed directly. + FALSE supresses error messages. + + @retval EFI_SUCCESS the command line executed and completed. + @retval EFI_ABORTED the operation did not complete due to abort. + @retval EFI_INVALID_PARAMETER A parameter did not have a valid value. + @retval EFI_OUT_OF_RESOURCES A required memory allocation failed. + +@sa HandleProtocol +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_EXECUTE) ( + IN EFI_HANDLE *ParentImageHandle, + IN CHAR16 *CommandLine, + IN BOOLEAN DebugOutput + ); + +/** + this function returns a shell environment variable value. + + @param Name pointer to the string with the shell environment + variables name + + @retval NULL the shell environment variable's value could not be found + @retval !NULL the value of the shell environment variable Name + +**/ +typedef +CHAR16 * +(EFIAPI *SHELLENV_GET_ENV) ( + IN CHAR16 *Name + ); + +/** + this function returns a shell environment map value. + + @param Name pointer to the string with the shell environment + map name + + @retval NULL the shell environment map's value could not be found + @retval !NULL the value of the shell environment map Name + +**/ +typedef +CHAR16 * +(EFIAPI *SHELLENV_GET_MAP) ( + IN CHAR16 *Name + ); + +/** + This function will add an internal command to the shell interface. + + This will allocate all required memory, put the new command on the command + list in the correct location. + + @param Handler the handler function to call when the command gets called + @param CmdStr The command name + @param GetLineHelp function to call of get help for this command + + @retval EFI_SUCCESS the command is now part of the command list + @retval EFI_OUT_OF_RESOURCES a memory allocation failed. + @sa SHELLENV_INTERNAL_COMMAND + @sa SHELLCMD_GET_LINE_HELP +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_ADD_CMD) ( + IN SHELLENV_INTERNAL_COMMAND Handler, + IN CHAR16 *Cmd, + IN SHELLCMD_GET_LINE_HELP GetLineHelp + ); + +/** + Internal interface to add protocol handlers. + + This function is for internal shell use only. This is how protocol handlers are added. + This will get the current protocol info and add the new info or update existing info + and then resave the info. + + @param SaveId save this change as an EFI variable + @param Protocol the protocol's GUID + @param DumpToken The function pointer to dump token function or + NULL + @param DumpInfo The function pointer to dump infomation function + or NULL + @param IdString The english name of the protocol +**/ +typedef +VOID +(EFIAPI *SHELLENV_ADD_PROT) ( + IN EFI_GUID *Protocol, + IN SHELLENV_DUMP_PROTOCOL_INFO DumpToken OPTIONAL, + IN SHELLENV_DUMP_PROTOCOL_INFO DumpInfo OPTIONAL, + IN CHAR16 *IdString + ); + +/** + this function finds a protocol handle by a GUID. + + This function will check for already known protocols by GUID and if one is + found it will return the name of that protocol. if no name is found and + GenId is TRUE it will generate ths string. + + @param Protocol the GUID of the protocol to look for. + @param GenId whether to generate a name string if its not found. + + @return !NULL the Name of the protocol. + @retval NULL the Name was not found and GenId was not TRUE. +**/ +typedef +CHAR16* +(EFIAPI *SHELLENV_GET_PROT) ( + IN EFI_GUID *Protocol, + IN BOOLEAN GenId + ); + +/** + this function returns the current directory on a given device + + If DeviceName is specified, then return the current shell directory on that + device. If DeviceName is NULL, then return the current directory on the + current device. The caller us responsible to free the returned string when + no londer required. + + @param DeviceName the name of the device to get the current + directory on or NULL for current device + + @return The current directory on the current or specified device. + +**/ +typedef +CHAR16* +(EFIAPI *SHELLENV_CUR_DIR) ( + IN CHAR16 *DeviceName OPTIONAL + ); + +/** + this function will open a group of files that match the Arg path, including + 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 + 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. + + @param Arg pointer Path to files to open + @param ListHead pointer to allocated and initialized list head + upon which to append all the opened file structures. + + @retval EFI_SUCCESS 1 or more files was opened and a struct of each file's + information was appended to ListHead. + @retval EFI_OUT_OF_RESOURCES a memory allocation failed. + @retval EFI_NOT_FOUND no matching files could be found. + @sa SHELLENV_FREE_FILE_LIST +**/typedef +EFI_STATUS +(EFIAPI *SHELLENV_FILE_META_ARG) ( + IN CHAR16 *Arg, + IN OUT EFI_LIST_ENTRY *ListHead + ); + +/** + this frees all of the nodes under the ListHead, but not ListHead itself. + + @param ListHead Pointer to list to free all nodes of. + + @retval EFI_SUCCESS always returned. +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_FREE_FILE_LIST) ( + IN OUT EFI_LIST_ENTRY *ListHead + ); + +/** + this function creates a new instance of the ShellInterface protocol for use on + the ImageHandle. + + This function is for internal shell usage. this will allocate and then populate + EFI_SHELL_INTERFACE protocol. it is the caller's responsibility to free the + memory. + + @param ImageHandle the handle which will use the new ShellInterface + protocol. + + @return the newly allocated shell interface protocol. + +**/ +typedef +EFI_SHELL_INTERFACE* +(EFIAPI *SHELLENV_NEW_SHELL) ( + IN EFI_HANDLE ImageHandle + ); + +/** + this function determins whether a script file is currently being processed. + + a script file (.nsh file) can contain a series of commands and this is useful to + know for some shell commands whether they are being run manually or as part of a + script. + + @retval TRUE A script file is being processed + @return FALSE A script file is not being processed +**/ +typedef +BOOLEAN +(EFIAPI *SHELLENV_BATCH_IS_ACTIVE) ( + IN VOID + ); + +/** + This is an internal shell function to free any and all allocated resources. + This should be called just closing the shell. +**/ +typedef +VOID +(EFIAPI *SHELLENV_FREE_RESOURCES) ( + VOID + ); + +/** + This function enables the page break mode. + + This mode causes the output to pause after each complete screen to enable a + user to more easily read it. if AutoWrap is TRUE then rows with too many + characters will be chopped and divided into 2 rows. if FALSE then rows with + too many characters may not be fully visible to the user on the screen. + + @param StartRow the row number to start this on. + @param AutoWrap whether to auto wrap rows that are +**/ +typedef +VOID +(EFIAPI *SHELLENV_ENABLE_PAGE_BREAK) ( + IN INT32 StartRow, + IN BOOLEAN AutoWrap + ); + +/** + This function disables the page break mode. + + disabling this causes the output to print out exactly as coded with no breaks + for readability. +**/ +typedef +VOID +(EFIAPI *SHELLENV_DISABLE_PAGE_BREAK) ( + IN VOID + ); + +/** + Get the status of the page break output mode. + + @retval FALSE page break output mode is not enabled + @retval TRUE page break output mode is enabled +**/ +typedef +BOOLEAN +(EFIAPI *SHELLENV_GET_PAGE_BREAK) ( + IN VOID + ); + +/** + this function sets the keys to filter for for the console in. the valid + values to set are: + + #define EFI_OUTPUT_SCROLL 0x00000001 + #define EFI_OUTPUT_PAUSE 0x00000002 + #define EFI_EXECUTION_BREAK 0x00000004 + + @param KeyFilter The new key filter to use. +**/ +typedef +VOID +(EFIAPI *SHELLENV_SET_KEY_FILTER) ( + IN UINT32 KeyFilter + ); + +/** + this function gets the keys to filter for for the console in. the valid + values to get are: + + #define EFI_OUTPUT_SCROLL 0x00000001 + #define EFI_OUTPUT_PAUSE 0x00000002 + #define EFI_EXECUTION_BREAK 0x00000004 + + @retval the current filter mask. +**/ +typedef +UINT32 +(EFIAPI *SHELLENV_GET_KEY_FILTER) ( + IN VOID + ); + +/** + this function determins if the shell application should break. + + This is used to inform a shell application that a break condition has been + initiated. long loops should check this to prevent delays to the break. + + @retval TRUE a break has been signaled. the application + should exit with EFI_ABORTED as soon as possible. + @retval FALSE continue as normal. +**/ +typedef +BOOLEAN +(EFIAPI *SHELLENV_GET_EXECUTION_BREAK) ( + IN VOID + ); + +/** + This is an internal-shell function used to increment the shell nesting level. + +**/ +typedef +VOID +(EFIAPI *SHELLENV_INCREMENT_SHELL_NESTING_LEVEL) ( + IN VOID + ); + +/** + This is an internal-shell function used to decrement the shell nesting level. +**/ +typedef +VOID +(EFIAPI *SHELLENV_DECREMENT_SHELL_NESTING_LEVEL) ( + IN VOID + ); + +/** + this function determins if the caller is running under the root shell. + + @retval TRUE The caller is running under the root shell + @retval FALSE The caller is not running under the root shell + +**/ +typedef +BOOLEAN +(EFIAPI *SHELLENV_IS_ROOT_SHELL) ( + IN VOID + ); + +/** + Close the console proxy to restore the original console. + + This is an internal shell function to handle shell cascading. it restores the + original set of console protocols. + + @param ConInHandle The handle of ConIn. + @param ConIn pointer to the location to return the pointer to + the original console input. + @param ConOutHandle The handle of ConOut + @param ConOut pointer to the location to return the pointer to + the original console output. +**/ +typedef +VOID +(EFIAPI *SHELLENV_CLOSE_CONSOLE_PROXY) ( + IN EFI_HANDLE ConInHandle, + IN OUT EFI_SIMPLE_TEXT_INPUT_PROTOCOL **ConIn, + IN EFI_HANDLE ConOutHandle, + IN OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL **ConOut + ); + +// +// declarations of handle enumerator +// +/** + For ease of use the shell maps handle #'s to short numbers. + This is only done on request for various internal commands and the references + are immediately freed when the internal command completes. +**/ +typedef +VOID +(EFIAPI *INIT_HANDLE_ENUMERATOR) ( + VOID + ); + +/** + this is an internal shell function to enumerate the handle database. + + this function gets the next handle in the handle database. if no handles are + found EFI_NOT_FOUND is returned. if the previous Handle was the last handle + it is set to NULL before returning. + + this must be called after INIT_HANDLE_ENUMERATOR and before CLOSE_HANDLE_ENUMERATOR. + + @param Handle pointer to pointer to Handle. will be set + on a sucessful return. + + @retval EFI_SUCCESS the next handle in the handle database is *Handle + @retval EFI_NOT_FOUND there is not another handle. +**/ +typedef +EFI_STATUS +(EFIAPI *NEXT_HANDLE) ( + IN OUT EFI_HANDLE **Handle + ); + +/** + this is an internal shell function to enumerate the handle database. + + this function skips the next SkipNum handles in the handle database. If there + are not enough handles left to skip that many EFI_ACCESS_DENIED is returned and + no skip is performed. + + this must be called after INIT_HANDLE_ENUMERATOR and before CLOSE_HANDLE_ENUMERATOR. + + @param SkipNum how many handles to skip + + @retval EFI_SUCCESS the next handle in the handle database is *Handle + @retval EFI_ACCESS_DENIED there are not SkipNum handles left in the database +**/ +typedef +EFI_STATUS +(EFIAPI *SKIP_HANDLE) ( + IN UINTN SkipNum + ); + +/** + this is an internal shell function to enumerate the handle database. + + this function resets the the handle database so that NEXT_HANDLE and SKIP_HANDLE + will start from EnumIndex on the next call. + + this must be called after INIT_HANDLE_ENUMERATOR and before CLOSE_HANDLE_ENUMERATOR. + + @param EnumIndex where to start. + + @retval the number of handles either read out or skipped before this reset. +**/ +typedef +UINTN +(EFIAPI *RESET_HANDLE_ENUMERATOR) ( + IN UINTN EnumIndex + ); + +/** + this is an internal shell function to enumerate the handle database. + + this must be called after INIT_HANDLE_ENUMERATOR. + + this function releases all memory and resources associated with the handle database. + after this no other handle enumerator functions except INIT_HANDLE_ENUMERATOR will + function properly. +**/ +typedef +VOID +(EFIAPI *CLOSE_HANDLE_ENUMERATOR) ( + VOID + ); + +/** + this is an internal shell function to enumerate the handle database. + + this function returns the number of handles in the handle database. + + this must be called after INIT_HANDLE_ENUMERATOR and before CLOSE_HANDLE_ENUMERATOR. + + @retval the number of handles in the handle database. +**/ +typedef +UINTN +(EFIAPI *GET_NUM) ( + VOID + ); + +/** +Handle Enumerator structure +**/ +typedef struct { + INIT_HANDLE_ENUMERATOR Init; ///< pointer to INIT_HANDLE_ENUMERATOR function + NEXT_HANDLE Next; ///< pointer to NEXT_HANDLE function + SKIP_HANDLE Skip; ///< pointer to SKIP_HANDLE function + RESET_HANDLE_ENUMERATOR Reset; ///< pointer to RESET_HANDLE_ENUMERATOR function + CLOSE_HANDLE_ENUMERATOR Close; ///< pointer to CLOSE_HANDLE_ENUMERATOR function + GET_NUM GetNum; ///< pointer to GET_NUM function +} HANDLE_ENUMERATOR; +/** + signature for the PROTOCOL_INFO structure +**/ +#define PROTOCOL_INFO_SIGNATURE SIGNATURE_32 ('s', 'p', 'i', 'n') +/** + PROTOCOL_INFO structure for protocol enumerator functions. + +**/ +typedef struct { + UINTN Signature; ///< PROTOCOL_INFO_SIGNATURE + EFI_LIST_ENTRY Link; ///< standard lined list helper member + // + // parsing info for the protocol + // + EFI_GUID ProtocolId; ///< GUID for the protocol + CHAR16 *IdString; ///< Name of the protocol + SHELLENV_DUMP_PROTOCOL_INFO DumpToken; ///< pointer to DumpToken function for the protocol + SHELLENV_DUMP_PROTOCOL_INFO DumpInfo; ///< pointer to DumpInfo function for the protocol + // + // database info on which handles are supporting this protocol + // + UINTN NoHandles; ///< how many handles produce this protocol + EFI_HANDLE *Handles; ///< array of handles + +} PROTOCOL_INFO; + +// +// declarations of protocol info enumerator +// +/** + this is an internal shell function to initialize the protocol enumerator. + + this must be called before NEXT_PROTOCOL_INFO, SKIP_PROTOCOL_INFO, + RESET_PROTOCOL_INFO_ENUMERATOR, and CLOSE_PROTOCOL_INFO_ENUMERATOR are + called. +**/ +typedef +VOID +(EFIAPI *INIT_PROTOCOL_INFO_ENUMERATOR) ( + VOID + ); + +/** + this function is an internal shell function for enumeration of protocols. + + This functiol will return the next protocol in the list. If this is called + immediately after initialization it will return the first. If this is called + immediately after reset it will return the protocol first again. + + This cannot be called after CLOSE_PROTOCOL_INFO_ENUMERATOR, but it must be + called after INIT_PROTOCOL_INFO_ENUMERATOR. + + @param ProtocolInfo pointer to pointer to protocol information structure. + + @retval EFI_SUCCESS the next protocol's information was sucessfully returned. + If there were no more protocols NULL was returned. +**/ +typedef +EFI_STATUS +(EFIAPI *NEXT_PROTOCOL_INFO) ( + IN OUT PROTOCOL_INFO **ProtocolInfo + ); + +/** + this function is an internal shell function for enumeration of protocols. + + This cannot be called after CLOSE_PROTOCOL_INFO_ENUMERATOR, but it must be + called after INIT_PROTOCOL_INFO_ENUMERATOR. + + this function does nothing and always returns EFI_SUCCESS. + + @retval EFI_SUCCESS always returned (see note). +**/ +typedef +EFI_STATUS +(EFIAPI *SKIP_PROTOCOL_INFO) ( + IN UINTN SkipNum + ); + +/** + this function is an internal shell function for enumeration of protocols. + + This cannot be called after CLOSE_PROTOCOL_INFO_ENUMERATOR, but it must be + called after INIT_PROTOCOL_INFO_ENUMERATOR. + + this function resets the list of protocols such that the next one in the + list is the begining of the list. +**/ +typedef +VOID +(EFIAPI *RESET_PROTOCOL_INFO_ENUMERATOR) ( + VOID + ); + + +/** + this function is an internal shell function for enumeration of protocols. + + This must be called after INIT_PROTOCOL_INFO_ENUMERATOR. After this call + no protocol enumerator calls except INIT_PROTOCOL_INFO_ENUMERATOR may be made. + + this function frees any memory or resources associated with the protocol + enumerator. +**/ +typedef +VOID +(EFIAPI *CLOSE_PROTOCOL_INFO_ENUMERATOR) ( + VOID + ); + +/** +* protocol enumerator structure of function pointers. +**/ +typedef struct { + INIT_PROTOCOL_INFO_ENUMERATOR Init; ///< pointer to INIT_PROTOCOL_INFO_ENUMERATOR function + NEXT_PROTOCOL_INFO Next; ///< pointer to NEXT_PROTOCOL_INFO function + SKIP_PROTOCOL_INFO Skip; ///< pointer to SKIP_PROTOCOL_INFO function + RESET_PROTOCOL_INFO_ENUMERATOR Reset; ///< pointer to RESET_PROTOCOL_INFO_ENUMERATOR function + CLOSE_PROTOCOL_INFO_ENUMERATOR Close; ///< pointer to CLOSE_PROTOCOL_INFO_ENUMERATOR function +} PROTOCOL_INFO_ENUMERATOR; + +/** + this function is used to retrieve a user-friendly display name for a handle. + + If UseComponentName is TRUE then the component name protocol for this device + or it's parent device (if required) will be used to obtain the name of the + device. If UseDevicePath is TRUE it will get the human readable device path + and return that. If both are TRUE it will try to use component name first + and device path if that fails. + + It will use either ComponentName or ComponentName2 protocol, depending on + what is present. + + This function will furthur verify whether the handle in question produced either + EFI_DRIVER_CONFIGRATION_PROTOCOL or EFI_DRIVER_CONFIGURATION2_PROTOCOL and also + whether the handle in question produced either EFI_DRIVER_DIAGNOSTICS_PROTOCOL or + EFI_DRIVER_DIAGNOSTICS2_PROTOCOL. + + Upon sucessful return the memory for *BestDeviceName is up to the caller to free. + + @param DeviceHandle the device handle whose name is desired + @param UseComponentName whether to use the ComponentName protocol at all + @param UseDevicePath whether to use the DevicePath protocol at all + @param Language pointer to language string to use + @param BestDeviceName pointer to pointer to string allocated with the name + @param ConfigurationStatus pointer to status for opening a Configuration protocol + @param DiagnosticsStatus pointer to status for opening a Diagnostics protocol + @param Display Whether to Print this out to default Print location + @param Indent how many characters to indent the printing + + @retval EFI_SUCCESS this function always returns EFI_SUCCESS +**/ +typedef +EFI_STATUS +(EFIAPI *GET_DEVICE_NAME) ( + EFI_HANDLE DeviceHandle, + BOOLEAN UseComponentName, + BOOLEAN UseDevicePath, + CHAR8 *Language, + CHAR16 **BestDeviceName, + EFI_STATUS *ConfigurationStatus, + EFI_STATUS *DiagnosticsStatus, + BOOLEAN Display, + UINTN Indent + ); + +#define EFI_SHELL_COMPATIBLE_MODE_VER L"1.1.1" ///< string for lowest version this shell supports +#define EFI_SHELL_ENHANCED_MODE_VER L"1.1.2" ///< string for highest version this shell supports + +/** + this function gets the shell mode as stored in the shell environment + "efishellmode". it will not fail. + + @param Mode returns a string representing one of the + 2 supported modes of the shell. + + @retval EFI_SUCCESS this function always returns success +**/ +typedef +EFI_STATUS +(EFIAPI *GET_SHELL_MODE) ( + OUT CHAR16 **Mode + ); + +/** + Convert a file system style name to an file path + + This function will convert a shell path name to a Device Path Protocol path. + This function will allocate any required memory for this operation and it + is the responsibility of the caller to free that memory when no longer required. + + if anything prevents the complete conversion free any allocated memory and + return NULL. + + @retval !NULL a pointer to the callee allocated Device Path + @retval NULL the operation could not be completed. +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *SHELLENV_NAME_TO_PATH) ( + IN CHAR16 *Path + ); + +/** + converts a device path into a file system map name. + + if DevPath is NULL then ASSERT + This function looks through the shell environment map for a map whose device + path matches the DevPath parameter. If one is found the Name is returned via + Name parameter. If sucessful the caller must free the memory allocated for + Name. + + this function will use the internal lock to prevent changes to the map during + the lookup operation. + + @param DevPath The device path to search for a name for + @param ConsistMapping what state to verify map flag VAR_ID_CONSIST + @param Name on sucessful return the name of that device path + + @retval EFI_SUCCESS the DevPath was found and the name returned + in Name. + @retval EFI_OUT_OF_RESOURCES A required memory allocation failed. + @retval EFI_UNSUPPORTED the DevPath was not found in the map +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_GET_FS_NAME) ( + IN EFI_DEVICE_PATH_PROTOCOL * DevPath, + IN BOOLEAN ConsistMapping, + OUT CHAR16 **Name + ); + +/** + this function will open a group of files that match the Arg path, but will not + 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 + 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. + + @param Arg pointer Path to files to open + @param ListHead pointer to allocated and initialized list head + upon which to append all the opened file structures. + + @retval EFI_SUCCESS 1 or more files was opened and a struct of each file's + information was appended to ListHead. + @retval EFI_OUT_OF_RESOURCES a memory allocation failed. + @retval EFI_NOT_FOUND no matching files could be found. + @sa SHELLENV_FREE_FILE_LIST +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_FILE_META_ARG_NO_WILDCARD) ( + IN CHAR16 *Arg, + IN OUT EFI_LIST_ENTRY *ListHead + ); + +/** + this function removes duplicate file listings from lists. + + this is a function for use with SHELLENV_FILE_META_ARG_NO_WILDCARD and + SHELLENV_FILE_META_ARG. this function will verify that there are no duplicate + files in the list of returned files. any file listed twice will have one of its + instances removed. + + @param ListHead pointer to linked list head that was returned from + SHELLENV_FILE_META_ARG_NO_WILDCARD or + SHELLENV_FILE_META_ARG. + + @retval EFI_SUCCESS this function always returns success. + +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_DEL_DUP_FILE) ( + IN EFI_LIST_ENTRY * ListHead + ); + +/** + Converts a File System map name to a device path. + + if DevPath is NULL then ASSERT() + + This function looks through the shell environment map for a map whose Name + matches the Name parameter. If one is found the device path pointer is + updated to point to that file systems device path. the caller should not + free the memory from that device path. + + this function will use the internal lock to prevent changes to the map during + the lookup operation. + + @param Name pointer to NULL terminated UNICODE string of the + file system name + @param DevPath pointer to pointer to DevicePath. only valid on + OUT if sucessful + + @retval EFI_SUCCESS the conversion was successful and the device + path was returned. + @retval EFI_NOT_FOUND the file system could not be found in the map. +**/ +typedef +EFI_STATUS +(EFIAPI *SHELLENV_GET_FS_DEVICE_PATH) ( + IN CHAR16 *Name, + OUT EFI_DEVICE_PATH_PROTOCOL **DevPath + ); + +/// EFI_SHELL_ENVIRONMENT2 protocol structure +/// contains pointers to functions +typedef struct { + SHELLENV_EXECUTE Execute; + SHELLENV_GET_ENV GetEnv; + SHELLENV_GET_MAP GetMap; + SHELLENV_ADD_CMD AddCmd; + SHELLENV_ADD_PROT AddProt; + SHELLENV_GET_PROT GetProt; + SHELLENV_CUR_DIR CurDir; + SHELLENV_FILE_META_ARG FileMetaArg; + SHELLENV_FREE_FILE_LIST FreeFileList; + + // + // The following services are only used by the shell itself + // + SHELLENV_NEW_SHELL NewShell; + SHELLENV_BATCH_IS_ACTIVE BatchIsActive; + + SHELLENV_FREE_RESOURCES FreeResources; + + // + // GUID to differentiate ShellEnvironment2 from ShellEnvironment + // + EFI_GUID SESGuid; + // + // Major Version grows if shell environment interface has been changes + // + UINT32 MajorVersion; + UINT32 MinorVersion; + SHELLENV_ENABLE_PAGE_BREAK EnablePageBreak; + SHELLENV_DISABLE_PAGE_BREAK DisablePageBreak; + SHELLENV_GET_PAGE_BREAK GetPageBreak; + + SHELLENV_SET_KEY_FILTER SetKeyFilter; + SHELLENV_GET_KEY_FILTER GetKeyFilter; + + SHELLENV_GET_EXECUTION_BREAK GetExecutionBreak; + SHELLENV_INCREMENT_SHELL_NESTING_LEVEL IncrementShellNestingLevel; + SHELLENV_DECREMENT_SHELL_NESTING_LEVEL DecrementShellNestingLevel; + SHELLENV_IS_ROOT_SHELL IsRootShell; + + SHELLENV_CLOSE_CONSOLE_PROXY CloseConsoleProxy; + HANDLE_ENUMERATOR HandleEnumerator; + PROTOCOL_INFO_ENUMERATOR ProtocolInfoEnumerator; + GET_DEVICE_NAME GetDeviceName; + GET_SHELL_MODE GetShellMode; + SHELLENV_NAME_TO_PATH NameToPath; + SHELLENV_GET_FS_NAME GetFsName; + SHELLENV_FILE_META_ARG_NO_WILDCARD FileMetaArgNoWildCard; + SHELLENV_DEL_DUP_FILE DelDupFileArg; + SHELLENV_GET_FS_DEVICE_PATH GetFsDevicePath; +} EFI_SHELL_ENVIRONMENT2; + +extern EFI_GUID gEfiShellEnvironment2Guid; +extern EFI_GUID gEfiShellEnvironment2ExtGuid; +#endif // _SHELLENV_H_ diff --git a/ShellPkg/Include/Protocol/EfiShellInterface.h b/ShellPkg/Include/Protocol/EfiShellInterface.h new file mode 100644 index 0000000000..bc15b4bca7 --- /dev/null +++ b/ShellPkg/Include/Protocol/EfiShellInterface.h @@ -0,0 +1,96 @@ +/** @file + EFI Shell Interface protocol from EDK shell (no spec). + + Shell Interface - additional information (over image_info) provided + to an application started by the shell. + + ConIo - provides a file style interface to the console. Note that the + ConOut & ConIn interfaces in the system table will work as well, and both + all will be redirected to a file if needed on a command line + + The shell interface's and data (including ConIo) are only valid during + the applications Entry Point. Once the application returns from it's + entry point the data is freed by the invoking shell. + + 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. + +**/ + +#ifndef _SHELLINTERFACE_H_ +#define _SHELLINTERFACE_H_ + +#include + +#define SHELL_INTERFACE_PROTOCOL_GUID \ + { \ + 0x47c7b223, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } + +/// +/// bit definitions for EFI_SHELL_ARG_INFO +/// +typedef enum { + ARG_NO_ATTRIB = 0x0, + ARG_IS_QUOTED = 0x1, + ARG_PARTIALLY_QUOTED = 0x2, + ARG_FIRST_HALF_QUOTED = 0x4, + ARG_FIRST_CHAR_IS_ESC = 0x8 +}; + +/// +/// attributes for an argument. +/// +typedef struct _EFI_SHELL_ARG_INFO { + UINT32 Attributes; +} EFI_SHELL_ARG_INFO; + +/// +/// This protocol provides access to additional information about a shell app. +/// +typedef struct { + /// + /// Handle back to original image handle & image info + /// + EFI_HANDLE ImageHandle; + EFI_LOADED_IMAGE_PROTOCOL *Info; + + /// + /// Parsed arg list converted more C like format + /// + CHAR16 **Argv; + UINTN Argc; + + /// + /// Storage for file redirection args after parsing + /// + CHAR16 **RedirArgv; + UINTN RedirArgc; + + /// + /// A file style handle for console io + /// + EFI_FILE_HANDLE StdIn; + EFI_FILE_HANDLE StdOut; + EFI_FILE_HANDLE StdErr; + + /// + /// list of attributes for each argument + /// + EFI_SHELL_ARG_INFO *ArgInfo; + + /// + /// whether we are echoing + /// + BOOLEAN EchoOn; +} EFI_SHELL_INTERFACE; + +extern EFI_GUID gEfiShellInterfaceGuid; + +#endif diff --git a/ShellPkg/Include/Protocol/EfiShellParameters.h b/ShellPkg/Include/Protocol/EfiShellParameters.h new file mode 100644 index 0000000000..49ad2fdc43 --- /dev/null +++ b/ShellPkg/Include/Protocol/EfiShellParameters.h @@ -0,0 +1,33 @@ +/** @file + EFI Shell protocol as defined in the UEFI Shell 2.0 specification. + + 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. + +**/ + +#ifndef __EFI_SHELL_PARAMETERS_PROTOCOL__ +#define __EFI_SHELL_PARAMETERS_PROTOCOL__ + +#define EFI_SHELL_PARAMETERS_PROTOCOL_GUID \ + { \ + 0x752f3136, 0x4e16, 0x4fdc, { 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca } \ + } + +typedef struct _EFI_SHELL_PARAMETERS_PROTOCOL { + CHAR16 **Argv; + UINTN Argc; + EFI_FILE_HANDLE StdIn; + EFI_FILE_HANDLE StdOut; + EFI_FILE_HANDLE StdErr; +} EFI_SHELL_PARAMETERS_PROTOCOL; + +extern EFI_GUID gEfiShellParametersProtocolGuid; + +#endif diff --git a/ShellPkg/Library/BaseShellLib/BaseShellLib.c b/ShellPkg/Library/BaseShellLib/BaseShellLib.c new file mode 100644 index 0000000000..205974d519 --- /dev/null +++ b/ShellPkg/Library/BaseShellLib/BaseShellLib.c @@ -0,0 +1,2099 @@ +/** @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. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + +/** + helper function to find ShellEnvironment2 for constructor +**/ +EFI_STATUS +EFIAPI +ShellFindSE2 ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Buffer; + UINTN BufferSize; + UINTN HandleIndex; + + BufferSize = 0; + Buffer = NULL; + Status = gBS->OpenProtocol(ImageHandle, + &gEfiShellEnvironment2Guid, + (VOID **)&mEfiShellEnvironment2, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + // + // look for the mEfiShellEnvironment2 protocol at a higher level + // + if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE && + (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER || + (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER)))) { + // + // figure out how big of a buffer we need. + // + Status = gBS->LocateHandle (ByProtocol, + &gEfiShellEnvironment2Guid, + NULL, // ignored for ByProtocol + &BufferSize, + Buffer + ); + ASSERT(Status == EFI_BUFFER_TOO_SMALL); + Buffer = (EFI_HANDLE*)AllocatePool(BufferSize); + ASSERT(Buffer != NULL); + Status = gBS->LocateHandle (ByProtocol, + &gEfiShellEnvironment2Guid, + NULL, // ignored for ByProtocol + &BufferSize, + Buffer + ); + if (!EFI_ERROR (Status)) { + // + // now parse the list of returned handles + // + Status = EFI_NOT_FOUND; + for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof(Buffer[0])); HandleIndex++) { + Status = gBS->OpenProtocol(Buffer[HandleIndex], + &gEfiShellEnvironment2Guid, + (VOID **)&mEfiShellEnvironment2, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid) != FALSE && + (mEfiShellEnvironment2->MajorVersion > EFI_SHELL_MAJOR_VER || + (mEfiShellEnvironment2->MajorVersion == EFI_SHELL_MAJOR_VER && mEfiShellEnvironment2->MinorVersion >= EFI_SHELL_MINOR_VER))) { + mEfiShellEnvironment2Handle = Buffer[HandleIndex]; + Status = EFI_SUCCESS; + break; + } + } + } + } + if (Buffer != NULL) { + FreePool (Buffer); + } + 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 ( + 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) + // + Status = gBS->OpenProtocol(ImageHandle, + &gEfiShellProtocolGuid, + (VOID **)&mEfiShellProtocol, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR(Status)) { + mEfiShellProtocol = NULL; + } + Status = gBS->OpenProtocol(ImageHandle, + &gEfiShellParametersProtocolGuid, + (VOID **)&mEfiShellParametersProtocol, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR(Status)) { + mEfiShellParametersProtocol = NULL; + } + + if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) { + // + // Moved to seperate function due to complexity + // + Status = ShellFindSE2(ImageHandle); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Status: 0x%08x\r\n", Status)); + mEfiShellEnvironment2 = NULL; + } + Status = gBS->OpenProtocol(ImageHandle, + &gEfiShellInterfaceGuid, + (VOID **)&mEfiShellInterface, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR(Status)) { + mEfiShellInterface = NULL; + } + } + // + // only success getting 2 of either the old or new, but no 1/2 and 1/2 + // + if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) || + (mEfiShellProtocol != NULL && mEfiShellParametersProtocol != NULL) ) { + return (EFI_SUCCESS); + } + return (EFI_NOT_FOUND); +} + +/** + Destructory for the library. free any resources. +**/ +EFI_STATUS +EFIAPI +ShellLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (mEfiShellEnvironment2 != NULL) { + gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle, + &gEfiShellEnvironment2Guid, + ImageHandle, + NULL); + } + if (mEfiShellInterface != NULL) { + gBS->CloseProtocol(ImageHandle, + &gEfiShellInterfaceGuid, + ImageHandle, + NULL); + } + if (mEfiShellProtocol != NULL) { + gBS->CloseProtocol(ImageHandle, + &gEfiShellProtocolGuid, + ImageHandle, + NULL); + } + if (mEfiShellParametersProtocol != NULL) { + gBS->CloseProtocol(ImageHandle, + &gEfiShellParametersProtocolGuid, + ImageHandle, + NULL); + } + return (EFI_SUCCESS); +} +/** + 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 +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); +} + +/** + 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 +ShellSetFileInfo ( + IN EFI_FILE_HANDLE FileHandle, + 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)); +} + + /** + This function will open a file or directory referenced by DevicePath. + + This function opens a file with the open mode according to the file path. The + Attributes is valid only for EFI_FILE_MODE_CREATE. + + @param FilePath on input the device path to the file. On output + the remaining device path. + @param DeviceHandle pointer to the system device handle. + @param FileHandle pointer to the file handle. + @param OpenMode the mode to open the file with. + @param Attributes the file's file attributes. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found on + the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +ShellOpenFileByDevicePath( + IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, + OUT EFI_HANDLE *DeviceHandle, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + CHAR16 *FileName; + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol; + EFI_FILE_HANDLE LastHandle; + + // + // ASERT for FileHandle, FilePath, and DeviceHandle being NULL + // + ASSERT(FilePath != NULL); + ASSERT(FileHandle != NULL); + ASSERT(DeviceHandle != NULL); + // + // which shell interface should we use + // + if (mEfiShellProtocol != NULL) { + // + // use UEFI Shell 2.0 method. + // + FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath); + if (FileName == NULL) { + return (EFI_INVALID_PARAMETER); + } + 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)) { + // + // 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; + + // + // Try to test opening an existing file + // + Status = LastHandle->Open ( + LastHandle, + FileHandle, + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, + OpenMode &~EFI_FILE_MODE_CREATE, + 0 + ); + + // + // 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); + } + return (EFI_SUCCESS); + } +} + +/** + This function will open a file or directory referenced by filename. + + If return is EFI_SUCCESS, the Filehandle is the opened file’s handle; + otherwise, the Filehandle is NULL. The Attributes is valid only for + EFI_FILE_MODE_CREATE. + + if FileNAme is NULL then ASSERT() + + @param FileName pointer to file name + @param FileHandle pointer to the file handle. + @param OpenMode the mode to open the file with. + @param Attributes the file's file attributes. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found + on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +ShellOpenFileByName( + IN CHAR16 *FileName, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + + // + // ASSERT if FileName is NULL + // + ASSERT(FileName != NULL); + + if (mEfiShellProtocol != NULL) { + // + // Use UEFI Shell 2.0 method + // + return (mEfiShellProtocol->OpenFileByName(FileName, + FileHandle, + OpenMode)); + } + // + // Using EFI Shell version + // this means convert name to path and call that function + // since this will use EFI method again that will open it. + // + ASSERT(mEfiShellEnvironment2 != NULL); + FilePath = mEfiShellEnvironment2->NameToPath (FileName); + if (FileDevicePath != NULL) { + return (ShellOpenFileByDevicePath(&FilePath, + &DeviceHandle, + FileHandle, + OpenMode, + Attributes )); + } + return (EFI_DEVICE_ERROR); +} +/** + This function create a directory + + If return is EFI_SUCCESS, the Filehandle is the opened directory's handle; + otherwise, the Filehandle is NULL. If the directory already existed, this + function opens the existing directory. + + @param DirectoryName pointer to directory name + @param FileHandle pointer to the file handle. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found + on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @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_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. + @sa ShellOpenFileByName +**/ +EFI_STATUS +EFIAPI +ShellCreateDirectory( + IN CHAR16 *DirectoryName, + OUT EFI_FILE_HANDLE *FileHandle + ) +{ + // + // this is a pass thru to the open file function with sepcific open mode and attributes + // + return (ShellOpenFileByName(DirectoryName, + FileHandle, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, + EFI_FILE_DIRECTORY + )); +} + +/** + 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 +ShellReadFile( + 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 +ShellWriteFile( + 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 +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; +} + +/** + 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 +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; +} + +/** + 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 +ShellSetFilePosition ( + 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 +ShellGetFilePosition ( + 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 +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); +} + +/** + 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 ShellFindNextFile() 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 ShellGetFileInfo, ShellSetFilePosition, + or ShellReadFile +**/ +EFI_STATUS +EFIAPI +ShellFindFirstFile ( + IN EFI_FILE_HANDLE DirHandle, + 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 + // + 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); +} +/** + Retrieves the next file in a directory. + + To use this function, caller must call the LibFindFirstFile() 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 ShellFindNextFile() 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 +ShellFindNextFile( + 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 = 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); +} +/** + 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 +ShellGetFileSize ( + 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 = 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); +} +/** + Retrieves the status of the break execution flag + + this function is useful to check whether the application is being asked to halt by the shell. + + @retval TRUE the execution break is enabled + @retval FALSE the execution break is not enabled +**/ +BOOLEAN +EFIAPI +ShellGetExecutionBreakFlag( + VOID + ) +{ + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + + // + // We are using UEFI Shell 2.0; see if the event has been triggered + // + if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) { + return (FALSE); + } + return (TRUE); + } + + // + // using EFI Shell; call the function to check + // + ASSERT(mEfiShellEnvironment2 != NULL); + return (mEfiShellEnvironment2->GetExecutionBreak()); +} +/** + return the value of an environment variable + + this function gets the value of the environment variable set by the + ShellSetEnvironmentVariable function + + @param EnvKey The key name of the environment variable. + + @retval NULL the named environment variable does not exist. + @return != NULL pointer to the value of the environment variable +**/ +CONST CHAR16* +EFIAPI +ShellGetEnvironmentVariable ( + IN CHAR16 *EnvKey + ) +{ + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + return (mEfiShellProtocol->GetEnv(EnvKey)); + } + + // + // ASSERT that we must have EFI shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + + // + // using EFI Shell + // + return (mEfiShellEnvironment2->GetEnv(EnvKey)); +} +/** + set the value of an environment variable + +This function changes the current value of the specified environment variable. If the +environment variable exists and the Value is an empty string, then the environment +variable is deleted. If the environment variable exists and the Value is not an empty +string, then the value of the environment variable is changed. If the environment +variable does not exist and the Value is an empty string, there is no action. If the +environment variable does not exist and the Value is a non-empty string, then the +environment variable is created and assigned the specified value. + + This is not supported pre-UEFI Shell 2.0. + + @param EnvKey The key name of the environment variable. + @param EnvVal The Value of the environment variable + @param Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE). + + @retval EFI_SUCCESS the operation was completed sucessfully + @retval EFI_UNSUPPORTED This operation is not allowed in pre UEFI 2.0 Shell environments +**/ +EFI_STATUS +EFIAPI +ShellSetEnvironmentVariable ( + IN CONST CHAR16 *EnvKey, + IN CONST CHAR16 *EnvVal, + IN BOOLEAN Volatile + ) +{ + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + return (mEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile)); + } + + // + // This feature does not exist under EFI shell + // + return (EFI_UNSUPPORTED); +} +/** + cause the shell to parse and execute a command line. + + This function creates a nested instance of the shell and executes the specified +command (CommandLine) with the specified environment (Environment). Upon return, +the status code returned by the specified command is placed in StatusCode. +If Environment is NULL, then the current environment is used and all changes made +by the commands executed will be reflected in the current environment. If the +Environment is non-NULL, then the changes made will be discarded. +The CommandLine is executed from the current working directory on the current +device. + +EnvironmentVariables and Status are only supported for UEFI Shell 2.0. +Output is only supported for pre-UEFI Shell 2.0 + + @param ImageHandle Parent image that is starting the operation + @param CommandLine pointer to null terminated command line. + @param Output true to display debug output. false to hide it. + @param EnvironmentVariables optional pointer to array of environment variables + in the form "x=y". if NULL current set is used. + @param Status the status of the run command line. + + @retval EFI_SUCCESS the operation completed sucessfully. Status + contains the status code returned. + @retval EFI_INVALID_PARAMETER a parameter contains an invalid value + @retval EFI_OUT_OF_RESOURCES out of resources + @retval EFI_UNSUPPORTED the operation is not allowed. +**/ +EFI_STATUS +EFIAPI +ShellExecute ( + IN EFI_HANDLE *ParentHandle, + IN CHAR16 *CommandLine OPTIONAL, + IN BOOLEAN Output OPTIONAL, + IN CHAR16 **EnvironmentVariables OPTIONAL, + OUT EFI_STATUS *Status OPTIONAL + ) +{ + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + // + // Call UEFI Shell 2.0 version (not using Output parameter) + // + return (mEfiShellProtocol->Execute(ParentHandle, + CommandLine, + EnvironmentVariables, + Status)); + } + // + // ASSERT that we must have EFI shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + // + // Call EFI Shell version (not using EnvironmentVariables or Status parameters) + // Due to oddity in the EFI shell we want to dereference the ParentHandle here + // + return (mEfiShellEnvironment2->Execute(*ParentHandle, + CommandLine, + Output)); +} +/** + Retreives the current directory path + + If the DeviceName is NULL, it returns the current device’s current directory + name. If the DeviceName is not NULL, it returns the current directory name + on specified drive. + + @param DeviceName the name of the drive to get directory on + + @retval NULL the directory does not exist + @return != NULL the directory +**/ +CONST CHAR16* +EFIAPI +ShellGetCurrentDir ( + IN CHAR16 *DeviceName OPTIONAL + ) +{ + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + return (mEfiShellProtocol->GetCurDir(DeviceName)); + } + // + // ASSERT that we must have EFI shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + return (mEfiShellEnvironment2->CurDir(DeviceName)); +} +/** + sets (enabled or disabled) the page break mode + + when page break mode is enabled the screen will stop scrolling + and wait for operator input before scrolling a subsequent screen. + + @param CurrentState TRUE to enable and FALSE to disable +**/ +VOID +EFIAPI +ShellSetPageBreakMode ( + IN BOOLEAN CurrentState + ) +{ + // + // check for enabling + // + if (CurrentState != 0x00) { + // + // check for UEFI Shell 2.0 + // + if (mEfiShellProtocol != NULL) { + // + // Enable with UEFI 2.0 Shell + // + mEfiShellProtocol->EnablePageBreak(); + return; + } else { + // + // ASSERT that must have EFI Shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + // + // Enable with EFI Shell + // + mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF); + return; + } + } else { + // + // check for UEFI Shell 2.0 + // + if (mEfiShellProtocol != NULL) { + // + // Disable with UEFI 2.0 Shell + // + mEfiShellProtocol->DisablePageBreak(); + return; + } else { + // + // ASSERT that must have EFI Shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + // + // Disable with EFI Shell + // + mEfiShellEnvironment2->DisablePageBreak (); + return; + } + } +} + +/// +/// version of EFI_SHELL_FILE_INFO struct, except has no CONST pointers. +/// This allows for the struct to be populated. +/// +typedef struct { + EFI_LIST_ENTRY Link; + EFI_STATUS Status; + CHAR16 *FullName; + CHAR16 *FileName; + EFI_FILE_HANDLE Handle; + EFI_FILE_INFO *Info; +} EFI_SHELL_FILE_INFO_NO_CONST; + +/** + Converts a EFI shell list of structures to the coresponding UEFI Shell 2.0 type of list. + + if OldStyleFileList is NULL then ASSERT() + + this function will convert a SHELL_FILE_ARG based list into a callee allocated + EFI_SHELL_FILE_INFO based list. it is up to the caller to free the memory via + the ShellCloseFileMetaArg function. + + @param FileList the EFI shell list type + + @retval the resultant head of the double linked new format list; +**/ +LIST_ENTRY* +EFIAPI +InternalShellConvertFileListType ( + EFI_LIST_ENTRY *FileList + ) +{ + LIST_ENTRY *ListHead; + SHELL_FILE_ARG *OldInfo; + EFI_LIST_ENTRY *Link; + EFI_SHELL_FILE_INFO_NO_CONST *NewInfo; + + // + // ASSERT that FileList is not NULL + // + ASSERT(FileList != NULL); + + // + // Allocate our list head and initialize the list + // + ListHead = AllocateZeroPool(sizeof(EFI_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) { + OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE); + + // + // make sure the old list was valid + // + ASSERT(OldInfo != NULL); + ASSERT(OldInfo->Info != NULL); + ASSERT(OldInfo->FullName != NULL); + ASSERT(OldInfo->FileName != NULL); + + // + // allocate a new EFI_SHELL_FILE_INFO object + // + NewInfo = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); + + // + // copy the simple items + // + NewInfo->Handle = OldInfo->Handle; + NewInfo->Status = OldInfo->Status; + + // + // allocate new space to copy strings and structure + // + NewInfo->FullName = AllocateZeroPool(StrSize(OldInfo->FullName)); + NewInfo->FileName = AllocateZeroPool(StrSize(OldInfo->FileName)); + NewInfo->Info = AllocateZeroPool((UINTN)OldInfo->Info->Size); + + // + // make sure all the memory allocations were sucessful + // + ASSERT(NewInfo->FullName != NULL); + ASSERT(NewInfo->FileName != NULL); + ASSERT(NewInfo->Info != NULL); + + // + // Copt the strings and structure + // + StrCpy(NewInfo->FullName, OldInfo->FullName); + StrCpy(NewInfo->FileName, OldInfo->FileName); + gBS->CopyMem (NewInfo->Info, OldInfo->Info, (UINTN)OldInfo->Info->Size); + + // + // add that to the list + // + InsertTailList(ListHead, (LIST_ENTRY*)NewInfo); + } + return (ListHead); +} +/** + Opens a group of files based on a path. + + This function uses the Arg to open all the matching files. Each matched + file has a SHELL_FILE_ARG structure to record the file information. These + structures are placed on the list ListHead. Users can get the SHELL_FILE_ARG + structures from ListHead to access each file. This function supports wildcards + and will process '?' and '*' as such. the list must be freed with a call to + ShellCloseFileMetaArg(). + + This function will fail if called sequentially without freeing the list in the middle. + + @param Arg pointer to path string + @param OpenMode mode to open files with + @param ListHead head of linked list of results + + @retval EFI_SUCCESS the operation was sucessful and the list head + contains the list of opened files + #retval EFI_UNSUPPORTED a previous ShellOpenFileMetaArg must be closed first. + *ListHead is set to NULL. + @return != EFI_SUCCESS the operation failed + + @sa InternalShellConvertFileListType +**/ +EFI_STATUS +EFIAPI +ShellOpenFileMetaArg ( + IN CHAR16 *Arg, + IN UINT64 OpenMode, + IN OUT EFI_SHELL_FILE_INFO **ListHead + ) +{ + EFI_STATUS Status; + LIST_ENTRY *EmptyNode; + + // + // make sure we have no outstanding list + // + if (mOldStyleFileList != NULL) { + *ListHead = NULL; + return (EFI_UNSUPPORTED); + } + + // + // ASSERT that Arg and ListHead are not NULL + // + ASSERT(Arg != NULL); + ASSERT(ListHead != NULL); + + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + return (mEfiShellProtocol->OpenFileList(Arg, + OpenMode, + ListHead)); + } + + // + // ASSERT that we must have EFI shell + // + ASSERT(mEfiShellEnvironment2 != NULL); + + // + // allocate memory for old list head + // + mOldStyleFileList = (EFI_LIST_ENTRY*)AllocatePool(sizeof(EFI_LIST_ENTRY)); + ASSERT(mOldStyleFileList != NULL); + + // + // make sure the list head is initialized + // + InitializeListHead((LIST_ENTRY*)mOldStyleFileList); + + // + // Get the EFI Shell list of files + // + Status = mEfiShellEnvironment2->FileMetaArg(Arg, mOldStyleFileList); + if (EFI_ERROR(Status)) { + *ListHead = NULL; + return (Status); + } + + // + // Convert that to equivalent of UEFI Shell 2.0 structure + // + EmptyNode = InternalShellConvertFileListType(mOldStyleFileList); + + // + // remove the empty head of the list + // + *ListHead = (EFI_SHELL_FILE_INFO*)RemoveEntryList(EmptyNode); + FreePool(EmptyNode); + + return (Status); +} +/** + Free the linked list returned from ShellOpenFileMetaArg + + if ListHead is NULL then ASSERT() + + @param ListHead the pointer to free + + @retval EFI_SUCCESS the operation was sucessful +**/ +EFI_STATUS +EFIAPI +ShellCloseFileMetaArg ( + IN OUT EFI_SHELL_FILE_INFO **ListHead + ) +{ + LIST_ENTRY *Node; + + // + // ASSERT that ListHead is not NULL + // + ASSERT(ListHead != NULL); + + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellProtocol != NULL) { + 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); + 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); + FreePool((EFI_SHELL_FILE_INFO_NO_CONST*)Node); + } + return EFI_SUCCESS; + } +} + +typedef struct { + EFI_LIST_ENTRY List; + CHAR16 *Name; + ParamType Type; + CHAR16 *Value; + UINTN OriginalPosition; +} SHELL_PARAM_PACKAGE; + +/** + Checks the list of valid arguments and returns TRUE if the item was found. If the + return value is TRUE then the type parameter is set also. + + if CheckList is NULL then ASSERT(); + if Name is NULL then ASSERT(); + if Type is NULL then ASSERT(); + + @param Type pointer to type of parameter if it was found + @param Name pointer to Name of parameter found + @param CheckList List to check against + + @retval TRUE the Parameter was found. Type is valid. + @retval FALSE the Parameter was not found. Type is not valid. +**/ +BOOLEAN +EFIAPI +IsCheckList ( + IN CONST CHAR16 *Name, + IN CONST SHELL_PARAM_ITEM *CheckList, + OUT ParamType *Type + ) +{ + SHELL_PARAM_ITEM *TempListItem; + + // + // ASSERT that all 3 pointer parameters aren't NULL + // + ASSERT(CheckList != NULL); + ASSERT(Type != NULL); + ASSERT(Name != NULL); + + // + // Enumerate through the list + // + for (TempListItem = (SHELL_PARAM_ITEM*)CheckList ; TempListItem->Name != NULL ; TempListItem++) { + // + // If the Name matches set the type and return TRUE + // + if (StrCmp(Name, TempListItem->Name) == 0) { + *Type = TempListItem->Type; + return (TRUE); + } + } + return (FALSE); +} +/** + Checks the string for indicators of "flag" status. this is a leading '/' or '-' + + @param Name pointer to Name of parameter found + + @retval TRUE the Parameter is a flag. + @retval FALSE the Parameter not a flag +**/ +BOOLEAN +EFIAPI +IsFlag ( + IN CONST CHAR16 *Name + ) +{ + // + // ASSERT that Name isn't NULL + // + ASSERT(Name != NULL); + + // + // If the Name has a / or - as the first character return TRUE + // + if ((Name[0] == L'/') || (Name[0] == L'-') ) { + return (TRUE); + } + return (FALSE); +} + +/** + Checks the command line arguments passed against the list of valid ones. + + If no initialization is required, then return RETURN_SUCCESS. + + @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. + @param AutoPageBreak will automatically set PageBreakEnabled for "b" parameter + @param Argc Count of parameters in Argv + @param Argv pointer to array of parameters + + @retval EFI_SUCCESS The operation completed sucessfully. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed + @retval EFI_INVALID_PARAMETER A parameter was invalid + @retval EFI_VOLUME_CORRUPTED the command line was corrupt. an argument was + duplicated. the duplicated command line argument + was returned in ProblemParam if provided. + @retval EFI_NOT_FOUND a argument required a value that was missing. + the invalid command line argument was returned in + ProblemParam if provided. +**/ +EFI_STATUS +EFIAPI +InternalCommandLineParse ( + IN CONST SHELL_PARAM_ITEM *CheckList, + OUT LIST_ENTRY **CheckPackage, + OUT CHAR16 **ProblemParam OPTIONAL, + IN BOOLEAN AutoPageBreak, + IN CONST CHAR16 **Argv, + IN UINTN Argc + ) +{ + UINTN LoopCounter; + UINTN Count; + ParamType CurrentItemType; + SHELL_PARAM_PACKAGE *CurrentItemPackage; + BOOLEAN GetItemValue; + + CurrentItemPackage = NULL; + + // + // ASSERTs + // + ASSERT(CheckList != NULL); + ASSERT(Argv != NULL); + + Count = 0; + GetItemValue = FALSE; + + // + // If there is only 1 item we dont need to do anything + // + if (Argc <= 1) { + *CheckPackage = NULL; + return (EFI_SUCCESS); + } + + // + // initialize the linked list + // + *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY)); + InitializeListHead(*CheckPackage); + + // + // loop through each of the arguments + // + for (LoopCounter = 0 ; LoopCounter < Argc ; ++LoopCounter) { + if (Argv[LoopCounter] == NULL) { + // + // do nothing for NULL argv + // + } else if (GetItemValue == TRUE) { + ASSERT(CurrentItemPackage != NULL); + // + // get the item VALUE for the previous flag + // + GetItemValue = FALSE; + CurrentItemPackage->Value = AllocateZeroPool(StrSize(Argv[LoopCounter])); + ASSERT(CurrentItemPackage->Value != NULL); + StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]); + InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage); + } else if (IsFlag(Argv[LoopCounter]) == FALSE) { + // + // add this one as a non-flag + // + CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE)); + ASSERT(CurrentItemPackage != NULL); + CurrentItemPackage->Name = NULL; + CurrentItemPackage->Type = TypePosition; + CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter])); + ASSERT(CurrentItemPackage->Value != NULL); + StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]); + CurrentItemPackage->OriginalPosition = Count++; + InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage); + } else if (IsCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) { + // + // this is a flag + // + CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE)); + ASSERT(CurrentItemPackage != NULL); + CurrentItemPackage->Name = AllocatePool(StrSize(Argv[LoopCounter])); + ASSERT(CurrentItemPackage->Name != NULL); + StrCpy(CurrentItemPackage->Name, Argv[LoopCounter]); + CurrentItemPackage->Type = CurrentItemType; + CurrentItemPackage->OriginalPosition = (UINTN)(-1); + + // + // Does this flag require a value + // + if (CurrentItemPackage->Type == TypeValue) { + // + // trigger the next loop to populate the value of this item + // + GetItemValue = TRUE; + } else { + // + // this item has no value expected; we are done + // + CurrentItemPackage->Value = NULL; + InsertTailList(*CheckPackage, (LIST_ENTRY*)CurrentItemPackage); + } + } else if (ProblemParam) { + // + // this was a non-recognised flag... error! + // + *ProblemParam = (CHAR16*)Argv[LoopCounter]; + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_VOLUME_CORRUPTED); + } else { + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_VOLUME_CORRUPTED); + } + } + // + // support for AutoPageBreak + // + if (AutoPageBreak && ShellCommandLineGetFlag(*CheckPackage, L"-b")) { + ShellSetPageBreakMode(TRUE); + } + return (EFI_SUCCESS); +} + +/** + Checks the command line arguments passed against the list of valid ones. + Optionally removes NULL values first. + + If no initialization is required, then return RETURN_SUCCESS. + + @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. + @param AutoPageBreak will automatically set PageBreakEnabled for "b" parameter + + @retval EFI_SUCCESS The operation completed sucessfully. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed + @retval EFI_INVALID_PARAMETER A parameter was invalid + @retval EFI_VOLUME_CORRUPTED the command line was corrupt. an argument was + duplicated. the duplicated command line argument + was returned in ProblemParam if provided. + @retval EFI_DEVICE_ERROR the commands contained 2 opposing arguments. one + of the command line arguments was returned in + ProblemParam if provided. + @retval EFI_NOT_FOUND a argument required a value that was missing. + the invalid command line argument was returned in + ProblemParam if provided. +**/ +EFI_STATUS +EFIAPI +ShellCommandLineParse ( + IN CONST SHELL_PARAM_ITEM *CheckList, + OUT LIST_ENTRY **CheckPackage, + OUT CHAR16 **ProblemParam OPTIONAL, + IN BOOLEAN AutoPageBreak + ) +{ + // + // ASSERT that CheckList and CheckPackage aren't NULL + // + ASSERT(CheckList != NULL); + ASSERT(CheckPackage != NULL); + + // + // Check for UEFI Shell 2.0 protocols + // + if (mEfiShellParametersProtocol != NULL) { + return (InternalCommandLineParse(CheckList, + CheckPackage, + ProblemParam, + AutoPageBreak, + mEfiShellParametersProtocol->Argv, + mEfiShellParametersProtocol->Argc )); + } + + // + // ASSERT That EFI Shell is not required + // + ASSERT (mEfiShellInterface != NULL); + return (InternalCommandLineParse(CheckList, + CheckPackage, + ProblemParam, + AutoPageBreak, + mEfiShellInterface->Argv, + mEfiShellInterface->Argc )); +} + +/** + Frees shell variable list that was returned from ShellCommandLineParse. + + This function will free all the memory that was used for the CheckPackage + list of postprocessed shell arguments. + + this function has no return value. + + if CheckPackage is NULL, then return + + @param CheckPackage the list to de-allocate + **/ +VOID +EFIAPI +ShellCommandLineFreeVarList ( + IN LIST_ENTRY *CheckPackage + ) +{ + LIST_ENTRY *Node; + + // + // check for CheckPackage == NULL + // + if (CheckPackage == NULL) { + return; + } + + // + // for each node in the list + // + for (Node = GetFirstNode(CheckPackage); Node != CheckPackage ; Node = GetFirstNode(CheckPackage)) { + // + // Remove it from the list + // + RemoveEntryList(Node); + + // + // if it has a name free the name + // + if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) { + FreePool(((SHELL_PARAM_PACKAGE*)Node)->Name); + } + + // + // if it has a value free the value + // + if (((SHELL_PARAM_PACKAGE*)Node)->Value != NULL) { + FreePool(((SHELL_PARAM_PACKAGE*)Node)->Value); + } + + // + // free the node structure + // + FreePool((SHELL_PARAM_PACKAGE*)Node); + } + // + // free the list head node + // + FreePool(CheckPackage); +} +/** + Checks for presence of a flag parameter + + flag arguments are in the form of "-" or "/", but do not have a value following the key + + if CheckPackage is NULL then return FALSE. + if KeyString is NULL then ASSERT() + + @param CheckPackage The package of parsed command line arguments + @param KeyString the Key of the command line argument to check for + + @retval TRUE the flag is on the command line + @retval FALSE the flag is not on the command line + **/ +BOOLEAN +EFIAPI +ShellCommandLineGetFlag ( + IN CONST LIST_ENTRY *CheckPackage, + IN CHAR16 *KeyString + ) +{ + LIST_ENTRY *Node; + + // + // ASSERT that both CheckPackage and KeyString aren't NULL + // + ASSERT(KeyString != NULL); + + // + // return FALSE for no package + // + if (CheckPackage == NULL) { + return (FALSE); + } + + // + // enumerate through the list of parametrs + // + for (Node = GetFirstNode(CheckPackage) ; Node != CheckPackage ; Node = GetNextNode(CheckPackage, Node) ) { + // + // If the Name matches, return TRUE (and there may be NULL name) + // + if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) { + if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) { + return (TRUE); + } + } + } + return (FALSE); +} +/** + returns value from command line argument + + value parameters are in the form of "- value" or "/ value" + + if CheckPackage is NULL, then return NULL; + + @param CheckPackage The package of parsed command line arguments + @param KeyString the Key of the command line argument to check for + + @retval NULL the flag is not on the command line + @return !=NULL pointer to unicode string of the value + **/ +CONST CHAR16* +EFIAPI +ShellCommandLineGetValue ( + IN CONST LIST_ENTRY *CheckPackage, + IN CHAR16 *KeyString + ) +{ + LIST_ENTRY *Node; + + // + // check for CheckPackage == NULL + // + if (CheckPackage == NULL) { + return (NULL); + } + + // + // enumerate through the list of parametrs + // + for (Node = GetFirstNode(CheckPackage) ; Node != NULL ; Node = GetNextNode(CheckPackage, Node) ) { + // + // If the Name matches, return the value (name can be NULL) + // + if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) { + if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) { + return (((SHELL_PARAM_PACKAGE*)Node)->Value); + } + } + } + return (NULL); +} +/** + returns raw value from command line argument + + raw value parameters are in the form of "value" in a specific position in the list + + if CheckPackage is NULL, then return NULL; + + @param CheckPackage The package of parsed command line arguments + @param Position the position of the value + + @retval NULL the flag is not on the command line + @return !=NULL pointer to unicode string of the value + **/ +CONST CHAR16* +EFIAPI +ShellCommandLineGetRawValue ( + IN CONST LIST_ENTRY *CheckPackage, + IN UINT32 Position + ) +{ + LIST_ENTRY *Node; + + // + // check for CheckPackage == NULL + // + if (CheckPackage == NULL) { + return (NULL); + } + + // + // enumerate through the list of parametrs + // + for (Node = GetFirstNode(CheckPackage) ; Node != NULL ; Node = GetNextNode(CheckPackage, Node) ) { + // + // If the position matches, return the value + // + if (((SHELL_PARAM_PACKAGE*)Node)->OriginalPosition == Position) { + return (((SHELL_PARAM_PACKAGE*)Node)->Value); + } + } + return (NULL); +} \ No newline at end of file diff --git a/ShellPkg/Library/BaseShellLib/BaseShellLib.inf b/ShellPkg/Library/BaseShellLib/BaseShellLib.inf new file mode 100644 index 0000000000..8a2c33b8a1 --- /dev/null +++ b/ShellPkg/Library/BaseShellLib/BaseShellLib.inf @@ -0,0 +1,61 @@ +#/** @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 = BaseShellLib + FILE_GUID = 449D0F00-2148-4a43-9836-F10B3980ECF5 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = ShellLib|UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = ShellLibConstructor + DESTRUCTOR = ShellLibDestructor + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + BaseShellLib.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + DevicePathLib + BaseLib + BaseMemoryLib + DebugLib + +[Protocols] + gEfiSimpleFileSystemProtocolGuid # ALWAYS_CONSUMED + + # shell 2.0 + gEfiShellProtocolGuid # SOMETIMES_CONSUMED + gEfiShellParametersProtocolGuid # SOMETIMES_CONSUMED + + # 'old' shell + gEfiShellEnvironment2Guid # SOMETIMES_CONSUMED + gEfiShellInterfaceGuid # SOMETIMES_CONSUMED + +[Guids] + gEfiFileInfoGuid # ALWAYS_CONSUMED + gEfiShellEnvironment2ExtGuid # ALWAYS_CONSUMED + +[Pcd.common] + diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec new file mode 100644 index 0000000000..922ad5e8ad --- /dev/null +++ b/ShellPkg/ShellPkg.dec @@ -0,0 +1,50 @@ +## @file ShellPkg.dec +# +# This Package provides all definitions for EFI and UEFI Shell +# +# 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. +# +## + + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = ShellPkg + PACKAGE_GUID = 9FB7587C-93F7-40a7-9C04-FD7BA94EE646 + PACKAGE_VERSION = 0.1 + + +[Includes.common] + Include + +[LibraryClasses.common] + ## @libraryclass Provides most Shell APIs. + # Only available for Shell applications + ## + ShellLib|Include/Library/ShellLib.h + +[Guids.common] + gEfiShellEnvironment2ExtGuid = {0xd2c18636, 0x40e5, 0x4eb5, {0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87}} + +[Protocols.common] + gEfiShellProtocolGuid = {0x6302d008, 0x7f9b, 0x4f30, {0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}} + gEfiShellParametersProtocolGuid = {0x752f3136, 0x4e16, 0x4fdc, {0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca}} + 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 diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc new file mode 100644 index 0000000000..ebe872aa7b --- /dev/null +++ b/ShellPkg/ShellPkg.dsc @@ -0,0 +1,48 @@ +#/** @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 +# +# 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] + PLATFORM_NAME = Shell + PLATFORM_GUID = E1DC9BF8-7013-4c99-9437-795DAA45F3BD + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/Shell + SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses.common] + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf + PrintLib|MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + ShellLib|ShellPkg/Library/BaseShellLib/BaseShellLib.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