/** This function invokes Boot Manager. If all devices have not a chance to be connected, the connect all will be triggered. It then enumerate all boot options. If a boot option from the Boot Manager page is selected, Boot Manager will boot from this boot option. **/ VOID UpdateBootManager ( VOID ) { UINTN Index; EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; UINTN BootOptionCount; EFI_STRING_ID Token; CHAR16 *HelpString; EFI_STRING_ID HelpToken; UINT16 *TempStr; EFI_HII_HANDLE HiiHandle; UINTN TempSize; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; UINT16 DeviceType; BOOLEAN IsLegacyOption; BOOLEAN NeedEndOp; UINTN MaxLen; DeviceType = (UINT16) -1; EfiBootManagerConnectAll (); // // for better user experience // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option // EfiBootManagerRefreshAllBootOption (); // // BdsDxe doesn't group the legacy boot options for the same device type // It's UI's choice. // GroupMultipleLegacyBootOption4SameType (); BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); HiiHandle = gBootManagerPrivate.HiiHandle; // // Allocate space for creation of UpdateData Buffer // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_BOOT_OPTION; // // Create Hii Extend Label OpCode as the end opcode // EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_BOOT_OPTION_END; mKeyInput = 0; NeedEndOp = FALSE; for (Index = 0; Index < BootOptionCount; Index++) { // // At this stage we are creating a menu entry, thus the Keys are reproduceable // mKeyInput++; // // Don't display the hidden/inactive boot option // if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) { continue; } // // Group the legacy boot option in the sub title created dynamically // IsLegacyOption = (BOOLEAN) ( (DevicePathType (BootOption[Index].FilePath) == BBS_DEVICE_PATH) && (DevicePathSubType (BootOption[Index].FilePath) == BBS_BBS_DP) ); if (!IsLegacyOption && NeedEndOp) { NeedEndOp = FALSE; HiiCreateEndOpCode (StartOpCodeHandle); } if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType) { if (NeedEndOp) { HiiCreateEndOpCode (StartOpCodeHandle); } DeviceType = ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType; Token = HiiSetString ( HiiHandle, 0, mDeviceTypeStr[ MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 1) ], NULL ); HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1); NeedEndOp = TRUE; } ASSERT (BootOption[Index].Description != NULL); Token = HiiSetString (HiiHandle, 0, BootOption[Index].Description, NULL); TempStr = BmDevicePathToStr (BootOption[Index].FilePath); TempSize = StrSize (TempStr); HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : ")); MaxLen = (TempSize + StrSize (L"Device Path : "))/sizeof(CHAR16); ASSERT (HelpString != NULL); StrCatS (HelpString, MaxLen, L"Device Path : "); StrCatS (HelpString, MaxLen, TempStr); HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL); HiiCreateActionOpCode ( StartOpCodeHandle, mKeyInput, Token, HelpToken, EFI_IFR_FLAG_CALLBACK, 0 ); } if (NeedEndOp) { HiiCreateEndOpCode (StartOpCodeHandle); } HiiUpdateForm ( HiiHandle, &mBootManagerGuid, BOOT_MANAGER_FORM_ID, StartOpCodeHandle, EndOpCodeHandle ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount); }
/** Function to take the destination path and target file name to generate the full destination path. @param[in] DestPath A pointer to the destination file path string. @param[out] FullDestPath A pointer to the full destination path string. @param[in] FileName Name string of the targe file. @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ EFI_STATUS EFIAPI CreateFullDestPath( IN CONST CHAR16 **DestPath, OUT CHAR16 **FullDestPath, IN CONST CHAR16 *FileName ) { UINTN Size; if (FullDestPath == NULL || FileName == NULL || DestPath == NULL || *DestPath == NULL){ return (EFI_INVALID_PARAMETER); } Size = StrSize(*DestPath) + StrSize(FileName); *FullDestPath = AllocateZeroPool(Size); if (*FullDestPath == NULL){ return (EFI_OUT_OF_RESOURCES); } StrCpyS(*FullDestPath, Size / sizeof(CHAR16), *DestPath); if ((*FullDestPath)[StrLen(*FullDestPath)-1] != L'\\' && FileName[0] != L'\\') { StrCatS(*FullDestPath, Size / sizeof(CHAR16), L"\\"); } StrCatS(*FullDestPath, Size / sizeof(CHAR16), FileName); return (EFI_SUCCESS); }
/** Convert Processor Frequency Data to a string. @param ProcessorFrequency The frequency data to process @param Base10Exponent The exponent based on 10 @param String The string that is created **/ VOID ConvertProcessorToString ( IN UINT16 ProcessorFrequency, IN UINT16 Base10Exponent, OUT CHAR16 **String ) { CHAR16 *StringBuffer; UINTN Index; UINT32 FreqMhz; if (Base10Exponent >= 6) { FreqMhz = ProcessorFrequency; for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) { FreqMhz *= 10; } } else { FreqMhz = 0; } StringBuffer = AllocateZeroPool (0x20); ASSERT (StringBuffer != NULL); Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3); StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L"."); UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2); StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L" GHz"); *String = (CHAR16 *) StringBuffer; return ; }
EFIAPI FileDevicePathToText(EFI_DEVICE_PATH_PROTOCOL *FilePathProto) { EFI_STATUS Status; FILEPATH_DEVICE_PATH *FilePath; CHAR16 FilePathText[256]; // possible problem: if filepath is bigger CHAR16 *OutFilePathText; INTN Size; INTN SizeAll; INTN i; FilePathText[0] = L'\0'; i = 4; SizeAll = 0; //PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto)); while (FilePathProto != NULL && FilePathProto->Type != END_DEVICE_PATH_TYPE && i > 0) { if (FilePathProto->Type == MEDIA_DEVICE_PATH && FilePathProto->SubType == MEDIA_FILEPATH_DP) { FilePath = (FILEPATH_DEVICE_PATH *) FilePathProto; Size = (DevicePathNodeLength(FilePathProto) - 4) / 2; if (SizeAll + Size < 256) { if (SizeAll > 0 && FilePathText[SizeAll / 2 - 2] != L'\\') { StrCatS(FilePathText, 256, L"\\"); } StrCatS(FilePathText, 256, FilePath->PathName); SizeAll = StrSize(FilePathText); } } FilePathProto = NextDevicePathNode(FilePathProto); //PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto)); i--; //PRINT("FilePathText: %s\n", FilePathText); } OutFilePathText = NULL; Size = StrSize(FilePathText); if (Size > 2) { // we are allocating mem here - should be released by caller Status = gBS->AllocatePool(EfiBootServicesData, Size, (VOID*)&OutFilePathText); if (Status == EFI_SUCCESS) { StrCpyS(OutFilePathText, Size/sizeof(CHAR16), FilePathText); } else { OutFilePathText = NULL; } } return OutFilePathText; }
/** Append Buffer With TpmAlgHash. @param[in] Buffer Buffer to be appended. @param[in] BufferSize Size of buffer. @param[in] TpmAlgHash TpmAlgHash. **/ VOID AppendBufferWithTpmAlgHash ( IN UINT16 *Buffer, IN UINTN BufferSize, IN UINT32 TpmAlgHash ) { switch (TpmAlgHash) { case TPM_ALG_SHA1: if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1"); break; case TPM_ALG_SHA256: if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256"); break; case TPM_ALG_SHA384: if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384"); break; case TPM_ALG_SHA512: if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512"); break; case TPM_ALG_SM3_256: if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256"); break; } }
/** Fill Buffer With TCG2EventLogFormat. @param[in] Buffer Buffer to be filled. @param[in] BufferSize Size of buffer. @param[in] TCG2EventLogFormat TCG2EventLogFormat. **/ VOID FillBufferWithTCG2EventLogFormat ( IN UINT16 *Buffer, IN UINTN BufferSize, IN UINT32 TCG2EventLogFormat ) { Buffer[0] = 0; if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_1_2"); } if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_2"); } if ((TCG2EventLogFormat & (~EFI_TCG2_EVENT_LOG_FORMAT_ALL)) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"UNKNOWN"); } }
/** Fill Buffer With BootHashAlg. @param[in] Buffer Buffer to be filled. @param[in] BufferSize Size of buffer. @param[in] BootHashAlg BootHashAlg. **/ VOID FillBufferWithBootHashAlg ( IN UINT16 *Buffer, IN UINTN BufferSize, IN UINT32 BootHashAlg ) { Buffer[0] = 0; if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1"); } if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256"); } if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384"); } if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512"); } if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) { if (Buffer[0] != 0) { StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", "); } StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256"); } }
/** Return the boot description for the controller. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetBootDescription ( IN EFI_HANDLE Handle ) { LIST_ENTRY *Link; BM_BOOT_DESCRIPTION_ENTRY *Entry; CHAR16 *Description; CHAR16 *DefaultDescription; CHAR16 *Temp; UINTN Index; // // Firstly get the default boot description // DefaultDescription = NULL; for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof (mBmBootDescriptionHandlers[0]); Index++) { DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle); if (DefaultDescription != NULL) { // // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix // ONLY for core provided boot description handler. // Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)); ASSERT (Temp != NULL); StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), mBmUefiPrefix); StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), DefaultDescription); FreePool (DefaultDescription); DefaultDescription = Temp; break; } } ASSERT (DefaultDescription != NULL); // // Secondly query platform for the better boot description // for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers) ; !IsNull (&mPlatformBootDescriptionHandlers, Link) ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link) ) { Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE); Description = Entry->Handler (Handle, DefaultDescription); if (Description != NULL) { FreePool (DefaultDescription); return Description; } } return DefaultDescription; }
/** Function will replace drive identifier with CWD. If FullPath begining with ':' is invalid path, then ASSERT. If FullPath not include dirve identifier , then do nothing. If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing. If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD. @param[in, out] FullPath The pointer to the string containing the path. @param[in] Cwd Current directory. @retval EFI_SUCCESS Success. @retval EFI_OUT_OF_SOURCES A memory allocation failed. **/ EFI_STATUS ReplaceDriveWithCwd ( IN OUT CHAR16 **FullPath, IN CONST CHAR16 *Cwd ) { CHAR16 *Splitter; CHAR16 *TempBuffer; UINTN TotalSize; Splitter = NULL; TempBuffer = NULL; TotalSize = 0; if (FullPath == NULL || *FullPath == NULL) { return EFI_SUCCESS; } Splitter = StrStr (*FullPath, L":"); ASSERT(Splitter != *FullPath); if (Splitter != NULL && *(Splitter + 1) != L'\\' && *(Splitter + 1) != L'/') { TotalSize = StrSize (Cwd) + StrSize (Splitter + 1); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } StrCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), L"\\"); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Splitter + 1); FreePool(*FullPath); *FullPath = TempBuffer; } return EFI_SUCCESS; }
/** Convert Memory Size to a string. @param MemorySize The size of the memory to process @param String The string that is created **/ VOID ConvertMemorySizeToString ( IN UINT32 MemorySize, OUT CHAR16 **String ) { CHAR16 *StringBuffer; StringBuffer = AllocateZeroPool (0x24); ASSERT (StringBuffer != NULL); UnicodeValueToStringS (StringBuffer, 0x24, LEFT_JUSTIFY, MemorySize, 10); StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM"); *String = (CHAR16 *) StringBuffer; return ; }
/** Function for 'mv' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunMv ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; CHAR16 *Cwd; UINTN CwdSize; SHELL_STATUS ShellStatus; UINTN ParamCount; UINTN LoopCounter; EFI_SHELL_FILE_INFO *FileList; VOID *Response; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; ParamCount = 0; FileList = NULL; Response = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mv", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } switch (ParamCount = ShellCommandLineGetCount(Package)) { case 0: case 1: // // we have insufficient parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mv"); ShellStatus = SHELL_INVALID_PARAMETER; break; case 2: // // must have valid CWD for single parameter... // if (ShellGetCurrentDir(NULL) == NULL){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"mv"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } else { // // ValidateAndMoveFiles will report errors to the screen itself // CwdSize = StrSize(ShellGetCurrentDir(NULL)) + sizeof(CHAR16); Cwd = AllocateZeroPool(CwdSize); ASSERT (Cwd != NULL); StrCpyS(Cwd, CwdSize/sizeof(CHAR16), ShellGetCurrentDir(NULL)); StrCatS(Cwd, CwdSize/sizeof(CHAR16), L"\\"); ShellStatus = ValidateAndMoveFiles(FileList, &Response, Cwd); FreePool(Cwd); } } break; default: ///@todo make sure this works with error half way through and continues... for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount ; LoopCounter++) { if (ShellGetExecutionBreakFlag()) { break; } Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, LoopCounter)); ShellStatus = SHELL_NOT_FOUND; } else { // // ValidateAndMoveFiles will report errors to the screen itself // Only change ShellStatus if it's sucessful // if (ShellStatus == SHELL_SUCCESS) { ShellStatus = ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount)); } else { ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount)); } } if (FileList != NULL && !IsListEmpty(&FileList->Link)) { Status = ShellCloseFileMetaArg(&FileList); if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { ShellStatus = SHELL_ACCESS_DENIED; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, 1), ShellStatus|MAX_BIT); } } } break; } // switch on parameter count if (FileList != NULL) { ShellCloseFileMetaArg(&FileList); } // // free the command line package // ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL(Response); if (ShellGetExecutionBreakFlag()) { return (SHELL_ABORTED); } return (ShellStatus); }
/** Get string or password input from user. @param MenuOption Pointer to the current input menu. @param Prompt The prompt string shown on popup window. @param StringPtr Old user input and destination for use input string. @retval EFI_SUCCESS If string input is read successfully @retval EFI_DEVICE_ERROR If operation fails **/ EFI_STATUS ReadString ( IN UI_MENU_OPTION *MenuOption, IN CHAR16 *Prompt, IN OUT CHAR16 *StringPtr ) { EFI_STATUS Status; EFI_INPUT_KEY Key; CHAR16 NullCharacter; UINTN ScreenSize; CHAR16 Space[2]; CHAR16 KeyPad[2]; CHAR16 *TempString; CHAR16 *BufferedString; UINTN Index; UINTN Index2; UINTN Count; UINTN Start; UINTN Top; UINTN DimensionsWidth; UINTN DimensionsHeight; UINTN CurrentCursor; BOOLEAN CursorVisible; UINTN Minimum; UINTN Maximum; FORM_DISPLAY_ENGINE_STATEMENT *Question; BOOLEAN IsPassword; UINTN MaxLen; DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow; NullCharacter = CHAR_NULL; ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); Space[0] = L' '; Space[1] = CHAR_NULL; Question = MenuOption->ThisTag; GetFieldFromOp(Question->OpCode, &Minimum, &Maximum); if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) { IsPassword = TRUE; } else { IsPassword = FALSE; } MaxLen = Maximum + 1; TempString = AllocateZeroPool (MaxLen * sizeof (CHAR16)); ASSERT (TempString); if (ScreenSize < (Maximum + 1)) { ScreenSize = Maximum + 1; } if ((ScreenSize + 2) > DimensionsWidth) { ScreenSize = DimensionsWidth - 2; } BufferedString = AllocateZeroPool (ScreenSize * 2); ASSERT (BufferedString); Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1; Top = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1; // // Display prompt for string // // CreateDialog (NULL, "", Prompt, Space, "", NULL); CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); CursorVisible = gST->ConOut->Mode->CursorVisible; gST->ConOut->EnableCursor (gST->ConOut, TRUE); CurrentCursor = GetStringWidth (StringPtr) / 2 - 1; if (CurrentCursor != 0) { // // Show the string which has beed saved before. // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); } do { Status = WaitForKeyStroke (&Key); ASSERT_EFI_ERROR (Status); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); switch (Key.UnicodeChar) { case CHAR_NULL: switch (Key.ScanCode) { case SCAN_LEFT: if (CurrentCursor > 0) { CurrentCursor--; } break; case SCAN_RIGHT: if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) { CurrentCursor++; } break; case SCAN_ESC: FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; case SCAN_DELETE: for (Index = CurrentCursor; StringPtr[Index] != CHAR_NULL; Index++) { StringPtr[Index] = StringPtr[Index + 1]; PrintCharAt (Start + Index + 1, Top + 3, IsPassword && StringPtr[Index] != CHAR_NULL? L'*' : StringPtr[Index]); } break; default: break; } break; case CHAR_CARRIAGE_RETURN: if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_SUCCESS; } else { // // Simply create a popup to tell the user that they had typed in too few characters. // To save code space, we can then treat this as an error and return back to the menu. // do { CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; } case CHAR_BACKSPACE: if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) { for (Index = 0; Index < CurrentCursor - 1; Index++) { TempString[Index] = StringPtr[Index]; } Count = GetStringWidth (StringPtr) / 2 - 1; if (Count >= CurrentCursor) { for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) { TempString[Index] = StringPtr[Index2]; } TempString[Index] = CHAR_NULL; } // // Effectively truncate string by 1 character // StrCpyS (StringPtr, MaxLen, TempString); CurrentCursor --; } default: // // If it is the beginning of the string, don't worry about checking maximum limits // if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { StrnCpyS (StringPtr, MaxLen, &Key.UnicodeChar, 1); CurrentCursor++; } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { KeyPad[0] = Key.UnicodeChar; KeyPad[1] = CHAR_NULL; Count = GetStringWidth (StringPtr) / 2 - 1; if (CurrentCursor < Count) { for (Index = 0; Index < CurrentCursor; Index++) { TempString[Index] = StringPtr[Index]; } TempString[Index] = CHAR_NULL; StrCatS (TempString, MaxLen, KeyPad); StrCatS (TempString, MaxLen, StringPtr + CurrentCursor); StrCpyS (StringPtr, MaxLen, TempString); } else { StrCatS (StringPtr, MaxLen, KeyPad); } CurrentCursor++; } // // If the width of the input string is now larger than the screen, we nee to // adjust the index to start printing portions of the string // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } break; } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3); } while (TRUE); }
/** Try to get the controller's USB description. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetUsbDescription ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; EFI_USB_IO_PROTOCOL *UsbIo; CHAR16 NullChar; CHAR16 *Manufacturer; CHAR16 *Product; CHAR16 *SerialNumber; CHAR16 *Description; EFI_USB_DEVICE_DESCRIPTOR DevDesc; UINTN DescMaxSize; Status = gBS->HandleProtocol ( Handle, &gEfiUsbIoProtocolGuid, (VOID **) &UsbIo ); if (EFI_ERROR (Status)) { return NULL; } NullChar = L'\0'; Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); if (EFI_ERROR (Status)) { return NULL; } Status = UsbIo->UsbGetStringDescriptor ( UsbIo, mBmUsbLangId, DevDesc.StrManufacturer, &Manufacturer ); if (EFI_ERROR (Status)) { Manufacturer = &NullChar; } Status = UsbIo->UsbGetStringDescriptor ( UsbIo, mBmUsbLangId, DevDesc.StrProduct, &Product ); if (EFI_ERROR (Status)) { Product = &NullChar; } Status = UsbIo->UsbGetStringDescriptor ( UsbIo, mBmUsbLangId, DevDesc.StrSerialNumber, &SerialNumber ); if (EFI_ERROR (Status)) { SerialNumber = &NullChar; } if ((Manufacturer == &NullChar) && (Product == &NullChar) && (SerialNumber == &NullChar) ) { return NULL; } DescMaxSize = StrSize (Manufacturer) + StrSize (Product) + StrSize (SerialNumber); Description = AllocateZeroPool (DescMaxSize); ASSERT (Description != NULL); StrCatS (Description, DescMaxSize/sizeof(CHAR16), Manufacturer); StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" "); StrCatS (Description, DescMaxSize/sizeof(CHAR16), Product); StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" "); StrCatS (Description, DescMaxSize/sizeof(CHAR16), SerialNumber); if (Manufacturer != &NullChar) { FreePool (Manufacturer); } if (Product != &NullChar) { FreePool (Product); } if (SerialNumber != &NullChar) { FreePool (SerialNumber); } BmEliminateExtraSpaces (Description); return Description; }
/** Function for 'cd' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunCd ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CONST CHAR16 *Cwd; CHAR16 *Path; CHAR16 *Drive; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CONST CHAR16 *Param1; CHAR16 *Param1Copy; CHAR16 *Walker; CHAR16 *Splitter; CHAR16 *TempBuffer; UINTN TotalSize; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; Cwd = NULL; Path = NULL; Drive = NULL; Splitter = NULL; TempBuffer = NULL; TotalSize = 0; Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cd", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"cd"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // remember that param 0 is the command name // If there are 0 value parameters, then print the current directory // else If there are 2 value parameters, then print the error message // else If there is 1 value paramerer , then change the directory // Cwd = ShellGetCurrentDir (NULL); if (Cwd == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd"); ShellStatus = SHELL_NOT_FOUND; } else { Param1 = ShellCommandLineGetRawValue (Package, 1); if (Param1 == NULL) { // // display the current directory // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT), gShellLevel2HiiHandle, Cwd); } else { Param1Copy = CatSPrint (NULL, L"%s", Param1, NULL); for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL; Walker++) { if (*Walker == L'\"') { CopyMem (Walker, Walker + 1, StrSize(Walker) - sizeof(Walker[0])); } } if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) { Status = ReplaceDriveWithCwd (&Param1Copy,Cwd); if (!EFI_ERROR (Status)) { Param1Copy = PathCleanUpDirectories (Param1Copy); } } else { // // Can't use cd command to change filesystem. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd"); Status = EFI_NOT_FOUND; } if (!EFI_ERROR(Status) && Param1Copy != NULL) { Splitter = StrStr (Cwd, L":"); if (Param1Copy[0] == L'\\') { // // Absolute Path on current drive letter. // TotalSize = ((Splitter - Cwd + 1) * sizeof(CHAR16)) + StrSize(Param1Copy); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrnCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd, (Splitter - Cwd + 1)); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Param1Copy); FreePool (Param1Copy); Param1Copy = TempBuffer; TempBuffer = NULL; } } else { if (StrStr (Param1Copy,L":") == NULL) { TotalSize = StrSize (Cwd) + StrSize (Param1Copy); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd); StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\"); StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy); FreePool (Param1Copy); Param1Copy = PathCleanUpDirectories (TempBuffer); } } } } if (!EFI_ERROR(Status)) { Status = ExtractDriveAndPath (Param1Copy, &Drive, &Path); } if (!EFI_ERROR (Status) && Drive != NULL && Path != NULL) { if (EFI_ERROR(ShellIsDirectory (Param1Copy))) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Param1Copy); ShellStatus = SHELL_NOT_FOUND; } else { Status = gEfiShellProtocol->SetCurDir (Drive, Path + 1); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy); ShellStatus = SHELL_NOT_FOUND; } } } if (Drive != NULL) { FreePool (Drive); } if (Path != NULL) { FreePool (Path); } FreePool (Param1Copy); } } } // // free the command line package // ShellCommandLineFreeVarList (Package); // // return the status // return (ShellStatus); }
/** Append file name to existing file name. @param Str1 The existing file name @param Str2 The file name to be appended @return Allocate a new string to hold the appended result. Caller is responsible to free the returned string. **/ CHAR16 * LibAppendFileName ( IN CHAR16 *Str1, IN CHAR16 *Str2 ) { UINTN Size1; UINTN Size2; UINTN MaxLen; CHAR16 *Str; CHAR16 *TmpStr; CHAR16 *Ptr; CHAR16 *LastSlash; Size1 = StrSize (Str1); Size2 = StrSize (Str2); // // Check overflow // if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof(CHAR16))) { return NULL; } MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16); Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); ASSERT (Str != NULL); TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); ASSERT (TmpStr != NULL); StrCpyS (Str, MaxLen, Str1); if (!((*Str == '\\') && (*(Str + 1) == 0))) { StrCatS (Str, MaxLen, L"\\"); } StrCatS (Str, MaxLen, Str2); Ptr = Str; LastSlash = Str; while (*Ptr != 0) { if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') { // // Convert "\Name\..\" to "\" // DO NOT convert the .. if it is at the end of the string. This will // break the .. behavior in changing directories. // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, MaxLen, Ptr + 3); StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') { // // Convert a "\.\" to a "\" // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, MaxLen, Ptr + 2); StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\') { LastSlash = Ptr; } Ptr++; } FreePool (TmpStr); return Str; }
/** parses through the MAN file formatted Buffer and returns the "Brief Description" for the .TH section as specified by Command. If the command section is not found return EFI_NOT_FOUND. Upon a sucessful return the caller is responsible to free the memory in *BriefDesc @param[in] Handle Buffer to read from @param[in] Command name of command's section to find @param[in] BriefDesc pointer to pointer to string where description goes. @param[in] BriefSize pointer to size of allocated BriefDesc @retval EFI_OUT_OF_RESOURCES a memory allocation failed. @retval EFI_SUCCESS the section was found and its description sotred in an alloceted buffer. **/ EFI_STATUS EFIAPI ManBufferFindTitleSection( IN CHAR16 **Buffer, IN CONST CHAR16 *Command, IN CHAR16 **BriefDesc, IN UINTN *BriefSize ) { EFI_STATUS Status; CHAR16 *TitleString; CHAR16 *TitleEnd; CHAR16 *CurrentLocation; UINTN TitleLength; CONST CHAR16 StartString[] = L".TH "; CONST CHAR16 EndString[] = L" 0 "; if ( Buffer == NULL || Command == NULL || (BriefDesc != NULL && BriefSize == NULL) ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; // // more characters for StartString and EndString // TitleLength = StrSize(Command) + (StrLen(StartString) + StrLen(EndString)) * sizeof(CHAR16); TitleString = AllocateZeroPool(TitleLength); if (TitleString == NULL) { return (EFI_OUT_OF_RESOURCES); } StrCpyS(TitleString, TitleLength/sizeof(CHAR16), StartString); StrCatS(TitleString, TitleLength/sizeof(CHAR16), Command); StrCatS(TitleString, TitleLength/sizeof(CHAR16), EndString); CurrentLocation = StrStr(*Buffer, TitleString); if (CurrentLocation == NULL){ Status = EFI_NOT_FOUND; } else { // // we found it so copy out the rest of the line into BriefDesc // After skipping any spaces or zeroes // for (CurrentLocation += StrLen(TitleString) ; *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"' ; CurrentLocation++); TitleEnd = StrStr(CurrentLocation, L"\""); if (TitleEnd == NULL) { Status = EFI_DEVICE_ERROR; } else { if (BriefDesc != NULL) { *BriefSize = StrSize(TitleEnd); *BriefDesc = AllocateZeroPool(*BriefSize); if (*BriefDesc == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrnCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), CurrentLocation, TitleEnd-CurrentLocation); } } for (CurrentLocation = TitleEnd ; *CurrentLocation != L'\n' ; CurrentLocation++); for ( ; *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r' ; CurrentLocation++); *Buffer = CurrentLocation; } } FreePool(TitleString); return (Status); }
/** Get selection for OneOf and OrderedList (Left/Right will be ignored). @param MenuOption Pointer to the current input menu. @retval EFI_SUCCESS If Option input is processed successfully @retval EFI_DEVICE_ERROR If operation fails **/ EFI_STATUS GetSelectionInputPopUp ( IN UI_MENU_OPTION *MenuOption ) { EFI_INPUT_KEY Key; UINTN Index; CHAR16 *StringPtr; CHAR16 *TempStringPtr; UINTN Index2; UINTN TopOptionIndex; UINTN HighlightOptionIndex; UINTN Start; UINTN End; UINTN Top; UINTN Bottom; UINTN PopUpMenuLines; UINTN MenuLinesInView; UINTN PopUpWidth; CHAR16 Character; INT32 SavedAttribute; BOOLEAN ShowDownArrow; BOOLEAN ShowUpArrow; UINTN DimensionsWidth; LIST_ENTRY *Link; BOOLEAN OrderedList; UINT8 *ValueArray; UINT8 *ReturnValue; UINT8 ValueType; EFI_HII_VALUE HiiValue; DISPLAY_QUESTION_OPTION *OneOfOption; DISPLAY_QUESTION_OPTION *CurrentOption; FORM_DISPLAY_ENGINE_STATEMENT *Question; INTN Result; EFI_IFR_ORDERED_LIST *OrderList; DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; ValueArray = NULL; ValueType = 0; CurrentOption = NULL; ShowDownArrow = FALSE; ShowUpArrow = FALSE; ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE)); Question = MenuOption->ThisTag; if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) { Link = GetFirstNode (&Question->OptionListHead); OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); ValueArray = Question->CurrentValue.Buffer; ValueType = OneOfOption->OptionOpCode->Type; OrderedList = TRUE; OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode; } else { OrderedList = FALSE; OrderList = NULL; } // // Calculate Option count // PopUpMenuLines = 0; if (OrderedList) { AdjustOptionOrder(Question, &PopUpMenuLines); } else { Link = GetFirstNode (&Question->OptionListHead); while (!IsNull (&Question->OptionListHead, Link)) { OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); PopUpMenuLines++; Link = GetNextNode (&Question->OptionListHead, Link); } } // // Get the number of one of options present and its size // PopUpWidth = 0; HighlightOptionIndex = 0; Link = GetFirstNode (&Question->OptionListHead); for (Index = 0; Index < PopUpMenuLines; Index++) { OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); if (StrLen (StringPtr) > PopUpWidth) { PopUpWidth = StrLen (StringPtr); } FreePool (StringPtr); HiiValue.Type = OneOfOption->OptionOpCode->Type; SetValuesByType (&HiiValue.Value, &OneOfOption->OptionOpCode->Value, HiiValue.Type); if (!OrderedList && (CompareHiiValue (&Question->CurrentValue, &HiiValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) { // // Find current selected Option for OneOf // HighlightOptionIndex = Index; } Link = GetNextNode (&Question->OptionListHead, Link); } // // Perform popup menu initialization. // PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT; SavedAttribute = gST->ConOut->Mode->Attribute; gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) { PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH; } Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn; End = Start + PopUpWidth + POPUP_FRAME_WIDTH; Top = gStatementDimensions.TopRow; Bottom = gStatementDimensions.BottomRow - 1; MenuLinesInView = Bottom - Top - 1; if (MenuLinesInView >= PopUpMenuLines) { Top = Top + (MenuLinesInView - PopUpMenuLines) / 2; Bottom = Top + PopUpMenuLines + 1; } else { ShowDownArrow = TRUE; } if (HighlightOptionIndex > (MenuLinesInView - 1)) { TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1; } else { TopOptionIndex = 0; } do { // // Clear that portion of the screen // ClearLines (Start, End, Top, Bottom, GetPopupColor ()); // // Draw "One of" pop-up menu // Character = BOXDRAW_DOWN_RIGHT; PrintCharAt (Start, Top, Character); for (Index = Start; Index + 2 < End; Index++) { if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) { Character = GEOMETRICSHAPE_UP_TRIANGLE; } else { Character = BOXDRAW_HORIZONTAL; } PrintCharAt ((UINTN)-1, (UINTN)-1, Character); } Character = BOXDRAW_DOWN_LEFT; PrintCharAt ((UINTN)-1, (UINTN)-1, Character); Character = BOXDRAW_VERTICAL; for (Index = Top + 1; Index < Bottom; Index++) { PrintCharAt (Start, Index, Character); PrintCharAt (End - 1, Index, Character); } // // Move to top Option // Link = GetFirstNode (&Question->OptionListHead); for (Index = 0; Index < TopOptionIndex; Index++) { Link = GetNextNode (&Question->OptionListHead, Link); } // // Display the One of options // Index2 = Top + 1; for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) { OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); Link = GetNextNode (&Question->OptionListHead, Link); StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); ASSERT (StringPtr != NULL); // // If the string occupies multiple lines, truncate it to fit in one line, // and append a "..." for indication. // if (StrLen (StringPtr) > (PopUpWidth - 1)) { TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1)); ASSERT ( TempStringPtr != NULL ); CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5))); FreePool (StringPtr); StringPtr = TempStringPtr; StrCatS (StringPtr, PopUpWidth - 1, L"..."); } if (Index == HighlightOptionIndex) { // // Highlight the selected one // CurrentOption = OneOfOption; gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ()); PrintStringAt (Start + 2, Index2, StringPtr); gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); } else { gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); PrintStringAt (Start + 2, Index2, StringPtr); } Index2++; FreePool (StringPtr); } Character = BOXDRAW_UP_RIGHT; PrintCharAt (Start, Bottom, Character); for (Index = Start; Index + 2 < End; Index++) { if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) { Character = GEOMETRICSHAPE_DOWN_TRIANGLE; } else { Character = BOXDRAW_HORIZONTAL; } PrintCharAt ((UINTN)-1, (UINTN)-1, Character); } Character = BOXDRAW_UP_LEFT; PrintCharAt ((UINTN)-1, (UINTN)-1, Character); // // Get User selection // Key.UnicodeChar = CHAR_NULL; if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) { Key.ScanCode = gDirection; gDirection = 0; goto TheKey; } WaitForKeyStroke (&Key); TheKey: switch (Key.UnicodeChar) { case '+': if (OrderedList) { if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { // // Highlight reaches the top of the popup window, scroll one menu item. // TopOptionIndex--; ShowDownArrow = TRUE; } if (TopOptionIndex == 0) { ShowUpArrow = FALSE; } if (HighlightOptionIndex > 0) { HighlightOptionIndex--; ASSERT (CurrentOption != NULL); SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link); } } break; case '-': // // If an ordered list op-code, we will allow for a popup of +/- keys // to create an ordered list of items // if (OrderedList) { if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { // // Highlight reaches the bottom of the popup window, scroll one menu item. // TopOptionIndex++; ShowUpArrow = TRUE; } if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { ShowDownArrow = FALSE; } if (HighlightOptionIndex < (PopUpMenuLines - 1)) { HighlightOptionIndex++; ASSERT (CurrentOption != NULL); SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink); } } break; case CHAR_NULL: switch (Key.ScanCode) { case SCAN_UP: case SCAN_DOWN: if (Key.ScanCode == SCAN_UP) { if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { // // Highlight reaches the top of the popup window, scroll one menu item. // TopOptionIndex--; ShowDownArrow = TRUE; } if (TopOptionIndex == 0) { ShowUpArrow = FALSE; } if (HighlightOptionIndex > 0) { HighlightOptionIndex--; } } else { if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { // // Highlight reaches the bottom of the popup window, scroll one menu item. // TopOptionIndex++; ShowUpArrow = TRUE; } if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { ShowDownArrow = FALSE; } if (HighlightOptionIndex < (PopUpMenuLines - 1)) { HighlightOptionIndex++; } } break; case SCAN_ESC: gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); // // Restore link list order for orderedlist // if (OrderedList) { HiiValue.Type = ValueType; HiiValue.Value.u64 = 0; for (Index = 0; Index < OrderList->MaxContainers; Index++) { HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index); if (HiiValue.Value.u64 == 0) { break; } OneOfOption = ValueToOption (Question, &HiiValue); if (OneOfOption == NULL) { return EFI_NOT_FOUND; } RemoveEntryList (&OneOfOption->Link); InsertTailList (&Question->OptionListHead, &OneOfOption->Link); } } return EFI_DEVICE_ERROR; default: break; } break; case CHAR_CARRIAGE_RETURN: // // return the current selection // if (OrderedList) { ReturnValue = AllocateZeroPool (Question->CurrentValue.BufferLen); ASSERT (ReturnValue != NULL); Index = 0; Link = GetFirstNode (&Question->OptionListHead); while (!IsNull (&Question->OptionListHead, Link)) { OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); Link = GetNextNode (&Question->OptionListHead, Link); SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64); Index++; if (Index > OrderList->MaxContainers) { break; } } if (CompareMem (ReturnValue, ValueArray, Question->CurrentValue.BufferLen) == 0) { FreePool (ReturnValue); return EFI_DEVICE_ERROR; } else { gUserInput->InputValue.Buffer = ReturnValue; gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen; } } else { ASSERT (CurrentOption != NULL); gUserInput->InputValue.Type = CurrentOption->OptionOpCode->Type; if (IsValuesEqual (&Question->CurrentValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type)) { return EFI_DEVICE_ERROR; } else { SetValuesByType (&gUserInput->InputValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type); } } gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); return EFI_SUCCESS; default: break; } } while (TRUE); }
/** This function invokes Boot Manager. If all devices have not a chance to be connected, the connect all will be triggered. It then enumerate all boot options. If a boot option from the Boot Manager page is selected, Boot Manager will boot from this boot option. **/ VOID CallBootManager ( VOID ) { EFI_STATUS Status; BDS_COMMON_OPTION *Option; LIST_ENTRY *Link; CHAR16 *ExitData; UINTN ExitDataSize; EFI_STRING_ID Token; EFI_INPUT_KEY Key; CHAR16 *HelpString; UINTN HelpSize; EFI_STRING_ID HelpToken; UINT16 *TempStr; EFI_HII_HANDLE HiiHandle; EFI_BROWSER_ACTION_REQUEST ActionRequest; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; UINT16 DeviceType; BOOLEAN IsLegacyOption; BOOLEAN NeedEndOp; DeviceType = (UINT16) -1; gOption = NULL; InitializeListHead (&mBootOptionsList); // // Connect all prior to entering the platform setup menu. // if (!gConnectAllHappened) { BdsLibConnectAllDriversToAllControllers (); gConnectAllHappened = TRUE; } BdsLibEnumerateAllBootOption (&mBootOptionsList); // // Group the legacy boot options for the same device type // GroupMultipleLegacyBootOption4SameType (); InitializeListHead (&mBootOptionsList); BdsLibBuildOptionFromVar (&mBootOptionsList, L"BootOrder"); HiiHandle = gBootManagerPrivate.HiiHandle; // // Allocate space for creation of UpdateData Buffer // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_BOOT_OPTION; // // Create Hii Extend Label OpCode as the end opcode // EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_BOOT_OPTION_END; mKeyInput = 0; NeedEndOp = FALSE; for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) { Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); // // At this stage we are creating a menu entry, thus the Keys are reproduceable // mKeyInput++; // // Don't display the hidden/inactive boot option // if (((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) || ((Option->Attribute & LOAD_OPTION_ACTIVE) == 0)) { continue; } // // Group the legacy boot option in the sub title created dynamically // IsLegacyOption = (BOOLEAN) ( (DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) && (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP) ); if (!IsLegacyOption && NeedEndOp) { NeedEndOp = FALSE; HiiCreateEndOpCode (StartOpCodeHandle); } if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType) { if (NeedEndOp) { HiiCreateEndOpCode (StartOpCodeHandle); } DeviceType = ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType; Token = HiiSetString ( HiiHandle, 0, mDeviceTypeStr[ MIN (DeviceType & 0xF, ARRAY_SIZE (mDeviceTypeStr) - 1) ], NULL ); HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1); NeedEndOp = TRUE; } ASSERT (Option->Description != NULL); Token = HiiSetString (HiiHandle, 0, Option->Description, NULL); TempStr = DevicePathToStr (Option->DevicePath); HelpSize = StrSize (TempStr) + StrSize (L"Device Path : "); HelpString = AllocateZeroPool (HelpSize); ASSERT (HelpString != NULL); StrCatS (HelpString, HelpSize / sizeof (CHAR16), L"Device Path : "); StrCatS (HelpString, HelpSize / sizeof (CHAR16), TempStr); HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL); HiiCreateActionOpCode ( StartOpCodeHandle, mKeyInput, Token, HelpToken, EFI_IFR_FLAG_CALLBACK, 0 ); } if (NeedEndOp) { HiiCreateEndOpCode (StartOpCodeHandle); } HiiUpdateForm ( HiiHandle, &gBootManagerFormSetGuid, BOOT_MANAGER_FORM_ID, StartOpCodeHandle, EndOpCodeHandle ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; Status = gFormBrowser2->SendForm ( gFormBrowser2, &HiiHandle, 1, &gBootManagerFormSetGuid, 0, NULL, &ActionRequest ); if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) { EnableResetRequired (); } if (gOption == NULL) { return ; } // // Will leave browser, check any reset required change is applied? if yes, reset system // SetupResetReminder (); // // Restore to original mode before launching boot option. // BdsSetConsoleMode (FALSE); // // parse the selected option // Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData); if (!EFI_ERROR (Status)) { gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); PlatformBdsBootSuccess (gOption); } else { gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED)); PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize); gST->ConOut->OutputString ( gST->ConOut, GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE)) ); gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); } }
/** Function to take a destination path that might contain wildcards and verify that there is only a single possible target (IE we cant have wildcards that have 2 possible destination). if the result is sucessful the caller must free *DestPathPointer. @param[in] DestParameter The original path to the destination. @param[in, out] DestPathPointer A pointer to the callee allocated final path. @param[in] Cwd A pointer to the current working directory. @param[in] SingleSource TRUE to have only one source file. @param[in, out] DestAttr A pointer to the destination information attribute. @retval SHELL_INVALID_PARAMETER The DestParameter could not be resolved to a location. @retval SHELL_INVALID_PARAMETER The DestParameter could be resolved to more than 1 location. @retval SHELL_INVALID_PARAMETER Cwd is required and is NULL. @retval SHELL_SUCCESS The operation was sucessful. **/ SHELL_STATUS EFIAPI GetDestinationLocation( IN CONST CHAR16 *DestParameter, IN OUT CHAR16 **DestPathPointer, IN CONST CHAR16 *Cwd, IN CONST BOOLEAN SingleSource, IN OUT UINT64 *DestAttr ) { EFI_SHELL_FILE_INFO *DestList; EFI_SHELL_FILE_INFO *Node; CHAR16 *DestPath; UINTN NewSize; UINTN CurrentSize; DestList = NULL; DestPath = NULL; ASSERT(DestAttr != NULL); if (StrStr(DestParameter, L"\\") == DestParameter) { if (Cwd == NULL) { return SHELL_INVALID_PARAMETER; } DestPath = AllocateZeroPool(StrSize(Cwd)); if (DestPath == NULL) { return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, StrSize(Cwd) / sizeof(CHAR16), Cwd); while (PathRemoveLastItem(DestPath)) ; // // Append DestParameter beyond '\' which may be present // CurrentSize = StrSize(DestPath); StrnCatGrow(&DestPath, &CurrentSize, &DestParameter[1], 0); *DestPathPointer = DestPath; return (SHELL_SUCCESS); } // // get the destination path // ShellOpenFileMetaArg((CHAR16*)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList); if (DestList == NULL || IsListEmpty(&DestList->Link)) { // // Not existing... must be renaming // if (StrStr(DestParameter, L":") == NULL) { if (Cwd == NULL) { ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); return (SHELL_INVALID_PARAMETER); } NewSize = StrSize(Cwd); NewSize += StrSize(DestParameter); DestPath = AllocateZeroPool(NewSize); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, NewSize / sizeof(CHAR16), Cwd); if (DestPath[StrLen(DestPath)-1] != L'\\' && DestParameter[0] != L'\\') { StrCatS(DestPath, NewSize / sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestParameter[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, NewSize / sizeof(CHAR16), DestParameter); } else { ASSERT(DestPath == NULL); DestPath = StrnCatGrow(&DestPath, NULL, DestParameter, 0); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } } } else { Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&DestList->Link); *DestAttr = Node->Info->Attribute; // // Make sure there is only 1 node in the list. // if (!IsNodeAtEnd(&DestList->Link, &Node->Link)) { ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); return (SHELL_INVALID_PARAMETER); } // // If we are a directory or a single file, then one node is fine. // if (ShellIsDirectory(Node->FullName)==EFI_SUCCESS || SingleSource) { DestPath = AllocateZeroPool(StrSize(Node->FullName)+sizeof(CHAR16)); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, (StrSize(Node->FullName)+sizeof(CHAR16)) / sizeof(CHAR16), Node->FullName); StrCatS(DestPath, (StrSize(Node->FullName)+sizeof(CHAR16)) / sizeof(CHAR16), L"\\"); } else { // // cant move multiple files onto a single file. // ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); return (SHELL_INVALID_PARAMETER); } } *DestPathPointer = DestPath; ShellCloseFileMetaArg(&DestList); return (SHELL_SUCCESS); }
/** Function to do a move within a file system. @param[in] Node A pointer to the file to be removed. @param[in] DestPath A pointer to the destination file path. @param[out] Resp A pointer to response from question. Pass back on looped calling. @retval SHELL_SUCCESS The source file was moved to the destination. @retval SHELL_OUT_OF_RESOURCES A memory allocation failed. **/ EFI_STATUS EFIAPI MoveWithinFileSystems( IN EFI_SHELL_FILE_INFO *Node, IN CHAR16 *DestPath, OUT VOID **Resp ) { EFI_FILE_INFO *NewFileInfo; CHAR16 *TempLocation; UINTN NewSize; UINTN Length; EFI_STATUS Status; // // Chop off map info from DestPath // if ((TempLocation = StrStr(DestPath, L":")) != NULL) { CopyMem(DestPath, TempLocation+1, StrSize(TempLocation+1)); } // // construct the new file info block // NewSize = StrSize(DestPath); NewSize += StrSize(Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); NewFileInfo = AllocateZeroPool(NewSize); if (NewFileInfo == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle); Status = EFI_OUT_OF_RESOURCES; } else { CopyMem(NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO); if (DestPath[0] != L'\\') { StrCpyS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), L"\\"); StrCatS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), DestPath); } else { StrCpyS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), DestPath); } Length = StrLen(NewFileInfo->FileName); if (Length > 0) { Length--; } if (NewFileInfo->FileName[Length] == L'\\') { if (Node->FileName[0] == L'\\') { // // Don't allow for double slashes. Eliminate one of them. // NewFileInfo->FileName[Length] = CHAR_NULL; } StrCatS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), Node->FileName); } NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize(NewFileInfo->FileName); // // Perform the move operation // Status = ShellSetFileInfo(Node->Handle, NewFileInfo); // // Free the info object we used... // FreePool(NewFileInfo); } return (Status); }
/** This function publish the VLAN configuration Form for a network device. The HII Config Access protocol will be installed on a child handle of the network device. @param[in, out] PrivateData Points to VLAN configuration private data. @retval EFI_SUCCESS HII Form is installed for this network device. @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. @retval Others Other errors as indicated. **/ EFI_STATUS InstallVlanConfigForm ( IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData ) { EFI_STATUS Status; EFI_HII_HANDLE HiiHandle; EFI_HANDLE DriverHandle; CHAR16 Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1]; CHAR16 *MacString; EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; // // Create child handle and install HII Config Access Protocol // ChildDevicePath = AppendDevicePathNode ( PrivateData->ParentDevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *) &mHiiVendorDevicePathNode ); if (ChildDevicePath == NULL) { return EFI_OUT_OF_RESOURCES; } PrivateData->ChildDevicePath = ChildDevicePath; DriverHandle = NULL; ConfigAccess = &PrivateData->ConfigAccess; Status = gBS->InstallMultipleProtocolInterfaces ( &DriverHandle, &gEfiDevicePathProtocolGuid, ChildDevicePath, &gEfiHiiConfigAccessProtocolGuid, ConfigAccess, NULL ); if (EFI_ERROR (Status)) { return Status; } PrivateData->DriverHandle = DriverHandle; // // Establish the parent-child relationship between the new created // child handle and the ControllerHandle. // Status = gBS->OpenProtocol ( PrivateData->ControllerHandle, &gEfiVlanConfigProtocolGuid, (VOID **)&VlanConfig, PrivateData->ImageHandle, PrivateData->DriverHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { return Status; } // // Publish the HII package list // HiiHandle = HiiAddPackages ( &gVlanConfigFormSetGuid, DriverHandle, VlanConfigDxeStrings, VlanConfigBin, NULL ); if (HiiHandle == NULL) { return EFI_OUT_OF_RESOURCES; } PrivateData->HiiHandle = HiiHandle; // // Update formset title help string. // MacString = NULL; Status = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString); if (EFI_ERROR (Status)) { return Status; } PrivateData->MacString = MacString; StrCpyS (Str, sizeof (Str) / sizeof (CHAR16), L"VLAN Configuration (MAC:"); StrCatS (Str, sizeof (Str) / sizeof (CHAR16), MacString); StrCatS (Str, sizeof (Str) / sizeof (CHAR16), L")"); HiiSetString ( HiiHandle, STRING_TOKEN (STR_VLAN_FORM_SET_TITLE_HELP), Str, NULL ); // // Update form title help string. // HiiSetString ( HiiHandle, STRING_TOKEN (STR_VLAN_FORM_HELP), Str, NULL ); return EFI_SUCCESS; }
/** Opens a new file relative to the source file's location. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to the source location. This would typically be an open handle to a directory. @param NewHandle A pointer to the location to return the opened handle for the new file. @param FileName The Null-terminated string of the name of the file to be opened. The file name may contain the following path modifiers: "\", ".", and "..". @param OpenMode The mode to open the file. The only valid combinations that the file may be opened with are: Read, Read/Write, or Create/Read/Write. @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the attribute bits for the newly created file. @retval EFI_SUCCESS The file was opened. @retval EFI_NOT_FOUND The specified file 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 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. **/ EFI_STATUS EFIAPI FvSimpleFileSystemOpen ( IN EFI_FILE_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes ) { FV_FILESYSTEM_INSTANCE *Instance; FV_FILESYSTEM_FILE *File; FV_FILESYSTEM_FILE *NewFile; FV_FILESYSTEM_FILE_INFO *FvFileInfo; LIST_ENTRY *FvFileInfoLink; EFI_STATUS Status; UINTN FileNameLength; UINTN NewFileNameLength; CHAR16 *FileNameWithExtension; // // Check for a valid mode // switch (OpenMode) { case EFI_FILE_MODE_READ: break; default: return EFI_WRITE_PROTECTED; } File = FVFS_FILE_FROM_FILE_THIS (This); Instance = File->Instance; FileName = TrimFilePathToAbsolutePath (FileName); if (FileName == NULL) { return EFI_INVALID_PARAMETER; } if (FileName[0] == L'\\') { FileName++; } // // Check for opening root // if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) { NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); if (NewFile == NULL) { return EFI_OUT_OF_RESOURCES; } NewFile->Signature = FVFS_FILE_SIGNATURE; NewFile->Instance = Instance; NewFile->FvFileInfo = File->FvFileInfo; CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); InitializeListHead (&NewFile->Link); InsertHeadList (&Instance->FileHead, &NewFile->Link); NewFile->DirReadNext = NULL; if (!IsListEmpty (&Instance->FileInfoHead)) { NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance); } *NewHandle = &NewFile->FileProtocol; return EFI_SUCCESS; } // // Do a linear search for a file in the FV with a matching filename // Status = EFI_NOT_FOUND; FvFileInfo = NULL; for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead); !IsNull (&Instance->FileInfoHead, FvFileInfoLink); FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) { FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink); if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) { Status = EFI_SUCCESS; break; } } // If the file has not been found check if the filename exists with an extension // in case there was no extension present. // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers // present in the Firmware Volume if (Status == EFI_NOT_FOUND) { FileNameLength = StrLen (FileName); // Does the filename already contain the '.EFI' extension? if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) { // No, there was no extension. So add one and search again for the file // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character) NewFileNameLength = FileNameLength + 1 + 4; FileNameWithExtension = AllocatePool (NewFileNameLength * 2); StrCpyS (FileNameWithExtension, NewFileNameLength, FileName); StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI"); for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead); !IsNull (&Instance->FileInfoHead, FvFileInfoLink); FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) { FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink); if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) { Status = EFI_SUCCESS; break; } } } } if (!EFI_ERROR (Status)) { NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); if (NewFile == NULL) { return EFI_OUT_OF_RESOURCES; } NewFile->Signature = FVFS_FILE_SIGNATURE; NewFile->Instance = Instance; NewFile->FvFileInfo = FvFileInfo; CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); InitializeListHead (&NewFile->Link); InsertHeadList (&Instance->FileHead, &NewFile->Link); *NewHandle = &NewFile->FileProtocol; return EFI_SUCCESS; } return EFI_NOT_FOUND; }
/** Append file name to existing file name, and allocate a new buffer to hold the appended result. @param[in] Str1 The existing file name @param[in] Str2 The file name to be appended @return A new string with appended result. **/ CHAR16 * AppendFileName ( IN CHAR16 *Str1, IN CHAR16 *Str2 ) { UINTN Size1; UINTN Size2; UINTN BufferSize; CHAR16 *Str; CHAR16 *TmpStr; CHAR16 *Ptr; CHAR16 *LastSlash; Size1 = StrSize (Str1); Size2 = StrSize (Str2); BufferSize = Size1 + Size2 + sizeof (CHAR16); Str = AllocateZeroPool (BufferSize); ASSERT (Str != NULL); TmpStr = AllocateZeroPool (BufferSize); ASSERT (TmpStr != NULL); StrCatS (Str, BufferSize / sizeof (CHAR16), Str1); if (!((*Str == '\\') && (*(Str + 1) == 0))) { StrCatS (Str, BufferSize / sizeof (CHAR16), L"\\"); } StrCatS (Str, BufferSize / sizeof (CHAR16), Str2); Ptr = Str; LastSlash = Str; while (*Ptr != 0) { if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') { // // Convert "\Name\..\" to "\" // DO NOT convert the .. if it is at the end of the string. This will // break the .. behavior in changing directories. // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, BufferSize / sizeof (CHAR16), Ptr + 3); StrCpyS (LastSlash, BufferSize / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') { // // Convert a "\.\" to a "\" // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, BufferSize / sizeof (CHAR16), Ptr + 2); StrCpyS (Ptr, BufferSize / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\') { LastSlash = Ptr; } Ptr++; } FreePool (TmpStr); return Str; }
/** Delete a node and all nodes under it (including sub directories). @param[in] Node The node to start deleting with. @param[in] Quiet TRUE to print no messages. @retval SHELL_SUCCESS The operation was successful. @retval SHELL_ACCESS_DENIED A file was read only. @retval SHELL_ABORTED The abort message was received. @retval SHELL_DEVICE_ERROR A device error occured reading this Node. **/ SHELL_STATUS CascadeDelete( IN EFI_SHELL_FILE_INFO *Node, IN CONST BOOLEAN Quiet ) { SHELL_STATUS ShellStatus; EFI_SHELL_FILE_INFO *List; EFI_SHELL_FILE_INFO *Node2; EFI_STATUS Status; SHELL_PROMPT_RESPONSE *Resp; CHAR16 *TempName; UINTN NewSize; Resp = NULL; ShellStatus = SHELL_SUCCESS; List = NULL; Status = EFI_SUCCESS; if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, L"rm", Node->FullName); return (SHELL_ACCESS_DENIED); } if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { if (!IsDirectoryEmpty(Node->Handle)) { if (!Quiet) { Status = ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName); Status = ShellPromptForResponse(ShellPromptResponseTypeYesNo, NULL, (VOID**)&Resp); ASSERT(Resp != NULL); if (EFI_ERROR(Status) || *Resp != ShellPromptResponseYes) { SHELL_FREE_NON_NULL(Resp); return (SHELL_ABORTED); } SHELL_FREE_NON_NULL(Resp); } // // empty out the directory // Status = gEfiShellProtocol->FindFilesInDir(Node->Handle, &List); if (EFI_ERROR(Status)) { if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } return (SHELL_DEVICE_ERROR); } for (Node2 = (EFI_SHELL_FILE_INFO *)GetFirstNode(&List->Link) ; !IsNull(&List->Link, &Node2->Link) ; Node2 = (EFI_SHELL_FILE_INFO *)GetNextNode(&List->Link, &Node2->Link) ){ // // skip the directory traversing stuff... // if (StrCmp(Node2->FileName, L".") == 0 || StrCmp(Node2->FileName, L"..") == 0) { continue; } Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); if (EFI_ERROR(Node2->Status) && StrStr(Node2->FileName, L":") == NULL) { // // Update the node filename to have full path with file system identifier // NewSize = StrSize(Node->FullName) + StrSize(Node2->FullName); TempName = AllocateZeroPool(NewSize); if (TempName == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else { StrCpyS(TempName, NewSize/sizeof(CHAR16), Node->FullName); TempName[StrStr(TempName, L":")+1-TempName] = CHAR_NULL; StrCatS(TempName, NewSize/sizeof(CHAR16), Node2->FullName); FreePool((VOID*)Node2->FullName); Node2->FullName = TempName; // // Now try again to open the file // Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); } } if (!EFI_ERROR(Node2->Status)) { ShellStatus = CascadeDelete(Node2, Quiet); } else if (ShellStatus == SHELL_SUCCESS) { ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000)); } if (ShellStatus != SHELL_SUCCESS) { if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } return (ShellStatus); } } if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } } } if (!(StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0)) { // // now delete the current node... // if (!Quiet) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName); } Status = gEfiShellProtocol->DeleteFile(Node->Handle); Node->Handle = NULL; } // // We cant allow for the warning here! (Dont use EFI_ERROR Macro). // if (Status != EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status); return (SHELL_ACCESS_DENIED); } else { if (!Quiet) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle); } return (SHELL_SUCCESS); } }
/** Refresh the text mode page. @param CallbackData The BMM context data. **/ VOID UpdateConModePage ( IN BMM_CALLBACK_DATA *CallbackData ) { UINTN Mode; UINTN Index; UINTN Col; UINTN Row; CHAR16 ModeString[50]; CHAR16 *PStr; UINTN MaxMode; UINTN ValidMode; EFI_STRING_ID *ModeToken; EFI_STATUS Status; VOID *OptionsOpCodeHandle; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; ConOut = gST->ConOut; Index = 0; ValidMode = 0; MaxMode = (UINTN) (ConOut->Mode->MaxMode); CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); // // Check valid mode // for (Mode = 0; Mode < MaxMode; Mode++) { Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row); if (EFI_ERROR (Status)) { continue; } ValidMode++; } if (ValidMode == 0) { return; } OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); ModeToken = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode); ASSERT(ModeToken != NULL); // // Determin which mode should be the first entry in menu // // GetConsoleOutMode (CallbackData); // // Build text mode options // for (Mode = 0; Mode < MaxMode; Mode++) { Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row); if (EFI_ERROR (Status)) { continue; } // // Build mode string Column x Row // UnicodeValueToString (ModeString, 0, Col, 0); PStr = &ModeString[0]; StrCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x "); PStr = PStr + StrLen (PStr); UnicodeValueToString (PStr , 0, Row, 0); ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL); if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, ModeToken[Index], EFI_IFR_OPTION_DEFAULT, EFI_IFR_TYPE_NUM_SIZE_16, (UINT16) Mode ); } else { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, ModeToken[Index], 0, EFI_IFR_TYPE_NUM_SIZE_16, (UINT16) Mode ); } Index++; } HiiCreateOneOfOpCode ( mStartOpCodeHandle, (EFI_QUESTION_ID) CON_MODE_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, CON_MODE_VAR_OFFSET, STRING_TOKEN (STR_CON_MODE_SETUP), STRING_TOKEN (STR_CON_MODE_SETUP), EFI_IFR_FLAG_RESET_REQUIRED, EFI_IFR_NUMERIC_SIZE_2, OptionsOpCodeHandle, NULL ); HiiFreeOpCodeHandle (OptionsOpCodeHandle); FreePool (ModeToken); UpdatePageEnd (CallbackData); }
/** function to take a list of files to move and a destination location and do the verification and moving of those files to that location. This function will report any errors to the user and continue to move the rest of the files. @param[in] FileList A LIST_ENTRY* based list of files to move @param[out] Resp pointer to response from question. Pass back on looped calling @param[in] DestParameter the originally specified destination location @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_SECURITY_VIOLATION a security violation ocurred @retval SHELL_WRITE_PROTECTED the destination was write protected @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ SHELL_STATUS EFIAPI ValidateAndMoveFiles( IN EFI_SHELL_FILE_INFO *FileList, OUT VOID **Resp, IN CONST CHAR16 *DestParameter ) { EFI_STATUS Status; CHAR16 *HiiOutput; CHAR16 *HiiResultOk; CHAR16 *DestPath; CHAR16 *FullDestPath; CONST CHAR16 *Cwd; CHAR16 *FullCwd; SHELL_STATUS ShellStatus; EFI_SHELL_FILE_INFO *Node; VOID *Response; UINT64 Attr; CHAR16 *CleanFilePathStr; ASSERT(FileList != NULL); ASSERT(DestParameter != NULL); DestPath = NULL; FullDestPath = NULL; Cwd = ShellGetCurrentDir(NULL); Response = *Resp; Attr = 0; CleanFilePathStr = NULL; FullCwd = NULL; if (Cwd != NULL) { FullCwd = AllocateZeroPool(StrSize(Cwd) + sizeof(CHAR16)); if (FullCwd == NULL) { return SHELL_OUT_OF_RESOURCES; } else { StrCpyS(FullCwd, StrSize(Cwd)/sizeof(CHAR16)+1, Cwd); StrCatS(FullCwd, StrSize(Cwd)/sizeof(CHAR16)+1, L"\\"); } } Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr); if (EFI_ERROR (Status)) { SHELL_FREE_NON_NULL(FullCwd); if (Status == EFI_OUT_OF_RESOURCES) { return SHELL_OUT_OF_RESOURCES; } else { return SHELL_INVALID_PARAMETER; } } ASSERT (CleanFilePathStr != NULL); // // Get and validate the destination location // ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, FullCwd, (BOOLEAN)(FileList->Link.ForwardLink == FileList->Link.BackLink), &Attr); FreePool (CleanFilePathStr); if (ShellStatus != SHELL_SUCCESS) { SHELL_FREE_NON_NULL (FullCwd); return (ShellStatus); } DestPath = PathCleanUpDirectories(DestPath); if (DestPath == NULL) { FreePool (FullCwd); return (SHELL_OUT_OF_RESOURCES); } HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL); HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); if (HiiOutput == NULL || HiiResultOk == NULL) { SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(FullCwd); return (SHELL_OUT_OF_RESOURCES); } // // Go through the list of files and directories to move... // for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag()) { break; } // // These should never be NULL // ASSERT(Node->FileName != NULL); ASSERT(Node->FullName != NULL); ASSERT(Node->Info != NULL); // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } SHELL_FREE_NON_NULL(FullDestPath); FullDestPath = NULL; if (ShellIsDirectory(DestPath)==EFI_SUCCESS) { CreateFullDestPath((CONST CHAR16 **)&DestPath, &FullDestPath, Node->FileName); } // // Validate that the move is valid // if (!IsValidMove(Node->FullName, FullCwd, FullDestPath!=NULL? FullDestPath:DestPath, Node->Info->Attribute, Attr, Node->Status)) { ShellStatus = SHELL_INVALID_PARAMETER; continue; } ShellPrintEx(-1, -1, HiiOutput, Node->FullName, FullDestPath!=NULL? FullDestPath:DestPath); // // See if destination exists // if (!EFI_ERROR(ShellFileExists(FullDestPath!=NULL? FullDestPath:DestPath))) { if (Response == NULL) { ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); } switch (*(SHELL_PROMPT_RESPONSE*)Response) { case ShellPromptResponseNo: FreePool(Response); Response = NULL; continue; case ShellPromptResponseCancel: *Resp = Response; // // indicate to stop everything // SHELL_FREE_NON_NULL(FullCwd); return (SHELL_ABORTED); case ShellPromptResponseAll: *Resp = Response; break; case ShellPromptResponseYes: FreePool(Response); Response = NULL; break; default: FreePool(Response); SHELL_FREE_NON_NULL(FullCwd); return SHELL_ABORTED; } Status = ShellDeleteFileByName(FullDestPath!=NULL? FullDestPath:DestPath); } if (IsBetweenFileSystem(Node->FullName, FullCwd, DestPath)) { while (FullDestPath == NULL && DestPath != NULL && DestPath[0] != CHAR_NULL && DestPath[StrLen(DestPath) - 1] == L'\\') { DestPath[StrLen(DestPath) - 1] = CHAR_NULL; } Status = MoveBetweenFileSystems(Node, FullDestPath!=NULL? FullDestPath:DestPath, &Response); } else { Status = MoveWithinFileSystems(Node, DestPath, &Response); // // Display error status // if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"mv", Status); } } // // Check our result // if (EFI_ERROR(Status)) { ShellStatus = SHELL_INVALID_PARAMETER; if (Status == EFI_SECURITY_VIOLATION) { ShellStatus = SHELL_SECURITY_VIOLATION; } else if (Status == EFI_WRITE_PROTECTED) { ShellStatus = SHELL_WRITE_PROTECTED; } else if (Status == EFI_OUT_OF_RESOURCES) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else if (Status == EFI_DEVICE_ERROR) { ShellStatus = SHELL_DEVICE_ERROR; } else if (Status == EFI_ACCESS_DENIED) { ShellStatus = SHELL_ACCESS_DENIED; } } else { ShellPrintEx(-1, -1, L"%s", HiiResultOk); } } // main for loop SHELL_FREE_NON_NULL(FullDestPath); SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(FullCwd); return (ShellStatus); }
/** function to take a list of files to copy and a destination location and do the verification and copying of those files to that location. This function will report any errors to the user and halt. The key is to have this function called ONLY once. this allows for the parameter verification to happen correctly. @param[in] FileList A LIST_ENTRY* based list of files to move. @param[in] DestDir The destination location. @param[in] SilentMode TRUE to eliminate screen output. @param[in] RecursiveMode TRUE to copy directories. @param[in] Resp The response to the overwrite query (if always). @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_SECURITY_VIOLATION a security violation ocurred @retval SHELL_WRITE_PROTECTED the destination was write protected @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ SHELL_STATUS ValidateAndCopyFiles( IN CONST EFI_SHELL_FILE_INFO *FileList, IN CONST CHAR16 *DestDir, IN BOOLEAN SilentMode, IN BOOLEAN RecursiveMode, IN VOID **Resp ) { CHAR16 *HiiOutput; CHAR16 *HiiResultOk; CONST EFI_SHELL_FILE_INFO *Node; SHELL_STATUS ShellStatus; EFI_STATUS Status; CHAR16 *DestPath; VOID *Response; UINTN PathSize; CONST CHAR16 *Cwd; UINTN NewSize; CHAR16 *CleanFilePathStr; if (Resp == NULL) { Response = NULL; } else { Response = *Resp; } DestPath = NULL; ShellStatus = SHELL_SUCCESS; PathSize = 0; Cwd = ShellGetCurrentDir(NULL); CleanFilePathStr = NULL; ASSERT(FileList != NULL); ASSERT(DestDir != NULL); Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); if (EFI_ERROR (Status)) { if (Status == EFI_OUT_OF_RESOURCES) { return SHELL_OUT_OF_RESOURCES; } else { return SHELL_INVALID_PARAMETER; } } ASSERT (CleanFilePathStr != NULL); // // If we are trying to copy multiple files... make sure we got a directory for the target... // if (EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { // // Error for destination not a directory // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } NewSize = StrSize(CleanFilePathStr); NewSize += StrSize(Node->FullName); NewSize += (Cwd == NULL)? 0 : (StrSize(Cwd) + sizeof(CHAR16)); if (NewSize > PathSize) { PathSize = NewSize; } // // Make sure got -r if required // if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp"); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } // // make sure got dest as dir if needed // if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(CleanFilePathStr))) { // // Error for destination not a directory // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } } HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL); HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); DestPath = AllocateZeroPool(PathSize); if (DestPath == NULL || HiiOutput == NULL || HiiResultOk == NULL) { SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); FreePool (CleanFilePathStr); return (SHELL_OUT_OF_RESOURCES); } // // Go through the list of files to copy... // for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag()) { break; } ASSERT(Node->FileName != NULL); ASSERT(Node->FullName != NULL); // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item && EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) // not an existing directory ) { if (StrStr(CleanFilePathStr, L":") == NULL) { // // simple copy of a single file // if (Cwd != NULL) { StrCpyS(DestPath, PathSize / sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); } else { StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); } } else { // // we have multiple files or a directory in the DestDir // // // Check for leading slash // if (CleanFilePathStr[0] == L'\\') { // // Copy to the root of CWD // if (Cwd != NULL) { StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } while (PathRemoveLastItem(DestPath)); StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr+1); StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } else if (StrStr(CleanFilePathStr, L":") == NULL) { if (Cwd != NULL) { StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } else { StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { ((CHAR16*)CleanFilePathStr)[StrLen(CleanFilePathStr)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } } // // Make sure the path exists // if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath); ShellStatus = SHELL_DEVICE_ERROR; break; } if ( !EFI_ERROR(ShellIsDirectory(Node->FullName)) && !EFI_ERROR(ShellIsDirectory(DestPath)) && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL ){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } if ((StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName)) == 0) && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\') ) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } PathCleanUpDirectories(DestPath); if (!SilentMode) { ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath); } // // copy single file... // ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode, L"cp"); if (ShellStatus != SHELL_SUCCESS) { break; } } if (ShellStatus == SHELL_SUCCESS && Resp == NULL) { ShellPrintEx(-1, -1, L"%s", HiiResultOk); } SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(CleanFilePathStr); if (Resp == NULL) { SHELL_FREE_NON_NULL(Response); } return (ShellStatus); }
/** Perform the memory test base on the memory test intensive level, and update the memory resource. @param Level The memory test intensive level. @retval EFI_STATUS Success test all the system memory and update the memory resource **/ EFI_STATUS EFIAPI BdsMemoryTest ( IN EXTENDMEM_COVERAGE_LEVEL Level ) { EFI_STATUS Status; EFI_STATUS KeyStatus; EFI_STATUS InitStatus; EFI_STATUS ReturnStatus; BOOLEAN RequireSoftECCInit; EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest; UINT64 TestedMemorySize; UINT64 TotalMemorySize; UINTN TestPercent; UINT64 PreviousValue; BOOLEAN ErrorOut; BOOLEAN TestAbort; EFI_INPUT_KEY Key; CHAR16 StrPercent[80]; CHAR16 *StrTotalMemory; CHAR16 *Pos; CHAR16 *TmpStr; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; BOOLEAN IsFirstBoot; UINT32 TempData; UINTN StrTotalMemorySize; ReturnStatus = EFI_SUCCESS; ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); StrTotalMemorySize = 128; Pos = AllocateZeroPool (StrTotalMemorySize); if (Pos == NULL) { return ReturnStatus; } StrTotalMemory = Pos; TestedMemorySize = 0; TotalMemorySize = 0; PreviousValue = 0; ErrorOut = FALSE; TestAbort = FALSE; SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); RequireSoftECCInit = FALSE; Status = gBS->LocateProtocol ( &gEfiGenericMemTestProtocolGuid, NULL, (VOID **) &GenMemoryTest ); if (EFI_ERROR (Status)) { FreePool (Pos); return EFI_SUCCESS; } InitStatus = GenMemoryTest->MemoryTestInit ( GenMemoryTest, Level, &RequireSoftECCInit ); if (InitStatus == EFI_NO_MEDIA) { // // The PEI codes also have the relevant memory test code to check the memory, // it can select to test some range of the memory or all of them. If PEI code // checks all the memory, this BDS memory test will has no not-test memory to // do the test, and then the status of EFI_NO_MEDIA will be returned by // "MemoryTestInit". So it does not need to test memory again, just return. // FreePool (Pos); return EFI_SUCCESS; } if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST)); if (TmpStr != NULL) { PrintXY (10, 10, NULL, NULL, TmpStr); FreePool (TmpStr); } } else { DEBUG ((EFI_D_INFO, "Enter memory test.\n")); } do { Status = GenMemoryTest->PerformMemoryTest ( GenMemoryTest, &TestedMemorySize, &TotalMemorySize, &ErrorOut, TestAbort ); if (ErrorOut && (Status == EFI_DEVICE_ERROR)) { TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR)); if (TmpStr != NULL) { PrintXY (10, 10, NULL, NULL, TmpStr); FreePool (TmpStr); } ASSERT (0); } if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TempData = (UINT32) DivU64x32 (TotalMemorySize, 16); TestPercent = (UINTN) DivU64x32 ( DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16), TempData ); if (TestPercent != PreviousValue) { UnicodeValueToString (StrPercent, 0, TestPercent, 0); TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT)); if (TmpStr != NULL) { // // TmpStr size is 64, StrPercent is reserved to 16. // StrCatS (StrPercent, sizeof (StrPercent) / sizeof (CHAR16), TmpStr); PrintXY (10, 10, NULL, NULL, StrPercent); FreePool (TmpStr); } TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST)); if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, TestPercent, (UINTN) PreviousValue ); FreePool (TmpStr); } } PreviousValue = TestPercent; } else { DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n")); } if (!PcdGetBool (PcdConInConnectOnDemand)) { KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) { if (!RequireSoftECCInit) { if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST)); if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, 100, (UINTN) PreviousValue ); FreePool (TmpStr); } PrintXY (10, 10, NULL, NULL, L"100"); } Status = GenMemoryTest->Finished (GenMemoryTest); goto Done; } TestAbort = TRUE; } } } while (Status != EFI_NOT_FOUND); Status = GenMemoryTest->Finished (GenMemoryTest); Done: if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0); if (StrTotalMemory[0] == L',') { StrTotalMemory++; StrTotalMemorySize -= sizeof (CHAR16); } TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED)); if (TmpStr != NULL) { StrCatS (StrTotalMemory, StrTotalMemorySize / sizeof (CHAR16), TmpStr); FreePool (TmpStr); } PrintXY (10, 10, NULL, NULL, StrTotalMemory); PlatformBdsShowProgress ( Foreground, Background, StrTotalMemory, Color, 100, (UINTN) PreviousValue ); } else { DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize)); } FreePool (Pos); // // Use a DynamicHii type pcd to save the boot status, which is used to // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration. // IsFirstBoot = PcdGetBool(PcdBootState); if (IsFirstBoot) { PcdSetBool(PcdBootState, FALSE); } return ReturnStatus; }
/** This function publish the TCG2 configuration Form for TPM device. @param[in, out] PrivateData Points to TCG2 configuration private data. @retval EFI_SUCCESS HII Form is installed for this network device. @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. @retval Others Other errors as indicated. **/ EFI_STATUS InstallTcg2ConfigForm ( IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData ) { EFI_STATUS Status; EFI_HII_HANDLE HiiHandle; EFI_HANDLE DriverHandle; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; UINTN Index; TPML_PCR_SELECTION Pcrs; CHAR16 TempBuffer[1024]; TCG2_CONFIGURATION_INFO Tcg2ConfigInfo; UINT8 TpmDeviceInterfaceDetected; DriverHandle = NULL; ConfigAccess = &PrivateData->ConfigAccess; Status = gBS->InstallMultipleProtocolInterfaces ( &DriverHandle, &gEfiDevicePathProtocolGuid, &mTcg2HiiVendorDevicePath, &gEfiHiiConfigAccessProtocolGuid, ConfigAccess, NULL ); if (EFI_ERROR (Status)) { return Status; } PrivateData->DriverHandle = DriverHandle; // // Publish the HII package list // HiiHandle = HiiAddPackages ( &gTcg2ConfigFormSetGuid, DriverHandle, Tcg2ConfigDxeStrings, Tcg2ConfigBin, NULL ); if (HiiHandle == NULL) { gBS->UninstallMultipleProtocolInterfaces ( DriverHandle, &gEfiDevicePathProtocolGuid, &mTcg2HiiVendorDevicePath, &gEfiHiiConfigAccessProtocolGuid, ConfigAccess, NULL ); return EFI_OUT_OF_RESOURCES; } PrivateData->HiiHandle = HiiHandle; // // Update static data // switch (PrivateData->TpmDeviceDetected) { case TPM_DEVICE_NULL: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Not Found", NULL); break; case TPM_DEVICE_1_2: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL); break; case TPM_DEVICE_2_0_DTPM: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 2.0", NULL); break; default: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Unknown", NULL); break; } ZeroMem (&Tcg2ConfigInfo, sizeof(Tcg2ConfigInfo)); Status = Tpm2GetCapabilityPcrs (&Pcrs); if (EFI_ERROR (Status)) { HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), L"[Unknown]", NULL); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), L"[Unknown]", NULL); } else { TempBuffer[0] = 0; for (Index = 0; Index < Pcrs.count; Index++) { if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash); } } HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), TempBuffer, NULL); TempBuffer[0] = 0; for (Index = 0; Index < Pcrs.count; Index++) { AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash); SetConfigInfo (&Tcg2ConfigInfo, Pcrs.pcrSelections[Index].hash); } HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), TempBuffer, NULL); } FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (PcdTcg2HashAlgorithmBitmap)); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_CONTENT), TempBuffer, NULL); // // Tcg2 Capability // FillBufferWithTCG2EventLogFormat (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.SupportedEventLogs); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT), TempBuffer, NULL); FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.HashAlgorithmBitmap); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_HASH_ALGO_BITMAP_CONTENT), TempBuffer, NULL); UnicodeSPrint (TempBuffer, sizeof (TempBuffer), L"%d", PrivateData->ProtocolCapability.NumberOfPCRBanks); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT), TempBuffer, NULL); FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.ActivePcrBanks); HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_ACTIVE_PCR_BANKS_CONTENT), TempBuffer, NULL); // // Update TPM device interface type // if (PrivateData->TpmDeviceDetected == TPM_DEVICE_2_0_DTPM) { TpmDeviceInterfaceDetected = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress)); switch (TpmDeviceInterfaceDetected) { case TPM_DEVICE_INTERFACE_TIS: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"TIS", NULL); break; case TPM_DEVICE_INTERFACE_PTP_FIFO: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP FIFO", NULL); break; case TPM_DEVICE_INTERFACE_PTP_CRB: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP CRB", NULL); break; default: HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"Unknown", NULL); break; } Tcg2ConfigInfo.TpmDeviceInterfaceAttempt = TpmDeviceInterfaceDetected; switch (TpmDeviceInterfaceDetected) { case TPM_DEVICE_INTERFACE_TIS: Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE; Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE; HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"TIS", NULL); break; case TPM_DEVICE_INTERFACE_PTP_FIFO: case TPM_DEVICE_INTERFACE_PTP_CRB: Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = IsPtpFifoSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress)); Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = IsPtpCrbSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress)); TempBuffer[0] = 0; if (Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported) { if (TempBuffer[0] != 0) { StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", "); } StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP FIFO"); } if (Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported) { if (TempBuffer[0] != 0) { StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", "); } StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP CRB"); } HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), TempBuffer, NULL); break; default: Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE; Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE; HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"Unknown", NULL); break; } } // // Set ConfigInfo, to control the check box. // Status = gRT->SetVariable ( TCG2_STORAGE_INFO_NAME, &gTcg2ConfigFormSetGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(Tcg2ConfigInfo), &Tcg2ConfigInfo ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_INFO_NAME\n")); } return EFI_SUCCESS; }