#include "lib.h"
#include "icns.h"
#include "screen.h"
-#include "refit_call_wrapper.h"
-#include "RemovableMedia.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);
CleanUpPathNameSlashes(DevicePathAsString);
- if (SelfDirPath != NULL)
- FreePool(SelfDirPath);
+ MyFreePool(SelfDirPath);
SelfDirPath = FindPath(DevicePathAsString);
- FreePool(DevicePathAsString);
+ MyFreePool(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)++;
{
UINTN i;
- if (*ElementCount > 0) {
+ if ((*ElementCount > 0) && (**ListPtr != NULL)) {
for (i = 0; i < *ElementCount; i++) {
// TODO: call a user-provided routine for each element here
- FreePool((*ListPtr)[i]);
+ MyFreePool((*ListPtr)[i]);
}
- FreePool(*ListPtr);
+ MyFreePool(*ListPtr);
}
-}
+} // VOID FreeList()
//
// firmware device path discovery
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++)
PathList[PathCount++] = AppendDevicePath(DevicePath, LegacyLoaderMediaPath);
}
- FreePool(Handles);
+ MyFreePool(Handles);
if (HardcodedPathList) {
for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++)
} // switch()
}
-static VOID ScanVolume(IN OUT REFIT_VOLUME *Volume)
+VOID ScanVolume(IN OUT REFIT_VOLUME *Volume)
{
EFI_STATUS Status;
EFI_DEVICE_PATH *DevicePath, *NextDevicePath;
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->BlockIO = WholeDiskVolume->BlockIO;
Volume->BlockIOOffset = ExtCurrent + EMbrTable[i].StartLBA;
Volume->WholeDiskBlockIO = WholeDiskVolume->BlockIO;
UINT8 *SectorBuffer1, *SectorBuffer2;
UINTN SectorSum, i;
- FreePool(Volumes);
+ MyFreePool(Volumes);
Volumes = NULL;
VolumesCount = 0;
// 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;
if (Volume->DeviceHandle == SelfLoadedImage->DeviceHandle)
SelfVolume = Volume;
}
- FreePool(Handles);
+ MyFreePool(Handles);
if (SelfVolume == NULL)
Print(L"WARNING: SelfVolume not found");
// 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;
}
- FreePool(SectorBuffer1);
- FreePool(SectorBuffer2);
+ MyFreePool(SectorBuffer1);
+ MyFreePool(SectorBuffer2);
}
}
// free pointer from last call
if (*DirEntry != NULL) {
- FreePool(*DirEntry);
- *DirEntry = NULL;
+ FreePool(*DirEntry);
+ *DirEntry = NULL;
}
// read next directory entry
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)
{
CHAR16 *OnePattern;
if (DirIter->LastFileInfo != NULL) {
- FreePool(DirIter->LastFileInfo);
- DirIter->LastFileInfo = NULL;
+ FreePool(DirIter->LastFileInfo);
+ DirIter->LastFileInfo = NULL;
}
if (EFI_ERROR(DirIter->LastStatus))
EFI_STATUS DirIterClose(IN OUT REFIT_DIR_ITER *DirIter)
{
- if (DirIter->LastFileInfo != NULL) {
- FreePool(DirIter->LastFileInfo);
- DirIter->LastFileInfo = NULL;
- }
- if (DirIter->CloseDirHandle)
- refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle);
+ if (DirIter->LastFileInfo != NULL) {
+ FreePool(DirIter->LastFileInfo);
+ DirIter->LastFileInfo = NULL;
+ }
+ if (DirIter->CloseDirHandle)
+ refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle);
return DirIter->LastStatus;
}
while ((!Found) && (StartPoint < NumCompares)) {
Found = (StrnCmp(SmallCopy, &BigCopy[StartPoint++], SmallLen) == 0);
} // while
- FreePool(SmallCopy);
- FreePool(BigCopy);
+ MyFreePool(SmallCopy);
+ MyFreePool(BigCopy);
} // if
return (Found);
} // if (*First != NULL)
if (Second != NULL)
StrCat(NewString, Second);
- FreePool(*First);
+ MyFreePool(*First);
*First = NewString;
} else {
Print(L"Error! Unable to allocate memory in MergeStrings()!\n");
// 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;
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()
+
+// Implement FreePool the way it should have been done to begin with, so that
+// it doesn't throw an ASSERT message if fed a NULL pointer....
+VOID MyFreePool(IN OUT VOID *Pointer) {
+ if (Pointer != NULL)
+ FreePool(Pointer);
+}
static EFI_GUID AppleRemovableMediaGuid = APPLE_REMOVABLE_MEDIA_PROTOCOL_GUID;
-// Eject all removable media
-VOID EjectMedia(VOID) {
+// Eject all removable media.
+// Returns TRUE if any media were ejected, FALSE otherwise.
+BOOLEAN EjectMedia(VOID) {
EFI_STATUS Status;
- UINTN HandleIndex, HandleCount = 0;
+ 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; // probably not an Apple system
+ return (FALSE); // probably not an Apple system
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
Handle = Handles[HandleIndex];
if (EFI_ERROR(Status))
continue;
Status = refit_call1_wrapper(Ejectable->Eject, Ejectable);
+ if (!EFI_ERROR(Status))
+ Ejected++;
}
- FreePool(Handles);
+ MyFreePool(Handles);
+ return (Ejected > 0);
} // VOID EjectMedia()
+