+ gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);\r
+\r
+ SHELL_FREE_NON_NULL(mPostReplaceFormat);\r
+ SHELL_FREE_NON_NULL(mPostReplaceFormat2);\r
+ return (Status);\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] Col the column to print at\r
+ @param[in] Row the row to print at\r
+ @param[in] Format the format string\r
+ @param[in] ... The variable argument list.\r
+\r
+ @return EFI_SUCCESS The printing was successful.\r
+ @return EFI_DEVICE_ERROR The console device reported an error.\r
+**/\r
+EFI_STATUS\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
+ EFI_STATUS RetVal;\r
+ if (Format == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ VA_START (Marker, Format);\r
+ RetVal = InternalShellPrintWorker(Col, Row, Format, Marker);\r
+ VA_END(Marker);\r
+ return(RetVal);\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] Col The column to print at.\r
+ @param[in] Row The row to print at.\r
+ @param[in] Language The language of the string to retrieve. If this parameter\r
+ is NULL, then the current platform language is used.\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
+ @param[in] ... The variable argument list.\r
+\r
+ @return EFI_SUCCESS The printing was successful.\r
+ @return EFI_DEVICE_ERROR The console device reported an error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellPrintHiiEx(\r
+ IN INT32 Col OPTIONAL,\r
+ IN INT32 Row OPTIONAL,\r
+ IN CONST CHAR8 *Language 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
+ EFI_STATUS RetVal;\r
+\r
+ RetVal = EFI_DEVICE_ERROR;\r
+\r
+ VA_START (Marker, HiiFormatHandle);\r
+ HiiFormatString = HiiGetString(HiiFormatHandle, HiiFormatStringId, Language);\r
+ if (HiiFormatString != NULL) {\r
+ RetVal = InternalShellPrintWorker (Col, Row, HiiFormatString, Marker);\r
+ SHELL_FREE_NON_NULL (HiiFormatString);\r
+ }\r
+ VA_END(Marker);\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
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
+ @return 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
+ SHELL_FILE_HANDLE Handle;\r
+ CHAR16 *TempLocation;\r
+ CHAR16 *TempLocation2;\r
+\r
+ ASSERT(DirName != NULL);\r
+\r
+ Handle = NULL;\r
+ TempLocation = NULL;\r
+\r
+ Status = ShellOpenFileByName(DirName, &Handle, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR(Status)) {\r
+ //\r
+ // try good logic first.\r
+ //\r
+ if (gEfiShellProtocol != NULL) {\r
+ TempLocation = StrnCatGrow(&TempLocation, NULL, DirName, 0);\r
+ if (TempLocation == NULL) {\r
+ ShellCloseFile(&Handle);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ TempLocation2 = StrStr(TempLocation, L":");\r
+ if (TempLocation2 != NULL && StrLen(StrStr(TempLocation, L":")) == 2) {\r
+ *(TempLocation2+1) = CHAR_NULL;\r
+ }\r
+ if (gEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) {\r
+ FreePool(TempLocation);\r
+ return (EFI_SUCCESS);\r
+ }\r
+ FreePool(TempLocation);\r
+ } else {\r
+ //\r
+ // probably a map name?!?!!?\r
+ //\r
+ TempLocation = StrStr(DirName, L"\\");\r
+ if (TempLocation != NULL && *(TempLocation+1) == CHAR_NULL) {\r
+ return (EFI_SUCCESS);\r
+ }\r
+ }\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
+/**\r
+ Function to determine if a given filename represents a file.\r
+\r
+ @param[in] Name Path to file to test.\r
+\r
+ @retval EFI_SUCCESS The Path represents a file.\r
+ @retval EFI_NOT_FOUND The Path does not represent a file.\r
+ @retval other The path failed to open.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellIsFile(\r
+ IN CONST CHAR16 *Name\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SHELL_FILE_HANDLE Handle;\r
+\r
+ ASSERT(Name != NULL);\r
+\r
+ Handle = NULL;\r
+\r
+ Status = ShellOpenFileByName(Name, &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
+/**\r
+ Function to determine if a given filename represents a file.\r
+\r
+ This will search the CWD and then the Path.\r
+\r
+ If Name is NULL, then ASSERT.\r
+\r
+ @param[in] Name Path to file to test.\r
+\r
+ @retval EFI_SUCCESS The Path represents a file.\r
+ @retval EFI_NOT_FOUND The Path does not represent a file.\r
+ @retval other The path failed to open.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellIsFileInPath(\r
+ IN CONST CHAR16 *Name\r
+ )\r
+{\r
+ CHAR16 *NewName;\r
+ EFI_STATUS Status;\r
+\r
+ if (!EFI_ERROR(ShellIsFile(Name))) {\r
+ return (EFI_SUCCESS);\r
+ }\r
+\r
+ NewName = ShellFindFilePath(Name);\r
+ if (NewName == NULL) {\r
+ return (EFI_NOT_FOUND);\r
+ }\r
+ Status = ShellIsFile(NewName);\r
+ FreePool(NewName);\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function return the number converted from a hex representation of a number.\r
+\r
+ Note: this function cannot be used when (UINTN)(-1), (0xFFFFFFFF) may be a valid\r
+ result. Use ShellConvertStringToUint64 instead.\r
+\r
+ @param[in] String String representation of a number.\r
+\r
+ @return The unsigned integer result of the conversion.\r
+ @retval (UINTN)(-1) An error occured.\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellHexStrToUintn(\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINT64 RetVal;\r
+\r
+ if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, TRUE, TRUE))) {\r
+ return ((UINTN)RetVal);\r
+ }\r
+ \r
+ return ((UINTN)(-1));\r
+}\r
+\r
+/**\r
+ Function to determine whether a string is decimal or hex representation of a number\r
+ and return the number converted from the string. Spaces are always skipped.\r
+\r
+ @param[in] String String representation of a number\r
+\r
+ @return the number\r
+ @retval (UINTN)(-1) An error ocurred.\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellStrToUintn(\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINT64 RetVal;\r
+ BOOLEAN Hex;\r
+\r
+ Hex = FALSE;\r
+\r
+ if (!InternalShellIsHexOrDecimalNumber(String, Hex, TRUE, FALSE)) {\r
+ Hex = TRUE;\r
+ }\r
+\r
+ if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, Hex, TRUE))) {\r
+ return ((UINTN)RetVal);\r
+ }\r
+ return ((UINTN)(-1));\r
+}\r
+\r
+/**\r
+ Safely append with automatic string resizing given length of Destination and\r
+ desired length of copy from Source.\r
+\r
+ append the first D characters of Source to the end of Destination, where D is\r
+ the lesser of Count and the StrLen() of Source. If appending those D characters\r
+ will fit within Destination (whose Size is given as CurrentSize) and\r
+ still leave room for a NULL terminator, then those characters are appended,\r
+ starting at the original terminating NULL of Destination, and a new terminating\r
+ NULL is appended.\r
+\r
+ If appending D characters onto Destination will result in a overflow of the size\r
+ given in CurrentSize the string will be grown such that the copy can be performed\r
+ and CurrentSize will be updated to the new size.\r
+\r
+ If Source is NULL, there is nothing to append, just return the current buffer in\r
+ Destination.\r
+\r
+ if Destination is NULL, then ASSERT()\r
+ if Destination's current length (including NULL terminator) is already more then\r
+ CurrentSize, then ASSERT()\r
+\r
+ @param[in, out] Destination The String to append onto\r
+ @param[in, out] CurrentSize on call the number of bytes in Destination. On\r
+ return possibly the new size (still in bytes). if NULL\r
+ then allocate whatever is needed.\r
+ @param[in] Source The String to append from\r
+ @param[in] Count Maximum number of characters to append. if 0 then\r
+ all are appended.\r
+\r
+ @return Destination return the resultant string.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+StrnCatGrow (\r
+ IN OUT CHAR16 **Destination,\r
+ IN OUT UINTN *CurrentSize,\r
+ IN CONST CHAR16 *Source,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ UINTN DestinationStartSize;\r
+ UINTN NewSize;\r
+\r
+ //\r
+ // ASSERTs\r
+ //\r
+ ASSERT(Destination != NULL);\r
+\r
+ //\r
+ // If there's nothing to do then just return Destination\r
+ //\r
+ if (Source == NULL) {\r
+ return (*Destination);\r
+ }\r
+\r
+ //\r
+ // allow for un-initialized pointers, based on size being 0\r
+ //\r
+ if (CurrentSize != NULL && *CurrentSize == 0) {\r
+ *Destination = NULL;\r
+ }\r
+\r
+ //\r
+ // allow for NULL pointers address as Destination\r
+ //\r
+ if (*Destination != NULL) {\r
+ ASSERT(CurrentSize != 0);\r
+ DestinationStartSize = StrSize(*Destination);\r
+ ASSERT(DestinationStartSize <= *CurrentSize);\r
+ } else {\r
+ DestinationStartSize = 0;\r
+// ASSERT(*CurrentSize == 0);\r
+ }\r
+\r
+ //\r
+ // Append all of Source?\r
+ //\r
+ if (Count == 0) {\r
+ Count = StrLen(Source);\r
+ }\r
+\r
+ //\r
+ // Test and grow if required\r
+ //\r
+ if (CurrentSize != NULL) {\r
+ NewSize = *CurrentSize;\r
+ if (NewSize < DestinationStartSize + (Count * sizeof(CHAR16))) {\r
+ while (NewSize < (DestinationStartSize + (Count*sizeof(CHAR16)))) {\r
+ NewSize += 2 * Count * sizeof(CHAR16);\r
+ }\r
+ *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);\r
+ *CurrentSize = NewSize;\r
+ }\r
+ } else {\r
+ NewSize = (Count+1)*sizeof(CHAR16);\r
+ *Destination = AllocateZeroPool(NewSize);\r
+ }\r
+\r
+ //\r
+ // Now use standard StrnCat on a big enough buffer\r
+ //\r
+ if (*Destination == NULL) {\r
+ return (NULL);\r
+ }\r
+ \r
+ StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);\r
+ return *Destination;\r
+}\r
+\r
+/**\r
+ Prompt the user and return the resultant answer to the requestor.\r
+\r
+ This function will display the requested question on the shell prompt and then\r
+ wait for an appropriate answer to be input from the console.\r
+\r
+ if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, ShellPromptResponseTypeQuitContinue\r
+ or SHELL_PROMPT_REQUEST_TYPE_YESNOCANCEL then *Response is of type SHELL_PROMPT_RESPONSE.\r
+\r
+ if the SHELL_PROMPT_REQUEST_TYPE is ShellPromptResponseTypeFreeform then *Response is of type\r
+ CHAR16*.\r
+\r
+ In either case *Response must be callee freed if Response was not NULL;\r
+\r
+ @param Type What type of question is asked. This is used to filter the input\r
+ to prevent invalid answers to question.\r
+ @param Prompt Pointer to string prompt to use to request input.\r
+ @param Response Pointer to Response which will be populated upon return.\r
+\r
+ @retval EFI_SUCCESS The operation was sucessful.\r
+ @retval EFI_UNSUPPORTED The operation is not supported as requested.\r
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
+ @return other The operation failed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellPromptForResponse (\r
+ IN SHELL_PROMPT_REQUEST_TYPE Type,\r
+ IN CHAR16 *Prompt OPTIONAL,\r
+ IN OUT VOID **Response OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_INPUT_KEY Key;\r
+ UINTN EventIndex;\r
+ SHELL_PROMPT_RESPONSE *Resp;\r
+ UINTN Size;\r
+ CHAR16 *Buffer;\r
+\r
+ Status = EFI_UNSUPPORTED;\r
+ Resp = NULL;\r
+ Buffer = NULL;\r
+ Size = 0;\r
+ if (Type != ShellPromptResponseTypeFreeform) {\r
+ Resp = (SHELL_PROMPT_RESPONSE*)AllocateZeroPool(sizeof(SHELL_PROMPT_RESPONSE));\r
+ if (Resp == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ }\r
+\r
+ switch(Type) {\r
+ case ShellPromptResponseTypeQuitContinue:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ //\r
+ // wait for valid response\r
+ //\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+ if (Key.UnicodeChar == L'Q' || Key.UnicodeChar ==L'q') {\r
+ *Resp = ShellPromptResponseQuit;\r
+ } else {\r
+ *Resp = ShellPromptResponseContinue;\r
+ }\r
+ break;\r
+ case ShellPromptResponseTypeYesNoCancel:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ //\r
+ // wait for valid response\r
+ //\r
+ *Resp = ShellPromptResponseMax;\r
+ while (*Resp == ShellPromptResponseMax) {\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+ switch (Key.UnicodeChar) {\r
+ case L'Y':\r
+ case L'y':\r
+ *Resp = ShellPromptResponseYes;\r
+ break;\r
+ case L'N':\r
+ case L'n':\r
+ *Resp = ShellPromptResponseNo;\r
+ break;\r
+ case L'C':\r
+ case L'c':\r
+ *Resp = ShellPromptResponseCancel;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case ShellPromptResponseTypeYesNoAllCancel:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ //\r
+ // wait for valid response\r
+ //\r
+ *Resp = ShellPromptResponseMax;\r
+ while (*Resp == ShellPromptResponseMax) {\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+\r
+ if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) {\r
+ ShellPrintEx (-1, -1, L"%c", Key.UnicodeChar);\r
+ }\r
+\r
+ switch (Key.UnicodeChar) {\r
+ case L'Y':\r
+ case L'y':\r
+ *Resp = ShellPromptResponseYes;\r
+ break;\r
+ case L'N':\r
+ case L'n':\r
+ *Resp = ShellPromptResponseNo;\r
+ break;\r
+ case L'A':\r
+ case L'a':\r
+ *Resp = ShellPromptResponseAll;\r
+ break;\r
+ case L'C':\r
+ case L'c':\r
+ *Resp = ShellPromptResponseCancel;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case ShellPromptResponseTypeEnterContinue:\r
+ case ShellPromptResponseTypeAnyKeyContinue:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ //\r
+ // wait for valid response\r
+ //\r
+ *Resp = ShellPromptResponseMax;\r
+ while (*Resp == ShellPromptResponseMax) {\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ if (Type == ShellPromptResponseTypeEnterContinue) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+ if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+ *Resp = ShellPromptResponseContinue;\r
+ break;\r
+ }\r
+ }\r
+ if (Type == ShellPromptResponseTypeAnyKeyContinue) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ ASSERT_EFI_ERROR(Status);\r
+ *Resp = ShellPromptResponseContinue;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case ShellPromptResponseTypeYesNo:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ //\r
+ // wait for valid response\r
+ //\r
+ *Resp = ShellPromptResponseMax;\r
+ while (*Resp == ShellPromptResponseMax) {\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+ switch (Key.UnicodeChar) {\r
+ case L'Y':\r
+ case L'y':\r
+ *Resp = ShellPromptResponseYes;\r
+ break;\r
+ case L'N':\r
+ case L'n':\r
+ *Resp = ShellPromptResponseNo;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case ShellPromptResponseTypeFreeform:\r
+ if (Prompt != NULL) {\r
+ ShellPrintEx(-1, -1, L"%s", Prompt);\r
+ }\r
+ while(1) {\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+ if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+ break;\r
+ }\r
+ ASSERT((Buffer == NULL && Size == 0) || (Buffer != NULL));\r
+ StrnCatGrow(&Buffer, &Size, &Key.UnicodeChar, 1);\r
+ }\r
+ break;\r
+ //\r
+ // This is the location to add new prompt types.\r
+ // If your new type loops remember to add ExecutionBreak support.\r
+ //\r
+ default:\r
+ ASSERT(FALSE);\r
+ }\r
+\r
+ if (Response != NULL) {\r
+ if (Resp != NULL) {\r
+ *Response = Resp;\r
+ } else if (Buffer != NULL) {\r
+ *Response = Buffer;\r
+ }\r
+ } else {\r
+ if (Resp != NULL) {\r
+ FreePool(Resp);\r
+ }\r
+ if (Buffer != NULL) {\r
+ FreePool(Buffer);\r
+ }\r
+ }\r
+\r
+ ShellPrintEx(-1, -1, L"\r\n");\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Prompt the user and return the resultant answer to the requestor.\r
+\r
+ This function is the same as ShellPromptForResponse, except that the prompt is\r
+ automatically pulled from HII.\r
+\r
+ @param Type What type of question is asked. This is used to filter the input\r
+ to prevent invalid answers to question.\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
+ @param Response Pointer to Response which will be populated upon return.\r
+\r
+ @retval EFI_SUCCESS the operation was sucessful.\r
+ @return other the operation failed.\r
+\r
+ @sa ShellPromptForResponse\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellPromptForResponseHii (\r
+ IN SHELL_PROMPT_REQUEST_TYPE Type,\r
+ IN CONST EFI_STRING_ID HiiFormatStringId,\r
+ IN CONST EFI_HANDLE HiiFormatHandle,\r
+ IN OUT VOID **Response\r
+ )\r
+{\r
+ CHAR16 *Prompt;\r
+ EFI_STATUS Status;\r
+\r
+ Prompt = HiiGetString(HiiFormatHandle, HiiFormatStringId, NULL);\r
+ Status = ShellPromptForResponse(Type, Prompt, Response);\r
+ FreePool(Prompt);\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function to determin if an entire string is a valid number.\r
+\r
+ If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.\r
+\r
+ @param[in] String The string to evaluate.\r
+ @param[in] ForceHex TRUE - always assume hex.\r
+ @param[in] StopAtSpace TRUE to halt upon finding a space, FALSE to keep going.\r
+ @param[in] TimeNumbers TRUE to allow numbers with ":", FALSE otherwise.\r
+\r
+ @retval TRUE It is all numeric (dec/hex) characters.\r
+ @retval FALSE There is a non-numeric character.\r
+**/\r
+BOOLEAN\r
+InternalShellIsHexOrDecimalNumber (\r
+ IN CONST CHAR16 *String,\r
+ IN CONST BOOLEAN ForceHex,\r
+ IN CONST BOOLEAN StopAtSpace,\r
+ IN CONST BOOLEAN TimeNumbers\r
+ )\r
+{\r
+ BOOLEAN Hex;\r
+ BOOLEAN LeadingZero;\r
+\r
+ if (String == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // chop off a single negative sign\r
+ //\r
+ if (*String == L'-') {\r
+ String++;\r
+ }\r
+\r
+ if (*String == CHAR_NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // chop leading zeroes\r
+ //\r
+ LeadingZero = FALSE;\r
+ while(*String == L'0'){\r
+ String++;\r
+ LeadingZero = TRUE;\r
+ }\r
+ //\r
+ // allow '0x' or '0X', but not 'x' or 'X'\r
+ //\r
+ if (*String == L'x' || *String == L'X') {\r
+ if (!LeadingZero) {\r
+ //\r
+ // we got an x without a preceeding 0\r
+ //\r
+ return (FALSE);\r
+ }\r
+ String++;\r
+ Hex = TRUE;\r
+ } else if (ForceHex) {\r
+ Hex = TRUE;\r
+ } else {\r
+ Hex = FALSE;\r
+ }\r
+\r
+ //\r
+ // loop through the remaining characters and use the lib function\r
+ //\r
+ for ( ; *String != CHAR_NULL && !(StopAtSpace && *String == L' ') ; String++){\r
+ if (TimeNumbers && (String[0] == L':')) {\r
+ continue;\r
+ }\r
+ if (Hex) {\r
+ if (!ShellIsHexaDecimalDigitCharacter(*String)) {\r
+ return (FALSE);\r
+ }\r
+ } else {\r
+ if (!ShellIsDecimalDigitCharacter(*String)) {\r
+ return (FALSE);\r
+ }\r
+ }\r
+ }\r
+\r
+ return (TRUE);\r
+}\r
+\r
+/**\r
+ Function to determine if a given filename exists.\r
+\r
+ @param[in] Name Path to test.\r
+\r
+ @retval EFI_SUCCESS The Path represents a file.\r
+ @retval EFI_NOT_FOUND The Path does not represent a file.\r
+ @retval other The path failed to open.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFileExists(\r
+ IN CONST CHAR16 *Name\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SHELL_FILE_INFO *List;\r
+\r
+ ASSERT(Name != NULL);\r
+\r
+ List = NULL;\r
+ Status = ShellOpenFileMetaArg((CHAR16*)Name, EFI_FILE_MODE_READ, &List);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+\r
+ ShellCloseFileMetaArg(&List);\r
+\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Convert a Unicode character to upper case only if\r
+ it maps to a valid small-case ASCII character.\r
+\r
+ This internal function only deal with Unicode character\r
+ which maps to a valid small-case ASCII character, i.e.\r
+ L'a' to L'z'. For other Unicode character, the input character\r
+ is returned directly.\r
+\r
+ @param Char The character to convert.\r
+\r
+ @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
+ @retval Unchanged Otherwise.\r
+\r
+**/\r
+CHAR16\r
+InternalShellCharToUpper (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ if (Char >= L'a' && Char <= L'z') {\r
+ return (CHAR16) (Char - (L'a' - L'A'));\r
+ }\r
+\r
+ return Char;\r
+}\r
+\r
+/**\r
+ Convert a Unicode character to numerical value.\r
+\r
+ This internal function only deal with Unicode character\r
+ which maps to a valid hexadecimal ASII character, i.e.\r
+ L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
+ Unicode character, the value returned does not make sense.\r
+\r
+ @param Char The character to convert.\r
+\r
+ @return The numerical value converted.\r
+\r
+**/\r
+UINTN\r
+InternalShellHexCharToUintn (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ if (ShellIsDecimalDigitCharacter (Char)) {\r
+ return Char - L'0';\r
+ }\r
+\r
+ return (10 + InternalShellCharToUpper (Char) - L'A');\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
+\r
+ This function returns a value of type UINT64 by interpreting the contents\r
+ of the Unicode string specified by String as a hexadecimal number.\r
+ The format of the input Unicode string String is:\r
+\r
+ [spaces][zeros][x][hexadecimal digits].\r
+\r
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
+ If "x" appears in the input string, it must be prefixed with at least one 0.\r
+ The function will ignore the pad space, which includes spaces or tab characters,\r
+ before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
+ [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
+ first valid hexadecimal digit. Then, the function stops at the first character that is\r
+ a not a valid hexadecimal character or NULL, whichever one comes first.\r
+\r
+ If String has only pad spaces, then zero is returned.\r
+ If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
+ then zero is returned.\r
+\r
+ @param[in] String A pointer to a Null-terminated Unicode string.\r
+ @param[out] Value Upon a successful return the value of the conversion.\r
+ @param[in] StopAtSpace FALSE to skip spaces.\r
+\r
+ @retval EFI_SUCCESS The conversion was successful.\r
+ @retval EFI_INVALID_PARAMETER A parameter was NULL or invalid.\r
+ @retval EFI_DEVICE_ERROR An overflow occured.\r
+**/\r
+EFI_STATUS\r
+InternalShellStrHexToUint64 (\r
+ IN CONST CHAR16 *String,\r
+ OUT UINT64 *Value,\r
+ IN CONST BOOLEAN StopAtSpace\r
+ )\r
+{\r
+ UINT64 Result;\r
+\r
+ if (String == NULL || StrSize(String) == 0 || Value == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ //\r
+ // Ignore the pad spaces (space or tab)\r
+ //\r
+ while ((*String == L' ') || (*String == L'\t')) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (*String == L'0') {\r
+ String++;\r
+ }\r
+\r
+ if (InternalShellCharToUpper (*String) == L'X') {\r
+ if (*(String - 1) != L'0') {\r
+ return 0;\r
+ }\r
+ //\r
+ // Skip the 'X'\r
+ //\r
+ String++;\r
+ }\r
+\r
+ Result = 0;\r
+\r
+ //\r
+ // there is a space where there should't be\r
+ //\r
+ if (*String == L' ') {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ while (ShellIsHexaDecimalDigitCharacter (*String)) {\r
+ //\r
+ // If the Hex Number represented by String overflows according\r
+ // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
+ //\r
+ if (!(Result <= (RShiftU64((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {\r
+// if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {\r
+ return (EFI_DEVICE_ERROR);\r
+ }\r
+\r
+ Result = (LShiftU64(Result, 4));\r
+ Result += InternalShellHexCharToUintn (*String);\r
+ String++;\r
+\r
+ //\r
+ // stop at spaces if requested\r
+ //\r
+ if (StopAtSpace && *String == L' ') {\r
+ break;\r
+ }\r
+ }\r
+\r
+ *Value = Result;\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated Unicode decimal string to a value of\r
+ type UINT64.\r
+\r
+ This function returns a value of type UINT64 by interpreting the contents\r
+ of the Unicode string specified by String as a decimal number. The format\r
+ of the input Unicode string String is:\r
+\r
+ [spaces] [decimal digits].\r
+\r
+ The valid decimal digit character is in the range [0-9]. The\r
+ function will ignore the pad space, which includes spaces or\r
+ tab characters, before [decimal digits]. The running zero in the\r
+ beginning of [decimal digits] will be ignored. Then, the function\r
+ stops at the first character that is a not a valid decimal character\r
+ or a Null-terminator, whichever one comes first.\r
+\r
+ If String has only pad spaces, then 0 is returned.\r
+ If String has no pad spaces or valid decimal digits,\r
+ then 0 is returned.\r
+\r
+ @param[in] String A pointer to a Null-terminated Unicode string.\r
+ @param[out] Value Upon a successful return the value of the conversion.\r
+ @param[in] StopAtSpace FALSE to skip spaces.\r
+\r
+ @retval EFI_SUCCESS The conversion was successful.\r
+ @retval EFI_INVALID_PARAMETER A parameter was NULL or invalid.\r
+ @retval EFI_DEVICE_ERROR An overflow occured.\r
+**/\r
+EFI_STATUS\r
+InternalShellStrDecimalToUint64 (\r
+ IN CONST CHAR16 *String,\r
+ OUT UINT64 *Value,\r
+ IN CONST BOOLEAN StopAtSpace\r
+ )\r
+{\r
+ UINT64 Result;\r
+\r
+ if (String == NULL || StrSize (String) == 0 || Value == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ //\r
+ // Ignore the pad spaces (space or tab)\r
+ //\r
+ while ((*String == L' ') || (*String == L'\t')) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (*String == L'0') {\r
+ String++;\r
+ }\r
+\r
+ Result = 0;\r
+\r
+ //\r
+ // Stop upon space if requested \r
+ // (if the whole value was 0)\r
+ //\r
+ if (StopAtSpace && *String == L' ') {\r
+ *Value = Result;\r
+ return (EFI_SUCCESS);\r
+ }\r
+\r
+ while (ShellIsDecimalDigitCharacter (*String)) {\r
+ //\r
+ // If the number represented by String overflows according\r
+ // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
+ //\r
+\r
+ if (!(Result <= (DivU64x32((((UINT64) ~0) - (*String - L'0')),10)))) {\r
+ return (EFI_DEVICE_ERROR);\r
+ }\r
+\r
+ Result = MultU64x32(Result, 10) + (*String - L'0');\r
+ String++;\r
+\r
+ //\r
+ // Stop at spaces if requested\r
+ //\r
+ if (StopAtSpace && *String == L' ') {\r
+ break;\r
+ }\r
+ }\r
+\r
+ *Value = Result;\r
+\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Function to verify and convert a string to its numerical value.\r
+\r
+ If Hex it must be preceeded with a 0x, 0X, or has ForceHex set TRUE.\r
+\r
+ @param[in] String The string to evaluate.\r
+ @param[out] Value Upon a successful return the value of the conversion.\r
+ @param[in] ForceHex TRUE - always assume hex.\r
+ @param[in] StopAtSpace FALSE to skip spaces.\r
+\r
+ @retval EFI_SUCCESS The conversion was successful.\r
+ @retval EFI_INVALID_PARAMETER String contained an invalid character.\r
+ @retval EFI_NOT_FOUND String was a number, but Value was NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellConvertStringToUint64(\r
+ IN CONST CHAR16 *String,\r
+ OUT UINT64 *Value,\r
+ IN CONST BOOLEAN ForceHex,\r
+ IN CONST BOOLEAN StopAtSpace\r
+ )\r
+{\r
+ UINT64 RetVal;\r
+ CONST CHAR16 *Walker;\r
+ EFI_STATUS Status;\r
+ BOOLEAN Hex;\r
+\r
+ Hex = ForceHex;\r
+\r
+ if (!InternalShellIsHexOrDecimalNumber(String, Hex, StopAtSpace, FALSE)) {\r
+ if (!Hex) {\r
+ Hex = TRUE;\r
+ if (!InternalShellIsHexOrDecimalNumber(String, Hex, StopAtSpace, FALSE)) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ } else {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Chop off leading spaces\r
+ //\r
+ for (Walker = String; Walker != NULL && *Walker != CHAR_NULL && *Walker == L' '; Walker++);\r
+\r
+ //\r
+ // make sure we have something left that is numeric.\r
+ //\r
+ if (Walker == NULL || *Walker == CHAR_NULL || !InternalShellIsHexOrDecimalNumber(Walker, Hex, StopAtSpace, FALSE)) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ //\r
+ // do the conversion.\r
+ //\r
+ if (Hex || StrnCmp(Walker, L"0x", 2) == 0 || StrnCmp(Walker, L"0X", 2) == 0){\r
+ Status = InternalShellStrHexToUint64(Walker, &RetVal, StopAtSpace);\r
+ } else {\r
+ Status = InternalShellStrDecimalToUint64(Walker, &RetVal, StopAtSpace);\r
+ }\r
+\r
+ if (Value == NULL && !EFI_ERROR(Status)) {\r
+ return (EFI_NOT_FOUND);\r
+ }\r
+\r
+ if (Value != NULL) {\r
+ *Value = RetVal;\r
+ }\r
+\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function to determin if an entire string is a valid number.\r
+\r
+ If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.\r
+\r
+ @param[in] String The string to evaluate.\r
+ @param[in] ForceHex TRUE - always assume hex.\r
+ @param[in] StopAtSpace TRUE to halt upon finding a space, FALSE to keep going.\r
+\r
+ @retval TRUE It is all numeric (dec/hex) characters.\r
+ @retval FALSE There is a non-numeric character.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ShellIsHexOrDecimalNumber (\r
+ IN CONST CHAR16 *String,\r
+ IN CONST BOOLEAN ForceHex,\r
+ IN CONST BOOLEAN StopAtSpace\r
+ )\r
+{\r
+ if (ShellConvertStringToUint64(String, NULL, ForceHex, StopAtSpace) == EFI_NOT_FOUND) {\r
+ return (TRUE);\r
+ }\r
+ return (FALSE);\r
+}\r
+\r
+/**\r
+ Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned\r
+ buffer. The returned buffer must be callee freed.\r
+\r
+ If the position upon start is 0, then the Ascii Boolean will be set. This should be\r
+ maintained and not changed for all operations with the same file.\r
+\r
+ @param[in] Handle SHELL_FILE_HANDLE to read from.\r
+ @param[in, out] Ascii Boolean value for indicating whether the file is\r
+ Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+ @return The line of text from the file.\r
+ @retval NULL There was not enough memory available.\r
+\r
+ @sa ShellFileHandleReadLine\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+ShellFileHandleReturnLine(\r
+ IN SHELL_FILE_HANDLE Handle,\r
+ IN OUT BOOLEAN *Ascii\r
+ )\r
+{\r
+ CHAR16 *RetVal;\r
+ UINTN Size;\r
+ EFI_STATUS Status;\r
+\r
+ Size = 0;\r
+ RetVal = NULL;\r
+\r
+ Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ RetVal = AllocateZeroPool(Size);\r
+ if (RetVal == NULL) {\r
+ return (NULL);\r
+ }\r
+ Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+\r
+ }\r
+ if (Status == EFI_END_OF_FILE && RetVal != NULL && *RetVal != CHAR_NULL) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
+ FreePool(RetVal);\r
+ RetVal = NULL;\r
+ }\r
+ return (RetVal);\r
+}\r
+\r
+/**\r
+ Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE.\r
+\r
+ If the position upon start is 0, then the Ascii Boolean will be set. This should be\r
+ maintained and not changed for all operations with the same file.\r
+\r
+ NOTE: LINES THAT ARE RETURNED BY THIS FUNCTION ARE UCS2, EVEN IF THE FILE BEING READ\r
+ IS IN ASCII FORMAT.\r
+\r
+ @param[in] Handle SHELL_FILE_HANDLE to read from.\r
+ @param[in, out] Buffer The pointer to buffer to read into. If this function\r
+ returns EFI_SUCCESS, then on output Buffer will\r
+ contain a UCS2 string, even if the file being\r
+ read is ASCII.\r
+ @param[in, out] Size On input, pointer to number of bytes in Buffer.\r
+ On output, unchanged unless Buffer is too small\r
+ to contain the next line of the file. In that\r
+ case Size is set to the number of bytes needed\r
+ to hold the next line of the file (as a UCS2\r
+ string, even if it is an ASCII file).\r
+ @param[in] Truncate If the buffer is large enough, this has no effect.\r
+ If the buffer is is too small and Truncate is TRUE,\r
+ the line will be truncated.\r
+ If the buffer is is too small and Truncate is FALSE,\r
+ then no read will occur.\r
+\r
+ @param[in, out] Ascii Boolean value for indicating whether the file is\r
+ Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+ @retval EFI_SUCCESS The operation was successful. The line is stored in\r
+ Buffer.\r
+ @retval EFI_END_OF_FILE There are no more lines in the file.\r
+ @retval EFI_INVALID_PARAMETER Handle was NULL.\r
+ @retval EFI_INVALID_PARAMETER Size was NULL.\r
+ @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.\r
+ Size was updated to the minimum space required.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellFileHandleReadLine(\r
+ IN SHELL_FILE_HANDLE Handle,\r
+ IN OUT CHAR16 *Buffer,\r
+ IN OUT UINTN *Size,\r
+ IN BOOLEAN Truncate,\r
+ IN OUT BOOLEAN *Ascii\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 CharBuffer;\r
+ UINTN CharSize;\r
+ UINTN CountSoFar;\r
+ UINT64 OriginalFilePosition;\r
+\r
+\r
+ if (Handle == NULL\r
+ ||Size == NULL\r
+ ){\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ if (Buffer == NULL) {\r
+ ASSERT(*Size == 0);\r
+ } else {\r
+ *Buffer = CHAR_NULL;\r
+ }\r
+ gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);\r
+ if (OriginalFilePosition == 0) {\r
+ CharSize = sizeof(CHAR16);\r
+ Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+ ASSERT_EFI_ERROR(Status);\r
+ if (CharBuffer == gUnicodeFileTag) {\r
+ *Ascii = FALSE;\r
+ } else {\r
+ *Ascii = TRUE;\r
+ gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+ }\r
+ }\r
+\r
+ if (*Ascii) {\r
+ CharSize = sizeof(CHAR8);\r
+ } else {\r
+ CharSize = sizeof(CHAR16);\r
+ }\r
+ for (CountSoFar = 0;;CountSoFar++){\r
+ CharBuffer = 0;\r
+ Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+ if ( EFI_ERROR(Status)\r
+ || CharSize == 0\r
+ || (CharBuffer == L'\n' && !(*Ascii))\r
+ || (CharBuffer == '\n' && *Ascii)\r
+ ){\r
+ if (CharSize == 0) {\r
+ Status = EFI_END_OF_FILE;\r
+ }\r
+ break;\r
+ }\r
+ //\r
+ // if we have space save it...\r
+ //\r
+ if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
+ ASSERT(Buffer != NULL);\r
+ ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
+ ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
+ }\r
+ }\r
+\r
+ //\r
+ // if we ran out of space tell when...\r
+ //\r
+ if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
+ *Size = (CountSoFar+1)*sizeof(CHAR16);\r
+ if (!Truncate) {\r
+ gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+ } else {\r
+ DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));\r
+ }\r
+ return (EFI_BUFFER_TOO_SMALL);\r
+ }\r
+ while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
+ Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
+ }\r
+\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function to print help file / man page content in the spec from the UEFI Shell protocol GetHelpText function.\r
+\r
+ @param[in] CommandToGetHelpOn Pointer to a string containing the command name of help file to be printed.\r
+ @param[in] SectionToGetHelpOn Pointer to the section specifier(s).\r
+ @param[in] PrintCommandText If TRUE, prints the command followed by the help content, otherwise prints \r
+ the help content only.\r
+ @retval EFI_DEVICE_ERROR The help data format was incorrect.\r
+ @retval EFI_NOT_FOUND The help data could not be found.\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellPrintHelp (\r
+ IN CONST CHAR16 *CommandToGetHelpOn,\r
+ IN CONST CHAR16 *SectionToGetHelpOn,\r
+ IN BOOLEAN PrintCommandText\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *OutText;\r
+ \r
+ OutText = NULL;\r
+ \r
+ //\r
+ // Get the string to print based\r
+ //\r
+ Status = gEfiShellProtocol->GetHelpText (CommandToGetHelpOn, SectionToGetHelpOn, &OutText);\r
+ \r
+ //\r
+ // make sure we got a valid string\r
+ //\r
+ if (EFI_ERROR(Status)){\r
+ return Status;\r
+ } \r
+ if (OutText == NULL || StrLen(OutText) == 0) {\r
+ return EFI_NOT_FOUND; \r
+ }\r
+ \r
+ //\r
+ // Chop off trailing stuff we dont need\r
+ //\r
+ while (OutText[StrLen(OutText)-1] == L'\r' || OutText[StrLen(OutText)-1] == L'\n' || OutText[StrLen(OutText)-1] == L' ') {\r
+ OutText[StrLen(OutText)-1] = CHAR_NULL;\r
+ }\r
+ \r
+ //\r
+ // Print this out to the console\r
+ //\r
+ if (PrintCommandText) {\r
+ ShellPrintEx(-1, -1, L"%H%-14s%N- %s\r\n", CommandToGetHelpOn, OutText);\r
+ } else {\r
+ ShellPrintEx(-1, -1, L"%N%s\r\n", OutText);\r
+ }\r
+ \r
+ SHELL_FREE_NON_NULL(OutText);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Function to delete a file by name\r
+ \r
+ @param[in] FileName Pointer to file name to delete.\r
+ \r
+ @retval EFI_SUCCESS the file was deleted sucessfully\r
+ @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not\r
+ deleted\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_NOT_FOUND The specified file could not be found on the\r
+ device or the file system could not be found\r
+ on the device.\r
+ @retval EFI_NO_MEDIA The device has no medium.\r
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the\r
+ medium is no longer supported.\r
+ @retval EFI_DEVICE_ERROR The device reported an error.\r
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.\r
+ @retval EFI_ACCESS_DENIED The file was opened read only.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the\r
+ file.\r
+ @retval other The file failed to open\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellDeleteFileByName(\r
+ IN CONST CHAR16 *FileName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SHELL_FILE_HANDLE FileHandle;\r
+ \r
+ Status = ShellFileExists(FileName);\r
+ \r
+ if (Status == EFI_SUCCESS){\r
+ Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0x0);\r
+ if (Status == EFI_SUCCESS){\r
+ Status = ShellDeleteFile(&FileHandle);\r
+ }\r
+ } \r
+\r
+ return(Status);\r
+ \r
+}\r
+\r
+/**\r
+ Cleans off all the quotes in the string.\r
+\r
+ @param[in] OriginalString pointer to the string to be cleaned.\r
+ @param[out] CleanString The new string with all quotes removed. \r
+ Memory allocated in the function and free \r
+ by caller.\r
+\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+InternalShellStripQuotes (\r
+ IN CONST CHAR16 *OriginalString,\r
+ OUT CHAR16 **CleanString\r
+ )\r
+{\r
+ CHAR16 *Walker;\r
+ \r
+ if (OriginalString == NULL || CleanString == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString);\r
+ if (*CleanString == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL ; Walker++) {\r
+ if (*Walker == L'\"') {\r
+ CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0]));\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r