/** This function converts an input device structure to a Unicode string. @param DevPath A pointer to the device path structure. @return A new allocated Unicode string that represents the device path. **/ CHAR16 * BmDevicePathToStr ( IN EFI_DEVICE_PATH_PROTOCOL *DevPath ) { EFI_STATUS Status; CHAR16 *ToText; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; if (DevPath == NULL) { return NULL; } Status = gBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevPathToText ); ASSERT_EFI_ERROR (Status); ToText = DevPathToText->ConvertDevicePathToText ( DevPath, FALSE, TRUE ); ASSERT (ToText != NULL); return ToText; }
/** Check whether the DevicePath2 is identical with DevicePath1, or identical with DevicePath1's child device path. If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device path, then TRUE returned. Otherwise, FALSE is returned. If DevicePath1 is NULL, then ASSERT(). If DevicePath2 is NULL, then ASSERT(). @param[in] DevicePath1 A pointer to a device path. @param[in] DevicePath2 A pointer to a device path. @retval TRUE Two device paths are identical , or DevicePath2 is DevicePath1's child device path. @retval FALSE Two device paths are not identical, and DevicePath2 is not DevicePath1's child device path. **/ BOOLEAN CheckDevicePath ( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath1, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2 ) { EFI_STATUS Status; EFI_STRING DevicePathStr1; EFI_STRING DevicePathStr2; UINTN StrLen1; UINTN StrLen2; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText; BOOLEAN DevicePathEqual; ASSERT (DevicePath1 != NULL); ASSERT (DevicePath2 != NULL); DevicePathEqual = FALSE; DevicePathText = NULL; Status = gBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevicePathText ); ASSERT (Status == EFI_SUCCESS); // // Get first device path string. // DevicePathStr1 = DevicePathText->ConvertDevicePathToText (DevicePath1, TRUE, TRUE); ConvertDPStr (DevicePathStr1); // // Get second device path string. // DevicePathStr2 = DevicePathText->ConvertDevicePathToText (DevicePath2, TRUE, TRUE); ConvertDPStr (DevicePathStr2); // // Compare device path string. // StrLen1 = StrSize (DevicePathStr1); StrLen2 = StrSize (DevicePathStr2); if (StrLen1 > StrLen2) { DevicePathEqual = FALSE; goto Done; } if (CompareMem (DevicePathStr1, DevicePathStr2, StrLen1) == 0) { DevicePathEqual = TRUE; } Done: FreePool (DevicePathStr1); FreePool (DevicePathStr2); return DevicePathEqual; }
/** Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle. @param[in] QuestionID The question ID. @param[in] DevicePath Points to device path. @param[in] OpCodeHandle Points to container for dynamic created opcodes. **/ VOID AddDevicePath ( IN UINTN QuestionID, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN VOID *OpCodeHandle ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *Next; EFI_STRING_ID NameID; EFI_STRING DriverName; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText; // // Locate device path to text protocol. // Status = gBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevicePathText ); if (EFI_ERROR (Status)) { return ; } // // Get driver file name node. // Next = DevicePath; while (!IsDevicePathEnd (Next)) { DevicePath = Next; Next = NextDevicePathNode (Next); } // // Display the device path in form. // DriverName = DevicePathText->ConvertDevicePathToText (DevicePath, FALSE, FALSE); NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL); FreePool (DriverName); if (NameID == 0) { return ; } HiiCreateActionOpCode ( OpCodeHandle, // Container for dynamic created opcodes (UINT16) QuestionID, // Question ID NameID, // Prompt text STRING_TOKEN (STR_NULL_STRING), // Help text EFI_IFR_FLAG_CALLBACK, // Question flag 0 // Action String ID ); }
/** Extract device path for given HII handle and class guid. @param Handle The HII handle. @retval NULL Fail to get the device path string. @return PathString Get the device path string. **/ CHAR16 * ExtractDevicePathFromHiiHandle ( IN EFI_HII_HANDLE Handle ) { EFI_STATUS Status; EFI_HANDLE DriverHandle; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *PathToText; CHAR16 *NewString; ASSERT (Handle != NULL); if (Handle == NULL) { return NULL; } Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); if (EFI_ERROR (Status)) { return NULL; } // // Get the device path by the got Driver handle . // Status = gBS->HandleProtocol (DriverHandle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath); if (EFI_ERROR (Status)) { return NULL; } Status = gBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &PathToText ); if (EFI_ERROR (Status)) { return NULL; } // // Get device path string. // NewString = PathToText->ConvertDevicePathToText(DevicePath, FALSE, FALSE); return NewString; }
EFI_STATUS GenerateDeviceDescriptionName ( IN EFI_HANDLE Handle, IN OUT CHAR16* Description ) { EFI_STATUS Status; EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; CHAR16* DriverName; CHAR16* DevicePathTxt; EFI_DEVICE_PATH* DevicePathNode; ComponentName2Protocol = NULL; Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol); if (!EFI_ERROR(Status)) { //TODO: Fixme. we must find the best langague Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName); if (!EFI_ERROR(Status)) { StrnCpy (Description, DriverName, BOOT_DEVICE_DESCRIPTION_MAX); } } if (EFI_ERROR(Status)) { // Use the lastest non null entry of the Device path as a description Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); if (EFI_ERROR(Status)) { return Status; } // Convert the last non end-type Device Path Node in text for the description DevicePathNode = GetLastDevicePathNode (DevicePathProtocol); Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePathNode, TRUE, TRUE); StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX); FreePool (DevicePathTxt); } return EFI_SUCCESS; }
EFI_STATUS EblDevicePaths ( IN UINTN Argc, IN CHAR8 **Argv ) { EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; CHAR16* String; EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; BdsConnectAllDrivers(); Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (EFI_ERROR (Status)) { AsciiPrint ("Did not find the DevicePathToTextProtocol.\n"); return EFI_SUCCESS; } Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { AsciiPrint ("No device path found\n"); return EFI_SUCCESS; } for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); String = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE); Print (L"[0x%X] %s\n",(UINTN)HandleBuffer[Index], String); } return EFI_SUCCESS; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); if (StrCmp ((CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt) != 0) { DEBUG ((EFI_D_ERROR, "Device Path given: '%s' Device Path expected: '%s'\n", (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt)); ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); } FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr (PcdDefaultBootDescription), BootDevicePath, (UINT8 *)DefaultBootArgument, // OptionalData CmdLineSize, // OptionalDataSize &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
STATIC EFI_STATUS InitializeConsolePipe ( IN EFI_DEVICE_PATH *ConsoleDevicePaths, IN EFI_GUID *Protocol, OUT EFI_HANDLE *Handle, OUT VOID* *Interface ) { EFI_STATUS Status; UINTN Size; UINTN NoHandles; EFI_HANDLE *Buffer; EFI_DEVICE_PATH_PROTOCOL* DevicePath; // Connect all the Device Path Consoles while (ConsoleDevicePaths != NULL) { DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size); Status = BdsConnectDevicePath (DevicePath, Handle, NULL); DEBUG_CODE_BEGIN(); if (EFI_ERROR(Status)) { // We convert back to the text representation of the device Path EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; EFI_STATUS Status; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (!EFI_ERROR(Status)) { DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE); DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status)); FreePool (DevicePathTxt); } } DEBUG_CODE_END(); // If the console splitter driver is not supported by the platform then use the first Device Path // instance for the console interface. if (!EFI_ERROR(Status) && (*Interface == NULL)) { Status = gBS->HandleProtocol (*Handle, Protocol, Interface); } } // No Device Path has been defined for this console interface. We take the first protocol implementation if (*Interface == NULL) { Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); if (EFI_ERROR (Status)) { BdsConnectAllDrivers(); Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); } if (!EFI_ERROR(Status)) { *Handle = Buffer[0]; Status = gBS->HandleProtocol (*Handle, Protocol, Interface); ASSERT_EFI_ERROR(Status); FreePool (Buffer); } } else { Status = EFI_SUCCESS; } return Status; }
EFI_STATUS LinuxLoaderConfig ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage ) { EFI_STATUS Status; LINUX_LOADER_ACTION Choice; UINTN BootOrderSize; UINT16* BootOrder; UINTN BootOrderCount; UINTN Index; CHAR16 Description[MAX_ASCII_INPUT]; CHAR8 CmdLine[MAX_ASCII_INPUT]; CHAR16 Initrd[MAX_STR_INPUT]; UINT16 InitrdPathListLength; UINT16 CmdLineLength; BDS_LOAD_OPTION* BdsLoadOption; BDS_LOAD_OPTION** SupportedBdsLoadOptions; UINTN SupportedBdsLoadOptionCount; LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData; EFI_DEVICE_PATH* DevicePathRoot; Choice = (LINUX_LOADER_ACTION)0; SupportedBdsLoadOptions = NULL; SupportedBdsLoadOptionCount = 0; do { Print (L"[%d] Create new Linux Boot Entry\n",LINUX_LOADER_NEW); Print (L"[%d] Update Linux Boot Entry\n",LINUX_LOADER_UPDATE); Print (L"Option: "); Status = GetHIInputInteger ((UINTN*)&Choice); if (Status == EFI_INVALID_PARAMETER) { Print (L"\n"); return Status; } else if ((Choice != LINUX_LOADER_NEW) && (Choice != LINUX_LOADER_UPDATE)) { Print (L"Error: the option should be either '%d' or '%d'\n",LINUX_LOADER_NEW,LINUX_LOADER_UPDATE); Status = EFI_INVALID_PARAMETER; } } while (EFI_ERROR(Status)); if (Choice == LINUX_LOADER_UPDATE) { // If no compatible entry then we just create a new entry Choice = LINUX_LOADER_NEW; // Scan the OptionalData of every entry for the correct signature Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); if (!EFI_ERROR(Status)) { BootOrderCount = BootOrderSize / sizeof(UINT16); // Allocate an array to handle maximum number of supported Boot Entry SupportedBdsLoadOptions = (BDS_LOAD_OPTION**)AllocatePool(sizeof(BDS_LOAD_OPTION*) * BootOrderCount); SupportedBdsLoadOptionCount = 0; // Check if the signature is present in the list of the current Boot entries for (Index = 0; Index < BootOrderCount; Index++) { Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption); if (!EFI_ERROR(Status)) { if ((BdsLoadOption->OptionalDataSize >= sizeof(UINT32)) && (*(UINT32*)BdsLoadOption->OptionalData == LINUX_LOADER_SIGNATURE)) { SupportedBdsLoadOptions[SupportedBdsLoadOptionCount++] = BdsLoadOption; Choice = LINUX_LOADER_UPDATE; } } } } FreePool (BootOrder); } if (Choice == LINUX_LOADER_NEW) { Description[0] = '\0'; CmdLine[0] = '\0'; Initrd[0] = '\0'; BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); DEBUG_CODE_BEGIN(); CHAR16* DevicePathTxt; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); Print(L"EFI OS Loader: %s\n",DevicePathTxt); FreePool(DevicePathTxt); DEBUG_CODE_END(); // // Fill the known fields of BdsLoadOption // BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT; // Get the full Device Path for this file Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathRoot); ASSERT_EFI_ERROR(Status); BdsLoadOption->FilePathList = AppendDevicePath (DevicePathRoot, LoadedImage->FilePath); BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList); } else { if (SupportedBdsLoadOptionCount > 1) { for (Index = 0; Index < SupportedBdsLoadOptionCount; Index++) { Print (L"[%d] %s\n",Index + 1,SupportedBdsLoadOptions[Index]->Description); } do { Print (L"Update Boot Entry: "); Status = GetHIInputInteger ((UINTN*)&Choice); if (Status == EFI_INVALID_PARAMETER) { Print (L"\n"); return Status; } else if ((Choice < 1) && (Choice > SupportedBdsLoadOptionCount)) { Print (L"Choose entry from 1 to %d\n",SupportedBdsLoadOptionCount); Status = EFI_INVALID_PARAMETER; } } while (EFI_ERROR(Status)); BdsLoadOption = SupportedBdsLoadOptions[Choice-1]; } StrnCpy (Description, BdsLoadOption->Description, MAX_STR_INPUT); LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)BdsLoadOption->OptionalData; if (LinuxOptionalData->CmdLineLength > 0) { CopyMem (CmdLine, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA), LinuxOptionalData->CmdLineLength); } else { CmdLine[0] = '\0'; } if (LinuxOptionalData->InitrdPathListLength > 0) { CopyMem (Initrd, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA) + LinuxOptionalData->CmdLineLength, LinuxOptionalData->InitrdPathListLength); } else { Initrd[0] = L'\0'; } DEBUG((EFI_D_ERROR,"L\n")); } // Description Print (L"Description: "); Status = EditHIInputStr (Description, MAX_STR_INPUT); if (EFI_ERROR(Status)) { return Status; } if (StrLen (Description) == 0) { StrnCpy (Description, DEFAULT_BOOT_ENTRY_DESCRIPTION, MAX_STR_INPUT); } BdsLoadOption->Description = Description; // CmdLine Print (L"Command Line: "); Status = EditHIInputAscii (CmdLine, MAX_ASCII_INPUT); if (EFI_ERROR(Status)) { return Status; } // Initrd Print (L"Initrd name: "); Status = EditHIInputStr (Initrd, MAX_STR_INPUT); if (EFI_ERROR(Status)) { return Status; } CmdLineLength = AsciiStrLen (CmdLine); if (CmdLineLength > 0) { CmdLineLength += sizeof(CHAR8); } InitrdPathListLength = StrLen (Initrd) * sizeof(CHAR16); if (InitrdPathListLength > 0) { InitrdPathListLength += sizeof(CHAR16); } BdsLoadOption->OptionalDataSize = sizeof(LINUX_LOADER_OPTIONAL_DATA) + CmdLineLength + InitrdPathListLength; LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)AllocatePool (BdsLoadOption->OptionalDataSize); BdsLoadOption->OptionalData = LinuxOptionalData; LinuxOptionalData->Signature = LINUX_LOADER_SIGNATURE; LinuxOptionalData->CmdLineLength = CmdLineLength; LinuxOptionalData->InitrdPathListLength = InitrdPathListLength; if (CmdLineLength > 0) { CopyMem (LinuxOptionalData + 1, CmdLine, CmdLineLength); } if (InitrdPathListLength > 0) { CopyMem ((UINT8*)(LinuxOptionalData + 1) + CmdLineLength, Initrd, InitrdPathListLength); } // Create or Update the boot entry Status = BootOptionToLoadOptionVariable (BdsLoadOption); return Status; }
EFI_STATUS BootMenuMain ( VOID ) { LIST_ENTRY BootOptionsList; UINTN OptionCount; UINTN BootOptionCount; EFI_STATUS Status; LIST_ENTRY* Entry; BDS_LOAD_OPTION* BootOption; UINTN BootOptionSelected; UINTN Index; UINTN BootMainEntryCount; BOOLEAN IsUnicode; BootOption = NULL; BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY); while (TRUE) { // Get Boot#### list BootOptionList (&BootOptionsList); OptionCount = 1; // Display the Boot options for (Entry = GetFirstNode (&BootOptionsList); !IsNull (&BootOptionsList,Entry); Entry = GetNextNode (&BootOptionsList,Entry) ) { BootOption = LOAD_OPTION_FROM_LINK(Entry); Print(L"[%d] %s\n", OptionCount, BootOption->Description); DEBUG_CODE_BEGIN(); CHAR16* DevicePathTxt; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; UINTN CmdLineSize; ARM_BDS_LOADER_TYPE LoaderType; Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n")); return Status; } DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE); Print(L"\t- %s\n",DevicePathTxt); // If it is a supported BootEntry then print its details if (IS_ARM_BDS_BOOTENTRY (BootOption)) { OptionalData = BootOption->OptionalData; LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) { if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) { CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ( GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE); Print(L"\t- Initrd: %s\n", DevicePathTxt); } if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) { Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1)); } } switch (LoaderType) { case BDS_LOADER_EFI_APPLICATION: Print(L"\t- LoaderType: EFI Application\n"); break; case BDS_LOADER_KERNEL_LINUX_ATAG: Print(L"\t- LoaderType: Linux kernel with ATAG support\n"); break; case BDS_LOADER_KERNEL_LINUX_FDT: Print(L"\t- LoaderType: Linux kernel with FDT support\n"); break; default: Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType); } } else if (BootOption->OptionalData != NULL) { if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) { if (IsUnicode) { Print (L"\t- Arguments: %s\n", BootOption->OptionalData); } else { AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData); } } } FreePool(DevicePathTxt); DEBUG_CODE_END(); OptionCount++; } BootOptionCount = OptionCount-1; // Display the hardcoded Boot entries for (Index = 0; Index < BootMainEntryCount; Index++) { Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]); OptionCount++; } // Request the boot entry from the user BootOptionSelected = 0; while (BootOptionSelected == 0) { Print(L"Start: "); Status = GetHIInputInteger (&BootOptionSelected); if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) { Print(L"Invalid input (max %d)\n",(OptionCount-1)); BootOptionSelected = 0; } } // Start the selected entry if (BootOptionSelected > BootOptionCount) { // Start the hardcoded entry Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList); } else { // Find the selected entry from the Boot#### list Index = 1; for (Entry = GetFirstNode (&BootOptionsList); !IsNull (&BootOptionsList,Entry); Entry = GetNextNode (&BootOptionsList,Entry) ) { if (Index == BootOptionSelected) { BootOption = LOAD_OPTION_FROM_LINK(Entry); break; } Index++; } Status = BootOptionStart (BootOption); } } // Should never go here }
/** Worker function that displays the list of boot options that is passed in. The function loops over the entries of the list of boot options that is passed in. For each entry, the boot option description is displayed on a single line along with the position of the option in the list. In debug mode, the UEFI device path and the arguments of the boot option are displayed as well in subsequent lines. @param[in] BootOptionsList List of the boot options **/ STATIC VOID DisplayBootOptions ( IN LIST_ENTRY* BootOptionsList ) { EFI_STATUS Status; UINTN BootOptionCount; LIST_ENTRY *Entry; BDS_LOAD_OPTION *BdsLoadOption; BOOLEAN IsUnicode; BootOptionCount = 0 ; for (Entry = GetFirstNode (BootOptionsList); !IsNull (BootOptionsList, Entry); Entry = GetNextNode (BootOptionsList, Entry) ) { BdsLoadOption = LOAD_OPTION_FROM_LINK (Entry); Print (L"[%d] %s\n", ++BootOptionCount, BdsLoadOption->Description); DEBUG_CODE_BEGIN (); CHAR16* DevicePathTxt; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; ARM_BDS_LOADER_TYPE LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; Status = gBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol ); ASSERT_EFI_ERROR (Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ( BdsLoadOption->FilePathList, TRUE, TRUE ); Print (L"\t- %s\n", DevicePathTxt); OptionalData = BdsLoadOption->OptionalData; if (IS_ARM_BDS_BOOTENTRY (BdsLoadOption)) { LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT ) ) { Print (L"\t- Arguments: %a\n", &OptionalData->Arguments.LinuxArguments + 1); } } else if (OptionalData != NULL) { if (IsPrintableString (OptionalData, &IsUnicode)) { if (IsUnicode) { Print (L"\t- Arguments: %s\n", OptionalData); } else { AsciiPrint ("\t- Arguments: %a\n", OptionalData); } } } FreePool (DevicePathTxt); DEBUG_CODE_END (); } }
STATIC EFI_STATUS SelectBootDevice ( OUT BDS_SUPPORTED_DEVICE** SupportedBootDevice ) { EFI_STATUS Status; LIST_ENTRY SupportedDeviceList; UINTN SupportedDeviceCount; LIST_ENTRY* Entry; UINTN SupportedDeviceSelected; UINTN Index; // // List the Boot Devices supported // // Start all the drivers first BdsConnectAllDrivers (); // List the supported devices Status = BootDeviceListSupportedInit (&SupportedDeviceList); ASSERT_EFI_ERROR(Status); SupportedDeviceCount = 0; for (Entry = GetFirstNode (&SupportedDeviceList); !IsNull (&SupportedDeviceList,Entry); Entry = GetNextNode (&SupportedDeviceList,Entry) ) { *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); Print(L"[%d] %s\n",SupportedDeviceCount+1,(*SupportedBootDevice)->Description); DEBUG_CODE_BEGIN(); CHAR16* DevicePathTxt; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ((*SupportedBootDevice)->DevicePathProtocol,TRUE,TRUE); Print(L"\t- %s\n",DevicePathTxt); FreePool(DevicePathTxt); DEBUG_CODE_END(); SupportedDeviceCount++; } if (SupportedDeviceCount == 0) { Print(L"There is no supported device.\n"); Status = EFI_ABORTED; goto EXIT; } // // Select the Boot Device // SupportedDeviceSelected = 0; while (SupportedDeviceSelected == 0) { Print(L"Select the Boot Device: "); Status = GetHIInputInteger (&SupportedDeviceSelected); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } else if ((SupportedDeviceSelected == 0) || (SupportedDeviceSelected > SupportedDeviceCount)) { Print(L"Invalid input (max %d)\n",SupportedDeviceCount); SupportedDeviceSelected = 0; } } // // Get the Device Path for the selected boot device // Index = 1; for (Entry = GetFirstNode (&SupportedDeviceList); !IsNull (&SupportedDeviceList,Entry); Entry = GetNextNode (&SupportedDeviceList,Entry) ) { if (Index == SupportedDeviceSelected) { *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); break; } Index++; } EXIT: BootDeviceListSupportedFree (&SupportedDeviceList, *SupportedBootDevice); return Status; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINT8* OptionalData; UINTN OptionalDataSize; ARM_BDS_LOADER_ARGUMENTS* BootArguments; ARM_BDS_LOADER_TYPE BootType; EFI_DEVICE_PATH* InitrdPath; UINTN InitrdSize; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); ASSERT (StrCmp ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath), DevicePathTxt) == 0); FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { BootType = (ARM_BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType); // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { InitrdPath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath)); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineAsciiSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); if (BootArguments == NULL) { return EFI_OUT_OF_RESOURCES; } BootArguments->LinuxArguments.CmdLineSize = CmdLineAsciiSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(BootArguments + 1), AsciiDefaultBootArgument, CmdLineAsciiSize); CopyMem ((VOID*)((UINTN)(BootArguments + 1) + CmdLineAsciiSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { OptionalData = (UINT8*)DefaultBootArgument; OptionalDataSize = CmdLineSize; } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr(PcdDefaultBootDescription), BootDevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
// // TDS // EFI_STATUS BBTestReceiveDataConformanceAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib = NULL; EFI_STATUS Status; EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityCommand = NULL; EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityTemp = NULL; EFI_BLOCK_IO_PROTOCOL *BlockIo = NULL; EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; EFI_DEVICE_PATH_PROTOCOL *DevPathNode = NULL; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText = NULL; EFI_STRING DevicePathNodeStr = NULL; UINTN Index; UINTN NoHandles; EFI_HANDLE *HandleBuffer = NULL; EFI_TEST_ASSERTION AssertionType; UINT8 *DataBuffer = NULL; UINTN RcvDataSize; EFI_HANDLE Handle = NULL; BOOLEAN IsAtaDevice = FALSE; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, (UINTN)__LINE__, Status ); return Status; } StorageSecurityCommand = (EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *)ClientInterface; // // Locate Block IO protocol on same handler to get media info // Status = gtBS->LocateHandleBuffer ( ByProtocol, &gEfiStorageSecurityCommandProtocolGuid, NULL, &NoHandles, &HandleBuffer ); for (Index = 0; Index < NoHandles; Index++) { Status = gtBS->HandleProtocol ( HandleBuffer[Index], &gEfiStorageSecurityCommandProtocolGuid, &StorageSecurityTemp ); if (Status == EFI_SUCCESS && StorageSecurityTemp == StorageSecurityCommand) { Status = gtBS->HandleProtocol ( HandleBuffer[Index], &gEfiBlockIoProtocolGuid, &BlockIo ); Handle = HandleBuffer[Index]; if (Status != EFI_SUCCESS) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"Can not Locate BlockIo Protocol on Current Handler", L"%a:%d:", __FILE__, (UINTN)__LINE__ ); goto EXIT; } } } // // both ATA8-ACS & SPC-4 security protocol payload are in 512 incremenet // DataBuffer = AllocateZeroPool(512); if (DataBuffer == NULL) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocateMemory - Allocate Memory Fail", L"%a:%d:", __FILE__, (UINTN)__LINE__ ); goto EXIT; } if (BlockIo->Media->MediaPresent) { // // EFI_WARN_BUFFER_TOO_SMALL // Status = gtBS->HandleProtocol ( Handle, &gEfiDevicePathProtocolGuid, &DevicePath ); if (!EFI_ERROR(Status)) { Status = gtBS->LocateProtocol ( &gEfiDevicePathToTextProtocolGuid, NULL, &DevicePathToText ); if (!EFI_ERROR(Status)) { // // Search for Ata device Node in devicepath // DevPathNode = DevicePath; while (!IsDevicePathEnd(DevPathNode)) { DevicePathNodeStr = DevicePathToText->ConvertDeviceNodeToText ( DevPathNode, FALSE, FALSE ); if ((DevicePathNodeStr != NULL) && ((EfiStrStr(DevicePathNodeStr, L"Ata(") != NULL) || (EfiStrStr(DevicePathNodeStr, L"Sata(") != NULL))) { IsAtaDevice = TRUE; FreePool(DevicePathNodeStr); DevicePathNodeStr = NULL; break; } FreePool(DevicePathNodeStr); DevicePathNodeStr = NULL; DevPathNode = NextDevicePathNode(DevPathNode); } } } // // According to TCG definition, when the Security Protocol field is set to 00h, and SP // Specific is set to 0000h in a TRUSTED RECEIVE command, return security protocol // information. This Command is not associated with a security send command // Status = StorageSecurityCommand->ReceiveData ( StorageSecurityCommand, BlockIo->Media->MediaId, 100000000, // Timeout 10-sec 0, // SecurityProtocol 0, // SecurityProtocolSpecifcData 10, // PayloadBufferSize, DataBuffer, // PayloadBuffer &RcvDataSize ); // // for ATA8-ACS SecurityProtocol, 512 byte is a request // if (IsAtaDevice) { if((Status == EFI_DEVICE_ERROR) || (Status == EFI_WARN_BUFFER_TOO_SMALL)){ AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } } else { if((!EFI_ERROR(Status)) || (Status == EFI_WARN_BUFFER_TOO_SMALL)){ AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } } if (IsAtaDevice) { StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid001, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get Ata device basic information with limited data buffer", L"%a:%d: Status: %r ExpectedStatus: %r", __FILE__, (UINTN)__LINE__, Status, EFI_DEVICE_ERROR ); } else { StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid001, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get Non-Ata device basic information with limited data buffer", L"%a:%d: Status: %r ExpectedStatus: %r or %r", __FILE__, (UINTN)__LINE__, Status, EFI_WARN_BUFFER_TOO_SMALL, EFI_SUCCESS ); } // // EFI_MEDIA_CHANGED // Status = StorageSecurityCommand->ReceiveData ( StorageSecurityCommand, BlockIo->Media->MediaId + 1, 100000000, // Timeout 10-sec 0, // SecurityProtocol 0, // SecurityProtocolSpecifcData 512, // PayloadBufferSize, DataBuffer, // PayloadBuffer &RcvDataSize ); if (Status == EFI_MEDIA_CHANGED) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid002, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get device basic information with invalid Media ID", L"%a:%d: Status: %r ExpectedStatus: %r", __FILE__, (UINTN)__LINE__, Status, EFI_MEDIA_CHANGED ); // // EFI_INVALID_PARAMETER // // // NULL PayloadBuffer // Status = StorageSecurityCommand->ReceiveData ( StorageSecurityCommand, BlockIo->Media->MediaId, 100000000, // Timeout 10-sec 0, // SecurityProtocol 0, // SecurityProtocolSpecifcData 512, // PayloadBufferSize, NULL, // PayloadBuffer &RcvDataSize ); if (Status == EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid003, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get device basic information with NULL Payload buffer", L"%a:%d: Status: %r ExpectedStatus: %r", __FILE__, (UINTN)__LINE__, Status, EFI_INVALID_PARAMETER ); // // NULL PayloadTransferSize // Status = StorageSecurityCommand->ReceiveData ( StorageSecurityCommand, BlockIo->Media->MediaId, 100000000, // Timeout 10-sec 0, // SecurityProtocol 0, // SecurityProtocolSpecifcData 512, // PayloadBufferSize, DataBuffer, // PayloadBuffer NULL ); if (Status == EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid004, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get device basic information with NULL PayloadTransferSize", L"%a:%d: Status: %r ExpectedStatus: %r", __FILE__, (UINTN)__LINE__, Status, EFI_INVALID_PARAMETER ); } else { // // EFI_NO_MEDIA // Status = StorageSecurityCommand->ReceiveData ( StorageSecurityCommand, BlockIo->Media->MediaId, 100000000, // Timeout 10-sec 0, // SecurityProtocol 0, // SecurityProtocolSpecifcData 512, // PayloadBufferSize, DataBuffer, // PayloadBuffer &RcvDataSize ); if (Status == EFI_NO_MEDIA) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gStorageSecurityCommandConformanceTestAssertionGuid005, L"EFI_STORAGE_SECURITY_COMMAND.ReceiveData - TRUSTED RECEIVE to get device basic information on a non-existing media", L"%a:%d: Status: %r ExpectedStatus: %r", __FILE__, (UINTN)__LINE__, Status, EFI_NO_MEDIA ); } EXIT: if (HandleBuffer != NULL) { gtBS->FreePool (HandleBuffer); } if (DataBuffer != NULL) { gtBS->FreePool(DataBuffer); } return EFI_SUCCESS; }
EFI_STATUS GetBootDeviceTypeInfo ( VOID ) { EFI_STATUS Status = EFI_SUCCESS; LIST_ENTRY BootOptionsList; LIST_ENTRY* Entry; UINT16 *SataDes = NULL; UINT16 *MacDes = NULL; UINTN SataDesSize = 0; UINTN MacDesSize = 0; BDS_LOAD_OPTION* BootOption; UINTN OptionCount = 0; CHAR16* SataStr = L"Sata"; CHAR16* MacStr = L"MAC"; CHAR16* DevicePathTxt = NULL; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol = NULL; // Get Boot#### list BootOptionList (&BootOptionsList); // Display the Boot options for (Entry = GetFirstNode (&BootOptionsList); !IsNull (&BootOptionsList,Entry); Entry = GetNextNode (&BootOptionsList,Entry) ) { BootOption = LOAD_OPTION_FROM_LINK(Entry); //Print(L"[%d] %s\n", OptionCount, BootOption->Description); //DEBUG_CODE_BEGIN(); Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n")); return Status; } DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE); //Print(L"\t- %s\n",DevicePathTxt); //DEBUG_CODE_END(); //FIND SATA BOOT DEVICES if(!(StringFind(DevicePathTxt, SataStr))) { if(SataDesSize != 0) { SataDes = ReallocatePool (SataDesSize, SataDesSize + sizeof(UINT16), SataDes); SataDes[SataDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex; SataDesSize += sizeof(UINT16); }else{ SataDesSize = sizeof(UINT16); SataDes = &(BootOption->LoadOptionIndex); } // Print(L"liuhuan SATA boot num: %d\n",SataDesSize / sizeof(UINT16)); } //FIND PXE BOOT DEVICES if(!(StringFind(DevicePathTxt, MacStr) )) { if(MacDesSize != 0) { MacDes = ReallocatePool (MacDesSize, MacDesSize + sizeof(UINT16), MacDes); MacDes[MacDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex; MacDesSize += sizeof(UINT16); }else{ MacDesSize = sizeof(UINT16); MacDes = &(BootOption->LoadOptionIndex); } // Print(L"liuhuan PXE boot num: %d\n",MacDesSize / sizeof(UINT16)); } //FreePool(DevicePathTxt); OptionCount++; } OemGetSataBootNum(SataDesSize); OemGetPXEBootNum(MacDesSize); if(SataDes != NULL) { FreePool(SataDes); } if(MacDes != NULL) { FreePool(MacDes); } if(DevicePathTxt != NULL) { FreePool(DevicePathTxt); } return EFI_SUCCESS; }