diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index 5271d19490..fcb7e430ed 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -197,6 +197,7 @@ ShellLibConstructorWorker (
mEfiShellInterface = NULL;
}
}
+
//
// only success getting 2 of either the old or new, but no 1/2 and 1/2
//
@@ -247,7 +248,6 @@ ShellLibConstructor (
IN EFI_SYSTEM_TABLE *SystemTable
) {
-
mEfiShellEnvironment2 = NULL;
mEfiShellProtocol = NULL;
mEfiShellParametersProtocol = NULL;
@@ -1278,6 +1278,10 @@ InternalShellConvertFileListType (
// allocate a new EFI_SHELL_FILE_INFO object
//
NewInfo = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
+ ASSERT(NewInfo != NULL);
+ if (NewInfo == NULL) {
+ break;
+ }
//
// copy the simple items
@@ -1498,6 +1502,10 @@ ShellFindFilePath (
Size = StrSize(Path);
Size += StrSize(FileName);
TestPath = AllocateZeroPool(Size);
+ ASSERT(TestPath != NULL);
+ if (TestPath == NULL) {
+ return (NULL);
+ }
StrCpy(TestPath, Path);
StrCat(TestPath, FileName);
Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);
@@ -1567,6 +1575,7 @@ ShellFindFilePathEx (
CONST CHAR16 *ExtensionWalker;
UINTN Size;
CHAR16 *TempChar;
+ CHAR16 *TempChar2;
ASSERT(FileName != NULL);
if (FileExtension == NULL) {
@@ -1579,7 +1588,11 @@ ShellFindFilePathEx (
Size = StrSize(FileName);
Size += StrSize(FileExtension);
TestPath = AllocateZeroPool(Size);
- for (ExtensionWalker = FileExtension ; ; ExtensionWalker = StrStr(ExtensionWalker, L";") + 1 ){
+ ASSERT(TestPath != NULL);
+ if (TestPath == NULL) {
+ return (NULL);
+ }
+ for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16*)FileExtension; TempChar2 != NULL ; ExtensionWalker = TempChar2 + 1 ){
StrCpy(TestPath, FileName);
if (ExtensionWalker != NULL) {
StrCat(TestPath, ExtensionWalker);
@@ -1592,12 +1605,7 @@ ShellFindFilePathEx (
if (RetVal != NULL) {
break;
}
- //
- // Must be after first loop...
- //
- if (StrStr(ExtensionWalker, L";") == NULL) {
- break;
- }
+ TempChar2 = StrStr(ExtensionWalker, L";");
}
FreePool(TestPath);
return (RetVal);
@@ -2804,13 +2812,185 @@ StrnCatGrow (
NewSize += 2 * Count * sizeof(CHAR16);
}
*Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);
+ ASSERT(*Destination != NULL);
*CurrentSize = NewSize;
} else {
*Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));
+ ASSERT(*Destination != NULL);
}
//
// Now use standard StrnCat on a big enough buffer
//
+ if (*Destination == NULL) {
+ return (NULL);
+ }
return StrnCat(*Destination, Source, Count);
}
+
+/**
+ Prompt the user and return the resultant answer to the requestor.
+
+ This function will display the requested question on the shell prompt and then
+ wait for an apropriate answer to be input from the console.
+
+ if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, SHELL_PROMPT_REQUEST_TYPE_QUIT_CONTINUE
+ or SHELL_PROMPT_REQUEST_TYPE_YESNOCANCEL then *Response is of type SHELL_PROMPT_RESPONSE.
+
+ if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_FREEFORM then *Response is of type
+ CHAR16*.
+
+ In either case *Response must be callee freed if Response was not NULL;
+
+ @param Type What type of question is asked. This is used to filter the input
+ to prevent invalid answers to question.
+ @param Prompt Pointer to string prompt to use to request input.
+ @param Response Pointer to Response which will be populated upon return.
+
+ @retval EFI_SUCCESS The operation was sucessful.
+ @retval EFI_UNSUPPORTED The operation is not supported as requested.
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.
+ @return other The operation failed.
+**/
+EFI_STATUS
+EFIAPI
+ShellPromptForResponse (
+ IN SHELL_PROMPT_REQUEST_TYPE Type,
+ IN CHAR16 *Prompt OPTIONAL,
+ IN OUT VOID **Response OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ UINTN EventIndex;
+ SHELL_PROMPT_RESPONSE *Resp;
+
+ Status = EFI_SUCCESS;
+ Resp = (SHELL_PROMPT_RESPONSE*)AllocatePool(sizeof(SHELL_PROMPT_RESPONSE));
+
+ switch(Type) {
+ case SHELL_PROMPT_REQUEST_TYPE_QUIT_CONTINUE:
+ if (Prompt != NULL) {
+ ShellPrintEx(-1, -1, L"%s", Prompt);
+ }
+ //
+ // wait for valid response
+ //
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR(Status);
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);
+ if (Key.UnicodeChar == L'Q' || Key.UnicodeChar ==L'q') {
+ *Resp = SHELL_PROMPT_RESPONSE_QUIT;
+ } else {
+ *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;
+ }
+ break;
+ case SHELL_PROMPT_REQUEST_TYPE_YES_NO_ALL_CANCEL:
+ if (Prompt != NULL) {
+ ShellPrintEx(-1, -1, L"%s", Prompt);
+ }
+ //
+ // wait for valid response
+ //
+ *Resp = SHELL_PROMPT_RESPONSE_MAX;
+ while (*Resp == SHELL_PROMPT_RESPONSE_MAX) {
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR(Status);
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);
+ switch (Key.UnicodeChar) {
+ case L'Y':
+ case L'y':
+ *Resp = SHELL_PROMPT_RESPONSE_YES;
+ break;
+ case L'N':
+ case L'n':
+ *Resp = SHELL_PROMPT_RESPONSE_NO;
+ break;
+ case L'A':
+ case L'a':
+ *Resp = SHELL_PROMPT_RESPONSE_ALL;
+ break;
+ case L'C':
+ case L'c':
+ *Resp = SHELL_PROMPT_RESPONSE_CANCEL;
+ break;
+ }
+ }
+ break;
+ case SHELL_PROMPT_REQUEST_TYPE_ENTER_TO_COMTINUE:
+ case SHELL_PROMPT_REQUEST_TYPE_ANYKEY_TO_COMTINUE:
+ if (Prompt != NULL) {
+ ShellPrintEx(-1, -1, L"%s", Prompt);
+ }
+ //
+ // wait for valid response
+ //
+ *Resp = SHELL_PROMPT_RESPONSE_MAX;
+ while (*Resp == SHELL_PROMPT_RESPONSE_MAX) {
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
+ if (Type == SHELL_PROMPT_REQUEST_TYPE_ENTER_TO_COMTINUE) {
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR(Status);
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);
+ if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;
+ break;
+ }
+ }
+ if (Type == SHELL_PROMPT_REQUEST_TYPE_ANYKEY_TO_COMTINUE) {
+ *Resp = SHELL_PROMPT_RESPONSE_CONTINUE;
+ break;
+ }
+ }
+ break;
+ ///@todo add more request types here!
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ if (Response != NULL) {
+ *Response = Resp;
+ } else {
+ FreePool(Resp);
+ }
+
+ return (Status);
+}
+
+/**
+ Prompt the user and return the resultant answer to the requestor.
+
+ This function is the same as ShellPromptForResponse, except that the prompt is
+ automatically pulled from HII.
+
+ @param Type What type of question is asked. This is used to filter the input
+ to prevent invalid answers to question.
+ @param Prompt Pointer to string prompt to use to request input.
+ @param Response Pointer to Response which will be populated upon return.
+
+ @retval EFI_SUCCESS the operation was sucessful.
+ @return other the operation failed.
+
+ @sa ShellPromptForResponse
+**/
+EFI_STATUS
+EFIAPI
+ShellPromptForResponseHii (
+ IN SHELL_PROMPT_REQUEST_TYPE Type,
+ IN CONST EFI_STRING_ID HiiFormatStringId,
+ IN CONST EFI_HANDLE HiiFormatHandle,
+ IN OUT VOID **Response
+ )
+{
+ CHAR16 *Prompt;
+ EFI_STATUS Status;
+
+ Prompt = HiiGetString(HiiFormatHandle, HiiFormatStringId, NULL);
+ Status = ShellPromptForResponse(Type, Prompt, Response);
+ FreePool(Prompt);
+ return (Status);
+}
+
+
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.inf b/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
index 4c4bf4a061..5aefe00893 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
@@ -1,7 +1,7 @@
#/** @file
# Provides interface to shell functionality for shell commands and applications.
#
-# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2010, 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