/** Show progress bar with title above it. It only works in Graphics mode. @param TitleForeground Foreground color for Title. @param TitleBackground Background color for Title. @param Title Title above progress bar. @param ProgressColor Progress bar color. @param Progress Progress (0-100) @param PreviousValue The previous value of the progress. @retval EFI_STATUS Success update the progress bar **/ EFI_STATUS PlatformBdsShowProgress ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, IN CHAR16 *Title, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, IN UINTN Progress, IN UINTN PreviousValue ) { EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_UGA_DRAW_PROTOCOL *UgaDraw; UINT32 SizeOfX; UINT32 SizeOfY; UINT32 ColorDepth; UINT32 RefreshRate; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINTN BlockHeight; UINTN BlockWidth; UINTN BlockNum; UINTN PosX; UINTN PosY; UINTN Index; if (Progress > 100) { return EFI_INVALID_PARAMETER; } UgaDraw = NULL; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput ); if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { GraphicsOutput = NULL; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw ); } if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } SizeOfX = 0; SizeOfY = 0; if (GraphicsOutput != NULL) { SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; } else if (UgaDraw != NULL) { Status = UgaDraw->GetMode ( UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } else { return EFI_UNSUPPORTED; } BlockWidth = SizeOfX / 100; BlockHeight = SizeOfY / 50; BlockNum = Progress; PosX = 0; PosY = SizeOfY * 48 / 50; if (BlockNum == 0) { // // Clear progress area // SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, &Color, EfiBltVideoFill, 0, 0, 0, PosY - EFI_GLYPH_HEIGHT - 1, SizeOfX, SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) &Color, EfiUgaVideoFill, 0, 0, 0, PosY - EFI_GLYPH_HEIGHT - 1, SizeOfX, SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), SizeOfX * sizeof (EFI_UGA_PIXEL) ); } else { return EFI_UNSUPPORTED; } } // // Show progress by drawing blocks // for (Index = PreviousValue; Index < BlockNum; Index++) { PosX = Index * BlockWidth; if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, &ProgressColor, EfiBltVideoFill, 0, 0, PosX, PosY, BlockWidth - 1, BlockHeight, (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) &ProgressColor, EfiUgaVideoFill, 0, 0, PosX, PosY, BlockWidth - 1, BlockHeight, (BlockWidth) * sizeof (EFI_UGA_PIXEL) ); } else { return EFI_UNSUPPORTED; } } PrintXY ( (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2, PosY - EFI_GLYPH_HEIGHT - 1, &TitleForeground, &TitleBackground, Title ); return EFI_SUCCESS; }
EFI_STATUS EnableQuietBootEx ( IN EFI_GUID *LogoFile, IN EFI_HANDLE ImageHandle ) /*++ Routine Description: Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console Arguments: LogoFile - File name of logo to display on the center of the screen. ImageHandle - The driver image handle of the caller. The parameter is used to optimize the loading of the logo file so that the FV from which the driver image is loaded will be tried first. Returns: EFI_SUCCESS - ConsoleControl has been flipped to graphics and logo displayed. EFI_UNSUPPORTED - Logo not found --*/ { EFI_STATUS Status; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; EFI_OEM_BADGING_PROTOCOL *Badging; UINT32 SizeOfX; UINT32 SizeOfY; INTN DestX; INTN DestY; UINT8 *ImageData; UINTN ImageSize; UINTN BltSize; UINT32 Instance; EFI_BADGING_FORMAT Format; EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; UINTN CoordinateX; UINTN CoordinateY; UINTN Height; UINTN Width; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; EFI_UGA_DRAW_PROTOCOL *UgaDraw; UINT32 ColorDepth; UINT32 RefreshRate; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } UgaDraw = NULL; // // Try to open GOP first // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; // // Open GOP failed, try to open UGA // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID**)&UgaDraw); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } Badging = NULL; Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID**)&Badging); ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics); if (GraphicsOutput != NULL) { SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; } else { Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } Instance = 0; while (1) { ImageData = NULL; ImageSize = 0; if (Badging != NULL) { Status = Badging->GetImage ( Badging, &Instance, &Format, &ImageData, &ImageSize, &Attribute, &CoordinateX, &CoordinateY ); if (EFI_ERROR (Status)) { return Status; } // // Currently only support BMP format // if (Format != EfiBadgingFormatBMP) { gBS->FreePool (ImageData); continue; } } else { Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } CoordinateX = 0; CoordinateY = 0; Attribute = EfiBadgingDisplayAttributeCenter; } Blt = NULL; Status = ConvertBmpToGopBlt ( ImageData, ImageSize, (VOID**)&Blt, &BltSize, &Height, &Width ); if (EFI_ERROR (Status)) { gBS->FreePool (ImageData); if (Badging == NULL) { return Status; } else { continue; } } switch (Attribute) { case EfiBadgingDisplayAttributeLeftTop: DestX = CoordinateX; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeCenterTop: DestX = (SizeOfX - Width) / 2; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeRightTop: DestX = (SizeOfX - Width - CoordinateX); DestY = CoordinateY;; break; case EfiBadgingDisplayAttributeCenterRight: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeRightBottom: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterBottom: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeLeftBottom: DestX = CoordinateX; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterLeft: DestX = CoordinateX; DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeCenter: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height) / 2; break; default: DestX = CoordinateX; DestY = CoordinateY; break; } if ((DestX >= 0) && (DestY >= 0)) { if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, Blt, EfiBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) Blt, EfiUgaBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_UGA_PIXEL) ); } } gBS->FreePool (ImageData); gBS->FreePool (Blt); if (Badging == NULL) { break; } } return Status; }
// // TDS 4.2.1 // EFI_STATUS BBTestGetModeConformanceAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_UGA_DRAW_PROTOCOL *UgaDraw; EFI_TEST_ASSERTION AssertionType; UINT32 HorizontalResolution; UINT32 VerticalResolution; UINT32 ColorDepth; UINT32 RefreshRate; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevicePathStr; // // 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__, __LINE__, Status ); return Status; } UgaDraw = (EFI_UGA_DRAW_PROTOCOL *)ClientInterface; // // Get Device Path of current Uga_Draw_Protocol // And out put device path or device name // Status = LocateDevicePathFromUgaDraw (UgaDraw, &DevicePath, StandardLib); if (Status == EFI_SUCCESS) { DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"\r\nCurrent Device: %s", DevicePathStr ); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free pool", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } DevicePathStr = NULL; } } else { // // Console Splitter/UgaDraw // StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"\r\nCurrent Device: ConsoleSplitter/UgaDraw" ); #ifdef TEST_CHIPSET_UGA_ONLY return EFI_SUCCESS; #endif } // // Assertion Point 4.2.1.2.1 // GetMode should not succeed with invalid parameter // // // Call GetMode with HorizontalResolution being NULL // Status = UgaDraw->GetMode ( UgaDraw, NULL, &VerticalResolution, &ColorDepth, &RefreshRate ); if (Status!=EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gUgaDrawConformanceTestAssertionGuid001, L"EFI_UGA_DRAW_PROTOCOL.GetMode - GetMode() with HorizontalResolution being NULL", L"%a:%d:Status:%r, Expected:%r", __FILE__, __LINE__, Status, EFI_INVALID_PARAMETER ); // // Call GetMode with VerticalResolution being NULL // Status = UgaDraw->GetMode ( UgaDraw, &HorizontalResolution, NULL, &ColorDepth, &RefreshRate ); if (Status!=EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gUgaDrawConformanceTestAssertionGuid002, L"EFI_UGA_DRAW_PROTOCOL.GetMode - GetMode() with VerticalResolution being NULL", L"%a:%d:Status:%r, Expected:%r", __FILE__, __LINE__, Status, EFI_INVALID_PARAMETER ); // // Call GetMode with RefreshRate being NULL // Status = UgaDraw->GetMode ( UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, NULL ); if (Status!=EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gUgaDrawConformanceTestAssertionGuid003, L"EFI_UGA_DRAW_PROTOCOL.GetMode - GetMode() with RefreshRate being NULL", L"%a:%d:Status:%r, Expected:%r", __FILE__, __LINE__, Status, EFI_INVALID_PARAMETER ); // // Call GetMode with ColorDepth being NULL // Status = UgaDraw->GetMode ( UgaDraw, &HorizontalResolution, &VerticalResolution, NULL, &RefreshRate ); if (Status!=EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gUgaDrawConformanceTestAssertionGuid004, L"EFI_UGA_DRAW_PROTOCOL.GetMode - GetMode() with ColorDepth being NULL", L"%a:%d:Status:%r, Expected:%r", __FILE__, __LINE__, Status, EFI_INVALID_PARAMETER ); return EFI_SUCCESS; }
/** Use SystemTable Conout to stop video based Simple Text Out consoles from going to the video device. Put up LogoFile on every video device that is a console. @param[in] LogoFile File name of logo to display on the center of the screen. @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. @retval EFI_UNSUPPORTED Logo not found **/ EFI_STATUS EFIAPI EnableQuietBoot ( IN EFI_GUID *LogoFile ) { EFI_STATUS Status; EFI_OEM_BADGING_PROTOCOL *Badging; UINT32 SizeOfX; UINT32 SizeOfY; INTN DestX; INTN DestY; UINT8 *ImageData; UINTN ImageSize; UINTN BltSize; UINT32 Instance; EFI_BADGING_FORMAT Format; EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; UINTN CoordinateX; UINTN CoordinateY; UINTN Height; UINTN Width; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; EFI_UGA_DRAW_PROTOCOL *UgaDraw; UINT32 ColorDepth; UINT32 RefreshRate; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_BOOT_LOGO_PROTOCOL *BootLogo; UINTN NumberOfLogos; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt; UINTN LogoDestX; UINTN LogoDestY; UINTN LogoHeight; UINTN LogoWidth; UINTN NewDestX; UINTN NewDestY; UINTN NewHeight; UINTN NewWidth; UINT64 BufferSize; UgaDraw = NULL; // // Try to open GOP first // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { GraphicsOutput = NULL; // // Open GOP failed, try to open UGA // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw); } if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } // // Try to open Boot Logo Protocol. // BootLogo = NULL; gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); // // Erase Cursor from screen // gST->ConOut->EnableCursor (gST->ConOut, FALSE); Badging = NULL; Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging); if (GraphicsOutput != NULL) { SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } else { return EFI_UNSUPPORTED; } Blt = NULL; NumberOfLogos = 0; LogoDestX = 0; LogoDestY = 0; LogoHeight = 0; LogoWidth = 0; NewDestX = 0; NewDestY = 0; NewHeight = 0; NewWidth = 0; Instance = 0; while (1) { ImageData = NULL; ImageSize = 0; if (Badging != NULL) { // // Get image from OEMBadging protocol. // Status = Badging->GetImage ( Badging, &Instance, &Format, &ImageData, &ImageSize, &Attribute, &CoordinateX, &CoordinateY ); if (EFI_ERROR (Status)) { goto Done; } // // Currently only support BMP format. // if (Format != EfiBadgingFormatBMP) { if (ImageData != NULL) { FreePool (ImageData); } continue; } } else { // // Get the specified image from FV. // Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } CoordinateX = 0; CoordinateY = 0; if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { Attribute = EfiBadgingDisplayAttributeCenter; } else { Attribute = EfiBadgingDisplayAttributeCustomized; } } if (Blt != NULL) { FreePool (Blt); } Blt = NULL; Status = TranslateBmpToGopBlt ( ImageData, ImageSize, &Blt, &BltSize, &Height, &Width ); if (EFI_ERROR (Status)) { FreePool (ImageData); if (Badging == NULL) { return Status; } else { continue; } } // // Calculate the display position according to Attribute. // switch (Attribute) { case EfiBadgingDisplayAttributeLeftTop: DestX = CoordinateX; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeCenterTop: DestX = (SizeOfX - Width) / 2; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeRightTop: DestX = (SizeOfX - Width - CoordinateX); DestY = CoordinateY;; break; case EfiBadgingDisplayAttributeCenterRight: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeRightBottom: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterBottom: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeLeftBottom: DestX = CoordinateX; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterLeft: DestX = CoordinateX; DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeCenter: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeCustomized: DestX = (SizeOfX - Width) / 2; DestY = ((SizeOfY * 382) / 1000) - Height / 2; break; default: DestX = CoordinateX; DestY = CoordinateY; break; } if ((DestX >= 0) && (DestY >= 0)) { if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, Blt, EfiBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) Blt, EfiUgaBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_UGA_PIXEL) ); } else { Status = EFI_UNSUPPORTED; } // // Report displayed Logo information. // if (!EFI_ERROR (Status)) { NumberOfLogos++; if (LogoWidth == 0) { // // The first Logo. // LogoDestX = (UINTN) DestX; LogoDestY = (UINTN) DestY; LogoWidth = Width; LogoHeight = Height; } else { // // Merge new logo with old one. // NewDestX = MIN ((UINTN) DestX, LogoDestX); NewDestY = MIN ((UINTN) DestY, LogoDestY); NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX; NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY; LogoDestX = NewDestX; LogoDestY = NewDestY; LogoWidth = NewWidth; LogoHeight = NewHeight; } } } FreePool (ImageData); if (Badging == NULL) { break; } } Done: if (BootLogo == NULL || NumberOfLogos == 0) { // // No logo displayed. // if (Blt != NULL) { FreePool (Blt); } return Status; } // // Advertise displayed Logo information. // if (NumberOfLogos == 1) { // // Only one logo displayed, use its Blt buffer directly for BootLogo protocol. // LogoBlt = Blt; Status = EFI_SUCCESS; } else { // // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. // if (Blt != NULL) { FreePool (Blt); } // // Ensure the LogoHeight * LogoWidth doesn't overflow // if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { return EFI_UNSUPPORTED; } BufferSize = MultU64x64 (LogoWidth, LogoHeight); // // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow // if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { return EFI_UNSUPPORTED; } LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); if (LogoBlt == NULL) { return EFI_OUT_OF_RESOURCES; } if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, LogoBlt, EfiBltVideoToBltBuffer, LogoDestX, LogoDestY, 0, 0, LogoWidth, LogoHeight, LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) LogoBlt, EfiUgaVideoToBltBuffer, LogoDestX, LogoDestY, 0, 0, LogoWidth, LogoHeight, LogoWidth * sizeof (EFI_UGA_PIXEL) ); } else { Status = EFI_UNSUPPORTED; } } if (!EFI_ERROR (Status)) { BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight); } FreePool (LogoBlt); return Status; }