// find the current directory
DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath);
+ GlobalConfig.SelfDevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, DevicePathAsString);
CleanUpPathNameSlashes(DevicePathAsString);
MyFreePool(SelfDirPath);
Temp = FindPath(DevicePathAsString);
}
} // VOID FreeList()
-//
-// firmware device path discovery
-//
-
-static UINT8 LegacyLoaderMediaPathData[] = {
- 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
- 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
- 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
-};
-static EFI_DEVICE_PATH *LegacyLoaderMediaPath = (EFI_DEVICE_PATH *)LegacyLoaderMediaPathData;
-
-VOID ExtractLegacyLoaderPaths(EFI_DEVICE_PATH **PathList, UINTN MaxPaths, EFI_DEVICE_PATH **HardcodedPathList)
-{
- EFI_STATUS Status;
- UINTN HandleCount = 0;
- UINTN HandleIndex, HardcodedIndex;
- EFI_HANDLE *Handles;
- EFI_HANDLE Handle;
- UINTN PathCount = 0;
- UINTN PathIndex;
- EFI_LOADED_IMAGE *LoadedImage;
- EFI_DEVICE_PATH *DevicePath;
- BOOLEAN Seen;
-
- MaxPaths--; // leave space for the terminating NULL pointer
-
- // get all LoadedImage 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++] = HardcodedPathList[HardcodedIndex];
- }
- PathList[PathCount] = NULL;
- return;
- }
- for (HandleIndex = 0; HandleIndex < HandleCount && PathCount < MaxPaths; HandleIndex++) {
- Handle = Handles[HandleIndex];
-
- Status = refit_call3_wrapper(BS->HandleProtocol, Handle, &LoadedImageProtocol, (VOID **) &LoadedImage);
- if (EFI_ERROR(Status))
- continue; // This can only happen if the firmware scewed up, ignore it.
-
- Status = refit_call3_wrapper(BS->HandleProtocol, LoadedImage->DeviceHandle, &DevicePathProtocol, (VOID **) &DevicePath);
- if (EFI_ERROR(Status))
- continue; // This happens, ignore it.
-
- // Only grab memory range nodes
- if (DevicePathType(DevicePath) != HARDWARE_DEVICE_PATH || DevicePathSubType(DevicePath) != HW_MEMMAP_DP)
- continue;
-
- // Check if we have this device path in the list already
- // WARNING: This assumes the first node in the device path is unique!
- Seen = FALSE;
- for (PathIndex = 0; PathIndex < PathCount; PathIndex++) {
- if (DevicePathNodeLength(DevicePath) != DevicePathNodeLength(PathList[PathIndex]))
- continue;
- if (CompareMem(DevicePath, PathList[PathIndex], DevicePathNodeLength(DevicePath)) == 0) {
- Seen = TRUE;
- break;
- }
- }
- if (Seen)
- continue;
-
- PathList[PathCount++] = AppendDevicePath(DevicePath, LegacyLoaderMediaPath);
- }
- MyFreePool(Handles);
-
- if (HardcodedPathList) {
- for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++)
- PathList[PathCount++] = HardcodedPathList[HardcodedIndex];
- }
- PathList[PathCount] = NULL;
-}
-
//
// volume functions
//
HARDDRIVE_DEVICE_PATH *HdDevicePath;
GPT_ENTRY *PartInfo;
- if ((Volume == NULL) || (DevicePath == NULL))
- return;
+ if ((Volume == NULL) || (DevicePath == NULL))
+ return;
- if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
- HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath;
- if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
- Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature);
- PartInfo = FindPartWithGuid(&(Volume->PartGuid));
- if (PartInfo) {
- Volume->PartName = StrDuplicate(PartInfo->name);
- CopyMem(&(Volume->PartTypeGuid), PartInfo->type_guid, sizeof(EFI_GUID));
- if (GuidsAreEqual (&(Volume->PartTypeGuid), &gFreedesktopRootGuid)) {
- GlobalConfig.DiscoveredRoot = Volume;
- Print(L"Found match!\n");
- PauseForKey();
- } // if (GUIDs match)
- } // if (PartInfo exists)
- } // if (GPT disk)
- } // if (disk device)
+ if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
+ HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath;
+ if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
+ Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature);
+ PartInfo = FindPartWithGuid(&(Volume->PartGuid));
+ if (PartInfo) {
+ Volume->PartName = StrDuplicate(PartInfo->name);
+ CopyMem(&(Volume->PartTypeGuid), PartInfo->type_guid, sizeof(EFI_GUID));
+ if (GuidsAreEqual(&(Volume->PartTypeGuid), &gFreedesktopRootGuid) &&
+ ((PartInfo->attributes & GPT_NO_AUTOMOUNT) == 0)) {
+ GlobalConfig.DiscoveredRoot = Volume;
+ } // if (GUIDs match && automounting OK)
+ Volume->IsMarkedReadOnly = ((PartInfo->attributes & GPT_READ_ONLY) > 0);
+ } // if (PartInfo exists)
+ } // if (GPT disk)
+ } // if (disk device)
} // VOID SetPartGuid()
// Return TRUE if NTFS boot files are found or if Volume is unreadable,
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,
if ((FileName != NULL) && ((Copy = StrDuplicate(FileName)) != NULL)) {
Length = StrLen(Copy);
- // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
- if ((Length >= 4) && ((StriCmp(&Copy[Length - 4], L".efi") == 0) || (StriCmp(&Copy[Length - 4], L".EFI") == 0))) {
+ if ((Length >= 4) && MyStriCmp(&Copy[Length - 4], L".efi")) {
Copy[Length - 4] = 0;
} // if
} // if
return -1;
}
-// Performs a case-insensitive search of BigStr for SmallStr.
-// Returns TRUE if found, FALSE if not.
BOOLEAN StriSubCmp(IN CHAR16 *SmallStr, IN CHAR16 *BigStr) {
- CHAR16 *SmallCopy, *BigCopy;
- BOOLEAN Found = FALSE;
- UINTN StartPoint = 0, NumCompares = 0, SmallLen = 0;
-
- if ((SmallStr != NULL) && (BigStr != NULL) && (StrLen(BigStr) >= StrLen(SmallStr))) {
- SmallCopy = StrDuplicate(SmallStr);
- BigCopy = StrDuplicate(BigStr);
- StrLwr(SmallCopy);
- StrLwr(BigCopy);
- SmallLen = StrLen(SmallCopy);
- NumCompares = StrLen(BigCopy) - SmallLen + 1;
- while ((!Found) && (StartPoint < NumCompares)) {
- Found = (StrnCmp(SmallCopy, &BigCopy[StartPoint++], SmallLen) == 0);
- } // while
- MyFreePool(SmallCopy);
- MyFreePool(BigCopy);
- } // if
+ BOOLEAN Found = 0, Terminate = 0;
+ UINTN BigIndex = 0, SmallIndex = 0, BigStart = 0;
- return (Found);
+ if (SmallStr && BigStr) {
+ while (!Terminate) {
+ if (BigStr[BigIndex] == '\0') {
+ Terminate = 1;
+ }
+ if (SmallStr[SmallIndex] == '\0') {
+ Found = 1;
+ Terminate = 1;
+ }
+ if ((SmallStr[SmallIndex] & ~0x20) == (BigStr[BigIndex] & ~0x20)) {
+ SmallIndex++;
+ BigIndex++;
+ } else {
+ SmallIndex = 0;
+ BigStart++;
+ BigIndex = BigStart;
+ }
+ } // while
+ } // if
+ return Found;
} // BOOLEAN StriSubCmp()
+// Performs a case-insensitive string comparison. This function is necesary
+// because some EFIs have buggy StriCmp() functions that actually perform
+// case-sensitive comparisons.
+// Returns TRUE if strings are identical, FALSE otherwise.
+BOOLEAN MyStriCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString) {
+ if (FirstString && SecondString) {
+ while ((*FirstString != L'\0') && ((*FirstString & ~0x20) == (*SecondString & ~0x20))) {
+ FirstString++;
+ SecondString++;
+ }
+ return (*FirstString == *SecondString);
+ } else {
+ return FALSE;
+ }
+} // BOOLEAN MyStriCmp()
+
// Convert input string to all-lowercase.
+// DO NOT USE the standard StrLwr() function, since it's broken on some EFIs!
VOID ToLower(CHAR16 * MyString) {
UINTN i = 0;
Length2 = StrLen(Second);
NewString = AllocatePool(sizeof(CHAR16) * (Length1 + Length2 + 2));
if (NewString != NULL) {
- if ((*First != NULL) && (StrLen(*First) == 0)) {
+ if ((*First != NULL) && (Length1 == 0)) {
MyFreePool(*First);
*First = NULL;
}
} else {
Print(L"Error! Unable to allocate memory in MergeStrings()!\n");
} // if/else
-} // static CHAR16* MergeStrings()
+} // VOID MergeStrings()
+
+// Similar to MergeStrings, but breaks the input string into word chunks and
+// merges each word separately. Words are defined as string fragments separated
+// by ' ', '_', or '-'.
+VOID MergeWords(CHAR16 **MergeTo, CHAR16 *SourceString, CHAR16 AddChar) {
+ CHAR16 *Temp, *Word, *p;
+ BOOLEAN LineFinished = FALSE;
+
+ if (SourceString) {
+ Temp = Word = p = StrDuplicate(SourceString);
+ if (Temp) {
+ while (!LineFinished) {
+ if ((*p == L' ') || (*p == L'_') || (*p == L'-') || (*p == L'\0')) {
+ if (*p == L'\0')
+ LineFinished = TRUE;
+ *p = L'\0';
+ if (*Word != L'\0')
+ MergeStrings(MergeTo, Word, AddChar);
+ Word = p + 1;
+ } // if
+ p++;
+ } // while
+ MyFreePool(Temp);
+ } else {
+ Print(L"Error! Unable to allocate memory in MergeWords()!\n");
+ } // if/else
+ } // if
+} // VOID MergeWords()
// Takes an input pathname (*Path) and returns the part of the filename from
// the final dot onwards, converted to lowercase. If the filename includes
} // while
if (Found) {
MergeStrings(&Extension, &Path[i], 0);
- StrLwr(Extension);
+ ToLower(Extension);
} // if (Found)
} // if
return (Extension);
while ((i < VolumesCount) && (!Found)) {
VolumeDeviceString = DevicePathToStr(Volumes[i]->DevicePath);
Temp = SplitDeviceString(VolumeDeviceString);
- if (StriCmp(DeviceString, VolumeDeviceString) == 0) {
+ if (MyStriCmp(DeviceString, VolumeDeviceString)) {
Found = TRUE;
*DeviceVolume = Volumes[i];
}
} // VOID SplitPathName
// 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).
+// FALSE otherwise. Performs comparison case-insensitively.
BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) {
UINTN i = 0;
BOOLEAN Found = FALSE;
if (SmallString && List) {
while (!Found && (OneElement = FindCommaDelimited(List, i++))) {
- if (StriCmp(OneElement, SmallString) == 0)
+ if (MyStriCmp(OneElement, SmallString))
Found = TRUE;
} // while
} // if
// element in the comma-delimited List, FALSE otherwise. Note that Directory and
// Filename must *NOT* include a volume or path specification (that's part of
// the Volume variable), but the List elements may. Performs comparison
-// case-insensitively (except on buggy EFIs with case-sensitive StriCmp()
-// functions).
+// case-insensitively.
BOOLEAN FilenameIn(REFIT_VOLUME *Volume, CHAR16 *Directory, CHAR16 *Filename, CHAR16 *List) {
UINTN i = 0;
BOOLEAN Found = FALSE;
Found = TRUE;
SplitPathName(OneElement, &TargetVolName, &TargetPath, &TargetFilename);
VolumeNumberToName(Volume, &TargetVolName);
- if (((TargetVolName != NULL) && ((Volume == NULL) || (StriCmp(TargetVolName, Volume->VolName) != 0))) ||
- ((TargetPath != NULL) && (StriCmp(TargetPath, Directory) != 0)) ||
- ((TargetFilename != NULL) && (StriCmp(TargetFilename, Filename) != 0))) {
+ if (((TargetVolName != NULL) && ((Volume == NULL) || (!MyStriCmp(TargetVolName, Volume->VolName)))) ||
+ ((TargetPath != NULL) && (!MyStriCmp(TargetPath, Directory))) ||
+ ((TargetFilename != NULL) && (!MyStriCmp(TargetFilename, Filename)))) {
Found = FALSE;
} // if
MyFreePool(OneElement);