/** Display the confirm text and get user confirmation. @param[in] TpmPpCommand The requested TPM physical presence command. @retval TRUE The user has confirmed the changes. @retval FALSE The user doesn't confirm the changes. **/ BOOLEAN UserConfirm ( IN UINT8 TpmPpCommand ) { CHAR16 *ConfirmText; CHAR16 *TmpStr1; CHAR16 *TmpStr2; UINTN BufSize; BOOLEAN CautionKey; UINT16 Index; CHAR16 DstStr[81]; TmpStr2 = NULL; CautionKey = FALSE; BufSize = CONFIRM_BUFFER_SIZE; ConfirmText = AllocateZeroPool (BufSize); ASSERT (ConfirmText != NULL); switch (TpmPpCommand) { case PHYSICAL_PRESENCE_ENABLE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_DISABLE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_ACTIVATE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_DEACTIVATE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_CLEAR: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: // // TPM_SetOperatorAuth // This command requires UI to prompt user for Auth data // Here it is NOT implemented // break; case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: CautionKey = TRUE; TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE)); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1); FreePool (TmpStr1); break; default: ; } if (TmpStr2 == NULL) { FreePool (ConfirmText); return FALSE; } TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY)); BufSize -= StrSize (ConfirmText); UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2); DstStr[80] = L'\0'; for (Index = 0; Index < StrLen (ConfirmText); Index += 80) { StrnCpy(DstStr, ConfirmText + Index, 80); Print (DstStr); } FreePool (TmpStr1); FreePool (TmpStr2); FreePool (ConfirmText); if (ReadUserKey (CautionKey)) { return TRUE; } return FALSE; }
/** Function to parse the Data by the type of Data, and save in the Buffer. @param[in] Data A pointer to a buffer to be parsed. @param[out] Buffer A pointer to a buffer to hold the return data. @param[in,out] BufferSize On input, indicates the size of Buffer in bytes. On output,indicates the size of data return in Buffer. Or the size in bytes of the buffer needed to obtain. @retval EFI_INVALID_PARAMETER The Buffer or BufferSize is NULL. @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to hold the data. @retval EFI_OUT_OF_RESOURCES A memory allcation failed. @retval EFI_SUCCESS The Data parsed successful and save in the Buffer. **/ EFI_STATUS ParseParameterData ( IN CONST CHAR16 *Data, OUT VOID *Buffer, IN OUT UINTN *BufferSize ) { UINT64 HexNumber; UINTN HexNumberLen; UINTN Size; CHAR8 *AsciiBuffer; DATA_TYPE DataType; EFI_DEVICE_PATH_PROTOCOL *DevPath; EFI_STATUS Status; HexNumber = 0; HexNumberLen = 0; Size = 0; AsciiBuffer = NULL; DevPath = NULL; Status = EFI_SUCCESS; if (Data == NULL || BufferSize == NULL) { return EFI_INVALID_PARAMETER; } DataType = TestDataType (Data); if (DataType == DataTypeHexNumber) { // // hex number // StrHexToUint64S (Data + 2, NULL, &HexNumber); HexNumberLen = StrLen (Data + 2); if (HexNumberLen >= 1 && HexNumberLen <= 2) { Size = 1; } else if (HexNumberLen >= 3 && HexNumberLen <= 4) { Size = 2; } else if (HexNumberLen >= 5 && HexNumberLen <= 8) { Size = 4; } else if (HexNumberLen >= 9 && HexNumberLen <= 16) { Size = 8; } if (Buffer != NULL && *BufferSize >= Size) { CopyMem(Buffer, (VOID *)&HexNumber, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeHexArray) { // // hex array // if (*Data == L'H') { Data = Data + 1; } Size = StrLen (Data) / 2; if (Buffer != NULL && *BufferSize >= Size) { StrHexToBytes(Data, StrLen (Data), (UINT8 *)Buffer, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeAscii) { // // ascii text // if (*Data == L'S') { Data = Data + 1; } AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2); if (AsciiBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data); Size = StrSize (Data) / 2 - 1; if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, AsciiBuffer, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } SHELL_FREE_NON_NULL (AsciiBuffer); } else if (DataType == DataTypeUnicode) { // // unicode text // if (*Data == L'L') { Data = Data + 1; } Size = StrSize (Data) - sizeof (CHAR16); if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, Data, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeDevicePath) { if (*Data == L'P') { Data = Data + 1; } else if (StrnCmp (Data, L"--", 2) == 0) { Data = Data + 2; } DevPath = ConvertTextToDevicePath (Data); if (DevPath == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar"); Status = EFI_INVALID_PARAMETER; } else { Size = GetDevicePathSize (DevPath); if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, DevPath, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } SHELL_FREE_NON_NULL (DevPath); } else { Status = EFI_INVALID_PARAMETER; } return Status; }
/** return the next parameter from a command line string; This function moves the next parameter from Walker into TempParameter and moves Walker up past that parameter for recursive calling. When the final parameter is moved *Walker will be set to NULL; Temp Parameter must be large enough to hold the parameter before calling this function. @param[in, out] Walker pointer to string of command line. Adjusted to reminaing command line on return @param[in, out] TempParameter pointer to string of command line item extracted. **/ VOID EFIAPI GetNextParameter( CHAR16 **Walker, CHAR16 **TempParameter ) { CHAR16 *NextDelim; CHAR16 *TempLoc; ASSERT(Walker != NULL); ASSERT(*Walker != NULL); ASSERT(TempParameter != NULL); ASSERT(*TempParameter != NULL); // // make sure we dont have any leading spaces // while ((*Walker)[0] == L' ') { (*Walker)++; } // // make sure we still have some params now... // if (StrLen(*Walker) == 0) { ASSERT((*Walker)[0] == CHAR_NULL); *Walker = NULL; return; } // // we have a quoted parameter // could be the last parameter, but SHOULD have a trailing quote // if ((*Walker)[0] == L'\"') { NextDelim = NULL; for (TempLoc = *Walker + 1 ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) { if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') { TempLoc++; } else if (*TempLoc == L'\"') { NextDelim = TempLoc; break; } } if (NextDelim - ((*Walker)+1) == 0) { // // found "" // StrCpy(*TempParameter, L""); *Walker = NextDelim + 1; } else if (NextDelim != NULL) { StrnCpy(*TempParameter, (*Walker)+1, NextDelim - ((*Walker)+1)); *Walker = NextDelim + 1; } else { // // last one... someone forgot the training quote! // StrCpy(*TempParameter, *Walker); *Walker = NULL; } for (TempLoc = *TempParameter ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) { if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') { CopyMem(TempLoc, TempLoc+1, StrSize(TempLoc) - sizeof(TempLoc[0])); } } } else { // // we have a regular parameter (no quote) OR // we have the final parameter (no trailing space) // NextDelim = StrStr((*Walker), L" "); if (NextDelim != NULL) { StrnCpy(*TempParameter, *Walker, NextDelim - (*Walker)); (*TempParameter)[NextDelim - (*Walker)] = CHAR_NULL; *Walker = NextDelim+1; } else { // // last one. // StrCpy(*TempParameter, *Walker); *Walker = NULL; } for (NextDelim = *TempParameter ; NextDelim != NULL && *NextDelim != CHAR_NULL ; NextDelim++) { if (*NextDelim == L'^' && *(NextDelim+1) == L'^') { CopyMem(NextDelim, NextDelim+1, StrSize(NextDelim) - sizeof(NextDelim[0])); } } while ((*TempParameter)[StrLen(*TempParameter)-1] == L' ') { (*TempParameter)[StrLen(*TempParameter)-1] = CHAR_NULL; } while ((*TempParameter)[0] == L' ') { CopyMem(*TempParameter, (*TempParameter)+1, StrSize(*TempParameter) - sizeof((*TempParameter)[0])); } } return; }
EFI_STATUS BootMenuUpdateBootOption ( IN LIST_ENTRY *BootOptionsList ) { EFI_STATUS Status; BDS_LOAD_OPTION_ENTRY *BootOptionEntry; BDS_LOAD_OPTION *BootOption; BDS_LOAD_OPTION_SUPPORT* DeviceSupport; ARM_BDS_LOADER_ARGUMENTS* BootArguments; CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; CHAR8 CmdLine[BOOT_DEVICE_OPTION_MAX]; CHAR16 UnicodeCmdLine[BOOT_DEVICE_OPTION_MAX]; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *TempInitrdPath; ARM_BDS_LOADER_TYPE BootType; ARM_BDS_LOADER_OPTIONAL_DATA* LoaderOptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; EFI_DEVICE_PATH *InitrdPathNodes; EFI_DEVICE_PATH *InitrdPath; UINTN InitrdSize; UINTN CmdLineSize; BOOLEAN InitrdSupport; UINT8* OptionalData; UINTN OptionalDataSize; BOOLEAN IsPrintable; BOOLEAN IsUnicode; DisplayBootOptions (BootOptionsList); Status = SelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, &BootOptionEntry); if (EFI_ERROR (Status)) { return Status; } BootOption = BootOptionEntry->BdsLoadOption; // Get the device support for this Boot Option Status = BootDeviceGetDeviceSupport (BootOption->FilePathList, &DeviceSupport); if (EFI_ERROR(Status)) { Print(L"Not possible to retrieve the supported device for the update\n"); return EFI_UNSUPPORTED; } Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } if (DeviceSupport->RequestBootType) { Status = BootDeviceGetType (DevicePath, &BootType, &BootOption->Attributes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } } LoaderOptionalData = BootOption->OptionalData; if (LoaderOptionalData != NULL) { BootType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((UINT32 *)(&LoaderOptionalData->Header.LoaderType)); } else { BootType = BDS_LOADER_EFI_APPLICATION; } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { LinuxArguments = &LoaderOptionalData->Arguments.LinuxArguments; CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Print(L"Keep the initrd: "); } else { Print(L"Add an initrd: "); } Status = GetHIInputBoolean (&InitrdSupport); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } if (InitrdSupport) { if (InitrdSize > 0) { // Case we update the initrd device path Status = DeviceSupport->UpdateDevicePathNode ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize), L"initrd", &InitrdPath); if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {// EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd Status = EFI_ABORTED; goto EXIT; } InitrdSize = GetDevicePathSize (InitrdPath); } else { // Case we create the initrd device path Status = DeviceSupport->CreateDevicePathNode (L"initrd", &InitrdPathNodes); if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd Status = EFI_ABORTED; goto EXIT; } if (InitrdPathNodes != NULL) { // Duplicate Linux kernel Device Path TempInitrdPath = DuplicateDevicePath (BootOption->FilePathList); // Replace Linux kernel Node by EndNode SetDevicePathEndNode (GetLastDevicePathNode (TempInitrdPath)); // Append the Device Path to the selected device path InitrdPath = AppendDevicePath (TempInitrdPath, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes); FreePool (TempInitrdPath); // Free the InitrdPathNodes created by Support->CreateDevicePathNode() FreePool (InitrdPathNodes); if (InitrdPath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } InitrdSize = GetDevicePathSize (InitrdPath); } else { InitrdPath = NULL; } } } else { InitrdSize = 0; } Print(L"Arguments to pass to the binary: "); if (CmdLineSize > 0) { AsciiStrnCpy (CmdLine, (CONST CHAR8*)(LinuxArguments + 1), sizeof (CmdLine)); CmdLine[sizeof (CmdLine) - 1] = '\0'; } else { CmdLine[0] = '\0'; } Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } CmdLineSize = AsciiStrSize (CmdLine); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); BootArguments->LinuxArguments.CmdLineSize = CmdLineSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem (&BootArguments->LinuxArguments + 1, CmdLine, CmdLineSize); CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { Print (L"Arguments to pass to the EFI Application: "); if (BootOption->OptionalDataSize > 0) { IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode); if (IsPrintable) { // // The size in bytes of the string, final zero included, should // be equal to or at least lower than "BootOption->OptionalDataSize" // and the "IsPrintableString()" has already tested that the length // in number of characters is smaller than BOOT_DEVICE_OPTION_MAX, // final '\0' included. We can thus copy the string for editing // using "CopyMem()". Furthermore, note that in the case of an Unicode // string "StrnCpy()" and "StrCpy()" can not be used to copy the // string because the data pointed to by "BootOption->OptionalData" // is not necessarily 2-byte aligned. // if (IsUnicode) { CopyMem ( UnicodeCmdLine, BootOption->OptionalData, MIN (sizeof (UnicodeCmdLine), BootOption->OptionalDataSize) ); } else { CopyMem ( CmdLine, BootOption->OptionalData, MIN (sizeof (CmdLine), BootOption->OptionalDataSize) ); } } } else { UnicodeCmdLine[0] = L'\0'; IsPrintable = TRUE; IsUnicode = TRUE; } // We do not request arguments for OptionalData that cannot be printed if (IsPrintable) { if (IsUnicode) { Status = EditHIInputStr (UnicodeCmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } OptionalData = (UINT8*)UnicodeCmdLine; OptionalDataSize = StrSize (UnicodeCmdLine); } else { Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } OptionalData = (UINT8*)CmdLine; OptionalDataSize = AsciiStrSize (CmdLine); } } else { // We keep the former OptionalData OptionalData = BootOption->OptionalData; OptionalDataSize = BootOption->OptionalDataSize; } } Print(L"Description for this new Entry: "); StrnCpy (BootDescription, BootOption->Description, BOOT_DEVICE_DESCRIPTION_MAX); Status = EditHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } // Update the entry Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize); FREE_DEVICE_PATH: FreePool (DevicePath); EXIT: if (Status == EFI_ABORTED) { Print(L"\n"); } return Status; }
EFIAPI StrnCatGrowLeft ( IN OUT CHAR16 **Destination, IN OUT UINTN *CurrentSize, IN CONST CHAR16 *Source, IN UINTN Count ) { UINTN DestinationStartSize; UINTN NewSize; UINTN CopySize; if (Destination == NULL) { return (NULL); } // // If there's nothing to do then just return Destination // if (Source == NULL) { return (*Destination); } // // allow for NULL pointers address as Destination // if (*Destination != NULL) { ASSERT(CurrentSize != 0); DestinationStartSize = StrSize(*Destination); ASSERT(DestinationStartSize <= *CurrentSize); } else { DestinationStartSize = 0; // ASSERT(*CurrentSize == 0); } // // Append all of Source? // if (Count == 0) { Count = StrSize(Source); } // // Test and grow if required // if (CurrentSize != NULL) { NewSize = *CurrentSize; while (NewSize < (DestinationStartSize + Count)) { NewSize += 2 * Count; } *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination); *CurrentSize = NewSize; } else { *Destination = AllocateZeroPool(Count+sizeof(CHAR16)); } if (*Destination == NULL) { return NULL; } CopySize = StrSize(*Destination); CopyMem((*Destination)+((Count-2)/sizeof(CHAR16)), *Destination, CopySize); CopyMem(*Destination, Source, Count-2); return (*Destination); }
/** Update the parameters of a TFTP boot option The function asks sequentially to update the IPv4 parameters as well as the boot file path, providing the previously set value if any. @param[in] OldDevicePath Current complete device path of the Tftp boot option. This has to be a valid complete Tftp boot option path. By complete, we mean that it is not only the Tftp specific end part built by the "BdsLoadOptionTftpCreateDevicePath()" function. This path is handled as read only. @param[in] FileName Description of the file the path is asked for @param[out] NewDevicePath Pointer to the new complete device path. @retval EFI_SUCCESS Update completed @retval EFI_ABORTED Update aborted by the user @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource **/ EFI_STATUS BdsLoadOptionTftpUpdateDevicePath ( IN EFI_DEVICE_PATH *OldDevicePath, IN CHAR16 *FileName, OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath ) { EFI_STATUS Status; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *DevicePathNode; UINT8 *Ipv4NodePtr; IPv4_DEVICE_PATH Ipv4Node; BOOLEAN IsDHCP; EFI_IP_ADDRESS OldIp; EFI_IP_ADDRESS LocalIp; EFI_IP_ADDRESS RemoteIp; UINT8 *FileNodePtr; CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; UINTN PathSize; UINTN BootFilePathSize; FILEPATH_DEVICE_PATH *NewFilePathNode; Ipv4NodePtr = NULL; // // Make a copy of the complete device path that is made of : // the device path of the device that support the Simple Network protocol // followed by an IPv4 node (type IPv4_DEVICE_PATH), // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up // by an end node. The IPv6 case is not handled yet. // DevicePath = DuplicateDevicePath (OldDevicePath); if (DevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the // call to this function, we know that the device path ends with an IPv4 node // followed by a file path node and finally an end node. To get the address of // the last IPv4 node, we loop over the whole device path, noting down the // address of each encountered IPv4 node. // for (DevicePathNode = DevicePath; !IsDevicePathEnd (DevicePathNode); DevicePathNode = NextDevicePathNode (DevicePathNode)) { if (IS_DEVICE_PATH_NODE (DevicePathNode, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)) { Ipv4NodePtr = (UINT8*)DevicePathNode; } } // Copy for alignment of the IPv4 node data CopyMem (&Ipv4Node, Ipv4NodePtr, sizeof (IPv4_DEVICE_PATH)); Print (L"Get the IP address from DHCP: "); Status = GetHIInputBoolean (&IsDHCP); if (EFI_ERROR (Status)) { goto ErrorExit; } if (!IsDHCP) { Print (L"Local static IP address: "); if (Ipv4Node.StaticIpAddress) { // Copy local IPv4 address into IPv4 or IPv6 union CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); Status = EditHIInputIP (&OldIp, &LocalIp); } else { Status = GetHIInputIP (&LocalIp); } if (EFI_ERROR (Status)) { goto ErrorExit; } } Print (L"TFTP server IP address: "); // Copy remote IPv4 address into IPv4 or IPv6 union CopyMem (&OldIp.v4, &Ipv4Node.RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS)); Status = EditHIInputIP (&OldIp, &RemoteIp); if (EFI_ERROR (Status)) { goto ErrorExit; } // Get the path of the boot file and its size in number of bytes FileNodePtr = Ipv4NodePtr + sizeof (IPv4_DEVICE_PATH); BootFilePathSize = DevicePathNodeLength (FileNodePtr) - SIZE_OF_FILEPATH_DEVICE_PATH; // // Ask for update of the boot file path // do { // Copy for 2-byte alignment of the Unicode string CopyMem ( BootFilePath, FileNodePtr + SIZE_OF_FILEPATH_DEVICE_PATH, MIN (BootFilePathSize, BOOT_DEVICE_FILEPATH_MAX) ); BootFilePath[BOOT_DEVICE_FILEPATH_MAX - 1] = L'\0'; Print (L"File path of the %s: ", FileName); Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); if (EFI_ERROR (Status)) { goto ErrorExit; } PathSize = StrSize (BootFilePath); if (PathSize > 2) { break; } // Empty string, give the user another try Print (L"Empty string - Invalid path\n"); } while (PathSize <= 2) ; // // Update the IPv4 node. IPv6 case not handled yet. // if (IsDHCP == TRUE) { Ipv4Node.StaticIpAddress = FALSE; } else { Ipv4Node.StaticIpAddress = TRUE; } CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH)); // // Create the new file path node // NewFilePathNode = (FILEPATH_DEVICE_PATH*)AllocatePool ( SIZE_OF_FILEPATH_DEVICE_PATH + PathSize ); NewFilePathNode->Header.Type = MEDIA_DEVICE_PATH; NewFilePathNode->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength ( NewFilePathNode, SIZE_OF_FILEPATH_DEVICE_PATH + PathSize ); CopyMem (NewFilePathNode->PathName, BootFilePath, PathSize); // // Generate the new Device Path by replacing the file path node at address // "FileNodePtr" by the new one "NewFilePathNode" and return its address. // SetDevicePathEndNode (FileNodePtr); *NewDevicePath = AppendDevicePathNode ( DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL*)NewFilePathNode ); ErrorExit: if (DevicePath != NULL) { FreePool (DevicePath) ; } return Status; }
/** Create the Boot####, Driver####, SysPrep####, PlatformRecovery#### variable from the load option. @param LoadOption Pointer to the load option. @retval EFI_SUCCESS The variable was created. @retval Others Error status returned by RT->SetVariable. **/ EFI_STATUS EFIAPI EfiBootManagerLoadOptionToVariable ( IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Option ) { EFI_STATUS Status; UINTN VariableSize; UINT8 *Variable; UINT8 *Ptr; CHAR16 OptionName[BM_OPTION_NAME_LEN]; CHAR16 *Description; CHAR16 NullChar; EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; UINT32 VariableAttributes; if ((Option->OptionNumber == LoadOptionNumberUnassigned) || (Option->FilePath == NULL) || ((UINT32) Option->OptionType >= LoadOptionTypeMax) ) { return EFI_INVALID_PARAMETER; } // // Convert NULL description to empty description // NullChar = L'\0'; Description = Option->Description; if (Description == NULL) { Description = &NullChar; } /* UINT32 Attributes; UINT16 FilePathListLength; CHAR16 Description[]; EFI_DEVICE_PATH_PROTOCOL FilePathList[]; UINT8 OptionalData[]; TODO: FilePathList[] IS: A packed array of UEFI device paths. The first element of the array is a device path that describes the device and location of the Image for this load option. The FilePathList[0] is specific to the device type. Other device paths may optionally exist in the FilePathList, but their usage is OSV specific. Each element in the array is variable length, and ends at the device path end structure. */ VariableSize = sizeof (Option->Attributes) + sizeof (UINT16) + StrSize (Description) + GetDevicePathSize (Option->FilePath) + Option->OptionalDataSize; Variable = AllocatePool (VariableSize); ASSERT (Variable != NULL); Ptr = Variable; WriteUnaligned32 ((UINT32 *) Ptr, Option->Attributes); Ptr += sizeof (Option->Attributes); WriteUnaligned16 ((UINT16 *) Ptr, (UINT16) GetDevicePathSize (Option->FilePath)); Ptr += sizeof (UINT16); CopyMem (Ptr, Description, StrSize (Description)); Ptr += StrSize (Description); CopyMem (Ptr, Option->FilePath, GetDevicePathSize (Option->FilePath)); Ptr += GetDevicePathSize (Option->FilePath); CopyMem (Ptr, Option->OptionalData, Option->OptionalDataSize); UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[Option->OptionType], Option->OptionNumber); VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; if (Option->OptionType == LoadOptionTypePlatformRecovery) { // // Lock the PlatformRecovery#### // Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock); if (!EFI_ERROR (Status)) { Status = VariableLock->RequestToLock (VariableLock, OptionName, &gEfiGlobalVariableGuid); ASSERT_EFI_ERROR (Status); } VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; } Status = gRT->SetVariable ( OptionName, &gEfiGlobalVariableGuid, VariableAttributes, VariableSize, Variable ); FreePool (Variable); return Status; }
/** Service routine for BdsInstance->Entry(). Devices are connected, the consoles are initialized, and the boot options are tried. @param This Protocol Instance structure. **/ VOID EFIAPI BdsEntry ( IN EFI_BDS_ARCH_PROTOCOL *This ) { LIST_ENTRY DriverOptionList; LIST_ENTRY BootOptionList; UINTN BootNextSize; CHAR16 *FirmwareVendor; EFI_STATUS Status; UINT16 BootTimeOut; UINTN Index; EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; // // Insert the performance probe // PERF_END (NULL, "DXE", NULL, 0); PERF_START (NULL, "BDS", NULL, 0); // // Initialize the global system boot option and driver option // InitializeListHead (&DriverOptionList); InitializeListHead (&BootOptionList); // // Initialize hotkey service // InitializeHotkeyService (); // // Fill in FirmwareVendor and FirmwareRevision from PCDs // FirmwareVendor = (CHAR16 *)PcdGetPtr (PcdFirmwareVendor); gST->FirmwareVendor = AllocateRuntimeCopyPool (StrSize (FirmwareVendor), FirmwareVendor); ASSERT (gST->FirmwareVendor != NULL); gST->FirmwareRevision = PcdGet32 (PcdFirmwareRevision); // // Fixup Tasble CRC after we updated Firmware Vendor and Revision // gST->Hdr.CRC32 = 0; gBS->CalculateCrc32 ((VOID *)gST, sizeof(EFI_SYSTEM_TABLE), &gST->Hdr.CRC32); // // Validate Variable. // BdsFormalizeEfiGlobalVariable(); // // Mark the read-only variables if the Variable Lock protocol exists // Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock); DEBUG ((EFI_D_INFO, "[BdsDxe] Locate Variable Lock protocol - %r\n", Status)); if (!EFI_ERROR (Status)) { for (Index = 0; Index < ARRAY_SIZE (mReadOnlyVariables); Index++) { Status = VariableLock->RequestToLock (VariableLock, mReadOnlyVariables[Index], &gEfiGlobalVariableGuid); ASSERT_EFI_ERROR (Status); } } // // Report Status Code to indicate connecting drivers will happen // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS) ); InitializeHwErrRecSupport(); // // Initialize L"Timeout" EFI global variable. // BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut); if (BootTimeOut != 0xFFFF) { // // If time out value equal 0xFFFF, no need set to 0xFFFF to variable area because UEFI specification // define same behavior between no value or 0xFFFF value for L"Timeout". // BdsDxeSetVariableAndReportStatusCodeOnError ( L"Timeout", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof (UINT16), &BootTimeOut ); } // // bugbug: platform specific code // Initialize the platform specific string and language // InitializeStringSupport (); InitializeLanguage (TRUE); InitializeFrontPage (TRUE); // // Do the platform init, can be customized by OEM/IBV // PERF_START (NULL, "PlatformBds", "BDS", 0); PlatformBdsInit (); // // Set up the device list based on EFI 1.1 variables // process Driver#### and Load the driver's in the // driver option list // BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder"); if (!IsListEmpty (&DriverOptionList)) { BdsLibLoadDrivers (&DriverOptionList); } // // Check if we have the boot next option // mBootNext = BdsLibGetVariableAndSize ( L"BootNext", &gEfiGlobalVariableGuid, &BootNextSize ); // // Setup some platform policy here // PlatformBdsPolicyBehavior (&DriverOptionList, &BootOptionList, BdsProcessCapsules, BdsMemoryTest); PERF_END (NULL, "PlatformBds", "BDS", 0); // // BDS select the boot device to load OS // BdsBootDeviceSelect (); // // Only assert here since this is the right behavior, we should never // return back to DxeCore. // ASSERT (FALSE); return ; }
/** 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); } StrnCpy(TitleString, StartString, TitleLength/sizeof(CHAR16) - 1); StrnCat(TitleString, Command, TitleLength/sizeof(CHAR16) - 1 - StrLen(TitleString)); StrnCat(TitleString, EndString, TitleLength/sizeof(CHAR16) - 1 - StrLen(TitleString)); 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 { StrnCpy(*BriefDesc, 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); }
/** Function for 'drivers' 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 ShellCommandRunDrivers ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR8 *Language; CONST CHAR16 *Lang; EFI_HANDLE *HandleList; EFI_HANDLE *HandleWalker; UINTN ChildCount; UINTN DeviceCount; CHAR16 *Temp2; CHAR16 *FormatString; UINT32 DriverVersion; BOOLEAN DriverConfig; BOOLEAN DriverDiag; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; Language = NULL; FormatString = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 1) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else { Lang = ShellCommandLineGetValue(Package, L"-l"); if (Lang != NULL) { Language = AllocateZeroPool(StrSize(Lang)); AsciiSPrint(Language, StrSize(Lang), "%S", Lang); } else if (!ShellCommandLineGetFlag(Package, L"-l")){ ASSERT(Language == NULL); // Language = AllocateZeroPool(10); // AsciiSPrint(Language, 10, "en-us"); } else { ASSERT(Language == NULL); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l"); ShellCommandLineFreeVarList (Package); return (SHELL_INVALID_PARAMETER); } if (ShellCommandLineGetFlag(Package, L"-sfo")) { FormatString = HiiGetString(gShellDriver1HiiHandle, STRING_TOKEN(STR_DRIVERS_ITEM_LINE_SFO), Language); } else { FormatString = HiiGetString(gShellDriver1HiiHandle, STRING_TOKEN(STR_DRIVERS_ITEM_LINE), Language); // // print the header row // ShellPrintHiiEx( -1, -1, Language, STRING_TOKEN(STR_DRIVERS_HEADER_LINES), gShellDriver1HiiHandle); } HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid); for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){ ChildCount = 0; DeviceCount = 0; Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL); Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL); Temp2 = GetDevicePathTextForHandle(*HandleWalker); DriverVersion = ReturnDriverVersion(*HandleWalker); DriverConfig = ReturnDriverConfig(*HandleWalker); DriverDiag = ReturnDriverDiag (*HandleWalker); Lang = GetStringNameFromHandle(*HandleWalker, Language==NULL?"en":Language); ShellPrintEx( -1, -1, FormatString, ConvertHandleToHandleIndex(*HandleWalker), DriverVersion, ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'), DriverConfig?L'Y':L'N', DriverDiag?L'Y':L'N', DeviceCount, ChildCount, Lang, Temp2==NULL?L"":Temp2 ); if (Temp2 != NULL) { FreePool(Temp2); } } } SHELL_FREE_NON_NULL(Language); ShellCommandLineFreeVarList (Package); SHELL_FREE_NON_NULL(FormatString); } return (ShellStatus); }
/** 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); } }
/** Create user variable node. **/ VOID CreateUserVariableNode ( VOID ) { EFI_STATUS Status; EFI_STATUS GetVariableStatus; CHAR16 *VarName; UINTN MaxVarNameSize; UINTN VarNameSize; UINTN MaxDataSize; UINTN DataSize; VOID *Data; UINT32 Attributes; EFI_GUID Guid; USER_VARIABLE_NODE *UserVariableNode; USER_VARIABLE_NAME_NODE *UserVariableNameNode; UINT16 Index; UINTN StringSize; // // Initialize 128 * sizeof (CHAR16) variable name size. // MaxVarNameSize = 128 * sizeof (CHAR16); VarName = AllocateZeroPool (MaxVarNameSize); ASSERT (VarName != NULL); // // Initialize 0x1000 variable data size. // MaxDataSize = 0x1000; Data = AllocateZeroPool (MaxDataSize); ASSERT (Data != NULL); Index = 0; do { VarNameSize = MaxVarNameSize; Status = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid); if (Status == EFI_BUFFER_TOO_SMALL) { VarName = ReallocatePool (MaxVarNameSize, VarNameSize, VarName); ASSERT (VarName != NULL); MaxVarNameSize = VarNameSize; Status = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid); } if (!EFI_ERROR (Status)) { if (IsUserVariable (VarName, &Guid)) { DataSize = MaxDataSize; GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data); if (GetVariableStatus == EFI_BUFFER_TOO_SMALL) { Data = ReallocatePool (MaxDataSize, DataSize, Data); ASSERT (Data != NULL); MaxDataSize = DataSize; GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data); } ASSERT_EFI_ERROR (GetVariableStatus); if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { UserVariableNode = FindUserVariableNodeByGuid (&Guid); ASSERT (UserVariableNode != NULL); // // Different variables that have same variable GUID share same user variable node. // UserVariableNameNode = AllocateZeroPool (sizeof (*UserVariableNameNode)); ASSERT (UserVariableNameNode != NULL); UserVariableNameNode->Signature = USER_VARIABLE_NAME_NODE_SIGNATURE; UserVariableNameNode->Name = AllocateCopyPool (VarNameSize, VarName); UserVariableNameNode->Attributes = Attributes; UserVariableNameNode->DataSize = DataSize; UserVariableNameNode->Index = Index; UserVariableNameNode->QuestionId = (EFI_QUESTION_ID) (USER_VARIABLE_QUESTION_ID + Index); // // 2 space * sizeof (CHAR16) + StrSize. // StringSize = 2 * sizeof (CHAR16) + StrSize (UserVariableNameNode->Name); UserVariableNameNode->PromptString = AllocatePool (StringSize); ASSERT (UserVariableNameNode->PromptString != NULL); UnicodeSPrint (UserVariableNameNode->PromptString, StringSize, L" %s", UserVariableNameNode->Name); // // (33 chars of "Attribtues = 0x and DataSize = 0x" + 1 terminator + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16). // StringSize = (33 + 1 + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16); UserVariableNameNode->HelpString = AllocatePool (StringSize); ASSERT (UserVariableNameNode->HelpString != NULL); UnicodeSPrint (UserVariableNameNode->HelpString, StringSize, L"Attribtues = 0x%08x and DataSize = 0x%x", UserVariableNameNode->Attributes, UserVariableNameNode->DataSize); UserVariableNameNode->Deleted = FALSE; InsertTailList (&UserVariableNode->NameLink, &UserVariableNameNode->Link); Index++; } } } } while (Status != EFI_NOT_FOUND); mUserVariableCount = Index; ASSERT (mUserVariableCount <= MAX_USER_VARIABLE_COUNT); DEBUG ((EFI_D_INFO, "PlatformVarCleanup - User variable count: 0x%04x\n", mUserVariableCount)); FreePool (VarName); FreePool (Data); }
/** 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; EFI_STRING_ID HelpToken; UINT16 *TempStr; EFI_HII_HANDLE HiiHandle; EFI_BROWSER_ACTION_REQUEST ActionRequest; UINTN TempSize; 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); 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 boot option marked as LOAD_OPTION_HIDDEN // if ((Option->Attribute & LOAD_OPTION_HIDDEN) != 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, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 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); TempSize = StrSize (TempStr); HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : ")); ASSERT (HelpString != NULL); StrCat (HelpString, L"Device Path : "); StrCat (HelpString, 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); } }
/** 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 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); }
/** Get the variable statistics information from the information buffer pointed by gVariableInfo. Caution: This function may be invoked at SMM runtime. InfoEntry and InfoSize are external input. Care must be taken to make sure not security issue at runtime. @param[in, out] InfoEntry A pointer to the buffer of variable information entry. On input, point to the variable information returned last time. if InfoEntry->VendorGuid is zero, return the first information. On output, point to the next variable information. @param[in, out] InfoSize On input, the size of the variable information buffer. On output, the returned variable information size. @retval EFI_SUCCESS The variable information is found and returned successfully. @retval EFI_UNSUPPORTED No variable inoformation exists in variable driver. The PcdVariableCollectStatistics should be set TRUE to support it. @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the next variable information. **/ EFI_STATUS SmmVariableGetStatistics ( IN OUT VARIABLE_INFO_ENTRY *InfoEntry, IN OUT UINTN *InfoSize ) { VARIABLE_INFO_ENTRY *VariableInfo; UINTN NameLength; UINTN StatisticsInfoSize; CHAR16 *InfoName; EFI_GUID VendorGuid; ASSERT (InfoEntry != NULL); VariableInfo = gVariableInfo; if (VariableInfo == NULL) { return EFI_UNSUPPORTED; } StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + StrSize (VariableInfo->Name); if (*InfoSize < StatisticsInfoSize) { *InfoSize = StatisticsInfoSize; return EFI_BUFFER_TOO_SMALL; } InfoName = (CHAR16 *)(InfoEntry + 1); CopyGuid (&VendorGuid, &InfoEntry->VendorGuid); if (CompareGuid (&VendorGuid, &mZeroGuid)) { // // Return the first variable info // CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY)); CopyMem (InfoName, VariableInfo->Name, StrSize (VariableInfo->Name)); *InfoSize = StatisticsInfoSize; return EFI_SUCCESS; } // // Get the next variable info // while (VariableInfo != NULL) { if (CompareGuid (&VariableInfo->VendorGuid, &VendorGuid)) { NameLength = StrSize (VariableInfo->Name); if (NameLength == StrSize (InfoName)) { if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) { // // Find the match one // VariableInfo = VariableInfo->Next; break; } } } VariableInfo = VariableInfo->Next; }; if (VariableInfo == NULL) { *InfoSize = 0; return EFI_SUCCESS; } // // Output the new variable info // StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + StrSize (VariableInfo->Name); if (*InfoSize < StatisticsInfoSize) { *InfoSize = StatisticsInfoSize; return EFI_BUFFER_TOO_SMALL; } CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY)); CopyMem (InfoName, VariableInfo->Name, StrSize (VariableInfo->Name)); *InfoSize = StatisticsInfoSize; return EFI_SUCCESS; }
/** Function for 'cp' 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 ShellCommandRunCp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; UINTN ParamCount; UINTN LoopCounter; EFI_SHELL_FILE_INFO *FileList; BOOLEAN SilentMode; BOOLEAN RecursiveMode; CONST CHAR16 *Cwd; CHAR16 *FullCwd; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; ParamCount = 0; FileList = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &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"cp", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } // // Initialize SilentMode and RecursiveMode // if (gEfiShellProtocol->BatchIsActive()) { SilentMode = TRUE; } else { SilentMode = ShellCommandLineGetFlag(Package, L"-q"); } RecursiveMode = ShellCommandLineGetFlag(Package, L"-r"); switch (ParamCount = ShellCommandLineGetCount(Package)) { case 0: case 1: // // we have insufficient parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; case 2: // // must have valid CWD for single parameter... // Cwd = ShellGetCurrentDir(NULL); if (Cwd == NULL){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp"); 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"cp", ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } else { FullCwd = AllocateZeroPool(StrSize(Cwd) + sizeof(CHAR16)); if (FullCwd == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_OUT_OF_RESOURCES; } else { StrCpyS (FullCwd, StrSize (Cwd) / sizeof (CHAR16) + 1, Cwd); ShellStatus = ProcessValidateAndCopyFiles (FileList, FullCwd, SilentMode, RecursiveMode); FreePool (FullCwd); } } } break; default: // // Make a big list of all the files... // for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) { if (ShellGetExecutionBreakFlag()) { break; } Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, LoopCounter)); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus != SHELL_SUCCESS) { Status = ShellCloseFileMetaArg(&FileList); } else { // // now copy them all... // if (FileList != NULL && !IsListEmpty(&FileList->Link)) { ShellStatus = ProcessValidateAndCopyFiles(FileList, PathCleanUpDirectories((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode); Status = ShellCloseFileMetaArg(&FileList); if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, ParamCount), ShellStatus|MAX_BIT); ShellStatus = SHELL_ACCESS_DENIED; } } } break; } // switch on parameter count if (FileList != NULL) { ShellCloseFileMetaArg(&FileList); } // // free the command line package // ShellCommandLineFreeVarList (Package); } if (ShellGetExecutionBreakFlag()) { return (SHELL_ABORTED); } return (ShellStatus); }
/** Function to populate Argc and Argv. This function parses the CommandLine and divides it into standard C style Argc/Argv parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space delimited and quote surrounded parameter definition. All special character processing (alias, environment variable, redirection, etc... must be complete before calling this API. @param[in] CommandLine String of command line to parse @param[in, out] Argv pointer to array of strings; one for each parameter @param[in, out] Argc pointer to number of strings in Argv array @return EFI_SUCCESS the operation was sucessful @return EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS EFIAPI ParseCommandLineToArgs( IN CONST CHAR16 *CommandLine, IN OUT CHAR16 ***Argv, IN OUT UINTN *Argc ) { UINTN Count; CHAR16 *TempParameter; CHAR16 *Walker; CHAR16 *NewParam; CHAR16 *NewCommandLine; UINTN Size; EFI_STATUS Status; ASSERT(Argc != NULL); ASSERT(Argv != NULL); if (CommandLine == NULL || StrLen(CommandLine)==0) { (*Argc) = 0; (*Argv) = NULL; return (EFI_SUCCESS); } NewCommandLine = AllocateCopyPool(StrSize(CommandLine), CommandLine); if (NewCommandLine == NULL){ return (EFI_OUT_OF_RESOURCES); } TrimSpaces(&NewCommandLine); Size = StrSize(NewCommandLine); TempParameter = AllocateZeroPool(Size); if (TempParameter == NULL) { SHELL_FREE_NON_NULL(NewCommandLine); return (EFI_OUT_OF_RESOURCES); } for ( Count = 0 , Walker = (CHAR16*)NewCommandLine ; Walker != NULL && *Walker != CHAR_NULL ; Count++ ) { if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) { break; } } // // lets allocate the pointer array // (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*)); if (*Argv == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } *Argc = 0; Walker = (CHAR16*)NewCommandLine; while(Walker != NULL && *Walker != CHAR_NULL) { SetMem16(TempParameter, Size, CHAR_NULL); if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) { Status = EFI_INVALID_PARAMETER; goto Done; } NewParam = AllocateCopyPool(StrSize(TempParameter), TempParameter); if (NewParam == NULL){ Status = EFI_OUT_OF_RESOURCES; goto Done; } ((CHAR16**)(*Argv))[(*Argc)] = NewParam; (*Argc)++; } ASSERT(Count >= (*Argc)); Status = EFI_SUCCESS; Done: SHELL_FREE_NON_NULL(TempParameter); SHELL_FREE_NON_NULL(NewCommandLine); return (Status); }
EFI_STATUS BdsLoadOptionTftpCreateDevicePath ( IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes ) { EFI_STATUS Status; BOOLEAN IsDHCP; EFI_IP_ADDRESS LocalIp; EFI_IP_ADDRESS RemoteIp; IPv4_DEVICE_PATH* IPv4DevicePathNode; FILEPATH_DEVICE_PATH* FilePathDevicePath; CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; UINTN BootFilePathSize; Print(L"Get the IP address from DHCP: "); Status = GetHIInputBoolean (&IsDHCP); if (EFI_ERROR(Status)) { return EFI_ABORTED; } if (!IsDHCP) { Print(L"Get the static IP address: "); Status = GetHIInputIP (&LocalIp); if (EFI_ERROR(Status)) { return EFI_ABORTED; } } Print(L"Get the TFTP server IP address: "); Status = GetHIInputIP (&RemoteIp); if (EFI_ERROR(Status)) { return EFI_ABORTED; } Print(L"File path of the %s : ", FileName); Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); if (EFI_ERROR(Status)) { return EFI_ABORTED; } BootFilePathSize = StrSize(BootFilePath); if (BootFilePathSize == 2) { return EFI_NOT_FOUND; } // Allocate the memory for the IPv4 + File Path Device Path Nodes IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); // Create the IPv4 Device Path IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH; IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP; SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH)); CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); IPv4DevicePathNode->LocalPort = 0; IPv4DevicePathNode->RemotePort = 0; IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP; IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE); // Create the FilePath Device Path node FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1); FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); // Set the End Device Path Node SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode; return Status; }
/** Return the next parameter from a command line string. This function moves the next parameter from Walker into TempParameter and moves Walker up past that parameter for recursive calling. When the final parameter is moved *Walker will be set to NULL; Temp Parameter must be large enough to hold the parameter before calling this function. This will also remove all remaining ^ characters after processing. @param[in, out] Walker pointer to string of command line. Adjusted to reminaing command line on return @param[in, out] TempParameter pointer to string of command line item extracted. @param[in] Length buffer size of TempParameter. @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. @return EFI_NOT_FOUND A closing " could not be found on the specified string **/ EFI_STATUS EFIAPI GetNextParameter( IN OUT CHAR16 **Walker, IN OUT CHAR16 **TempParameter, IN CONST UINTN Length ) { CONST CHAR16 *NextDelim; if (Walker == NULL ||*Walker == NULL ||TempParameter == NULL ||*TempParameter == NULL ){ return (EFI_INVALID_PARAMETER); } // // make sure we dont have any leading spaces // while ((*Walker)[0] == L' ') { (*Walker)++; } // // make sure we still have some params now... // if (StrLen(*Walker) == 0) { DEBUG_CODE_BEGIN(); *Walker = NULL; DEBUG_CODE_END(); return (EFI_INVALID_PARAMETER); } NextDelim = FindEndOfParameter(*Walker); if (NextDelim == NULL){ DEBUG_CODE_BEGIN(); *Walker = NULL; DEBUG_CODE_END(); return (EFI_NOT_FOUND); } StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker); // // Add a CHAR_NULL if we didnt get one via the copy // if (*NextDelim != CHAR_NULL) { (*TempParameter)[NextDelim - *Walker] = CHAR_NULL; } // // Update Walker for the next iteration through the function // *Walker = (CHAR16*)NextDelim; // // Remove any non-escaped quotes in the string // Remove any remaining escape characters in the string // for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL) ; *NextDelim != CHAR_NULL ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL) ) { if (*NextDelim == L'^') { // // eliminate the escape ^ // CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); NextDelim++; } else if (*NextDelim == L'\"') { // // eliminate the unescaped quote // CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); } } return EFI_SUCCESS; }
EFI_STATUS BootMenuAddBootOption ( IN LIST_ENTRY *BootOptionsList ) { EFI_STATUS Status; BDS_SUPPORTED_DEVICE* SupportedBootDevice; ARM_BDS_LOADER_ARGUMENTS* BootArguments; CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; CHAR8 AsciiCmdLine[BOOT_DEVICE_OPTION_MAX]; CHAR16 CmdLine[BOOT_DEVICE_OPTION_MAX]; UINT32 Attributes; ARM_BDS_LOADER_TYPE BootType; BDS_LOAD_OPTION_ENTRY *BdsLoadOptionEntry; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPath; UINTN CmdLineSize; BOOLEAN InitrdSupport; UINTN InitrdSize; UINT8* OptionalData; UINTN OptionalDataSize; Attributes = 0; SupportedBootDevice = NULL; // List the Boot Devices supported Status = SelectBootDevice (&SupportedBootDevice); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Append the Device Path to the selected device path DevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNodes); if (DevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } if (SupportedBootDevice->Support->RequestBootType) { Status = BootDeviceGetType (DevicePath, &BootType, &Attributes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } } else { BootType = BDS_LOADER_EFI_APPLICATION; } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { Print(L"Add an initrd: "); Status = GetHIInputBoolean (&InitrdSupport); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } if (InitrdSupport) { // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes); if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd Status = EFI_ABORTED; goto EXIT; } if (InitrdPathNodes != NULL) { // Append the Device Path to the selected device path InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes); // Free the InitrdPathNodes created by Support->CreateDevicePathNode() FreePool (InitrdPathNodes); if (InitrdPath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } } else { InitrdPath = NULL; } } else { InitrdPath = NULL; } Print(L"Arguments to pass to the binary: "); Status = GetHIInputAscii (AsciiCmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } CmdLineSize = AsciiStrSize (AsciiCmdLine); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); BootArguments->LinuxArguments.CmdLineSize = CmdLineSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(&BootArguments->LinuxArguments + 1), AsciiCmdLine, CmdLineSize); CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { Print (L"Arguments to pass to the EFI Application: "); Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto EXIT; } OptionalData = (UINT8*)CmdLine; OptionalDataSize = StrSize (CmdLine); } Print(L"Description for this new Entry: "); Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } // Create new entry BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY)); Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption); if (!EFI_ERROR(Status)) { InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link); } FREE_DEVICE_PATH: FreePool (DevicePath); EXIT: if (Status == EFI_ABORTED) { Print(L"\n"); } FreePool(SupportedBootDevice); return Status; }
// // Initialize the global system boot option and driver option // InitializeListHead (&DriverOptionList); InitializeListHead (&BootOptionList); // // Initialize hotkey service // InitializeHotkeyService (); // // Fill in FirmwareVendor and FirmwareRevision from PCDs // FirmwareVendor = (CHAR16 *)PcdGetPtr (PcdFirmwareVendor); gST->FirmwareVendor = AllocateRuntimeCopyPool (StrSize (FirmwareVendor), FirmwareVendor); ASSERT (gST->FirmwareVendor != NULL); gST->FirmwareRevision = PcdGet32 (PcdFirmwareRevision); // // Fixup Tasble CRC after we updated Firmware Vendor and Revision // gST->Hdr.CRC32 = 0; gBS->CalculateCrc32 ((VOID *)gST, sizeof(EFI_SYSTEM_TABLE), &gST->Hdr.CRC32); // // Validate Variable. // BdsFormalizeEfiGlobalVariable(); //
/** Function to write a line of text to a file. If the file is a Unicode file (with UNICODE file tag) then write the unicode text. If the file is an ASCII file then write the ASCII text. If the size of file is zero (without file tag at the beginning) then write ASCII text as default. @param[in] Handle FileHandle to write to. @param[in] Buffer Buffer to write, if NULL the function will take no action and return EFI_SUCCESS. @retval EFI_SUCCESS The data was written. Buffer is NULL. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_OUT_OF_RESOURCES Unable to allocate temporary space for ASCII string due to out of resources. @sa FileHandleWrite **/ EFI_STATUS EFIAPI FileHandleWriteLine( IN EFI_FILE_HANDLE Handle, IN CHAR16 *Buffer ) { EFI_STATUS Status; CHAR16 CharBuffer; UINTN Size; UINTN Index; UINTN CharSize; UINT64 FileSize; UINT64 OriginalFilePosition; BOOLEAN Ascii; CHAR8 *AsciiBuffer; if (Buffer == NULL) { return (EFI_SUCCESS); } if (Handle == NULL) { return (EFI_INVALID_PARAMETER); } Ascii = FALSE; AsciiBuffer = NULL; Status = FileHandleGetPosition(Handle, &OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleSetPosition(Handle, 0); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleGetSize(Handle, &FileSize); if (EFI_ERROR(Status)) { return Status; } if (FileSize == 0) { Ascii = TRUE; } else { CharSize = sizeof (CHAR16); Status = FileHandleRead (Handle, &CharSize, &CharBuffer); ASSERT_EFI_ERROR (Status); if (CharBuffer == gUnicodeFileTag) { Ascii = FALSE; } else { Ascii = TRUE; } } Status = FileHandleSetPosition(Handle, OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } if (Ascii) { Size = ( StrSize(Buffer) / sizeof(CHAR16) ) * sizeof(CHAR8); AsciiBuffer = (CHAR8 *)AllocateZeroPool(Size); if (AsciiBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size); for (Index = 0; Index < Size; Index++) { if (!((AsciiBuffer[Index] >= 0) && (AsciiBuffer[Index] < 128))){ FreePool(AsciiBuffer); return EFI_INVALID_PARAMETER; } } Size = AsciiStrSize(AsciiBuffer) - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, AsciiBuffer); if (EFI_ERROR(Status)) { FreePool (AsciiBuffer); return (Status); } Size = AsciiStrSize("\r\n") - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, "\r\n"); } else { if (OriginalFilePosition == 0) { Status = FileHandleSetPosition (Handle, sizeof(CHAR16)); if (EFI_ERROR(Status)) { return Status; } } Size = StrSize(Buffer) - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, Buffer); if (EFI_ERROR(Status)) { return (Status); } Size = StrSize(L"\r\n") - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, L"\r\n"); } if (AsciiBuffer != NULL) { FreePool (AsciiBuffer); } return Status; }
/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @param NvRamMap The file explorer formset internal state. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData, IN FILE_EXPLORER_NV_DATA *NvRamMap ) { UINT16 *BootOrderList; UINT16 *NewBootOrderList; UINTN BootOrderListSize; UINT16 BootString[10]; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpy (NvRamMap->BootDescriptionData, BootString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (NvRamMap->BootOptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, NvRamMap->BootDescriptionData, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (NvRamMap->BootDescriptionData) ); Ptr += StrSize (NvRamMap->BootDescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData)); } Status = gRT->SetVariable ( BootString, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BufferSize, Buffer ); if (!EFI_ERROR (Status)) { BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); ASSERT (BootOrderList != NULL); NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16)); ASSERT (NewBootOrderList != NULL); CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize); NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index; if (BootOrderList != NULL) { FreePool (BootOrderList); } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BootOrderListSize + sizeof (UINT16), NewBootOrderList ); if (!EFI_ERROR (Status)) { FreePool (NewBootOrderList); NewBootOrderList = NULL; InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; NvRamMap->BootDescriptionData[0] = 0x0000; NvRamMap->BootOptionalData[0] = 0x0000; } } return EFI_SUCCESS; }
static HRESULT ExecuteCertificateOperation( __in MSIHANDLE hInstall, __in SCA_ACTION saAction, __in DWORD dwStoreLocation ) { //AssertSz(FALSE, "Debug ExecuteCertificateOperation() here."); Assert(saAction & SCA_ACTION_INSTALL || saAction & SCA_ACTION_UNINSTALL); HRESULT hr = S_OK; LPWSTR pwzCaData = NULL; LPWSTR pwz; LPWSTR pwzName = NULL; LPWSTR pwzStore = NULL; int iAttributes = 0; LPWSTR pwzPFXPassword = NULL; LPWSTR pwzFilePath = NULL; BYTE* pbData = NULL; DWORD cbData = 0; DWORD cbPFXPassword = 0; BOOL fUserStoreLocation = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation); HCERTSTORE hCertStore = NULL; hr = WcaGetProperty(L"CustomActionData", &pwzCaData); ExitOnFailure(hr, "Failed to get CustomActionData"); WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCaData); pwz = pwzCaData; hr = WcaReadStringFromCaData(&pwz, &pwzName); ExitOnFailure(hr, "Failed to parse certificate name."); hr = WcaReadStringFromCaData(&pwz, &pwzStore); ExitOnFailure(hr, "Failed to parse CustomActionData, StoreName"); hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); ExitOnFailure(hr, "Failed to parse certificate attribute"); if (SCA_ACTION_INSTALL == saAction) // install operations need more data { hr = WcaReadStreamFromCaData(&pwz, &pbData, (DWORD_PTR*)&cbData); ExitOnFailure(hr, "Failed to parse certificate stream."); hr = WcaReadStringFromCaData(&pwz, &pwzPFXPassword); ExitOnFailure(hr, "Failed to parse certificate password."); } // Open the right store. hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation, pwzStore); MessageExitOnNullWithLastError1(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store: %ls", pwzStore); if (SCA_ACTION_INSTALL == saAction) // install operations need more data { // Uninstall existing versions of this package. Ignore any failures // This is needed to clean up the private key of a cert when we replace an existing cert // CertAddCertificateContextToStore(CERT_STORE_ADD_REPLACE_EXISTING) does not remove the private key if the cert is replaced UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); hr = InstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName, pbData, cbData, pwzPFXPassword); ExitOnFailure(hr, "Failed to install certificate."); } else { Assert(SCA_ACTION_UNINSTALL == saAction); hr = UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); ExitOnFailure(hr, "Failed to uninstall certificate."); } LExit: if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword))) { SecureZeroMemory(pwzPFXPassword, cbPFXPassword); } if (hCertStore) { if (!::CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) { WcaLog(LOGMSG_VERBOSE, "Cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); } } ReleaseMem(pbData); ReleaseStr(pwzFilePath); ReleaseStr(pwzPFXPassword); ReleaseStr(pwzStore); ReleaseStr(pwzName); ReleaseStr(pwzCaData); return hr; }
/** Function for 'drvdiag' 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 ShellCommandRunDrvDiag ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; DRV_DIAG_TEST_MODE Mode; CHAR8 *Language; CONST CHAR16 *DriverHandleStr; CONST CHAR16 *ControllerHandleStr; CONST CHAR16 *ChildHandleStr; CONST CHAR16 *Lang; EFI_HANDLE Handle1; EFI_HANDLE Handle2; EFI_HANDLE Handle3; UINT64 Intermediate; ShellStatus = SHELL_SUCCESS; Mode = TestModeMax; Language = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags // if ((ShellCommandLineGetCount(Package) > 4) ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-e")) ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-m")) ||(ShellCommandLineGetFlag(Package, L"-e") && ShellCommandLineGetFlag(Package, L"-m")) ){ // // error for too many parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else if ((ShellCommandLineGetFlag(Package, L"-s")) || (ShellCommandLineGetFlag(Package, L"-e")) || (ShellCommandLineGetFlag(Package, L"-m")) ){ // // Run the apropriate test // if (ShellCommandLineGetFlag(Package, L"-s")) { Mode = TestModeStandard; } else if (ShellCommandLineGetFlag(Package, L"-e")) { Mode = TestModeExtended; } else if (ShellCommandLineGetFlag(Package, L"-m")) { Mode = TestModeManufacturing; } else { ASSERT(FALSE); } } else { // // Do a listing of what's available to test // Mode = TestModeList; } Lang = ShellCommandLineGetValue(Package, L"-l"); if (ShellCommandLineGetFlag(Package, L"-l") && Lang == NULL) { ASSERT(Language == NULL); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l"); ShellCommandLineFreeVarList (Package); return (SHELL_INVALID_PARAMETER); } else if (Lang != NULL) { Language = AllocateZeroPool(StrSize(Lang)); AsciiSPrint(Language, StrSize(Lang), "%S", Lang); } DriverHandleStr = ShellCommandLineGetRawValue(Package, 1); ControllerHandleStr = ShellCommandLineGetRawValue(Package, 2); ChildHandleStr = ShellCommandLineGetRawValue(Package, 3); if (DriverHandleStr == NULL) { Handle1 = NULL; } else { ShellConvertStringToUint64(DriverHandleStr, &Intermediate, TRUE, FALSE); Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate); } if (ControllerHandleStr == NULL) { Handle2 = NULL; } else { ShellConvertStringToUint64(ControllerHandleStr, &Intermediate, TRUE, FALSE); Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate); } if (ChildHandleStr == NULL) { Handle3 = NULL; } else { ShellConvertStringToUint64(ChildHandleStr, &Intermediate, TRUE, FALSE); Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate); } Status = DoDiagnostics ( Mode, Language, ShellCommandLineGetFlag(Package, L"-c"), Handle1, Handle2, Handle3 ); SHELL_FREE_NON_NULL(Language); ShellCommandLineFreeVarList (Package); } if (ShellStatus == SHELL_SUCCESS) { if (Status == EFI_SECURITY_VIOLATION) { ShellStatus = SHELL_SECURITY_VIOLATION; } else if (Status == EFI_INVALID_PARAMETER) { ShellStatus = SHELL_INVALID_PARAMETER; } else if (Status == EFI_NOT_FOUND) { ShellStatus = SHELL_NOT_FOUND; } else if (EFI_ERROR(Status)) { ShellStatus = SHELL_NOT_FOUND; } } return (ShellStatus); }
/** Function to populate Argc and Argv. This function parses the CommandLine and divides it into standard C style Argc/Argv parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space delimited and quote surrounded parameter definition. @param[in] CommandLine String of command line to parse @param[in, out] Argv pointer to array of strings; one for each parameter @param[in, out] Argc pointer to number of strings in Argv array @return EFI_SUCCESS the operation was sucessful @return EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS EFIAPI ParseCommandLineToArgs( IN CONST CHAR16 *CommandLine, IN OUT CHAR16 ***Argv, IN OUT UINTN *Argc ) { UINTN Count; CHAR16 *TempParameter; CHAR16 *Walker; CHAR16 *NewParam; UINTN Size; ASSERT(Argc != NULL); ASSERT(Argv != NULL); if (CommandLine == NULL || StrLen(CommandLine)==0) { (*Argc) = 0; (*Argv) = NULL; return (EFI_SUCCESS); } Size = StrSize(CommandLine); TempParameter = AllocateZeroPool(Size); if (TempParameter == NULL) { return (EFI_OUT_OF_RESOURCES); } for ( Count = 0 , Walker = (CHAR16*)CommandLine ; Walker != NULL && *Walker != CHAR_NULL ; GetNextParameter(&Walker, &TempParameter) , Count++ ); /* Count = 0; Walker = (CHAR16*)CommandLine; while(Walker != NULL) { GetNextParameter(&Walker, &TempParameter); Count++; } */ // // lets allocate the pointer array // (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*)); if (*Argv == NULL) { SHELL_FREE_NON_NULL(TempParameter); return (EFI_OUT_OF_RESOURCES); } *Argc = 0; Walker = (CHAR16*)CommandLine; while(Walker != NULL && *Walker != CHAR_NULL) { SetMem16(TempParameter, Size, CHAR_NULL); GetNextParameter(&Walker, &TempParameter); NewParam = AllocateZeroPool(StrSize(TempParameter)); ASSERT(NewParam != NULL); StrCpy(NewParam, TempParameter); ((CHAR16**)(*Argv))[(*Argc)] = NewParam; (*Argc)++; } ASSERT(Count >= (*Argc)); SHELL_FREE_NON_NULL(TempParameter); return (EFI_SUCCESS); }
void EWCharString::Replace( int Start_Index, const EWCSChar* p_String ) { // keep the buffer EBuffer* p_Tmp = m_pBuffer; int Cur_Len = m_pBuffer->m_Data_Length; // unshare any shared buffers ChecEBuffer(); gosASSERT( Start_Index <= Cur_Len ); // check the current buffer, not the current // length if ( Start_Index <= Cur_Len ) { int Length = StrSize( p_String ); int Alloc_Length = Start_Index + Length + 1; if ( Alloc_Length <= m_pBuffer->m_Alloc_Length ) { memcpy( m_pBuffer->Data() + Start_Index, p_String, Length * sizeof( EWCSChar ) ); // Add on the NULL if necessary if ( Start_Index + Length > Cur_Len ) { *(m_pBuffer->Data() + Start_Index + Length + 1 ) = NULL; m_pBuffer->m_Data_Length = Length + Start_Index; } } else // need to reallocate here { EBuffer* p_Old_Buffer = m_pBuffer; m_pBuffer = EBuffer::s_p_Empty_Buffer; if ( Cur_Len > Alloc_Length ) { Alloc_Length = Cur_Len; } Alloc( Alloc_Length ); memcpy( m_pBuffer->Data(), p_Tmp->Data(), (Cur_Len + 1)*sizeof(EWCSChar) ); memcpy( m_pBuffer->Data() + Start_Index, p_String, Length*sizeof(EWCSChar) ); m_pBuffer->m_Data_Length = Alloc_Length; p_Old_Buffer->Release(); } // check to see if the p_String is null if ( p_String == NULL ) { *(m_pBuffer->Data() + Start_Index) = 0; } } }
/** Append one variable to file. @param[in] FileHandle The file to be appended. @param[in] Name The variable name. @param[in] Guid The variable GUID. @param[in] Attributes The variable attributes. @param[in] DataSize The variable data size. @param[in] Data The variable data. @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation. @retval EFI_SUCCESS The variable is appended to file successfully. @retval others Failed to append the variable to file. **/ EFI_STATUS AppendSingleVariableToFile ( IN SHELL_FILE_HANDLE FileHandle, IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, IN UINT32 Attributes, IN UINT32 DataSize, IN CONST UINT8 *Data ) { UINT32 NameSize; UINT8 *Buffer; UINT8 *Ptr; UINTN BufferSize; EFI_STATUS Status; NameSize = (UINT32) StrSize (Name); BufferSize = sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32); Buffer = AllocatePool (BufferSize); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } Ptr = Buffer; // // NameSize and DataSize // * (UINT32 *) Ptr = NameSize; Ptr += sizeof (NameSize); *(UINT32 *) Ptr = DataSize; Ptr += sizeof (DataSize); // // Name // CopyMem (Ptr, Name, NameSize); Ptr += NameSize; // // Guid // CopyMem (Ptr, Guid, sizeof (*Guid)); Ptr += sizeof (*Guid); // // Attributes // * (UINT32 *) Ptr = Attributes; Ptr += sizeof (Attributes); // // Data // CopyMem (Ptr, Data, DataSize); Ptr += DataSize; // // Crc32 // gBS->CalculateCrc32 (Buffer, (UINTN) (Ptr - Buffer), (UINT32 *) Ptr); Status = ShellWriteFile (FileHandle, &BufferSize, Buffer); FreePool (Buffer); if (!EFI_ERROR (Status) && (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32)) ) { Status = EFI_DEVICE_ERROR; } return Status; }
/** 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] Buffer 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; UINTN Start; 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; // // Do not pass any leading path information that may be present to IsTitleHeader(). // Start = StrLen(Command); while ((Start != 0) && (*(Command + Start - 1) != L'\\') && (*(Command + Start - 1) != L'/') && (*(Command + Start - 1) != L':')) { --Start; } // // more characters for StartString and EndString // TitleLength = StrSize(Command + Start) + (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 + Start); 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); }