#include <Library/FileHandleLib.h>\r
#include <Library/PrintLib.h>\r
#include <Library/UefiLib.h>\r
+#include <Library/HiiLib.h>\r
\r
#include <Protocol/EfiShellEnvironment2.h>\r
#include <Protocol/EfiShellInterface.h>\r
STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;\r
STATIC EFI_HANDLE mEfiShellEnvironment2Handle;\r
STATIC FILE_HANDLE_FUNCTION_MAP FileFunctionMap;\r
+STATIC UINTN mTotalParameterCount;\r
+\r
+/**\r
+ Check if a Unicode character is a hexadecimal character.\r
+\r
+ This internal function checks if a Unicode character is a \r
+ decimal character. The valid hexadecimal character is \r
+ L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
+\r
+\r
+ @param Char The character to check against.\r
+\r
+ @retval TRUE If the Char is a hexadecmial character.\r
+ @retval FALSE If the Char is not a hexadecmial character.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellInternalIsHexaDecimalDigitCharacter (\r
+ IN CHAR16 Char\r
+ ) {\r
+ return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));\r
+}\r
\r
/**\r
helper function to find ShellEnvironment2 for constructor\r
EFIAPI\r
ShellFindSE2 (\r
IN EFI_HANDLE ImageHandle\r
- )\r
-{\r
+ ) {\r
EFI_STATUS Status;\r
EFI_HANDLE *Buffer;\r
UINTN BufferSize;\r
&BufferSize,\r
Buffer\r
);\r
- ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
- Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
- ASSERT(Buffer != NULL);\r
- Status = gBS->LocateHandle (ByProtocol,\r
- &gEfiShellEnvironment2Guid,\r
- NULL, // ignored for ByProtocol\r
- &BufferSize,\r
- Buffer\r
- );\r
+ //\r
+ // maybe it's not there???\r
+ //\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);\r
+ ASSERT(Buffer != NULL);\r
+ Status = gBS->LocateHandle (ByProtocol,\r
+ &gEfiShellEnvironment2Guid,\r
+ NULL, // ignored for ByProtocol\r
+ &BufferSize,\r
+ Buffer\r
+ );\r
+ }\r
if (!EFI_ERROR (Status)) {\r
//\r
// now parse the list of returned handles\r
ShellLibConstructorWorker (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
-){\r
+ ) {\r
EFI_STATUS Status;\r
\r
+ //\r
+ // Set the parameter count to an invalid number\r
+ //\r
+ mTotalParameterCount = (UINTN)(-1);\r
+\r
//\r
// UEFI 2.0 shell interfaces (used preferentially)\r
//\r
ShellLibConstructor (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
+ ) {\r
\r
\r
mEfiShellEnvironment2 = NULL;\r
ShellLibDestructor (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
- ){\r
+ ) {\r
if (mEfiShellEnvironment2 != NULL) {\r
gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
&gEfiShellEnvironment2Guid,\r
EFIAPI\r
ShellGetFileInfo (\r
IN EFI_FILE_HANDLE FileHandle\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.GetFileInfo(FileHandle));\r
}\r
\r
ShellSetFileInfo (\r
IN EFI_FILE_HANDLE FileHandle,\r
IN EFI_FILE_INFO *FileInfo\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.SetFileInfo(FileHandle, FileInfo));\r
} \r
\r
OUT EFI_FILE_HANDLE *FileHandle,\r
IN UINT64 OpenMode,\r
IN UINT64 Attributes\r
- )\r
-{\r
+ ) {\r
CHAR16 *FileName;\r
EFI_STATUS Status;\r
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
OUT EFI_FILE_HANDLE *FileHandle,\r
IN UINT64 OpenMode,\r
IN UINT64 Attributes\r
- )\r
-{\r
+ ) {\r
EFI_HANDLE DeviceHandle;\r
EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
EFI_STATUS Status;\r
Status = mEfiShellProtocol->OpenFileByName(FileName,\r
FileHandle,\r
OpenMode);\r
- if (!EFI_ERROR(Status)){\r
- FileInfo = FileHandleGetInfo(*FileHandle);\r
+ if (!EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
+ FileInfo = FileFunctionMap.GetFileInfo(*FileHandle);\r
ASSERT(FileInfo != NULL);\r
FileInfo->Attribute = Attributes;\r
- Status = FileHandleSetInfo(*FileHandle, FileInfo);\r
+ Status = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
+ FreePool(FileInfo);\r
}\r
return (Status);\r
} \r
ShellCreateDirectory(\r
IN CONST CHAR16 *DirectoryName,\r
OUT EFI_FILE_HANDLE *FileHandle\r
- )\r
-{\r
- //\r
- // this is a pass thru to the open file function with sepcific open mode and attributes\r
- //\r
- return (ShellOpenFileByName(DirectoryName,\r
- FileHandle,\r
- EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
- EFI_FILE_DIRECTORY\r
- ));\r
+ ) {\r
+ if (mEfiShellProtocol != NULL) {\r
+ //\r
+ // Use UEFI Shell 2.0 method\r
+ //\r
+ return (mEfiShellProtocol->CreateFile(DirectoryName,\r
+ EFI_FILE_DIRECTORY,\r
+ FileHandle\r
+ ));\r
+ } else {\r
+ return (ShellOpenFileByName(DirectoryName,\r
+ FileHandle,\r
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
+ EFI_FILE_DIRECTORY\r
+ ));\r
+ }\r
}\r
\r
/**\r
IN EFI_FILE_HANDLE FileHandle,\r
IN OUT UINTN *BufferSize,\r
OUT VOID *Buffer\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.ReadFile(FileHandle, BufferSize, Buffer));\r
}\r
\r
IN EFI_FILE_HANDLE FileHandle,\r
IN OUT UINTN *BufferSize,\r
IN VOID *Buffer\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.WriteFile(FileHandle, BufferSize, Buffer));\r
}\r
\r
EFIAPI\r
ShellCloseFile (\r
IN EFI_FILE_HANDLE *FileHandle\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.CloseFile(*FileHandle));\r
}\r
\r
EFIAPI\r
ShellDeleteFile (\r
IN EFI_FILE_HANDLE *FileHandle\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.DeleteFile(*FileHandle));\r
}\r
\r
ShellSetFilePosition (\r
IN EFI_FILE_HANDLE FileHandle,\r
IN UINT64 Position\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.SetFilePosition(FileHandle, Position));\r
}\r
\r
ShellGetFilePosition (\r
IN EFI_FILE_HANDLE FileHandle,\r
OUT UINT64 *Position\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.GetFilePosition(FileHandle, Position));\r
}\r
/**\r
EFIAPI\r
ShellFlushFile (\r
IN EFI_FILE_HANDLE FileHandle\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.FlushFile(FileHandle));\r
}\r
\r
ShellFindFirstFile (\r
IN EFI_FILE_HANDLE DirHandle,\r
OUT EFI_FILE_INFO **Buffer\r
- )\r
-{\r
+ ) {\r
//\r
// pass to file handle lib\r
//\r
IN EFI_FILE_HANDLE DirHandle,\r
OUT EFI_FILE_INFO *Buffer,\r
OUT BOOLEAN *NoFile\r
- )\r
-{\r
+ ) {\r
//\r
// pass to file handle lib\r
//\r
ShellGetFileSize (\r
IN EFI_FILE_HANDLE FileHandle,\r
OUT UINT64 *Size\r
- )\r
-{\r
+ ) {\r
return (FileFunctionMap.GetFileSize(FileHandle, Size));\r
}\r
/**\r
}\r
InitializeListHead(&((*ListHead)->Link));\r
} \r
- return (mEfiShellProtocol->OpenFileList(Arg, \r
+ Status = mEfiShellProtocol->OpenFileList(Arg, \r
OpenMode, \r
- ListHead));\r
+ ListHead);\r
+ if (EFI_ERROR(Status)) {\r
+ mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+ } else {\r
+ Status = mEfiShellProtocol->RemoveDupInFileList(ListHead);\r
+ }\r
+ return (Status);\r
} \r
\r
//\r
IN CONST CHAR16 *Name,\r
IN CONST SHELL_PARAM_ITEM *CheckList,\r
OUT ParamType *Type\r
- )\r
-{\r
+ ) {\r
SHELL_PARAM_ITEM *TempListItem;\r
\r
//\r
return (TRUE);\r
}\r
}\r
+\r
return (FALSE);\r
}\r
/**\r
BOOLEAN\r
EFIAPI\r
InternalIsFlag (\r
- IN CONST CHAR16 *Name\r
+ IN CONST CHAR16 *Name,\r
+ IN BOOLEAN AlwaysAllowNumbers\r
)\r
{\r
//\r
//\r
ASSERT(Name != NULL);\r
\r
+ //\r
+ // If we accept numbers then dont return TRUE. (they will be values)\r
+ //\r
+ if (((Name[0] == L'-' || Name[0] == L'+') && ShellInternalIsHexaDecimalDigitCharacter(Name[1])) && AlwaysAllowNumbers == TRUE) {\r
+ return (FALSE);\r
+ }\r
+\r
//\r
// If the Name has a / or - as the first character return TRUE\r
//\r
the invalid command line argument was returned in\r
ProblemParam if provided.\r
**/\r
+STATIC\r
EFI_STATUS\r
EFIAPI\r
InternalCommandLineParse (\r
OUT CHAR16 **ProblemParam OPTIONAL,\r
IN BOOLEAN AutoPageBreak,\r
IN CONST CHAR16 **Argv,\r
- IN UINTN Argc\r
- )\r
-{\r
+ IN UINTN Argc,\r
+ IN BOOLEAN AlwaysAllowNumbers\r
+ ) {\r
UINTN LoopCounter;\r
- UINTN Count;\r
ParamType CurrentItemType;\r
SHELL_PARAM_PACKAGE *CurrentItemPackage;\r
BOOLEAN GetItemValue;\r
\r
CurrentItemPackage = NULL;\r
-\r
- //\r
- // ASSERTs\r
- //\r
- ASSERT(CheckList != NULL);\r
- ASSERT(Argv != NULL);\r
-\r
- Count = 0;\r
+ mTotalParameterCount = 0;\r
GetItemValue = FALSE;\r
\r
//\r
return (EFI_SUCCESS);\r
}\r
\r
+ //\r
+ // ASSERTs\r
+ //\r
+ ASSERT(CheckList != NULL);\r
+ ASSERT(Argv != NULL);\r
+\r
//\r
// initialize the linked list\r
//\r
// do nothing for NULL argv\r
//\r
} else if (InternalIsOnCheckList(Argv[LoopCounter], CheckList, &CurrentItemType) == TRUE) {\r
+ //\r
+ // We might have leftover if last parameter didnt have optional value\r
+ //\r
+ if (GetItemValue == TRUE) {\r
+ GetItemValue = FALSE;\r
+ InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
+ }\r
//\r
// this is a flag\r
//\r
//\r
InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
}\r
- } else if (GetItemValue == TRUE && InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
+ } else if (GetItemValue == TRUE && InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
ASSERT(CurrentItemPackage != NULL);\r
//\r
// get the item VALUE for the previous flag\r
ASSERT(CurrentItemPackage->Value != NULL);\r
StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
- } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {\r
+ } else if (InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers) == FALSE) {\r
//\r
// add this one as a non-flag\r
//\r
CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));\r
ASSERT(CurrentItemPackage->Value != NULL);\r
StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);\r
- CurrentItemPackage->OriginalPosition = Count++;\r
+ CurrentItemPackage->OriginalPosition = mTotalParameterCount++;\r
InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
} else if (ProblemParam) {\r
//\r
**/\r
EFI_STATUS\r
EFIAPI\r
-ShellCommandLineParse (\r
+ShellCommandLineParseEx (\r
IN CONST SHELL_PARAM_ITEM *CheckList,\r
OUT LIST_ENTRY **CheckPackage,\r
OUT CHAR16 **ProblemParam OPTIONAL,\r
- IN BOOLEAN AutoPageBreak\r
- )\r
-{\r
+ IN BOOLEAN AutoPageBreak,\r
+ IN BOOLEAN AlwaysAllowNumbers\r
+ ) {\r
// \r
// ASSERT that CheckList and CheckPackage aren't NULL\r
//\r
ProblemParam, \r
AutoPageBreak, \r
(CONST CHAR16**) mEfiShellParametersProtocol->Argv,\r
- mEfiShellParametersProtocol->Argc ));\r
+ mEfiShellParametersProtocol->Argc,\r
+ AlwaysAllowNumbers));\r
}\r
\r
// \r
ProblemParam, \r
AutoPageBreak, \r
(CONST CHAR16**) mEfiShellInterface->Argv,\r
- mEfiShellInterface->Argc ));\r
+ mEfiShellInterface->Argc,\r
+ AlwaysAllowNumbers));\r
}\r
\r
/**\r
EFIAPI\r
ShellCommandLineFreeVarList (\r
IN LIST_ENTRY *CheckPackage\r
- )\r
-{\r
+ ) {\r
LIST_ENTRY *Node;\r
\r
//\r
// for each node in the list\r
//\r
for ( Node = GetFirstNode(CheckPackage)\r
- ; Node != CheckPackage \r
+ ; IsListEmpty(CheckPackage) == FALSE\r
; Node = GetFirstNode(CheckPackage)\r
){\r
//\r
ShellCommandLineGetFlag (\r
IN CONST LIST_ENTRY *CheckPackage,\r
IN CHAR16 *KeyString\r
- )\r
-{\r
+ ) {\r
LIST_ENTRY *Node;\r
\r
//\r
ShellCommandLineGetValue (\r
IN CONST LIST_ENTRY *CheckPackage,\r
IN CHAR16 *KeyString\r
- )\r
-{\r
+ ) {\r
LIST_ENTRY *Node;\r
\r
//\r
ShellCommandLineGetRawValue (\r
IN CONST LIST_ENTRY *CheckPackage,\r
IN UINT32 Position\r
- )\r
-{\r
+ ) {\r
LIST_ENTRY *Node;\r
\r
//\r
}\r
return (NULL);\r
}\r
+\r
+/**\r
+ returns the number of command line value parameters that were parsed. \r
+ \r
+ this will not include flags.\r
+\r
+ @retval (UINTN)-1 No parsing has ocurred\r
+ @return other The number of value parameters found\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellCommandLineGetCount(\r
+ VOID\r
+ ){\r
+ return (mTotalParameterCount);\r
+}\r
+\r
/**\r
This is a find and replace function. it will return the NewString as a copy of \r
SourceString with each instance of FindTarget replaced with ReplaceWith.\r
IN UINTN NewSize,\r
IN CONST CHAR16 *FindTarget,\r
IN CONST CHAR16 *ReplaceWith\r
- ){\r
+ ) \r
+{\r
UINTN Size;\r
if ( (SourceString == NULL)\r
|| (NewString == NULL)\r
){\r
return (EFI_INVALID_PARAMETER);\r
}\r
- NewString = SetMem16(NewString, NewSize, L'\0');\r
- while (*SourceString != L'\0') {\r
+ NewString = SetMem16(NewString, NewSize, CHAR_NULL);\r
+ while (*SourceString != CHAR_NULL) {\r
if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0) {\r
SourceString += StrLen(FindTarget);\r
Size = StrSize(NewString);\r
@param[in] Row the row to print at\r
@param[in] Col the column to print at\r
@param[in] Format the format string\r
+ @param[in] Marker the marker for the variable argument list\r
\r
@return the number of characters printed to the screen\r
**/\r
\r
UINTN\r
EFIAPI\r
-ShellPrintEx(\r
+InternalShellPrintWorker(\r
IN INT32 Col OPTIONAL,\r
IN INT32 Row OPTIONAL,\r
IN CONST CHAR16 *Format,\r
- ...\r
- ){\r
- VA_LIST Marker;\r
+ VA_LIST Marker\r
+ ) \r
+{\r
UINTN BufferSize;\r
CHAR16 *PostReplaceFormat;\r
CHAR16 *PostReplaceFormat2;\r
UINTN Return;\r
-\r
EFI_STATUS Status;\r
UINTN NormalAttribute;\r
CHAR16 *ResumeLocation;\r
CHAR16 *FormatWalker;\r
-\r
- VA_START (Marker, Format);\r
\r
BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
PostReplaceFormat = AllocateZeroPool (BufferSize);\r
\r
NormalAttribute = gST->ConOut->Mode->Attribute;\r
FormatWalker = PostReplaceFormat2;\r
- while (*FormatWalker != L'\0') {\r
+ while (*FormatWalker != CHAR_NULL) {\r
//\r
// Find the next attribute change request\r
//\r
ResumeLocation = StrStr(FormatWalker, L"%");\r
if (ResumeLocation != NULL) {\r
- *ResumeLocation = L'\0';\r
+ *ResumeLocation = CHAR_NULL;\r
}\r
//\r
// print the current FormatWalker string\r
\r
return (Return);\r
}\r
+\r
+/**\r
+ Print at a specific location on the screen.\r
+\r
+ This function will move the cursor to a given screen location and print the specified string\r
+ \r
+ If -1 is specified for either the Row or Col the current screen location for BOTH \r
+ will be used.\r
+\r
+ if either Row or Col is out of range for the current console, then ASSERT\r
+ if Format is NULL, then ASSERT\r
+\r
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports \r
+ the following additional flags:\r
+ %N - Set output attribute to normal\r
+ %H - Set output attribute to highlight\r
+ %E - Set output attribute to error\r
+ %B - Set output attribute to blue color\r
+ %V - Set output attribute to green color\r
+\r
+ Note: The background color is controlled by the shell command cls.\r
+\r
+ @param[in] Row the row to print at\r
+ @param[in] Col the column to print at\r
+ @param[in] Format the format string\r
+\r
+ @return the number of characters printed to the screen\r
+**/\r
+\r
+UINTN\r
+EFIAPI\r
+ShellPrintEx(\r
+ IN INT32 Col OPTIONAL,\r
+ IN INT32 Row OPTIONAL,\r
+ IN CONST CHAR16 *Format,\r
+ ...\r
+ ) \r
+{\r
+ VA_LIST Marker;\r
+ VA_START (Marker, Format);\r
+ return (InternalShellPrintWorker(Col, Row, Format, Marker));\r
+}\r
+\r
+/**\r
+ Print at a specific location on the screen.\r
+\r
+ This function will move the cursor to a given screen location, print the specified string, \r
+ and return the cursor to the original locaiton. \r
+ \r
+ If -1 is specified for either the Row or Col the current screen location for BOTH \r
+ will be used and the cursor's position will not be moved back to an original location.\r
+\r
+ if either Row or Col is out of range for the current console, then ASSERT\r
+ if Format is NULL, then ASSERT\r
+\r
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports \r
+ the following additional flags:\r
+ %N - Set output attribute to normal\r
+ %H - Set output attribute to highlight\r
+ %E - Set output attribute to error\r
+ %B - Set output attribute to blue color\r
+ %V - Set output attribute to green color\r
+\r
+ Note: The background color is controlled by the shell command cls.\r
+\r
+ @param[in] Row the row to print at\r
+ @param[in] Col the column to print at\r
+ @param[in] HiiFormatStringId the format string Id for getting from Hii\r
+ @param[in] HiiFormatHandle the format string Handle for getting from Hii\r
+\r
+ @return the number of characters printed to the screen\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellPrintHiiEx(\r
+ IN INT32 Col OPTIONAL,\r
+ IN INT32 Row OPTIONAL,\r
+ IN CONST EFI_STRING_ID HiiFormatStringId,\r
+ IN CONST EFI_HANDLE HiiFormatHandle,\r
+ ...\r
+ )\r
+{\r
+ VA_LIST Marker;\r
+ CHAR16 *HiiFormatString;\r
+ UINTN RetVal;\r
+\r
+ VA_START (Marker, HiiFormatHandle);\r
+ HiiFormatString = HiiGetString(HiiFormatHandle, HiiFormatStringId, NULL);\r
+ ASSERT(HiiFormatString != NULL);\r
+\r
+ RetVal = InternalShellPrintWorker(Col, Row, HiiFormatString, Marker);\r
+\r
+ FreePool(HiiFormatString);\r
+\r
+ return (RetVal);\r
+}\r
+\r
+/**\r
+ Function to determine if a given filename represents a file or a directory.\r
+\r
+ @param[in] DirName Path to directory to test.\r
+\r
+ @retval EFI_SUCCESS The Path represents a directory\r
+ @retval EFI_NOT_FOUND The Path does not represent a directory\r
+ @return other The path failed to open\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellIsDirectory(\r
+ IN CONST CHAR16 *DirName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_HANDLE Handle;\r
+\r
+ Handle = NULL;\r
+\r
+ Status = ShellOpenFileByName(DirName, &Handle, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+\r
+ if (FileHandleIsDirectory(Handle) == EFI_SUCCESS) {\r
+ ShellCloseFile(&Handle);\r
+ return (EFI_SUCCESS);\r
+ }\r
+ ShellCloseFile(&Handle);\r
+ return (EFI_NOT_FOUND);\r
+}\r
+\r