X-Git-Url: https://code.delx.au/refind/blobdiff_plain/4cbcc9d19f8bfa11a4bc396645c5689d4c6f9482..480ba418c97ece5557ac0efc5dc189ff19fb8b8f:/refind/config.c diff --git a/refind/config.c b/refind/config.c index 6227c67..8aa2850 100644 --- a/refind/config.c +++ b/refind/config.c @@ -38,10 +38,23 @@ * Modifications copyright (c) 2012-2015 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public - * License (GPL) version 3 (GPLv3), a copy of which must be distributed - * with this source code or binaries made from it. + * License (GPL) version 3 (GPLv3) or (at your option) any later version. * */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ #include "global.h" #include "lib.h" @@ -49,6 +62,8 @@ #include "menu.h" #include "config.h" #include "screen.h" +#include "apple.h" +#include "mystrings.h" #include "../include/refit_call_wrapper.h" #include "../mok/mok.h" @@ -364,6 +379,48 @@ static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 } // for } // static VOID HandleStrings() +// Handle a parameter with a series of hexadecimal arguments, to replace or be added to a +// linked list of UINT32 values. Any item with a non-hexadecimal value is discarded, as is +// any value that exceeds MaxValue. If the first non-keyword token is "+", the new list is +// added to the existing Target; otherwise, the interpreted tokens replace the current +// Target. +static VOID HandleHexes(IN CHAR16 **TokenList, IN UINTN TokenCount, IN UINTN MaxValue, OUT UINT32_LIST **Target) { + UINTN InputIndex = 1, i; + UINT32 Value; + UINT32_LIST *EndOfList = NULL; + UINT32_LIST *NewEntry; + + if ((TokenCount > 2) && (StrCmp(TokenList[1], L"+") == 0)) { + InputIndex = 2; + EndOfList = *Target; + while (EndOfList && (EndOfList->Next != NULL)) { + EndOfList = EndOfList->Next; + } + } else { + EraseUint32List(Target); + } + + for (i = InputIndex; i < TokenCount; i++) { + if (IsValidHex(TokenList[i])) { + Value = (UINT32) StrToHex(TokenList[i], 0, 8); + if (Value <= MaxValue) { + NewEntry = AllocatePool(sizeof(UINT32_LIST)); + if (NewEntry) { + NewEntry->Value = Value; + NewEntry->Next = NULL; + if (EndOfList == NULL) { + EndOfList = NewEntry; + *Target = NewEntry; + } else { + EndOfList->Next = NewEntry; + EndOfList = NewEntry; + } // if/else + } // if allocated memory for NewEntry + } // if (Value < MaxValue) + } // if is valid hex value + } // for +} // static VOID HandleHexes() + // Convert TimeString (in "HH:MM" format) to a pure-minute format. Values should be // in the range from 0 (for 00:00, or midnight) to 1439 (for 23:59; aka LAST_MINUTE). // Any value outside that range denotes an error in the specification. Note that if @@ -592,6 +649,8 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.ShowTools[i - 1] = TAG_WINDOWS_RECOVERY; } else if (MyStriCmp(FlagName, L"mok_tool")) { GlobalConfig.ShowTools[i - 1] = TAG_MOK_TOOL; + } else if (MyStriCmp(FlagName, L"csr_rotate")) { + GlobalConfig.ShowTools[i - 1] = TAG_CSR_ROTATE; } else if (MyStriCmp(FlagName, L"firmware")) { GlobalConfig.ShowTools[i - 1] = TAG_FIRMWARE; } else if (MyStriCmp(FlagName, L"memtest86") || MyStriCmp(FlagName, L"memtest")) { @@ -685,8 +744,14 @@ VOID ReadConfig(CHAR16 *FileName) } else if (MyStriCmp(TokenList[0], L"max_tags")) { HandleInt(TokenList, TokenCount, &(GlobalConfig.MaxTags)); - } else if (MyStriCmp(TokenList[0], L"enable_and_lock_vmx")) { - GlobalConfig.EnableAndLockVMX = HandleBoolean(TokenList, TokenCount); + } else if (MyStriCmp(TokenList[0], L"enable_and_lock_vmx")) { + GlobalConfig.EnableAndLockVMX = HandleBoolean(TokenList, TokenCount); + + } else if (MyStriCmp(TokenList[0], L"spoof_osx_version")) { + HandleString(TokenList, TokenCount, &(GlobalConfig.SpoofOSXVersion)); + + } else if (MyStriCmp(TokenList[0], L"csr_values")) { + HandleHexes(TokenList, TokenCount, CSR_MAX_LEGAL_VALUE, &(GlobalConfig.CsrValues)); } else if (MyStriCmp(TokenList[0], L"include") && (TokenCount == 2) && MyStriCmp(FileName, GlobalConfig.ConfigFilename)) { if (!MyStriCmp(TokenList[1], FileName)) { @@ -1029,25 +1094,26 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { // 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". +// "ro root=/dev/disk/by-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; + CHAR16 *Line, *GuidString, *WriteStatus; if (GlobalConfig.DiscoveredRoot) { Options = AllocateZeroPool(sizeof(REFIT_FILE)); if (Options) { Options->Encoding = ENCODING_UTF16_LE; GuidString = GuidAsString(&(GlobalConfig.DiscoveredRoot->PartGuid)); + WriteStatus = GlobalConfig.DiscoveredRoot->IsMarkedReadOnly ? L"ro" : L"rw"; ToLower(GuidString); if (GuidString) { - Line = PoolPrint(L"\"Boot with normal options\" \"ro root=/dev/disk/by-partuuid/%s\"\n", GuidString); + Line = PoolPrint(L"\"Boot with normal options\" \"%s root=/dev/disk/by-partuuid/%s\"\n", WriteStatus, 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); + Line = PoolPrint(L"\"Boot into single-user mode\" \"%s root=/dev/disk/by-partuuid/%s single\"\n", WriteStatus, GuidString); MergeStrings((CHAR16**) &(Options->Buffer), Line, 0); MyFreePool(Line); MyFreePool(GuidString);