typedef struct {
CHAR8 CharB;
CHAR8 CharM;
- UINT32 Size;
- UINT16 Reserved[2];
- UINT32 ImageOffset;
- UINT32 HeaderSize;
- UINT32 PixelWidth;
- UINT32 PixelHeight;
- UINT16 Planes; // Must be 1
- UINT16 BitPerPixel; // 1, 4, 8, or 24
- UINT32 CompressionType;
- UINT32 ImageSize; // Compressed image size in bytes
- UINT32 XPixelsPerMeter;
- UINT32 YPixelsPerMeter;
- UINT32 NumberOfColors;
- UINT32 ImportantColors;
+ INT32 Size;
+ INT16 Reserved[2];
+ INT32 ImageOffset;
+ INT32 HeaderSize;
+ INT32 PixelWidth;
+ INT32 PixelHeight;
+ INT16 Planes; // Must be 1
+ INT16 BitPerPixel; // 1, 4, 8, or 24
+ INT32 CompressionType;
+ INT32 ImageSize; // Compressed image size in bytes
+ INT32 XPixelsPerMeter;
+ INT32 YPixelsPerMeter;
+ INT32 NumberOfColors;
+ INT32 ImportantColors;
} BMP_IMAGE_HEADER;
#pragma pack()
UINTN x, y;
UINT8 *ImagePtr;
UINT8 *ImagePtrBase;
- UINTN ImageLineOffset;
+ UINTN PixelWidth, PixelHeight, ImageLineOffset;
UINT8 ImageValue = 0, AlphaValue;
+ BOOLEAN UpsideDown;
EG_PIXEL *PixelPtr;
UINTN Index, BitIndex;
if (BmpHeader->BitPerPixel != 1 && BmpHeader->BitPerPixel != 4 &&
BmpHeader->BitPerPixel != 8 && BmpHeader->BitPerPixel != 24)
return NULL;
+ if (BmpHeader->PixelWidth < 1 || BmpHeader->PixelWidth > 4096 ||
+ BmpHeader->PixelHeight < -4096 || BmpHeader->PixelHeight == 0 ||
+ BmpHeader->PixelHeight > 4096)
+ return NULL;
// calculate parameters
- ImageLineOffset = BmpHeader->PixelWidth;
+ PixelWidth = BmpHeader->PixelWidth;
+ UpsideDown = BmpHeader->PixelHeight >= 0;
+ if (BmpHeader->PixelHeight < 0)
+ PixelHeight = -BmpHeader->PixelHeight;
+ else
+ PixelHeight = BmpHeader->PixelHeight;
+ ImageLineOffset = PixelWidth;
if (BmpHeader->BitPerPixel == 24)
ImageLineOffset *= 3;
else if (BmpHeader->BitPerPixel == 1)
if ((ImageLineOffset % 4) != 0)
ImageLineOffset = ImageLineOffset + (4 - (ImageLineOffset % 4));
// check bounds
- if (BmpHeader->ImageOffset + ImageLineOffset * BmpHeader->PixelHeight > FileDataLength)
+ if (BmpHeader->ImageOffset + ImageLineOffset * PixelHeight > FileDataLength)
return NULL;
// allocate image structure and buffer
- NewImage = egCreateImage(BmpHeader->PixelWidth, BmpHeader->PixelHeight, WantAlpha);
+ NewImage = egCreateImage(PixelWidth, PixelHeight, WantAlpha);
if (NewImage == NULL)
return NULL;
AlphaValue = WantAlpha ? 255 : 0;
// convert image
BmpColorMap = (BMP_COLOR_MAP *)(FileData + sizeof(BMP_IMAGE_HEADER));
ImagePtrBase = FileData + BmpHeader->ImageOffset;
- for (y = 0; y < BmpHeader->PixelHeight; y++) {
+ for (y = 0; y < PixelHeight; y++) {
ImagePtr = ImagePtrBase;
ImagePtrBase += ImageLineOffset;
- PixelPtr = NewImage->PixelData + (BmpHeader->PixelHeight - 1 - y) * BmpHeader->PixelWidth;
+ if (UpsideDown)
+ PixelPtr = NewImage->PixelData + (PixelHeight - 1 - y) * PixelWidth;
+ else
+ PixelPtr = NewImage->PixelData + y * PixelWidth;
switch (BmpHeader->BitPerPixel) {
case 1:
- for (x = 0; x < BmpHeader->PixelWidth; x++) {
+ for (x = 0; x < PixelWidth; x++) {
BitIndex = x & 0x07;
if (BitIndex == 0)
ImageValue = *ImagePtr++;
break;
case 4:
- for (x = 0; x <= BmpHeader->PixelWidth - 2; x += 2) {
+ for (x = 0; x <= PixelWidth - 2; x += 2) {
ImageValue = *ImagePtr++;
Index = ImageValue >> 4;
PixelPtr->a = AlphaValue;
PixelPtr++;
}
- if (x < BmpHeader->PixelWidth) {
+ if (x < PixelWidth) {
ImageValue = *ImagePtr++;
Index = ImageValue >> 4;
break;
case 8:
- for (x = 0; x < BmpHeader->PixelWidth; x++) {
+ for (x = 0; x < PixelWidth; x++) {
Index = *ImagePtr++;
PixelPtr->b = BmpColorMap[Index].Blue;
PixelPtr->g = BmpColorMap[Index].Green;
break;
case 24:
- for (x = 0; x < BmpHeader->PixelWidth; x++) {
+ for (x = 0; x < PixelWidth; x++) {
PixelPtr->b = *ImagePtr++;
PixelPtr->g = *ImagePtr++;
PixelPtr->r = *ImagePtr++;
BmpHeader = (BMP_IMAGE_HEADER *)FileData;
BmpHeader->CharB = 'B';
BmpHeader->CharM = 'M';
- BmpHeader->Size = FileDataLength;
+ BmpHeader->Size = (INT32)FileDataLength;
BmpHeader->ImageOffset = sizeof(BMP_IMAGE_HEADER);
BmpHeader->HeaderSize = 40;
- BmpHeader->PixelWidth = Image->Width;
- BmpHeader->PixelHeight = Image->Height;
+ BmpHeader->PixelWidth = (INT32)Image->Width;
+ BmpHeader->PixelHeight = (INT32)Image->Height;
BmpHeader->Planes = 1;
BmpHeader->BitPerPixel = 24;
BmpHeader->CompressionType = 0;
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.4.1");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.4.2");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith");
return EFI_SUCCESS;
} /* static EFI_STATUS ActivateMbrPartition() */
+static EFI_GUID AppleVariableVendorID = { 0x7C436110, 0xAB2A, 0x4BBB, 0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82 };
+
+static EFI_STATUS WriteBootDiskHint(IN EFI_DEVICE_PATH *WholeDiskDevicePath)
+{
+ EFI_STATUS Status;
+
+ Status = refit_call5_wrapper(RT->SetVariable, L"BootCampHD", &AppleVariableVendorID,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ GetDevicePathSize(WholeDiskDevicePath), WholeDiskDevicePath);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ return EFI_SUCCESS;
+}
+
// early 2006 Core Duo / Core Solo models
static UINT8 LegacyLoaderDevicePath1Data[] = {
0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
(UGAHeight - BootLogoImage->Height) >> 1,
&StdBackgroundPixel);
- if (Entry->Volume->IsMbrPartition) {
+ if (Entry->Volume->IsMbrPartition)
ActivateMbrPartition(Entry->Volume->WholeDiskBlockIO, Entry->Volume->MbrPartitionIndex);
- }
+
+ if (Entry->Volume->DiskKind != DISK_KIND_OPTICAL && Entry->Volume->WholeDiskDevicePath != NULL)
+ WriteBootDiskHint(Entry->Volume->WholeDiskDevicePath);
ExtractLegacyLoaderPaths(DiscoveredPathList, MAX_DISCOVERED_PATHS, LegacyLoaderList);
case TAG_SHELL:
j = 0;
while ((FileName = FindCommaDelimited(SHELL_NAMES, j++)) != NULL) {
- if (FileExists(SelfRootDir, FileName)) {
+ if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL),
'S', FALSE);
}
case TAG_GPTSYNC:
j = 0;
while ((FileName = FindCommaDelimited(GPTSYNC_NAMES, j++)) != NULL) {
- if (FileExists(SelfRootDir, FileName)) {
+ if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Hybrid MBR tool", BuiltinIcon(BUILTIN_ICON_TOOL_PART),
'P', FALSE);
} // if
case TAG_GDISK:
j = 0;
while ((FileName = FindCommaDelimited(GDISK_NAMES, j++)) != NULL) {
- if (FileExists(SelfRootDir, FileName)) {
+ if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"disk partitioning tool",
BuiltinIcon(BUILTIN_ICON_TOOL_PART), 'G', FALSE);
} // if
case TAG_NETBOOT:
j = 0;
while ((FileName = FindCommaDelimited(NETBOOT_NAMES, j++)) != NULL) {
- if (FileExists(SelfRootDir, FileName)) {
+ if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Netboot",
BuiltinIcon(BUILTIN_ICON_TOOL_NETBOOT), 'N', FALSE);
} // if
case TAG_APPLE_RECOVERY:
FileName = StrDuplicate(L"\\com.apple.recovery.boot\\boot.efi");
for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
- if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName))) {
+ if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) &&
+ IsValidLoader(Volumes[VolumeIndex]->RootDir, FileName)) {
SPrint(Description, 255, L"Apple Recovery on %s", Volumes[VolumeIndex]->VolName);
AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,
BuiltinIcon(BUILTIN_ICON_TOOL_APPLE_RESCUE), 'R', TRUE);
SplitVolumeAndFilename(&FileName, &VolName);
for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) &&
+ IsValidLoader(Volumes[VolumeIndex]->RootDir, FileName) &&
((VolName == NULL) || (StriCmp(VolName, Volumes[VolumeIndex]->VolName) == 0))) {
SPrint(Description, 255, L"Microsoft Recovery on %s", Volumes[VolumeIndex]->VolName);
AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,