X-Git-Url: https://code.delx.au/refind/blobdiff_plain/224ffad523048df8ad5f14038de21b7afe6a3b6a..2cc79ea9b33424d5fc32f15683adf7c956656b9b:/refind/lib.c diff --git a/refind/lib.c b/refind/lib.c index 0c4089f..1a7bb81 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -265,6 +265,43 @@ static EFI_STATUS FinishInitRefitLib(VOID) return EFI_SUCCESS; } +// +// EFI variable read and write functions +// + +// From gummiboot: Retrieve a raw EFI variable. +// Returns EFI status +EFI_STATUS EfivarGetRaw(EFI_GUID *vendor, CHAR16 *name, CHAR8 **buffer, UINTN *size) { + CHAR8 *buf; + UINTN l; + EFI_STATUS err; + + l = sizeof(CHAR16 *) * EFI_MAXIMUM_VARIABLE_SIZE; + buf = AllocatePool(l); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + err = refit_call5_wrapper(RT->GetVariable, name, vendor, NULL, &l, buf); + if (EFI_ERROR(err) == EFI_SUCCESS) { + *buffer = buf; + if (size) + *size = l; + } else + MyFreePool(buf); + return err; +} // EFI_STATUS EfivarGetRaw() + +// From gummiboot: Set an EFI variable +EFI_STATUS EfivarSetRaw(EFI_GUID *vendor, CHAR16 *name, CHAR8 *buf, UINTN size, BOOLEAN persistent) { + UINT32 flags; + + flags = EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS; + if (persistent) + flags |= EFI_VARIABLE_NON_VOLATILE; + + return refit_call5_wrapper(RT->SetVariable, name, vendor, flags, size, buf); +} // EFI_STATUS EfivarSetRaw() + // // list functions // @@ -676,6 +713,9 @@ VOID SetVolumeBadgeIcon(REFIT_VOLUME *Volume) case DISK_KIND_OPTICAL: Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_OPTICAL); break; + case DISK_KIND_NET: + Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_NET); + break; } // switch() } } // VOID SetVolumeBadgeIcon() @@ -714,42 +754,45 @@ static CHAR16 *SizeInIEEEUnits(UINT64 SizeInBytes) { // The calling function is responsible for freeing the memory allocated // for the name string. static CHAR16 *GetVolumeName(REFIT_VOLUME *Volume) { - EFI_FILE_SYSTEM_INFO *FileSystemInfoPtr; + EFI_FILE_SYSTEM_INFO *FileSystemInfoPtr = NULL; CHAR16 *FoundName = NULL; CHAR16 *SISize, *TypeName; - FileSystemInfoPtr = LibFileSystemInfo(Volume->RootDir); - if (FileSystemInfoPtr != NULL) { // we have filesystem information (size, label).... - if ((FileSystemInfoPtr->VolumeLabel != NULL) && (StrLen(FileSystemInfoPtr->VolumeLabel) > 0)) { - FoundName = StrDuplicate(FileSystemInfoPtr->VolumeLabel); - } - - // Special case: Old versions of the rEFInd HFS+ driver always returns label of "HFS+ volume", so wipe - // this so that we can build a new name that includes the size.... - if ((FoundName != NULL) && (StrCmp(FoundName, L"HFS+ volume") == 0) && (Volume->FSType == FS_TYPE_HFSPLUS)) { - MyFreePool(FoundName); - FoundName = NULL; - } // if rEFInd HFS+ driver suspected - - // If no filesystem name, try to use the partition name.... - if ((FoundName == NULL) && (Volume->PartName != NULL) && (StrLen(Volume->PartName) > 0) && - !IsIn(Volume->PartName, IGNORE_PARTITION_NAMES)) { - FoundName = StrDuplicate(Volume->PartName); - } // if use partition name - - // No filesystem or acceptable partition name, so use fs type and size - if (FoundName == NULL) { - FoundName = AllocateZeroPool(sizeof(CHAR16) * 256); - if (FoundName != NULL) { - SISize = SizeInIEEEUnits(FileSystemInfoPtr->VolumeSize); - SPrint(FoundName, 255, L"%s%s volume", SISize, FSTypeName(Volume->FSType)); - MyFreePool(SISize); - } // if allocated memory OK - } // if (FoundName == NULL) - - FreePool(FileSystemInfoPtr); - - } else { // fs driver not returning info; fall back on our own information.... + if (Volume->RootDir != NULL) { + FileSystemInfoPtr = LibFileSystemInfo(Volume->RootDir); + } + + if ((FileSystemInfoPtr != NULL) && (FileSystemInfoPtr->VolumeLabel != NULL) && + (StrLen(FileSystemInfoPtr->VolumeLabel) > 0)) { + FoundName = StrDuplicate(FileSystemInfoPtr->VolumeLabel); + } + + // Special case: Old versions of the rEFInd HFS+ driver always returns label of "HFS+ volume", so wipe + // this so that we can build a new name that includes the size.... + if ((FoundName != NULL) && (StrCmp(FoundName, L"HFS+ volume") == 0) && (Volume->FSType == FS_TYPE_HFSPLUS)) { + MyFreePool(FoundName); + FoundName = NULL; + } // if rEFInd HFS+ driver suspected + + // If no filesystem name, try to use the partition name.... + if ((FoundName == NULL) && (Volume->PartName != NULL) && (StrLen(Volume->PartName) > 0) && + !IsIn(Volume->PartName, IGNORE_PARTITION_NAMES)) { + FoundName = StrDuplicate(Volume->PartName); + } // if use partition name + + // No filesystem or acceptable partition name, so use fs type and size + if ((FoundName == NULL) && (FileSystemInfoPtr != NULL)) { + FoundName = AllocateZeroPool(sizeof(CHAR16) * 256); + if (FoundName != NULL) { + SISize = SizeInIEEEUnits(FileSystemInfoPtr->VolumeSize); + SPrint(FoundName, 255, L"%s%s volume", SISize, FSTypeName(Volume->FSType)); + MyFreePool(SISize); + } // if allocated memory OK + } // if (FoundName == NULL) + + MyFreePool(FileSystemInfoPtr); + + if (FoundName == NULL) { FoundName = AllocateZeroPool(sizeof(CHAR16) * 256); if (FoundName != NULL) { TypeName = FSTypeName(Volume->FSType); // NOTE: Don't free TypeName; function returns constant @@ -762,7 +805,6 @@ static CHAR16 *GetVolumeName(REFIT_VOLUME *Volume) { // TODO: Above could be improved/extended, in case filesystem name is not found, // such as: - // - use partition label // - use or add disk/partition number (e.g., "(hd0,2)") // Desperate fallback name.... @@ -905,6 +947,8 @@ VOID ScanVolume(REFIT_VOLUME *Volume) // Set volume icon based on .VolumeBadge icon or disk kind SetVolumeBadgeIcon(Volume); + Volume->VolName = GetVolumeName(Volume); + if (Volume->RootDir == NULL) { Volume->IsReadable = FALSE; return; @@ -912,8 +956,6 @@ VOID ScanVolume(REFIT_VOLUME *Volume) Volume->IsReadable = TRUE; } - Volume->VolName = GetVolumeName(Volume); - // get custom volume icons if present if (!Volume->VolIconImage) Volume->VolIconImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeIcon", GlobalConfig.IconSizes[ICON_SIZE_BIG]); @@ -1061,8 +1103,9 @@ VOID ScanVolumes(VOID) Volume->BlockIO != Volume->WholeDiskBlockIO) { for (VolumeIndex2 = 0; VolumeIndex2 < VolumesCount; VolumeIndex2++) { if (Volumes[VolumeIndex2]->BlockIO == Volume->WholeDiskBlockIO && - Volumes[VolumeIndex2]->BlockIOOffset == 0) + Volumes[VolumeIndex2]->BlockIOOffset == 0) { WholeDiskVolume = Volumes[VolumeIndex2]; + } } } @@ -1862,9 +1905,26 @@ BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) { Found = TRUE; } // while } // if - return Found; + return Found; } // BOOLEAN IsIn() +// Returns TRUE if any element of List can be found as a substring of +// BigString, FALSE otherwise. Performs comparisons case-insensitively. +BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List) { + UINTN i = 0, ElementLength; + BOOLEAN Found = FALSE; + CHAR16 *OneElement; + + if (BigString && List) { + while (!Found && (OneElement = FindCommaDelimited(List, i++))) { + ElementLength = StrLen(OneElement); + if ((ElementLength <= StrLen(BigString)) && (StriSubCmp(OneElement, BigString))) + Found = TRUE; + } // while + } // if + return Found; +} // BOOLEAN IsSubstringIn() + // Returns TRUE if specified Volume, Directory, and Filename correspond to an // 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 @@ -2007,11 +2067,12 @@ BOOLEAN IsGuid(CHAR16 *UnknownString) { for (i = 0; i < Length; i++) { a = UnknownString[i]; - if (((i == 8) || (i == 13) || (i == 18) || (i == 23)) && (a != '-')) { - retval = FALSE; + if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { + if (a != '-') + retval = FALSE; } else if (((a < 'a') || (a > 'f')) && ((a < 'A') || (a > 'F')) && ((a < '0') && (a > '9'))) { retval = FALSE; - } // if/else + } // if/else if } // for return retval; } // BOOLEAN IsGuid()