X-Git-Url: https://code.delx.au/refind/blobdiff_plain/abc9e3f475669d8e7615ed6dbc1e901cb21384a8..f92a7032373fc63e9d8946574d4fb42464d1c916:/refind/config.c diff --git a/refind/config.c b/refind/config.c index 731adb7..4abd48b 100644 --- a/refind/config.c +++ b/refind/config.c @@ -267,6 +267,10 @@ UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList) Line = ReadLine(File); if (Line == NULL) return(0); + if (Line[0] == L'\0') { + MyFreePool(Line); + return(0); + } // if p = Line; LineFinished = FALSE; @@ -400,7 +404,7 @@ static BOOLEAN HandleBoolean(IN CHAR16 **TokenList, IN UINTN TokenCount) { static VOID SetDefaultByTime(IN CHAR16 **TokenList, OUT CHAR16 **Default) { EFI_STATUS Status; EFI_TIME CurrentTime; - UINTN StartTime = LAST_MINUTE + 1, EndTime = LAST_MINUTE + 1, Now; + UINTN StartTime, EndTime, Now; BOOLEAN SetIt = FALSE; StartTime = HandleTime(TokenList[2]); @@ -770,11 +774,13 @@ static VOID AddSubmenu(LOADER_ENTRY *Entry, REFIT_FILE *File, REFIT_VOLUME *Volu } else if ((StriCmp(TokenList[0], L"volume") == 0) && (TokenCount > 1)) { if (FindVolume(&Volume, TokenList[1])) { - MyFreePool(SubEntry->me.Title); - SubEntry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); - SPrint(SubEntry->me.Title, 255, L"Boot %s from %s", (Title != NULL) ? Title : L"Unknown", Volume->VolName); - SubEntry->me.BadgeImage = Volume->VolBadgeImage; - SubEntry->VolName = Volume->VolName; + if ((Volume != NULL) && (Volume->IsReadable) && (Volume->RootDir)) { + MyFreePool(SubEntry->me.Title); + SubEntry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(SubEntry->me.Title, 255, L"Boot %s from %s", (Title != NULL) ? Title : L"Unknown", Volume->VolName); + SubEntry->me.BadgeImage = Volume->VolBadgeImage; + SubEntry->VolName = Volume->VolName; + } // if volume is readable } // if match found } else if (StriCmp(TokenList[0], L"initrd") == 0) { @@ -851,11 +857,13 @@ static LOADER_ENTRY * AddStanzaEntries(REFIT_FILE *File, REFIT_VOLUME *Volume, C } else if ((StriCmp(TokenList[0], L"volume") == 0) && (TokenCount > 1)) { if (FindVolume(&CurrentVolume, TokenList[1])) { - MyFreePool(Entry->me.Title); - Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); - SPrint(Entry->me.Title, 255, L"Boot %s from %s", (Title != NULL) ? Title : L"Unknown", CurrentVolume->VolName); - Entry->me.BadgeImage = CurrentVolume->VolBadgeImage; - Entry->VolName = CurrentVolume->VolName; + if ((CurrentVolume != NULL) && (CurrentVolume->IsReadable) && (CurrentVolume->RootDir)) { + MyFreePool(Entry->me.Title); + Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(Entry->me.Title, 255, L"Boot %s from %s", (Title != NULL) ? Title : L"Unknown", CurrentVolume->VolName); + Entry->me.BadgeImage = CurrentVolume->VolBadgeImage; + Entry->VolName = CurrentVolume->VolName; + } // if volume is readable } // if match found } else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) { @@ -1010,6 +1018,44 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { return Options; } // GenerateOptionsFromEtcFstab() +// Create options from partition type codes. Specifically, if the earlier +// partition scan found a partition with a type code corresponding to a root +// filesystem according to the Freedesktop.org Discoverable Partitions Spec +// (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/), +// this function returns an appropriate file with two lines, one with +// "ro root=PARTUUID={GUID}" and the other with that plus "single". +// Note that this function returns the LAST partition found with the +// appropriate type code, so this will work poorly on dual-boot systems or +// if the type code is set incorrectly. +static REFIT_FILE * GenerateOptionsFromPartTypes(VOID) { + REFIT_FILE *Options = NULL; + CHAR16 *Line, *GuidString; + + if (GlobalConfig.DiscoveredRoot) { + Options = AllocateZeroPool(sizeof(REFIT_FILE)); + if (Options) { + Options->Encoding = ENCODING_UTF16_LE; + GuidString = GuidAsString(&(GlobalConfig.DiscoveredRoot->PartGuid)); + ToLower(GuidString); + if (GuidString) { + Line = PoolPrint(L"\"Boot with normal options\" \"ro root=/dev/disk/by-partuuid/%s\"\n", GuidString); + MergeStrings((CHAR16 **) &(Options->Buffer), Line, 0); + MyFreePool(Line); + Line = PoolPrint(L"\"Boot into single-user mode\" \"ro root=/dev/disk/by-partuuid/%s single\"\n", GuidString); + MergeStrings((CHAR16**) &(Options->Buffer), Line, 0); + MyFreePool(Line); + MyFreePool(GuidString); + } // if (GuidString) + Options->BufferSize = StrLen((CHAR16*) Options->Buffer) * sizeof(CHAR16); + + Options->Current8Ptr = (CHAR8 *)Options->Buffer; + Options->End8Ptr = Options->Current8Ptr + Options->BufferSize; + Options->Current16Ptr = (CHAR16 *)Options->Buffer; + Options->End16Ptr = Options->Current16Ptr + (Options->BufferSize >> 1); + } // if (Options allocated OK) + } // if (partition has root GUID) + return Options; +} // REFIT_FILE * GenerateOptionsFromPartTypes() // Read a Linux kernel options file for a Linux boot loader into memory. The LoaderPath // and Volume variables identify the location of the options file, but not its name -- @@ -1054,12 +1100,17 @@ REFIT_FILE * ReadLinuxOptionsFile(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume } else { // a filename string is NULL GoOn = FALSE; } // if/else - if (!FileFound) - File = GenerateOptionsFromEtcFstab(Volume); MyFreePool(OptionsFilename); MyFreePool(FullFilename); OptionsFilename = FullFilename = NULL; } while (GoOn); + if (!FileFound) { + // No refind_linux.conf file; look for /etc/fstab and try to pull values from there.... + File = GenerateOptionsFromEtcFstab(Volume); + // If still no joy, try to use Freedesktop.org Discoverable Partitions Spec.... + if (!File) + File = GenerateOptionsFromPartTypes(); + } // if return (File); } // static REFIT_FILE * ReadLinuxOptionsFile()