bug#31994: Support for WinRe partition

Hans-Joachim Baader <[email protected]>
Newsgroups gmane.comp.gnu.parted.bugs
Message-ID <[email protected]>
Hello maintainers,

finally I found the time to complete a patch. If I have to sign a copyright assignment it will
take some more time.

I have amended the documentation and ran the tests. The existing tests covered the flag
already so I didn't write a new test.

Also I had to patch libparted/unit.c to make it compile (Debian 9, GCC 6.3):

diff --git a/libparted/unit.c b/libparted/unit.c
index e47e868..84ba8c4 100644
--- a/libparted/unit.c
+++ b/libparted/unit.c
@@ -151,6 +151,7 @@ ped_unit_get_size (const PedDevice* dev, PedUnit unit)
  *
  * For example, the textual representation of PED_UNIT_SECTOR is "s".
  */
+__attribute__ ((const))
 const char*
 ped_unit_get_name (PedUnit unit)
 {


Here's the patch.

Best regards,
Hans-Joachim Baader


From e20005b1889a51b479c62a176a3e75f5af30d696 Mon Sep 17 00:00:00 2001
From: Hans-Joachim Baader <[email protected]>
Date: Mon, 14 Jan 2019 16:01:07 +0100
Subject: [PATCH] Added support for Windows recovery partition (WINRE) on MBR

Windows 10 uses a recovery partition which is sometimes marked with
partition type 0x27 on MBR systems. It wasn't possible to handle such
a partition with parted. Therefore the partition type PARTITION_MSFT_RECOVERY
is now used properly also on MBR when the flag msftres is set.
---
 doc/C/parted.8         |  2 +-
 doc/parted.texi        |  4 ++--
 libparted/labels/dos.c | 40 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/doc/C/parted.8 b/doc/C/parted.8
index fecdc29..15932c2 100644
--- a/doc/C/parted.8
+++ b/doc/C/parted.8
@@ -112,7 +112,7 @@ or an LVM logical volume if necessary.
 .B set \fIpartition\fP \fIflag\fP \fIstate\fP
 Change the state of the \fIflag\fP on \fIpartition\fP to \fIstate\fP.
 Supported flags are: "boot", "root", "swap", "hidden", "raid", "lvm", "lba",
-"legacy_boot", "irst", "esp" and "palo".
+"legacy_boot", "irst", "msftres", "esp" and "palo".
 \fIstate\fP should be either "on" or "off".
 .TP
 .B unit \fIunit\fP
diff --git a/doc/parted.texi b/doc/parted.texi
index c08cdc7..98dc162 100644
--- a/doc/parted.texi
+++ b/doc/parted.texi
@@ -861,8 +861,8 @@ flag can only be removed within parted by replacing it with a competing
 flag, such as boot or msftres.
 
 @item msftres
-(GPT) - This flag identifies a "Microsoft Reserved" partition, which is
-used by Windows on GPT disks.  Note that this flag should not normally be
+(MS-DOS,GPT) - This flag identifies a "Microsoft Reserved" partition, which
+is used by Windows.  Note that this flag should not normally be
 set on Windows filesystem partitions (those that contain NTFS or FAT
 filesystems).
 
diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
index b2b8de9..d736b9e 100644
--- a/libparted/labels/dos.c
+++ b/libparted/labels/dos.c
@@ -156,6 +156,7 @@ typedef struct {
 	unsigned char	system;
 	int		boot;
 	int		hidden;
+	int		msftres;
 	int		raid;
 	int		lvm;
 	int		lba;
@@ -949,8 +950,8 @@ raw_part_parse (const PedDisk* disk, const DosRawPartition* raw_part,
 	dos_data->system = raw_part->type;
 	dos_data->boot = raw_part->boot_ind != 0;
 	dos_data->diag = raw_part->type == PARTITION_COMPAQ_DIAG ||
-			 raw_part->type == PARTITION_MSFT_RECOVERY ||
 			 raw_part->type == PARTITION_DELL_DIAG;
+	dos_data->msftres = raw_part->type == PARTITION_MSFT_RECOVERY;
 	dos_data->hidden = raw_part_is_hidden (raw_part);
 	dos_data->raid = raw_part->type == PARTITION_LINUX_RAID;
 	dos_data->lvm = raw_part->type == PARTITION_LINUX_LVM_OLD
@@ -1345,6 +1346,7 @@ msdos_partition_new (const PedDisk* disk, PedPartitionType part_type,
 		dos_data->orig = NULL;
 		dos_data->system = PARTITION_LINUX;
 		dos_data->hidden = 0;
+		dos_data->msftres = 0;
 		dos_data->boot = 0;
 		dos_data->diag = 0;
 		dos_data->raid = 0;
@@ -1384,6 +1386,7 @@ msdos_partition_duplicate (const PedPartition* part)
 	new_dos_data->boot = old_dos_data->boot;
 	new_dos_data->diag = old_dos_data->diag;
 	new_dos_data->hidden = old_dos_data->hidden;
+	new_dos_data->msftres = old_dos_data->msftres;
 	new_dos_data->raid = old_dos_data->raid;
 	new_dos_data->lvm = old_dos_data->lvm;
 	new_dos_data->lba = old_dos_data->lba;
@@ -1433,6 +1436,11 @@ msdos_partition_set_system (PedPartition* part,
 		    && strcmp (fs_type->name, "ntfs") != 0)
 		dos_data->hidden = 0;
 
+	if (dos_data->msftres
+		    && fs_type
+		    && strcmp (fs_type->name, "ntfs") != 0)
+		dos_data->msftres = 0;
+
 	if (part->type & PED_PARTITION_EXTENDED) {
 		dos_data->diag = 0;
 		dos_data->raid = 0;
@@ -1452,11 +1460,14 @@ msdos_partition_set_system (PedPartition* part,
 		/* Don't change the system if it already is a diag type,
 		   otherwise use Compaq as almost all vendors use that. */
 		if (dos_data->system != PARTITION_COMPAQ_DIAG &&
-		    dos_data->system != PARTITION_MSFT_RECOVERY &&
 		    dos_data->system != PARTITION_DELL_DIAG)
 			dos_data->system = PARTITION_COMPAQ_DIAG;
 		return 1;
 	}
+	if (dos_data->msftres) {
+		dos_data->system = PARTITION_MSFT_RECOVERY;
+		return 1;
+	}
 	if (dos_data->lvm) {
 		dos_data->system = PARTITION_LINUX_LVM;
 		return 1;
@@ -1516,6 +1527,7 @@ clear_flags (DosPartitionData *dos_data)
 {
   dos_data->diag = 0;
   dos_data->hidden = 0;
+  dos_data->msftres = 0;
   dos_data->lvm = 0;
   dos_data->palo = 0;
   dos_data->prep = 0;
@@ -1552,6 +1564,18 @@ msdos_partition_set_flag (PedPartition* part,
 		dos_data->hidden = state;
 		return ped_partition_set_system (part, part->fs_type);
 
+	case PED_PARTITION_MSFT_RESERVED:
+		if (part->type == PED_PARTITION_EXTENDED) {
+			ped_exception_throw (
+				PED_EXCEPTION_ERROR,
+				PED_EXCEPTION_CANCEL,
+				_("Extended partitions cannot be recovery partitions on "
+				  "msdos disk labels."));
+			return 0;
+		}
+		dos_data->msftres = state;
+		return ped_partition_set_system (part, part->fs_type);
+
 	case PED_PARTITION_BOOT:
 		dos_data->boot = state;
 		if (!state)
@@ -1632,6 +1656,12 @@ msdos_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
 		else
 			return dos_data->hidden;
 
+	case PED_PARTITION_MSFT_RESERVED:
+		if (part->type == PED_PARTITION_EXTENDED)
+			return 0;
+		else
+			return dos_data->msftres;
+
 	case PED_PARTITION_BOOT:
 		return dos_data->boot;
 
@@ -1675,6 +1705,12 @@ msdos_partition_is_flag_available (const PedPartition* part,
 		else
 			return 1;
 
+	case PED_PARTITION_MSFT_RESERVED:
+		if (part->type == PED_PARTITION_EXTENDED)
+			return 0;
+		else
+			return 1;
+
 	case PED_PARTITION_BOOT:
 	case PED_PARTITION_RAID:
 	case PED_PARTITION_LVM:
-- 
2.11.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.