#include "lib.h"
#include "icns.h"
#include "screen.h"
-#include "refit_call_wrapper.h"
+#include "../include/refit_call_wrapper.h"
+#include "../include/RemovableMedia.h"
+
+#ifdef __MAKEWITH_GNUEFI
+#define EfiReallocatePool ReallocatePool
+#else
+#define LibLocateHandle gBS->LocateHandleBuffer
+#define DevicePathProtocol gEfiDevicePathProtocolGuid
+#define BlockIoProtocol gEfiBlockIoProtocolGuid
+#define LibFileSystemInfo EfiLibFileSystemInfo
+#define LibOpenRoot EfiLibOpenRoot
+EFI_DEVICE_PATH EndDevicePath[] = {
+ {END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0}}
+};
+
+//#define EndDevicePath DevicePath
+#endif
// variables
// find the current directory
DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath);
+// Print(L"DevicePathAsString is '%s'\n", DevicePathAsString);
CleanUpPathNameSlashes(DevicePathAsString);
if (SelfDirPath != NULL)
FreePool(SelfDirPath);
SelfDirPath = FindPath(DevicePathAsString);
+// Print(L"SelfDirPath is '%s'\n", SelfDirPath);
+// PauseForKey();
FreePool(DevicePathAsString);
return FinishInitRefitLib();
if (*ElementCount == 0)
*ListPtr = AllocatePool(sizeof(VOID *) * AllocateCount);
else
- *ListPtr = ReallocatePool(*ListPtr, sizeof(VOID *) * (*ElementCount), sizeof(VOID *) * AllocateCount);
+ *ListPtr = EfiReallocatePool(*ListPtr, sizeof(VOID *) * (*ElementCount), sizeof(VOID *) * AllocateCount);
}
(*ListPtr)[*ElementCount] = NewElement;
(*ElementCount)++;
MaxPaths--; // leave space for the terminating NULL pointer
// get all LoadedImage handles
- Status = LibLocateHandle(ByProtocol, &LoadedImageProtocol, NULL,
- &HandleCount, &Handles);
+ Status = LibLocateHandle(ByProtocol, &LoadedImageProtocol, NULL, &HandleCount, &Handles);
if (CheckError(Status, L"while listing LoadedImage handles")) {
if (HardcodedPathList) {
for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++)
Volume->OSIconName = L"grub,linux";
Volume->OSName = L"Linux";
+// // Below doesn't produce a bootable entry, so commented out for the moment....
+// // GRUB in BIOS boot partition:
+// } else if (FindMem(SectorBuffer, 512, "Geom\0Read\0 Error", 16) >= 0) {
+// Volume->HasBootCode = TRUE;
+// Volume->OSIconName = L"grub,linux";
+// Volume->OSName = L"Linux";
+// Volume->VolName = L"BIOS Boot Partition";
+// *Bootable = TRUE;
+
} else if ((*((UINT32 *)(SectorBuffer + 502)) == 0 &&
*((UINT32 *)(SectorBuffer + 506)) == 50000 &&
*((UINT16 *)(SectorBuffer + 510)) == 0xaa55) ||
Volume->OSName, Volume->OSIconName);
#endif
- if (FindMem(SectorBuffer, 512, "Non-system disk", 15) >= 0) // dummy FAT boot sector
+ // dummy FAT boot sector (created by OS X's newfs_msdos)
+ if (FindMem(SectorBuffer, 512, "Non-system disk", 15) >= 0)
+ Volume->HasBootCode = FALSE;
+
+ // dummy FAT boot sector (created by Linux's mkdosfs)
+ if (FindMem(SectorBuffer, 512, "This is not a bootable disk", 27) >= 0)
+ Volume->HasBootCode = FALSE;
+
+ // dummy FAT boot sector (created by Windows)
+ if (FindMem(SectorBuffer, 512, "Press any key to restart", 24) >= 0)
Volume->HasBootCode = FALSE;
// check for MBR partition table
}
}
-// default volume icon based on disk kind
+// default volume badge icon based on disk kind
static VOID ScanVolumeDefaultIcon(IN OUT REFIT_VOLUME *Volume)
{
switch (Volume->DiskKind) {
if (FileExists(Volume->RootDir, VOLUME_ICON_NAME)) {
Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAME, 128);
}
-}
+} // ScanVolume()
static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_INFO *MbrEntry)
{
Volume->DiskKind = WholeDiskVolume->DiskKind;
Volume->IsMbrPartition = TRUE;
Volume->MbrPartitionIndex = LogicalPartitionIndex++;
- Volume->VolName = PoolPrint(L"Partition %d", Volume->MbrPartitionIndex + 1);
+ Volume->VolName = AllocateZeroPool(256 * sizeof(UINT16));
+ SPrint(Volume->VolName, 255, L"Partition %d", Volume->MbrPartitionIndex + 1);
+// Volume->VolName = PoolPrint(L"Partition %d", Volume->MbrPartitionIndex + 1);
Volume->BlockIO = WholeDiskVolume->BlockIO;
Volume->BlockIOOffset = ExtCurrent + EMbrTable[i].StartLBA;
Volume->WholeDiskBlockIO = WholeDiskVolume->BlockIO;
// get all filesystem handles
Status = LibLocateHandle(ByProtocol, &BlockIoProtocol, NULL, &HandleCount, &Handles);
// was: &FileSystemProtocol
- if (Status == EFI_NOT_FOUND)
+ if (Status == EFI_NOT_FOUND) {
return; // no filesystems. strange, but true...
+ }
if (CheckError(Status, L"while listing all file systems"))
return;
// now we're reasonably sure the association is correct...
Volume->IsMbrPartition = TRUE;
Volume->MbrPartitionIndex = PartitionIndex;
- if (Volume->VolName == NULL)
- Volume->VolName = PoolPrint(L"Partition %d", PartitionIndex + 1);
+ if (Volume->VolName == NULL) {
+ Volume->VolName = AllocateZeroPool(sizeof(CHAR16) * 256);
+ SPrint(Volume->VolName, 255, L"Partition %d", PartitionIndex + 1);
+ }
break;
}
Print(L"Reallocating buffer from %d to %d\n", LastBufferSize, BufferSize);
#endif
}
- Buffer = ReallocatePool(Buffer, LastBufferSize, BufferSize);
+ Buffer = EfiReallocatePool(Buffer, LastBufferSize, BufferSize);
LastBufferSize = BufferSize;
}
if (EFI_ERROR(Status)) {
DirIter->LastFileInfo = NULL;
}
+#ifndef __MAKEWITH_GNUEFI
+EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;
+
+static EFI_STATUS
+InitializeUnicodeCollationProtocol (VOID)
+{
+ EFI_STATUS Status;
+
+ if (mUnicodeCollation != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol
+ // instances first and then select one which support English language.
+ // Current implementation just pick the first instance.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiUnicodeCollation2ProtocolGuid,
+ NULL,
+ (VOID **) &mUnicodeCollation
+ );
+ if (EFI_ERROR(Status)) {
+ Status = gBS->LocateProtocol (
+ &gEfiUnicodeCollationProtocolGuid,
+ NULL,
+ (VOID **) &mUnicodeCollation
+ );
+
+ }
+ return Status;
+}
+
+static BOOLEAN
+MetaiMatch (IN CHAR16 *String, IN CHAR16 *Pattern)
+{
+ if (!mUnicodeCollation) {
+ InitializeUnicodeCollationProtocol();
+ }
+ if (mUnicodeCollation)
+ return mUnicodeCollation->MetaiMatch (mUnicodeCollation, String, Pattern);
+ return FALSE; // Shouldn't happen
+}
+
+static VOID StrLwr (IN OUT CHAR16 *Str) {
+ if (!mUnicodeCollation) {
+ InitializeUnicodeCollationProtocol();
+ }
+ if (mUnicodeCollation)
+ mUnicodeCollation->StrLwr (mUnicodeCollation, Str);
+}
+
+#endif
+
BOOLEAN DirIterNext(IN OUT REFIT_DIR_ITER *DirIter, IN UINTN FilterMode, IN CHAR16 *FilePattern OPTIONAL,
OUT EFI_FILE_INFO **DirEntry)
{
// Returns the directory portion of a pathname. For instance,
// if FullPath is 'EFI\foo\bar.efi', this function returns the
-// string 'EFI\foo'.
+// string 'EFI\foo'. The calling function is responsible for
+// freeing the returned string's memory.
CHAR16 *FindPath(IN CHAR16* FullPath) {
UINTN i, LastBackslash = 0;
CHAR16 *PathOnly;
} // if
return (FoundString);
} // CHAR16 *FindCommaDelimited()
+
+// Returns TRUE if SmallString is an element in the comma-delimited List,
+// FALSE otherwise. Performs comparison case-insensitively (except on
+// buggy EFIs with case-sensitive StriCmp() functions).
+BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) {
+ UINTN i = 0;
+ BOOLEAN Found = FALSE;
+ CHAR16 *OneElement;
+
+ if (SmallString && List) {
+ while (!Found && (OneElement = FindCommaDelimited(List, i++))) {
+ if (StriCmp(OneElement, SmallString) == 0)
+ Found = TRUE;
+ } // while
+ } // if
+ return Found;
+} // BOOLEAN IsIn()
+
+static EFI_GUID AppleRemovableMediaGuid = APPLE_REMOVABLE_MEDIA_PROTOCOL_GUID;
+
+// Eject all removable media.
+// Returns TRUE if any media were ejected, FALSE otherwise.
+BOOLEAN EjectMedia(VOID) {
+ EFI_STATUS Status;
+ UINTN HandleIndex, HandleCount = 0, Ejected = 0;
+ EFI_HANDLE *Handles, Handle;
+ APPLE_REMOVABLE_MEDIA_PROTOCOL *Ejectable;
+
+ Status = LibLocateHandle(ByProtocol, &AppleRemovableMediaGuid, NULL, &HandleCount, &Handles);
+ if (EFI_ERROR(Status) || HandleCount == 0)
+ return (FALSE); // probably not an Apple system
+
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ Handle = Handles[HandleIndex];
+ Status = refit_call3_wrapper(BS->HandleProtocol, Handle, &AppleRemovableMediaGuid, (VOID **) &Ejectable);
+ if (EFI_ERROR(Status))
+ continue;
+ Status = refit_call1_wrapper(Ejectable->Eject, Ejectable);
+ if (!EFI_ERROR(Status))
+ Ejected++;
+ }
+ FreePool(Handles);
+ return (Ejected > 0);
+} // VOID EjectMedia()
+