attributes in Discoverable Partition Specification code.
0.9.1 (?/??/2015):
------------------
+- When rEFInd identifies the root (/) partition via the Freedesktop.org
+ Discoverable Partitions Specification, it now checks two of the
+ partition's attributes, as per the DPS (see
+ http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/):
+ - The partition's read-only attribute determines whether to pass a "rw"
+ or "ro" option to the kernel.
+ - If the partition's do-not-automount flag is set, rEFInd will not pass
+ it as a "root=" option to the kernel. This flag can be used to remove
+ all but one partition from consideration as a root (/) partition if a
+ system has more than one with the correct type code.
+
- Improved Freedesktop.org Discoverable Partitions Specification support:
Previously, if no refind_linux.conf file was present but an /etc/fstab
file was found, rEFInd ignored the Discoverable Partitions Specification
// 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);
EFI_GUID VolUuid;
EFI_GUID PartGuid;
EFI_GUID PartTypeGuid;
+ BOOLEAN IsMarkedReadOnly;
UINTN VolNumber;
EG_IMAGE *VolIconImage;
EG_IMAGE *VolBadgeImage;
return Status;
} // EFI_STATUS ReadGptData()
-// // Look in gPartitions for a partition with the specified Guid. If found, return
-// // a pointer to that partition's name string. If not found, return a NULL pointer.
-// // The calling function is responsible for freeing the returned memory.
-// CHAR16 * PartNameFromGuid(EFI_GUID *Guid) {
-// UINTN i;
-// CHAR16 *Found = NULL;
-// GPT_DATA *GptData;
-//
-// if ((Guid == NULL) || (gPartitions == NULL))
-// return NULL;
-//
-// GptData = gPartitions;
-// while ((GptData != NULL) && (!Found)) {
-// i = 0;
-// while ((i < GptData->Header->entry_count) && (!Found)) {
-// if (GuidsAreEqual((EFI_GUID*) &(GptData->Entries[i].partition_guid), Guid))
-// Found = StrDuplicate(GptData->Entries[i].name);
-// else
-// i++;
-// } // while(scanning entries)
-// GptData = GptData->NextEntry;
-// } // while(scanning GPTs)
-// return Found;
-// } // CHAR16 * PartNameFromGuid()
-
// Look in gPartitions for a partition with the specified Guid. If found, return
// a pointer to that partition's data. If not found, return a NULL pointer.
// The calling function is responsible for freeing the returned memory.
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;
- } // 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,
#define IS_EXTENDED_PART_TYPE(type) ((type) == 0x05 || (type) == 0x0f || (type) == 0x85)
+// GPT attributes of interest to us for Freedesktop.org Discoverable
+// Partitions Specification....
+#define GPT_READ_ONLY 0x1000000000000000
+#define GPT_NO_AUTOMOUNT 0x8000000000000000
+
// Partition names to be ignored when setting volume name
#define IGNORE_PARTITION_NAMES L"Microsoft basic data,Linux filesystem,Apple HFS/HFS+"
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.0.4");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.0.5");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith");