EFI & BMP - Shell error when compiling with vs2019
Posted: Fri Feb 05, 2021 9:23 am
I am trying to render a bmp file for my EFI app. Normally, I do not use uefi-shell.
I found this link to begin: https://blog.fpmurphy.com/2015/08/displ ... shell.html
I modified given code like this:
gBMP.h
When I put my gBMP header into main.c as header then put my RenderBMP as: RenderBMP(L"logo.bmp",ImageHandle,gop,HandleCount); I see following errors:
What am I missing here ?
I found this link to begin: https://blog.fpmurphy.com/2015/08/displ ... shell.html
I modified given code like this:
gBMP.h
Code: Select all
#pragma once
#include "efi_reference.h"
/*
"efi_reference.h" contains:
#include <efi.h>
#include <efilib.h>
#include <efipoint.h>
*/
#include <efishellparm.h>
typedef struct {
CHAR8 CharB;
CHAR8 CharM;
UINT32 Size;
UINT16 Reserved[2];
UINT32 ImageOffset;
UINT32 HeaderSize;
UINT32 PixelWidth;
UINT32 PixelHeight;
UINT16 Planes;
UINT16 BitPerPixel;
UINT32 CompressionType;
UINT32 ImageSize;
UINT32 XPixelsPerMeter;
UINT32 YPixelsPerMeter;
UINT32 NumberOfColors;
UINT32 ImportantColors;
} __attribute__((__packed__)) BMP_IMAGE_HEADER;
static VOID
AsciiToUnicodeSize(CHAR8* String,
UINT8 length,
CHAR16* UniString)
{
int len = length;
while (*String != '\0' && len > 0) {
*(UniString++) = (CHAR16) * (String++);
len--;
}
*UniString = '\0';
}
static EFI_STATUS
DisplayImage(EFI_GRAPHICS_OUTPUT_PROTOCOL* Gop, EFI_HANDLE* BmpBuffer)
{
BMP_IMAGE_HEADER* BmpHeader = (BMP_IMAGE_HEADER*)BmpBuffer;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* BltBuffer;
EFI_STATUS Status = EFI_SUCCESS;
UINT8* BitmapData;
UINT32* Palette;
UINTN Pixels;
UINTN XIndex;
UINTN YIndex;
UINTN Pos;
UINTN BltPos;
BitmapData = (UINT8*)BmpBuffer + BmpHeader->ImageOffset;
Palette = (UINT32*)((UINT8*)BmpBuffer + 0x36);
Pixels = (UINTN)BmpHeader->PixelWidth * (UINTN)BmpHeader->PixelHeight;
BltBuffer = AllocateZeroPool(sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Pixels);
if (BltBuffer == NULL) {
Print(L"ERROR: BltBuffer. No memory resources\n");
return EFI_OUT_OF_RESOURCES;
}
for (YIndex = BmpHeader->PixelHeight; YIndex > 0; YIndex--) {
for (XIndex = 0; XIndex < BmpHeader->PixelWidth; XIndex++) {
Pos = (YIndex - 1) * ((UINTN)((UINTN)BmpHeader->PixelWidth + 3) / 4) * 4 + XIndex;
BltPos = (BmpHeader->PixelHeight - YIndex) * BmpHeader->PixelWidth + XIndex;
BltBuffer[BltPos].Blue = (UINT8)BitFieldRead32(Palette[BitmapData[Pos]], 0, 7);
BltBuffer[BltPos].Green = (UINT8)BitFieldRead32(Palette[BitmapData[Pos]], 8, 15);
BltBuffer[BltPos].Red = (UINT8)BitFieldRead32(Palette[BitmapData[Pos]], 16, 23);
BltBuffer[BltPos].Reserved = (UINT8)BitFieldRead32(Palette[BitmapData[Pos]], 24, 31);
}
}
Status = Gop->Blt(Gop,
BltBuffer,
EfiBltBufferToVideo,
0, 0, /* Source X, Y */
50, 50, /* Dest X, Y */
BmpHeader->PixelWidth, BmpHeader->PixelHeight,
0);
FreePool(BltBuffer);
return Status;
}
static RenderBMP(char file[]/*zani_logo.bmp*/, EFI_HANDLE *gImageHandle, EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop, UINTN HandleCount)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_HANDLE* HandleBuffer = NULL;
SHELL_FILE_HANDLE FileHandle;
EFI_FILE_INFO* FileInfo = NULL;
EFI_HANDLE* FileBuffer = NULL;
UINTN FileSize;
int OrgMode, NewMode = 0, Pixels = 0;
BOOLEAN LowerHandle = FALSE;
// Open the file ( has to be LAST arguement on command line )
Status = ShellOpenFileByName(file, &FileHandle, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status)) {
Print(L"ERROR: Could not open specified file [%d]\n", Status);
return Status;
}
// Allocate buffer for file contents
FileInfo = ShellGetFileInfo(FileHandle);
FileBuffer = AllocateZeroPool((UINTN)FileInfo->FileSize);
if (FileBuffer == NULL) {
Print(L"ERROR: File buffer. No memory resources\n");
return 0;
}
// Read file contents into allocated buffer
FileSize = (UINTN)FileInfo->FileSize;
Status = ShellReadFile(FileHandle, &FileSize, FileBuffer);
if (EFI_ERROR(Status)) {
Print(L"ERROR: ShellReadFile failed [%d]\n", Status);
goto cleanup;
}
ShellCloseFile(&FileHandle);
// Try locating GOP by handle
Status = gBS->LocateHandleBuffer(ByProtocol,
&gEfiGraphicsOutputProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer);
if (EFI_ERROR(Status)) {
Print(L"ERROR: No GOP handles found via LocateHandleBuffer\n");
goto cleanup;
}
else {
Print(L"Found %d GOP handles via LocateHandleBuffer\n", HandleCount);
if (LowerHandle)
HandleCount = 0;
else
HandleCount--;
Status = gBS->OpenProtocol(HandleBuffer[HandleCount],
&gEfiGraphicsOutputProtocolGuid,
(VOID**)&Gop,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if (EFI_ERROR(Status)) {
Print(L"ERROR: OpenProtocol [%d]\n", Status);
goto cleanup;
}
FreePool(HandleBuffer);
}
// Figure out maximum resolution and use it
OrgMode = Gop->Mode->Mode;
for (int i = 0; i < Gop->Mode->MaxMode; i++) {
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* Info;
UINTN SizeOfInfo;
Status = Gop->QueryMode(Gop, i, &SizeOfInfo, &Info);
if (EFI_ERROR(Status) && Status == EFI_NOT_STARTED) {
Gop->SetMode(Gop, Gop->Mode->Mode);
Status = Gop->QueryMode(Gop, i, &SizeOfInfo, &Info);
}
if (EFI_ERROR(Status)) {
continue;
}
if (Info->PixelsPerScanLine > Pixels) {
Pixels = Info->PixelsPerScanLine;
NewMode = i;
}
}
// change screen mode
Status = Gop->SetMode(Gop, NewMode);
if (EFI_ERROR(Status)) {
Print(L"ERROR: SetMode [%d]\n, Status");
goto cleanup;
}
DisplayImage(Gop, FileBuffer);
Status = Gop->SetMode(Gop, OrgMode);
cleanup:
FreePool(FileBuffer);
return Status;
}
Code: Select all
Error LNK2019 unresolved external symbol BitFieldRead32 için DisplayImage ...
Error LNK2019 unresolved external symbol ShellOpenFileByName için RenderBMP ...
Error LNK2019 unresolved external symbol ShellGetFileInfo için RenderBMP ...
Error LNK2019 unresolved external symbol ShellReadFile için RenderBMP ...
Error LNK2019 çözümlenmemiş dış sembol ShellCloseFile için RenderBMP ...