diff --git a/README b/README
index 1c41500a..3b21d16a 100644
--- a/README
+++ b/README
@@ -129,12 +129,12 @@ Optional packages include:
btrfs-tools
e2fsprogs
dosfstools
- mtools - required to read and write FAT16/32 volume labels
+ mtools - required to read and write FAT16/32 volume labels and UUIDs
hfsutils
hfsprogs
jfsutils
nilfs-utils
- ntfsprogs
+ ntfsprogs / ntfs-3g
reiser4progs
reiserfsprogs
xfsprogs, xfsdump
diff --git a/help/C/gparted.xml b/help/C/gparted.xml
index ffc88fd8..1ed67dec 100644
--- a/help/C/gparted.xml
+++ b/help/C/gparted.xml
@@ -268,7 +268,7 @@
On startup, &app; will scan your
computer for disk devices.
-
+
@@ -1044,6 +1044,11 @@
the partition when mounting the partition.
+ Note that using UUIDs is not a panacea. See
+ for
+ more information.
+
+
Changes in a device name might adversely affect the
following files:
@@ -1141,13 +1146,187 @@
Choose:
Partition
- New UUID.
- The application displays the set a new random UUID
- operation in the Operations Pending
- pane.
+ New UUID.
+ The application displays the set a new random UUID
+ operation in the Operations Pending
+ pane.
+
+
+ Changing the UUID of an existing filesystem may affect the ability of a
+ Linux system to boot. On Windows, it may affect the validity of the
+ Windows Product Activation key.
+
+
+ Please read (one of) the following sections for more information
+ if this may be a concern.
+
+
+
+
+ For FAT and NTFS filesystems, what GParted names, and treats as, the
+ UUID, is in fact its Volume Serial Number.
+
+
+ An NTFS filesystem also has a real UUID, but that is a different number,
+ which cannot and should not be changed - at all.
+
+
+
+ UUIDs in Linux
+
+ Modern Linux systems are usually configured to use UUIDs to locate
+ and identify the different filesystems or partitions when booting. Some
+ partition types, like LVM physical volumes, are only
+ identified using their UUID. Making changes to partitions may therefore
+ affect the Linux boot process in different ways:
+
+
+
+
+ When copying a partition
+
+
+ When a copy was made of a partition, and both the original
+ and the copy are ever present on the same machine at the same
+ time, Linux may (will)
+ not be able to predictably identify which is which. This is caused
+ by the fact that the UUID is used for identification, and
+ both partitions, being copies, have the same UUID.
+
+
+ If such confusion happens at boot time, the results will be
+ unpredictable. One or the other will essentially be selected at random,
+ and possibly a different one at each boot. Over time, this random
+ nature of partition selection might make files seem to mysteriously
+ appear or disappear depending upon which partition is selected. It may
+ also cause severe data corruption or loss.
+
+
+ This can, and should, be avoided by changing the UUID of the copy. It
+ is safest to change the UUID of a copied partition at all times, as both
+ partitions, or other copies of it, may meet again on the same computer,
+ with unexpected and unpredictable
+ results.
+
+
+
+
+ When changing the UUID of a partition
+
+
+ When changing he UUID of a partition, Linux may no longer be able to
+ correctly identify the partition. If the partition is needed when
+ booting, this may result in a failure to boot.
+
+
+ Do not change a partition's UUID if that partition is not intended to be
+ a copy of an existing partition, unless you know what you are doing,
+ and prepared to deal with the consequences.
+
+
+ Before changing UUIDs of Windows partitions, please be sure to
+ read .
+
+
+
+
+
+
+
+ UUIDs in Windows
+
+ On NTFS and FAT filesystems, the number that GParted names, and treats as
+ UUID, is in fact the Volume Serial Number.
+
+
+
+ When changing the UUID / Volume Serial Number on a partition that will
+ (continue to) be used on the same hardware, using the same Windows licence,
+ please read this section carefully.
+
+
+ The information in this section is provided as is.
+ It is believed to be accurate, but it might in fact be incorrect, or subtly
+ misleading. Use GParted at your own risk. If you cannot afford to take
+ the risk of making Windows unbootable and/or loosing your data, then do
+ not use GParted.
+
+
+
+ Changing the Volume Serial Number of an NTFS or FAT partition that is used by Windows, may
+ have different consequences depending on the kind of partition in question.
+
+
+
+
+ UUIDs on Windows system partitions
+
+
+ On Windows, the Volume Serial Number of the System partition is
+ usually used
+
+ In atypical cases, the Volume Serial Number of another partition might
+ be the one that is used instead.
+
+
+ for Windows Product Activation (WPA). The first modification of this number will
+ count as a change for WPA. Subsequent modifications are 'free'.
+
+
+ Too many such WPA-affecting changes, like replacing the primary harddisk
+ or the processor, or adding memory, will invalidate the WPA key. In that
+ case, windows needs to be re-activated.
+
+
+ For NTFS filesystems only, GParted can, and will, attempt to avoid making a
+ change that could be WPA-affecting, by changing only half of the NTFS Volume
+ Serial Number. Such a half-change should also be safe, in principle.
+ Nevertheless, no guarantees can be given.
+
+
+ As there is no easy way to revert a Volume Serial Number change (it will not,
+ for instance, be included in a regular backup), it should not be changed
+ casually, and not unless one is prepared to take the risk, and re-activate
+ Windows when the change proved to be one too many for WPA.
+
+
+ As long as a partition having the original Volume Serial
+ Number is present at Windows boot time, WPA requirements should normally be
+ satisfied, and no WPA change should be noted by Windows.
+
+
+
+
+
+
+ UUIDs on data partitions
+
+
+ The NTFS or FAT Volume Serial Number on a data partition is not normally used
+ for WPA, although there may be exceptions. Changing it should therefore not
+ affect WPA.
+
+
+
+
+
+
+ UUIDs on external storage media
+
+
+ On external storage media that are not permanently attached, and not present
+ at Windows boot time, the Volume Serial Number is not (cannot be) used for
+ WPA, and therefore the validity of the WPA key should not be affected when
+ the Volume Serial Number is changed.
+
+
+
+
+
+
diff --git a/include/Utils.h b/include/Utils.h
index 121f7e02..2d53f4fd 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -48,6 +48,9 @@ const Byte_Value MEBIBYTE=(KIBIBYTE * KIBIBYTE);
const Byte_Value GIBIBYTE=(MEBIBYTE * KIBIBYTE);
const Byte_Value TEBIBYTE=(GIBIBYTE * KIBIBYTE);
+const Glib::ustring UUID_RANDOM = _("(New UUID - will be randomly generated)") ;
+const Glib::ustring UUID_RANDOM_NTFS_HALF = _("(Half new UUID - will be randomly generated)") ;
+
enum FILESYSTEM
{
FS_UNALLOCATED = 0,
@@ -96,6 +99,7 @@ enum CUSTOM_TEXT
CTEXT_NONE,
CTEXT_ACTIVATE_FILESYSTEM, // Activate text ('Mount', 'Swapon', ...)
CTEXT_DEACTIVATE_FILESYSTEM, // Deactivate text ('Unmount', 'Swapoff', ...)
+ CTEXT_CHANGE_UUID_WARNING, // Warning to print when changing UUIDs
} ;
//struct to store file system information
diff --git a/include/fat16.h b/include/fat16.h
index d010a6cc..7d9203bb 100644
--- a/include/fat16.h
+++ b/include/fat16.h
@@ -28,6 +28,7 @@ namespace GParted
class fat16 : public FileSystem
{
public:
+ const Glib::ustring get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) ;
FS get_filesystem_support() ;
void set_used_sectors( Partition & partition ) ;
void read_label( Partition & partition ) ;
@@ -44,6 +45,8 @@ public:
const Glib::ustring & dest_part_path,
OperationDetail & operationdetail ) ;
bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
+
+ static const Glib::ustring Change_UUID_Warning [] ;
};
} //GParted
diff --git a/include/fat32.h b/include/fat32.h
index bce0eee7..8839ad54 100644
--- a/include/fat32.h
+++ b/include/fat32.h
@@ -28,6 +28,7 @@ namespace GParted
class fat32 : public FileSystem
{
public:
+ const Glib::ustring get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) ;
FS get_filesystem_support();
void set_used_sectors( Partition & partition ) ;
void read_label( Partition & partition ) ;
@@ -44,6 +45,8 @@ public:
const Glib::ustring & dest_part_path,
OperationDetail & operationdetail ) ;
bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
+
+ const static Glib::ustring ( & Change_UUID_Warning ) [] ;
};
} //GParted
diff --git a/include/ntfs.h b/include/ntfs.h
index 0274e180..6101c8be 100644
--- a/include/ntfs.h
+++ b/include/ntfs.h
@@ -28,6 +28,7 @@ namespace GParted
class ntfs : public FileSystem
{
public:
+ const Glib::ustring get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) ;
FS get_filesystem_support() ;
void set_used_sectors( Partition & partition ) ;
void read_label( Partition & partition ) ;
@@ -44,6 +45,8 @@ public:
const Glib::ustring & dest_part_path,
OperationDetail & operationdetail ) ;
bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
+
+ static const Glib::ustring Change_UUID_Warning [] ;
};
} //GParted
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 21b2ec31..12810ce1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,7 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
gparted.desktop.in.in
+include/Utils.h
src/Dialog_Base_Partition.cc
src/Dialog_Disklabel.cc
src/Dialog_Partition_Copy.cc
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 413527af..9d6ceb81 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1748,10 +1748,17 @@ bool GParted_Core::label_partition( const Partition & partition, OperationDetail
bool GParted_Core::change_uuid( const Partition & partition, OperationDetail & operationdetail )
{
- operationdetail .add_child( OperationDetail( String::ucompose(
- _("Set UUID on %1 to a new, random value"),
- partition .get_path()
- ) ) ) ;
+ if ( partition .uuid == UUID_RANDOM_NTFS_HALF ) {
+ operationdetail .add_child( OperationDetail( String::ucompose(
+ _("Set half of the UUID on %1 to a new, random value"),
+ partition .get_path()
+ ) ) ) ;
+ } else {
+ operationdetail .add_child( OperationDetail( String::ucompose(
+ _("Set UUID on %1 to a new, random value"),
+ partition .get_path()
+ ) ) ) ;
+ }
bool succes = false ;
if ( partition .type != TYPE_EXTENDED )
diff --git a/src/OperationChangeUUID.cc b/src/OperationChangeUUID.cc
index 25e5a61b..270852a8 100644
--- a/src/OperationChangeUUID.cc
+++ b/src/OperationChangeUUID.cc
@@ -55,11 +55,19 @@ void OperationChangeUUID::apply_to_visual( std::vector & partitions )
void OperationChangeUUID::create_description()
{
- /*TO TRANSLATORS: looks like Set a new random UUID on ext4 file system on /dev/sda1 */
- description = String::ucompose( _("Set a new random UUID on %1 file system on %2")
- , Utils::get_filesystem_string( partition_new .filesystem )
- , partition_new .get_path()
- ) ;
+ if ( partition_new .uuid == UUID_RANDOM_NTFS_HALF ) {
+ /*TO TRANSLATORS: looks like Set half the UUID to a new, random value on ntfs filesystem on /dev/sda1 */
+ description = String::ucompose( _("Set half the UUID to a new, random value on %1 filesystem on %2")
+ , Utils::get_filesystem_string( partition_new .filesystem )
+ , partition_new .get_path()
+ ) ;
+ } else {
+ /*TO TRANSLATORS: looks like Set a new random UUID on ext4 filesystem on /dev/sda1 */
+ description = String::ucompose( _("Set a new random UUID on %1 filesystem on %2")
+ , Utils::get_filesystem_string( partition_new .filesystem )
+ , partition_new .get_path()
+ ) ;
+ }
}
} //GParted
diff --git a/src/Utils.cc b/src/Utils.cc
index e2152011..6413925c 100644
--- a/src/Utils.cc
+++ b/src/Utils.cc
@@ -183,7 +183,7 @@ Glib::ustring Utils::get_filesystem_software( FILESYSTEM filesystem )
case FS_LINUX_SWAP : return "util-linux" ;
case FS_LVM2_PV : return "lvm2" ;
case FS_NILFS2 : return "nilfs-utils" ;
- case FS_NTFS : return "ntfsprogs" ;
+ case FS_NTFS : return "ntfsprogs / ntfs-3g" ;
case FS_REISER4 : return "reiser4progs" ;
case FS_REISERFS : return "reiserfsprogs" ;
case FS_UFS : return "" ;
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index dead3e90..2706c1bf 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -769,7 +769,10 @@ bool Win_GParted::Merge_Operations( unsigned int first, unsigned int second )
operations[ first ]->partition_new == operations[ second ]->partition_original
)
{
- operations[ first ]->partition_new.uuid = operations[ second ]->partition_new.uuid;
+ // Changing half the UUID should not override changing all of it
+ if ( operations[ first ]->partition_new.uuid == UUID_RANDOM_NTFS_HALF ||
+ operations[ second ]->partition_new.uuid == UUID_RANDOM )
+ operations[ first ]->partition_new.uuid = operations[ second ]->partition_new.uuid;
operations[ first ]->create_description() ;
remove_operation( second );
@@ -2369,6 +2372,25 @@ void Win_GParted::activate_label_partition()
void Win_GParted::activate_change_uuid()
{
+ if ( gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING ) != "" ) {
+ int i ;
+ Gtk::MessageDialog dialog( *this
+ , gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING, 0 )
+ , false
+ , Gtk::MESSAGE_WARNING
+ , Gtk::BUTTONS_OK
+ , true
+ ) ;
+ Glib::ustring tmp_msg = "" ;
+ for ( i = 1 ; gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING, i ) != "" ; i++ ) {
+ if ( i > 1 )
+ tmp_msg += "\n\n" ;
+ tmp_msg += gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING, i ) ;
+ }
+ dialog .set_secondary_text( tmp_msg ) ;
+ dialog .run() ;
+ }
+
//Make a duplicate of the selected partition (used in UNDO)
Partition part_temp ;
part_temp .Set( devices[ current_device ] .get_path(),
@@ -2383,7 +2405,14 @@ void Win_GParted::activate_change_uuid()
false ) ;
part_temp .label = selected_partition .label ;
- part_temp .uuid = _("(New UUID - will be randomly generated)") ;
+
+ if ( part_temp .filesystem == GParted::FS_NTFS )
+ //Explicitly ask for half, so that the user will be aware of it
+ //Also, keep this kind of policy out of the NTFS code.
+ part_temp .uuid = UUID_RANDOM_NTFS_HALF ;
+ else
+ part_temp .uuid = UUID_RANDOM ;
+
Operation * operation = new OperationChangeUUID( devices[ current_device ],
selected_partition, part_temp ) ;
diff --git a/src/fat16.cc b/src/fat16.cc
index b510af9a..6e4ba441 100644
--- a/src/fat16.cc
+++ b/src/fat16.cc
@@ -29,6 +29,36 @@
namespace GParted
{
+const Glib::ustring fat16::Change_UUID_Warning [] = { _( "This may invalidate your Windows Activation key."
+ )
+ , _( "On FAT and NTFS filesystems, GParted"
+ " uses the Volume Serial Number as UUID."
+ " Changing the Volume Serial Number on the Windows"
+ " system partition may invalidate the Windows Activation key."
+ )
+ , _( "External storage media and non-system partitions are normally safe,"
+ " but guarantees cannot be given."
+ )
+ , _( "Please read the manual for more information, and do not apply"
+ " this change if you are not prepared to re-activate Windows"
+ )
+ , ""
+ } ;
+
+const Glib::ustring fat16::get_custom_text( CUSTOM_TEXT ttype, int index )
+{
+ int i ;
+ switch ( ttype ) {
+ case CTEXT_CHANGE_UUID_WARNING :
+ for ( i = 0 ; i < index && Change_UUID_Warning[ i ] != "" ; i++ ) {
+ // Just iterate...
+ }
+ return Change_UUID_Warning [ i ] ;
+ default :
+ return FileSystem::get_custom_text( ttype, index ) ;
+ }
+}
+
FS fat16::get_filesystem_support()
{
FS fs ;
diff --git a/src/fat32.cc b/src/fat32.cc
index 72080f49..db479f29 100644
--- a/src/fat32.cc
+++ b/src/fat32.cc
@@ -17,6 +17,7 @@
*/
+#include "../include/fat16.h"
#include "../include/fat32.h"
/*****
@@ -29,6 +30,22 @@
namespace GParted
{
+const Glib::ustring ( & fat32::Change_UUID_Warning ) [] = fat16::Change_UUID_Warning ;
+
+const Glib::ustring fat32::get_custom_text( CUSTOM_TEXT ttype, int index )
+{
+ int i ;
+ switch ( ttype ) {
+ case CTEXT_CHANGE_UUID_WARNING :
+ for ( i = 0 ; i < index && Change_UUID_Warning[ i ] != "" ; i++ ) {
+ // Just iterate...
+ }
+ return Change_UUID_Warning [ i ] ;
+ default :
+ return FileSystem::get_custom_text( ttype, index ) ;
+ }
+}
+
FS fat32::get_filesystem_support()
{
FS fs ;
diff --git a/src/ntfs.cc b/src/ntfs.cc
index 7223cb5e..3d93c257 100644
--- a/src/ntfs.cc
+++ b/src/ntfs.cc
@@ -22,6 +22,38 @@
namespace GParted
{
+const Glib::ustring ntfs::Change_UUID_Warning [] = { _( "This may invalidate your Windows Activation key."
+ )
+ , _( "On FAT and NTFS filesystems, GParted"
+ " uses the Volume Serial Number as UUID."
+ " Changing the Volume Serial Number on the Windows"
+ " system partition may invalidate the Windows Activation key."
+ )
+ , _( "External storage media and non-system partitions are normally safe."
+ " GParted also attempts to avoid the problem by changing only"
+ " half of the serial number, which should be safe as well."
+ " Nevertheless, guarantees cannot be given."
+ )
+ , _( "Please read the manual for more information, and do not apply"
+ " this change if you are not prepared to re-activate Windows"
+ )
+ , ""
+ } ;
+
+const Glib::ustring ntfs::get_custom_text( CUSTOM_TEXT ttype, int index )
+{
+ int i ;
+ switch ( ttype ) {
+ case CTEXT_CHANGE_UUID_WARNING :
+ for ( i = 0 ; i < index && Change_UUID_Warning[ i ] != "" ; i++ ) {
+ // Just iterate...
+ }
+ return Change_UUID_Warning [ i ] ;
+ default :
+ return FileSystem::get_custom_text( ttype, index ) ;
+ }
+}
+
FS ntfs::get_filesystem_support()
{
FS fs ;
@@ -34,8 +66,21 @@ FS ntfs::get_filesystem_support()
}
if ( ! Glib::find_program_in_path( "ntfslabel" ) .empty() ) {
+ Glib::ustring version ;
+
fs .read_label = FS::EXTERNAL ;
fs .write_label = FS::EXTERNAL ;
+
+ //Not all versions of ntfslabel support setting the Volume Serial Number
+ //The advanced (AR) release does as of the first 2012 release
+ //The stable release does not have it yet, at the time of this writing
+ //So: check for the presence of the command-line option.
+
+ //ntfslabel --help exits with non-zero error code (1)
+ Utils::execute_command( "ntfslabel --help ", output, error, false ) ;
+
+ if ( ! ( version = Utils::regexp_label( output, "--new-serial[[:blank:]]" ) ) .empty() )
+ fs .write_uuid = FS::EXTERNAL ;
}
if ( ! Glib::find_program_in_path( "mkntfs" ) .empty() )
@@ -110,6 +155,11 @@ void ntfs::read_uuid( Partition & partition )
bool ntfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
{
+ if ( partition .uuid == UUID_RANDOM_NTFS_HALF )
+ return ! execute_command( "ntfslabel --new-half-serial " + partition .get_path(), operationdetail ) ;
+ else
+ return ! execute_command( "ntfslabel --new-serial " + partition .get_path(), operationdetail ) ;
+
return true ;
}