[gparted] Add support for setting UUID (#667278)



commit 9e96159bb2e6a843ac9465b340ad5f32b0320937
Author: Rogier Goossens <goossens rogier gmail com>
Date:   Sun Jan 22 13:49:52 2012 -0700

    Add support for setting UUID (#667278)
    
    Add the ability to set a new random UUID on file systems that provide
    the appropriate tools to perform this action.
    
    Update the help manual to include this new functionality.  Also add
    reference links to "setting a partition label" and "changing a
    partition UUID" in the "copying and pasting a partition" section.
    
    This patch does not include setting the UUID on an NTFS file system.
    
    Bug #667278 - Add support for setting UUID
    
    Bug #608308 - fix documentation - Copying and Pasting a Partition

 help/C/gparted.xml            |   30 +++++++++++++++++++
 include/DialogFeatures.h      |    2 +
 include/FileSystem.h          |    2 +
 include/GParted_Core.h        |    3 ++
 include/Makefile.am           |    1 +
 include/Operation.h           |    3 +-
 include/OperationChangeUUID.h |   42 ++++++++++++++++++++++++++
 include/Utils.h               |    7 ++++-
 include/Win_GParted.h         |    7 ++++-
 include/btrfs.h               |    2 +
 include/exfat.h               |    2 +
 include/ext2.h                |    2 +
 include/ext3.h                |    2 +
 include/ext4.h                |    2 +
 include/fat16.h               |    2 +
 include/fat32.h               |    2 +
 include/hfs.h                 |    2 +
 include/hfsplus.h             |    2 +
 include/jfs.h                 |    2 +
 include/linux_swap.h          |    2 +
 include/nilfs2.h              |    2 +
 include/ntfs.h                |    2 +
 include/reiser4.h             |    2 +
 include/reiserfs.h            |    2 +
 include/ufs.h                 |    2 +
 include/xfs.h                 |    2 +
 po/POTFILES.in                |    1 +
 src/DialogFeatures.cc         |    2 +
 src/GParted_Core.cc           |   56 ++++++++++++++++++++++++++++++++++-
 src/Makefile.am               |    1 +
 src/OperationChangeUUID.cc    |   65 +++++++++++++++++++++++++++++++++++++++++
 src/Utils.cc                  |   13 ++++++++
 src/Win_GParted.cc            |   65 ++++++++++++++++++++++++++++++++++++++++-
 src/btrfs.cc                  |   35 ++++++++++++++++++++++
 src/exfat.cc                  |    9 ++++++
 src/ext2.cc                   |   29 ++++++++++++++++++
 src/ext3.cc                   |   28 +++++++++++++++++
 src/ext4.cc                   |   30 ++++++++++++++++++-
 src/fat16.cc                  |   60 +++++++++++++++++++++++++++++++++++++
 src/fat32.cc                  |   61 ++++++++++++++++++++++++++++++++++++++
 src/hfs.cc                    |    9 ++++++
 src/hfsplus.cc                |    9 ++++++
 src/jfs.cc                    |   28 +++++++++++++++++-
 src/linux_swap.cc             |   27 ++++++++++++++++-
 src/nilfs2.cc                 |   25 ++++++++++++++++
 src/ntfs.cc                   |    9 ++++++
 src/reiser4.cc                |   24 +++++++++++++++
 src/reiserfs.cc               |   25 ++++++++++++++++
 src/ufs.cc                    |    9 ++++++
 src/xfs.cc                    |   27 +++++++++++++++++
 50 files changed, 770 insertions(+), 8 deletions(-)
---
diff --git a/help/C/gparted.xml b/help/C/gparted.xml
index 5997771..3748d5f 100644
--- a/help/C/gparted.xml
+++ b/help/C/gparted.xml
@@ -1116,6 +1116,32 @@
         </para>
       </sect3>
 
+<!-- ============= To Change a Partition's UUID ========================== -->
+      <sect3 id="gparted-changing-partition-uuid">
+        <title>Changing a Partition UUID</title>
+        <para>
+        To change the UUID of a partition:
+          <orderedlist>
+            <listitem>
+              <para>
+              Select an unmounted partition.
+              See <xref linkend="gparted-select-partition"/>.
+              </para>
+            </listitem>
+            <listitem>
+              <para>
+              Choose:
+              <menuchoice><guimenu>Partition</guimenu>
+	      <guimenuitem>New UUID</guimenuitem></menuchoice>.
+	      The application displays the set a new random UUID
+	      operation in the <guilabel>Operations Pending</guilabel>
+	      pane.
+              </para>
+            </listitem>
+          </orderedlist>
+        </para>
+      </sect3>
+
 <!-- ============= Specifying Partition Details ====================== -->
       <sect3 id="gparted-specify-partition-details">
         <title>Specifying Partition Details</title>
@@ -1650,8 +1676,12 @@
               <listitem>
                 <para>
                 Change the UUID of the partition.
+                See <xref linkend="gparted-changing-partition-uuid"/>.
+                </para>
+                <para>
                 If the partition label is not blank, change the label
                 of the partition.
+                See <xref linkend="gparted-setting-partition-label"/>.
                 </para>
               </listitem>
               <listitem>
diff --git a/include/DialogFeatures.h b/include/DialogFeatures.h
index f32d370..6fb256d 100644
--- a/include/DialogFeatures.h
+++ b/include/DialogFeatures.h
@@ -56,6 +56,7 @@ private:
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > copy ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > check ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > label ;
+		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > uuid ;
 		Gtk::TreeModelColumn<Glib::ustring> software ;
 				
 		treeview_filesystems_Columns() 
@@ -68,6 +69,7 @@ private:
 			add( copy ) ;
 			add( check ) ;
 			add( label ) ;
+			add( uuid ) ;
 			add( software ) ;
 		}
 	};
diff --git a/include/FileSystem.h b/include/FileSystem.h
index 589eb14..b681c35 100644
--- a/include/FileSystem.h
+++ b/include/FileSystem.h
@@ -38,6 +38,8 @@ public:
 	virtual void set_used_sectors( Partition & partition ) = 0 ;
 	virtual void read_label( Partition & partition ) = 0 ;
 	virtual bool write_label( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
+	virtual void read_uuid( Partition & partition ) = 0 ;
+	virtual bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
 	virtual bool create( const Partition & new_partition, OperationDetail & operationdetail ) = 0 ;
 	virtual bool resize( const Partition & partition_new,
 			     OperationDetail & operationdetail,
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index 670ae5d..ac4909a 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -71,6 +71,7 @@ private:
 	void set_device_partitions( Device & device ) ;
 	GParted::FILESYSTEM get_filesystem() ; 
 	void read_label( Partition & partition ) ;
+	void read_uuid( Partition & partition ) ;
 	void insert_unallocated( const Glib::ustring & device_path,
 				 std::vector<Partition> & partitions,
 				 Sector start,
@@ -95,6 +96,8 @@ private:
 	
 	bool label_partition( const Partition & partition, OperationDetail & operation_detail ) ;
 	
+	bool change_uuid( const Partition & partition, OperationDetail & operation_detail ) ;
+
 	bool resize_move( const Device & device,
 			  const Partition & partition_old,
 			  Partition & partition_new,
diff --git a/include/Makefile.am b/include/Makefile.am
index 1975adc..2d6ed7b 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -29,6 +29,7 @@ EXTRA_DIST = \
 	OperationDetail.h		\
 	OperationFormat.h		\
 	OperationResizeMove.h		\
+	OperationChangeUUID.h		\
 	OperationLabelPartition.h	\
 	Partition.h  			\
 	Proc_Partitions_Info.h	\
diff --git a/include/Operation.h b/include/Operation.h
index 936618b..669b8b6 100644
--- a/include/Operation.h
+++ b/include/Operation.h
@@ -32,7 +32,8 @@ enum OperationType {
 	OPERATION_RESIZE_MOVE	= 3,
 	OPERATION_FORMAT	= 4,
 	OPERATION_COPY		= 5,
-	OPERATION_LABEL_PARTITION = 6
+	OPERATION_LABEL_PARTITION = 6,
+	OPERATION_CHANGE_UUID	= 7
 };
 
 class Operation
diff --git a/include/OperationChangeUUID.h b/include/OperationChangeUUID.h
new file mode 100644
index 0000000..2de424f
--- /dev/null
+++ b/include/OperationChangeUUID.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 2012 Rogier Goossens
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef OPERATIONCHANGEUUID_H_
+#define OPERATIONCHANGEUUID_H_
+
+#include "../include/Operation.h"
+
+namespace GParted
+{
+
+class OperationChangeUUID : public Operation
+{
+public:
+	OperationChangeUUID( const Device & device
+	                   , const Partition & partition_orig
+	                   , const Partition & partition_new
+	                   ) ;
+
+void apply_to_visual( std::vector<Partition> & partitions ) ;
+
+private:
+	void create_description() ;
+} ;
+
+} //GParted
+
+#endif //OPERATIONCHANGEUUID_H_
diff --git a/include/Utils.h b/include/Utils.h
index 5416f26..4cdad54 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -34,6 +34,8 @@
 #include <ctime>
 #include <vector>
 
+#define UUID_STRING_LENGTH 36
+
 namespace GParted
 {
 
@@ -106,6 +108,8 @@ struct FS
 	Support read ; //can we get the amount of used sectors?
 	Support read_label ;
 	Support write_label ;
+	Support read_uuid ;
+	Support write_uuid ;
 	Support create ;
 	Support grow ;
 	Support shrink ;
@@ -118,7 +122,7 @@ struct FS
 	
 	FS()
 	{
-		read = read_label = write_label = create = grow = shrink = move = check = copy = NONE;
+		read = read_label = write_label = read_uuid = write_uuid = create = grow = shrink = move = check = copy = NONE;
 		MIN = MAX = 0 ;
 	} 
 } ;
@@ -163,6 +167,7 @@ public:
 	                      std::vector<Glib::ustring>& tokens,
 	                      const Glib::ustring& delimiters ) ;
 	static int convert_to_int(const Glib::ustring & src);
+	static Glib::ustring generate_uuid(void);
 };
 
 
diff --git a/include/Win_GParted.h b/include/Win_GParted.h
index 0e14a26..6738347 100644
--- a/include/Win_GParted.h
+++ b/include/Win_GParted.h
@@ -105,6 +105,9 @@ private:
 	void allow_label_partition( bool state )	{
 		toggle_item( state, MENU_LABEL_PARTITION ) ; } 
 
+	void allow_change_uuid( bool state )	{
+		toggle_item( state, MENU_CHANGE_UUID ) ; }
+
 	void allow_info( bool state )	{
 		toggle_item( state, MENU_INFO ) ; } 
 
@@ -167,6 +170,7 @@ private:
 	void activate_attempt_rescue_data();
 	void activate_manage_flags() ;
 	void activate_check() ;
+	void activate_change_uuid() ;
 	void activate_label_partition() ;
 	
 	void activate_undo();
@@ -235,7 +239,8 @@ private:
         MENU_MOUNT,
         MENU_FLAGS,
         MENU_CHECK,
-		MENU_LABEL_PARTITION,
+	MENU_LABEL_PARTITION,
+	MENU_CHANGE_UUID,
         MENU_INFO,
         TOOLBAR_UNDO,
         TOOLBAR_APPLY ;
diff --git a/include/btrfs.h b/include/btrfs.h
index 1f28fc6..f1f8fac 100644
--- a/include/btrfs.h
+++ b/include/btrfs.h
@@ -31,6 +31,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/exfat.h b/include/exfat.h
index eb82f3b..2518e5d 100644
--- a/include/exfat.h
+++ b/include/exfat.h
@@ -31,6 +31,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new
 	           , OperationDetail & operationdetail
diff --git a/include/ext2.h b/include/ext2.h
index 42e55f9..7a1de2a 100644
--- a/include/ext2.h
+++ b/include/ext2.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/ext3.h b/include/ext3.h
index caf4c26..3e349f7 100644
--- a/include/ext3.h
+++ b/include/ext3.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/ext4.h b/include/ext4.h
index 4f04bae..e51dbd5 100644
--- a/include/ext4.h
+++ b/include/ext4.h
@@ -31,6 +31,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/fat16.h b/include/fat16.h
index d0d527d..d010a6c 100644
--- a/include/fat16.h
+++ b/include/fat16.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/fat32.h b/include/fat32.h
index 9d20dce..bce0eee 100644
--- a/include/fat32.h
+++ b/include/fat32.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/hfs.h b/include/hfs.h
index 8455c03..fe495a9 100644
--- a/include/hfs.h
+++ b/include/hfs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/hfsplus.h b/include/hfsplus.h
index 4bbc0ed..4724ac2 100644
--- a/include/hfsplus.h
+++ b/include/hfsplus.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/jfs.h b/include/jfs.h
index 77e793a..5eba900 100644
--- a/include/jfs.h
+++ b/include/jfs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/linux_swap.h b/include/linux_swap.h
index f7d3295..b7d1beb 100644
--- a/include/linux_swap.h
+++ b/include/linux_swap.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/nilfs2.h b/include/nilfs2.h
index 01c4bdb..dae5167 100644
--- a/include/nilfs2.h
+++ b/include/nilfs2.h
@@ -31,6 +31,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/ntfs.h b/include/ntfs.h
index 2668013..0274e18 100644
--- a/include/ntfs.h
+++ b/include/ntfs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/reiser4.h b/include/reiser4.h
index cc14dd1..38c60f8 100644
--- a/include/reiser4.h
+++ b/include/reiser4.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/reiserfs.h b/include/reiserfs.h
index 4839333..74a24cb 100644
--- a/include/reiserfs.h
+++ b/include/reiserfs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/ufs.h b/include/ufs.h
index 46e7ffe..26dc256 100644
--- a/include/ufs.h
+++ b/include/ufs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/include/xfs.h b/include/xfs.h
index 11bba4e..bc43ba1 100644
--- a/include/xfs.h
+++ b/include/xfs.h
@@ -32,6 +32,8 @@ public:
 	void set_used_sectors( Partition & partition ) ;
 	void read_label( Partition & partition ) ;
 	bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
+	void read_uuid( Partition & partition ) ;
+	bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
 	bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
 	bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;
 	bool move( const Partition & partition_new
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 045e41d..f89f5af 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -16,6 +16,7 @@ src/DMRaid.cc
 src/FileSystem.cc
 src/GParted_Core.cc
 src/HBoxOperations.cc
+src/OperationChangeUUID.cc
 src/OperationCopy.cc
 src/OperationCheck.cc
 src/OperationCreate.cc
diff --git a/src/DialogFeatures.cc b/src/DialogFeatures.cc
index a3995f5..890123c 100644
--- a/src/DialogFeatures.cc
+++ b/src/DialogFeatures.cc
@@ -40,6 +40,7 @@ DialogFeatures::DialogFeatures()
 	treeview_filesystems .append_column( _("Copy"), treeview_filesystems_columns .copy );
 	treeview_filesystems .append_column( _("Check"), treeview_filesystems_columns .check );
 	treeview_filesystems .append_column( _("Label"), treeview_filesystems_columns .label );
+	treeview_filesystems .append_column( _("UUID"), treeview_filesystems_columns .uuid );
 	treeview_filesystems .append_column( _("Required Software"), treeview_filesystems_columns .software );
 	treeview_filesystems .get_selection() ->set_mode( Gtk::SELECTION_NONE );
 	treeview_filesystems .set_rules_hint( true ) ;
@@ -145,6 +146,7 @@ void DialogFeatures::show_filesystem( const FS & fs )
 	treerow[ treeview_filesystems_columns .copy ] = fs .copy ? icon_yes : icon_no ; 
 	treerow[ treeview_filesystems_columns .check ] = fs .check ? icon_yes : icon_no ; 
 	treerow[ treeview_filesystems_columns .label ] = fs .write_label ? icon_yes : icon_no ; 
+	treerow[ treeview_filesystems_columns .uuid ] = fs .write_uuid ? icon_yes : icon_no ;
 
 	treerow[ treeview_filesystems_columns .software ] = Utils::get_filesystem_software( fs .filesystem ) ;
 }
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 346a27d..8ae89a0 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -26,6 +26,7 @@
 #include "../include/OperationDelete.h"
 #include "../include/OperationFormat.h"
 #include "../include/OperationResizeMove.h"
+#include "../include/OperationChangeUUID.h"
 #include "../include/OperationLabelPartition.h"
 #include "../include/Proc_Partitions_Info.h"
 
@@ -631,6 +632,9 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
 			case OPERATION_LABEL_PARTITION:
 				succes = label_partition( operation ->partition_new, operation ->operation_detail ) ;
 				break ;
+			case OPERATION_CHANGE_UUID:
+				succes = change_uuid( operation ->partition_new, operation ->operation_detail ) ;
+				break ;
 		}
 
 	if ( libparted_messages .size() > 0 )
@@ -1010,7 +1014,13 @@ void GParted_Core::set_device_partitions( Device & device )
 				bool label_found = false ;
 				partition_temp .label = fs_info .get_label( partition_temp .get_path(), label_found ) ;
 			}
-			partition_temp .uuid = fs_info .get_uuid( partition_temp .get_path() ) ;
+
+			//Retrieve file system UUID
+			read_uuid( partition_temp ) ;
+			if ( partition_temp .uuid .empty() )
+			{
+				partition_temp .uuid = fs_info .get_uuid( partition_temp .get_path() ) ;
+			}
 		}
 
 		partition_temp .messages .insert( partition_temp .messages .end(),
@@ -1250,6 +1260,23 @@ void GParted_Core::read_label( Partition & partition )
 	}
 }
 
+void GParted_Core::read_uuid( Partition & partition )
+{
+	if ( partition .type != TYPE_EXTENDED )
+	{
+		switch( get_fs( partition .filesystem ) .read_uuid )
+		{
+			case FS::EXTERNAL:
+				if ( set_proper_filesystem( partition .filesystem ) )
+					p_filesystem ->read_uuid( partition ) ;
+				break ;
+
+			default:
+				break ;
+		}
+	}
+}
+
 void GParted_Core::insert_unallocated( const Glib::ustring & device_path,
 				       std::vector<Partition> & partitions,
 				       Sector start,
@@ -1731,6 +1758,33 @@ bool GParted_Core::label_partition( const Partition & partition, OperationDetail
 	return succes ;	
 }
 
+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()
+								 ) ) ) ;
+
+	bool succes = false ;
+	if ( partition .type != TYPE_EXTENDED )
+	{
+		switch( get_fs( partition .filesystem ) .write_uuid )
+		{
+			case FS::EXTERNAL:
+				succes = set_proper_filesystem( partition .filesystem ) &&
+					 p_filesystem ->write_uuid( partition, operationdetail .get_last_child() ) ;
+				break ;
+
+			default:
+				break;
+		}
+	}
+
+	operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
+
+	return succes ;
+}
+
 bool GParted_Core::resize_move( const Device & device,
 				const Partition & partition_old,
 			  	Partition & partition_new,
diff --git a/src/Makefile.am b/src/Makefile.am
index d3b0b5d..5d0ab02 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,7 @@ gpartedbin_SOURCES = \
 	GParted_Core.cc			\
 	HBoxOperations.cc		\
 	Operation.cc			\
+	OperationChangeUUID.cc		\
 	OperationCopy.cc		\
 	OperationCheck.cc		\
 	OperationCreate.cc		\
diff --git a/src/OperationChangeUUID.cc b/src/OperationChangeUUID.cc
new file mode 100644
index 0000000..25e5a61
--- /dev/null
+++ b/src/OperationChangeUUID.cc
@@ -0,0 +1,65 @@
+/* Copyright (C) 2012 Rogier Goossens
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../include/OperationChangeUUID.h"
+
+namespace GParted
+{
+
+OperationChangeUUID::OperationChangeUUID( const Device & device
+                                        , const Partition & partition_orig
+                                        , const Partition & partition_new
+                                        )
+{
+	type = OPERATION_CHANGE_UUID ;
+
+	this ->device = device ;
+	this ->partition_original = partition_orig ;
+	this ->partition_new = partition_new ;
+}
+
+void OperationChangeUUID::apply_to_visual( std::vector<Partition> & partitions )
+{
+	if ( partition_original .inside_extended )
+	{
+		index_extended = find_index_extended( partitions ) ;
+
+		if ( index_extended >= 0 )
+			index = find_index_original( partitions[ index_extended ] .logicals ) ;
+
+		if ( index >= 0 )
+			partitions[ index_extended ] .logicals[ index ] = partition_new ;
+	}
+	else
+	{
+		index = find_index_original( partitions ) ;
+
+		if ( index >= 0 )
+			partitions[ index ] = partition_new ;
+	}
+}
+
+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()
+	                              ) ;
+}
+
+} //GParted
diff --git a/src/Utils.cc b/src/Utils.cc
index 598b121..a2941d8 100644
--- a/src/Utils.cc
+++ b/src/Utils.cc
@@ -23,6 +23,7 @@
 #include <iomanip>
 #include <glibmm/regex.h>
 #include <locale.h>
+#include <uuid/uuid.h>
 
 
 namespace GParted
@@ -553,5 +554,17 @@ int Utils::convert_to_int(const Glib::ustring & src)
 	return ret_val;
 }
 
+// Create a new UUID
+Glib::ustring Utils::generate_uuid(void)
+{
+	uuid_t uuid;
+	char uuid_str[UUID_STRING_LENGTH+1];
+
+	uuid_generate(uuid);
+	uuid_unparse(uuid,uuid_str);
+
+	return uuid_str;
+}
+
 
 } //GParted..
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 38a67d9..6db904d 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -33,6 +33,7 @@
 #include "../include/OperationDelete.h"
 #include "../include/OperationFormat.h"
 #include "../include/OperationResizeMove.h"
+#include "../include/OperationChangeUUID.h"
 #include "../include/OperationLabelPartition.h"
 #include "../config.h"
 
@@ -65,6 +66,7 @@ Win_GParted::Win_GParted( const std::vector<Glib::ustring> & user_devices )
         MENU_FLAGS =
         MENU_INFO =
         MENU_LABEL_PARTITION =
+        MENU_CHANGE_UUID =
         TOOLBAR_UNDO =
         TOOLBAR_APPLY = -1 ;
 
@@ -381,6 +383,11 @@ void Win_GParted::init_partition_menu()
 						     sigc::mem_fun( *this, &Win_GParted::activate_label_partition ) ) );
 	MENU_LABEL_PARTITION = index++ ;
 
+	menu_partition .items() .push_back(
+			Gtk::Menu_Helpers::MenuElem( _("New UU_ID"),
+						     sigc::mem_fun( *this, &Win_GParted::activate_change_uuid ) ) );
+	MENU_CHANGE_UUID = index++ ;
+
 	menu_partition .items() .push_back( Gtk::Menu_Helpers::SeparatorElem() ) ;
 	index++ ;
 	
@@ -678,6 +685,7 @@ void Win_GParted::Add_Operation( Operation * operation, int index )
 		if ( operation ->type == OPERATION_DELETE ||
 		     operation ->type == OPERATION_FORMAT ||
 		     operation ->type == OPERATION_CHECK ||
+		     operation ->type == OPERATION_CHANGE_UUID ||
 		     operation ->type == OPERATION_LABEL_PARTITION ||
 		     gparted_core .snap_to_alignment( operation ->device, operation ->partition_new, error )
 		   )
@@ -753,6 +761,20 @@ bool Win_GParted::Merge_Operations( unsigned int first, unsigned int second )
 
 		return true;
 	}
+	// Two change-uuid change operations on the same partition
+	else if ( operations[ first ]->type == OPERATION_CHANGE_UUID &&
+	          operations[ second ]->type == OPERATION_CHANGE_UUID &&
+	          operations[ first ]->partition_new == operations[ second ]->partition_original
+	        )
+	{
+		operations[ first ]->partition_new.uuid = operations[ second ]->partition_new.uuid;
+		operations[ first ]->create_description() ;
+		remove_operation( second );
+
+		Refresh_Visual();
+
+		return true;
+	}
 	// Two check operations of the same partition
 	else if ( operations[ first ]->type == OPERATION_CHECK &&
 	          operations[ second ]->type == OPERATION_CHECK &&
@@ -879,7 +901,7 @@ void Win_GParted::set_valid_operations()
 	allow_new( false ); allow_delete( false ); allow_resize( false ); allow_copy( false );
 	allow_paste( false ); allow_format( false ); allow_toggle_swap_mount_state( false ) ;
 	allow_manage_flags( false ) ; allow_check( false ) ; allow_label_partition( false ) ;
-	allow_info( false ) ;
+	allow_change_uuid( false ); allow_info( false ) ;
 	
        	dynamic_cast<Gtk::Label*>( menu_partition .items()[ MENU_TOGGLE_MOUNT_SWAP ] .get_child() )
 		->set_label( _("_Unmount") ) ;
@@ -1017,6 +1039,10 @@ void Win_GParted::set_valid_operations()
 		if ( selected_partition .status == GParted::STAT_REAL && fs .write_label )
 			allow_label_partition( true ) ;
 
+		//only allow changing UUID of real partitions that support it
+		if ( selected_partition .status == GParted::STAT_REAL && fs .write_uuid )
+			allow_change_uuid( true ) ;
+
 		if ( selected_partition .get_mountpoints() .size() )
 		{
 			allow_toggle_swap_mount_state( true ) ;
@@ -1596,6 +1622,7 @@ void Win_GParted::activate_paste()
 		Partition partition_new = selected_partition ;
 		partition_new .filesystem = copied_partition .filesystem ;
 		partition_new .label = copied_partition .label ;
+		partition_new .uuid = copied_partition .uuid ;
 		partition_new .color = copied_partition .color ;
 		partition_new .set_used( copied_partition .sectors_used ) ;
 		partition_new .messages .clear() ;
@@ -2310,6 +2337,7 @@ void Win_GParted::activate_label_partition()
 		part_temp .set_used( selected_partition.sectors_used );
 
 		part_temp .label = dialog .get_new_label();
+		part_temp .uuid = selected_partition .uuid ;
 
 		Operation * operation = new OperationLabelPartition( devices[ current_device ],
 									selected_partition, part_temp ) ;
@@ -2329,6 +2357,41 @@ void Win_GParted::activate_label_partition()
 	}
 }
 	
+void Win_GParted::activate_change_uuid()
+{
+	//Make a duplicate of the selected partition (used in UNDO)
+	Partition part_temp ;
+	part_temp .Set( devices[ current_device ] .get_path(),
+			selected_partition .get_path(),
+			selected_partition .partition_number,
+			selected_partition .type,
+			selected_partition .filesystem,
+			selected_partition .sector_start,
+			selected_partition .sector_end,
+			devices[ current_device ] .sector_size,
+			selected_partition .inside_extended,
+			false ) ;
+
+	part_temp .label = selected_partition .label ;
+	part_temp .uuid = _("(New UUID - will be randomly generated)") ;
+
+	Operation * operation = new OperationChangeUUID( devices[ current_device ],
+								selected_partition, part_temp ) ;
+	operation ->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
+
+	Add_Operation( operation ) ;
+
+	// Verify if the two operations can be merged
+	for ( unsigned int t = 0 ; t < operations .size() - 1 ; t++ )
+	{
+		if ( operations[ t ] ->type == OPERATION_CHANGE_UUID )
+		{
+			if( Merge_Operations( t, operations .size() -1 ) )
+				break;
+		}
+	}
+}
+
 void Win_GParted::activate_undo()
 {
 	//when undoing a creation it's safe to decrease the newcount by one
diff --git a/src/btrfs.cc b/src/btrfs.cc
index 016c0e7..419190b 100644
--- a/src/btrfs.cc
+++ b/src/btrfs.cc
@@ -44,6 +44,7 @@ FS btrfs::get_filesystem_support()
 
 		fs .read = GParted::FS::EXTERNAL ;
 		fs .read_label = FS::EXTERNAL ;
+		fs .read_uuid = FS::EXTERNAL ;
 
 		//Resizing of btrfs requires mount, umount and kernel
 		//  support as well as btrfs filesystem resize
@@ -160,6 +161,11 @@ bool btrfs::write_label( const Partition & partition, OperationDetail & operatio
 	return ! execute_command( "btrfs filesystem label " + partition .get_path() + " \"" + partition .label + "\"", operationdetail ) ;
 }
 
+bool btrfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool btrfs::move( const Partition & partition_new
                 , const Partition & partition_old
                 , OperationDetail & operationdetail
@@ -264,4 +270,33 @@ void btrfs::read_label( Partition & partition )
 	}
 }
 
+void btrfs::read_uuid( Partition & partition )
+{
+	if ( btrfs_found )
+	{
+		exit_status = Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
+		if ( ! exit_status )
+		{
+			partition .uuid = Utils::regexp_label( output, "uuid:[[:blank:]]*([^[:space:]]*)" );
+		}
+	}
+	else
+	{
+		exit_status = Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
+		if ( ! exit_status )
+		{
+			partition .uuid = Utils::regexp_label( output, "uuid:[[:blank:]]*([^[:space:]]*)" );
+		}
+	}
+	if ( exit_status )
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+
 } //GParted
diff --git a/src/exfat.cc b/src/exfat.cc
index e0dfcff..4b66b6f 100644
--- a/src/exfat.cc
+++ b/src/exfat.cc
@@ -46,6 +46,15 @@ bool exfat::write_label( const Partition & partition, OperationDetail & operatio
 	return true ;
 }
 
+void exfat::read_uuid( Partition & partition )
+{
+}
+
+bool exfat::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool exfat::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return true ;
diff --git a/src/ext2.cc b/src/ext2.cc
index d2eff7f..1a899a4 100644
--- a/src/ext2.cc
+++ b/src/ext2.cc
@@ -29,6 +29,11 @@ FS ext2::get_filesystem_support()
 	if ( ! Glib::find_program_in_path( "dumpe2fs" ) .empty() )
 		fs .read = FS::EXTERNAL ;
 
+	if ( ! Glib::find_program_in_path( "tune2fs" ) .empty() ) {
+		fs .read_uuid = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
+	}
+
 	if ( ! Glib::find_program_in_path( "e2label" ) .empty() ) {
 		fs .read_label = FS::EXTERNAL ;
 		fs .write_label = FS::EXTERNAL ;
@@ -105,6 +110,30 @@ bool ext2::write_label( const Partition & partition, OperationDetail & operation
 	return ! execute_command( "e2label " + partition .get_path() + " \"" + partition .label + "\"", operationdetail ) ;
 }
 
+void ext2::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "tune2fs -l " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^Filesystem UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+		if (partition .uuid == "<none>")
+			partition .uuid .clear() ;
+
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool ext2::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "tune2fs -U random " + partition .get_path(), operationdetail ) ;
+}
+
 bool ext2::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.ext2 -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/ext3.cc b/src/ext3.cc
index d9e6cd5..9a438da 100644
--- a/src/ext3.cc
+++ b/src/ext3.cc
@@ -30,6 +30,11 @@ FS ext3::get_filesystem_support()
 	if ( ! Glib::find_program_in_path( "dumpe2fs" ) .empty() )
 		fs .read = GParted::FS::EXTERNAL ;
 
+	if ( ! Glib::find_program_in_path( "tune2fs" ) .empty() ) {
+		fs .read_uuid = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
+	}
+
 	if ( ! Glib::find_program_in_path( "e2label" ) .empty() ) {
 		fs .read_label = FS::EXTERNAL ;
 		fs .write_label = FS::EXTERNAL ;
@@ -106,6 +111,29 @@ bool ext3::write_label( const Partition & partition, OperationDetail & operation
 	return ! execute_command( "e2label " + partition .get_path() + " \"" + partition .label + "\"", operationdetail ) ;
 }
 
+void ext3::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "tune2fs -l " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^Filesystem UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+		if (partition .uuid == "<none>")
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool ext3::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "tune2fs -U random " + partition .get_path(), operationdetail ) ;
+}
+
 bool ext3::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.ext3 -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/ext4.cc b/src/ext4.cc
index 4f5546e..bdd00cb 100644
--- a/src/ext4.cc
+++ b/src/ext4.cc
@@ -34,7 +34,12 @@ FS ext4::get_filesystem_support()
 
 		if ( ! Glib::find_program_in_path( "dumpe2fs" ) .empty() )
 			fs .read = GParted::FS::EXTERNAL ;
-	
+
+		if ( ! Glib::find_program_in_path( "tune2fs" ) .empty() ) {
+			fs .read_uuid = FS::EXTERNAL ;
+			fs .write_uuid = FS::EXTERNAL ;
+		}
+
 		if ( ! Glib::find_program_in_path( "e2label" ) .empty() ) {
 			fs .read_label = FS::EXTERNAL ;
 			fs .write_label = FS::EXTERNAL ;
@@ -109,6 +114,29 @@ bool ext4::write_label( const Partition & partition, OperationDetail & operation
 	return ! execute_command( "e2label " + partition .get_path() + " \"" + partition .label + "\"", operationdetail ) ;
 }
 
+void ext4::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "tune2fs -l " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^Filesystem UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+		if (partition .uuid == "<none>")
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool ext4::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "tune2fs -U random " + partition .get_path(), operationdetail ) ;
+}
+
 bool ext4::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.ext4 -j -O extent -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/fat16.cc b/src/fat16.cc
index 2fe73c9..b510af9 100644
--- a/src/fat16.cc
+++ b/src/fat16.cc
@@ -44,9 +44,13 @@ FS fat16::get_filesystem_support()
 		fs .read = GParted::FS::EXTERNAL ;
 	}
 
+	if ( ! Glib::find_program_in_path( "mdir" ) .empty() )
+		fs .read_uuid = FS::EXTERNAL ;
+
 	if ( ! Glib::find_program_in_path( "mlabel" ) .empty() ) {
 		fs .read_label = FS::EXTERNAL ;
 		fs .write_label = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
 	}
 
 #ifndef HAVE_LIBPARTED_3_0_0_PLUS
@@ -155,6 +159,62 @@ bool fat16::write_label( const Partition & partition, OperationDetail & operatio
 	return ( exit_status == 0 );
 }
 
+void fat16::read_uuid( Partition & partition )
+{
+	//Create mtools config file
+	char fname[] = "/tmp/gparted-XXXXXXXX" ;
+	char dletter = 'H' ;
+	Glib::ustring err_msg = "" ;
+	err_msg = Utils::create_mtoolsrc_file( fname, dletter, partition.get_path() ) ;
+	if( err_msg.length() != 0 )
+		partition .messages .push_back( err_msg );
+
+	Glib::ustring cmd = String::ucompose( "export MTOOLSRC=%1 && mdir -f %2:", fname, dletter ) ;
+
+	if ( ! Utils::execute_command( cmd, output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "Volume Serial Number is[[:blank:]]([^[:space:]]+)" ) ;
+		if ( partition .uuid == "0000-0000" )
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool fat16::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	//Create mtools config file
+	char fname[] = "/tmp/gparted-XXXXXXXX" ;
+	char dletter = 'H' ;
+	Glib::ustring err_msg = "" ;
+	err_msg = Utils::create_mtoolsrc_file( fname, dletter, partition.get_path() ) ;
+
+	// Wait some time - 'random' UUIDs turn out identical if generated in quick succession...
+	sleep(1);
+	Glib::ustring cmd = String::ucompose( "export MTOOLSRC=%1 && mlabel -s -n %2:", fname, dletter ) ;
+
+	operationdetail .add_child( OperationDetail( cmd, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
+
+	int exit_status = Utils::execute_command( cmd, output, error ) ;
+
+	if ( ! output .empty() )
+		operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
+
+	if ( ! error .empty() )
+		operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
+
+	//Delete mtools config file
+	err_msg = Utils::delete_mtoolsrc_file( fname );
+
+	return ( exit_status == 0 );
+}
+
 bool fat16::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkdosfs -F16 -v -n \"" + Utils::fat_compliant_label( new_partition .label ) + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/fat32.cc b/src/fat32.cc
index 8860a5e..95a6f22 100644
--- a/src/fat32.cc
+++ b/src/fat32.cc
@@ -44,9 +44,13 @@ FS fat32::get_filesystem_support()
 		fs .read = GParted::FS::EXTERNAL ;
 	}
 
+	if ( ! Glib::find_program_in_path( "mdir" ) .empty() )
+		fs .read_uuid = FS::EXTERNAL ;
+
 	if ( ! Glib::find_program_in_path( "mlabel" ) .empty() ) {
 		fs .read_label = FS::EXTERNAL ;
 		fs .write_label = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
 	}
 
 #ifndef HAVE_LIBPARTED_3_0_0_PLUS
@@ -154,6 +158,63 @@ bool fat32::write_label( const Partition & partition, OperationDetail & operatio
 	return ( exit_status == 0 );
 }
 
+void fat32::read_uuid( Partition & partition )
+{
+	//Create mtools config file
+	char fname[] = "/tmp/gparted-XXXXXXXX" ;
+	char dletter = 'H' ;
+	Glib::ustring err_msg = "" ;
+	err_msg = Utils::create_mtoolsrc_file( fname, dletter, partition.get_path() ) ;
+	if( err_msg.length() != 0 )
+		partition .messages .push_back( err_msg );
+
+	Glib::ustring cmd = String::ucompose( "export MTOOLSRC=%1 && mdir -f %2:", fname, dletter ) ;
+
+	if ( ! Utils::execute_command( cmd, output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "Volume Serial Number is[[:blank:]]([^[:space:]]+)" ) ;
+		if ( partition .uuid == "0000-0000" )
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+
+bool fat32::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	//Create mtools config file
+	char fname[] = "/tmp/gparted-XXXXXXXX" ;
+	char dletter = 'H' ;
+	Glib::ustring err_msg = "" ;
+	err_msg = Utils::create_mtoolsrc_file( fname, dletter, partition.get_path() ) ;
+
+	// Wait some time - 'random' UUIDs turn out identical if generated in quick succession...
+	sleep(1);
+	Glib::ustring cmd = String::ucompose( "export MTOOLSRC=%1 && mlabel -s -n %2:", fname, dletter ) ;
+
+	operationdetail .add_child( OperationDetail( cmd, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
+
+	int exit_status = Utils::execute_command( cmd, output, error ) ;
+
+	if ( ! output .empty() )
+		operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
+
+	if ( ! error .empty() )
+		operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
+
+	//Delete mtools config file
+	err_msg = Utils::delete_mtoolsrc_file( fname );
+
+	return ( exit_status == 0 );
+}
+
 bool fat32::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkdosfs -F32 -v -n \"" + Utils::fat_compliant_label( new_partition .label ) + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/hfs.cc b/src/hfs.cc
index 0856aaa..525ea14 100644
--- a/src/hfs.cc
+++ b/src/hfs.cc
@@ -78,6 +78,15 @@ bool hfs::write_label( const Partition & partition, OperationDetail & operationd
 	return true ;
 }
 
+void hfs::read_uuid( Partition & partition )
+{
+}
+
+bool hfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool hfs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	Glib::ustring cmd = "";
diff --git a/src/hfsplus.cc b/src/hfsplus.cc
index 31925a0..f6c08e2 100644
--- a/src/hfsplus.cc
+++ b/src/hfsplus.cc
@@ -76,6 +76,15 @@ bool hfsplus::write_label( const Partition & partition, OperationDetail & operat
 	return true ;
 }
 
+void hfsplus::read_uuid( Partition & partition )
+{
+}
+
+bool hfsplus::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool hfsplus::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	Glib::ustring cmd = "";
diff --git a/src/jfs.cc b/src/jfs.cc
index 5410d46..fe1ecb5 100644
--- a/src/jfs.cc
+++ b/src/jfs.cc
@@ -29,12 +29,15 @@ FS jfs::get_filesystem_support()
 	FS fs ;
 	fs .filesystem = GParted::FS_JFS ;
 		
-	if ( ! Glib::find_program_in_path( "jfs_debugfs" ) .empty() )
+	if ( ! Glib::find_program_in_path( "jfs_debugfs" ) .empty() ) {
 		fs .read = GParted::FS::EXTERNAL ;
+		fs .read_uuid = GParted::FS::EXTERNAL ;
+	}
 	
 	if ( ! Glib::find_program_in_path( "jfs_tune" ) .empty() ) {
 		fs .read_label = FS::EXTERNAL ;
 		fs .write_label = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
 	}
 
 	if ( ! Glib::find_program_in_path( "mkfs.jfs" ) .empty() )
@@ -113,6 +116,29 @@ bool jfs::write_label( const Partition & partition, OperationDetail & operationd
 	return ! execute_command( "jfs_tune -L \"" + partition .label + "\" " + partition .get_path(), operationdetail ) ;
 }
 
+void jfs::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "echo su | jfs_debugfs " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "s_uuid:[[:blank:]]*([^[:space:]]+)" ) ;
+		if ( partition .uuid == "00000000-0000-0000-0000-000000000000" )
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool jfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "jfs_tune -U random " + partition .get_path(), operationdetail ) ;
+}
+
 bool jfs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.jfs -q -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/linux_swap.cc b/src/linux_swap.cc
index 3b0d292..aa345ef 100644
--- a/src/linux_swap.cc
+++ b/src/linux_swap.cc
@@ -38,7 +38,10 @@ FS linux_swap::get_filesystem_support()
 		fs .read_label = FS::EXTERNAL ;
 
 	if ( ! Glib::find_program_in_path( "swaplabel" ) .empty() )
-		fs .write_label = FS::EXTERNAL ;
+	{
+		fs .read_uuid = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
+	}
 
 	fs .copy = GParted::FS::EXTERNAL ;
 	fs .move = GParted::FS::EXTERNAL ;
@@ -71,6 +74,28 @@ bool linux_swap::write_label( const Partition & partition, OperationDetail & ope
 	return ! execute_command( "swaplabel -L \"" + partition .label + "\" " + partition .get_path(), operationdetail ) ;
 }
 
+void linux_swap::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "swaplabel " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+
+bool linux_swap::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "swaplabel -U \"" + Utils::generate_uuid() + "\" " + partition .get_path(), operationdetail ) ;
+}
+
 bool linux_swap::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkswap -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/nilfs2.cc b/src/nilfs2.cc
index bf66b85..2ac7085 100644
--- a/src/nilfs2.cc
+++ b/src/nilfs2.cc
@@ -36,6 +36,8 @@ FS nilfs2::get_filesystem_support()
 		fs .read = GParted::FS::EXTERNAL ;
 		fs .read_label = GParted::FS::EXTERNAL ;
 		fs .write_label = GParted::FS::EXTERNAL ;
+		fs .read_uuid = GParted::FS::EXTERNAL ;
+		fs .write_uuid = GParted::FS::EXTERNAL ;
 	}
 
         //Nilfs2 resizing is an online only operation and needs:
@@ -127,6 +129,29 @@ bool nilfs2::write_label( const Partition & partition, OperationDetail & operati
 	return ! execute_command( "nilfs-tune -L \"" + partition .label + "\" " + partition .get_path(), operationdetail ) ;
 }
 
+void nilfs2::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "nilfs-tune -l " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^Filesystem UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+		if (partition .uuid == "00000000-0000-0000-0000-000000000000")
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool nilfs2::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "nilfs-tune -U " + Utils::generate_uuid() + " " + partition .get_path(), operationdetail ) ;
+}
+
 bool nilfs2::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.nilfs2 -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/ntfs.cc b/src/ntfs.cc
index ce11631..7223cb5 100644
--- a/src/ntfs.cc
+++ b/src/ntfs.cc
@@ -104,6 +104,15 @@ bool ntfs::write_label( const Partition & partition, OperationDetail & operation
 	return ! execute_command( "ntfslabel --force " + partition .get_path() + " \"" + partition .label + "\"", operationdetail ) ;
 }
 
+void ntfs::read_uuid( Partition & partition )
+{
+}
+
+bool ntfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool ntfs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkntfs -Q -v -L \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/reiser4.cc b/src/reiser4.cc
index f36e7c1..859b8f3 100644
--- a/src/reiser4.cc
+++ b/src/reiser4.cc
@@ -37,7 +37,10 @@ FS reiser4::get_filesystem_support()
 		fs .create = GParted::FS::EXTERNAL ;
 	
 	if ( ! Glib::find_program_in_path( "fsck.reiser4" ) .empty() )
+	{
+		fs .read_uuid = GParted::FS::EXTERNAL ;
 		fs .check = GParted::FS::EXTERNAL ;
+	}
 	
 
 	if ( fs .check )
@@ -102,6 +105,27 @@ bool reiser4::write_label( const Partition & partition, OperationDetail & operat
 	return true ;
 }
 
+void reiser4::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "fsck.reiser4 --check --yes " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( error, "uuid:[[:blank:]]*([^[:space:]]*)" ) ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool reiser4::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool reiser4::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkfs.reiser4 --yes --label \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ; 
diff --git a/src/reiserfs.cc b/src/reiserfs.cc
index 9409d10..fc7a564 100644
--- a/src/reiserfs.cc
+++ b/src/reiserfs.cc
@@ -34,7 +34,11 @@ FS reiserfs::get_filesystem_support()
 	}
 
 	if ( ! Glib::find_program_in_path( "reiserfstune" ) .empty() )
+	{
 		fs .write_label = FS::EXTERNAL ;
+		fs .read_uuid = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
+	}
 
 	if ( ! Glib::find_program_in_path( "mkreiserfs" ) .empty() )
 		fs .create = GParted::FS::EXTERNAL ;
@@ -112,6 +116,27 @@ bool reiserfs::write_label( const Partition & partition, OperationDetail & opera
 	return ! execute_command( "reiserfstune --label \"" + partition .label + "\" " + partition .get_path(), operationdetail ) ;
 }
 
+void reiserfs::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "reiserfstune " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^UUID:[[:blank:]]*([^[:space:]]*)" ) ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool reiserfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "reiserfstune -u random " + partition .get_path(), operationdetail ) ;
+}
+
 bool reiserfs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return ! execute_command( "mkreiserfs -f --label \"" + new_partition .label + "\" " + new_partition .get_path(), operationdetail ) ;
diff --git a/src/ufs.cc b/src/ufs.cc
index 80b8cfe..80f572f 100644
--- a/src/ufs.cc
+++ b/src/ufs.cc
@@ -47,6 +47,15 @@ bool ufs::write_label( const Partition & partition, OperationDetail & operationd
 	return true ;
 }
 
+void ufs::read_uuid( Partition & partition )
+{
+}
+
+bool ufs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return true ;
+}
+
 bool ufs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	return true ;
diff --git a/src/xfs.cc b/src/xfs.cc
index 90562c4..6f4e160 100644
--- a/src/xfs.cc
+++ b/src/xfs.cc
@@ -36,7 +36,11 @@ FS xfs::get_filesystem_support()
 	}
 
 	if ( ! Glib::find_program_in_path( "xfs_admin" ) .empty() ) 	
+	{
 		fs .write_label = FS::EXTERNAL ;
+		fs .read_uuid = FS::EXTERNAL ;
+		fs .write_uuid = FS::EXTERNAL ;
+	}
 
 	if ( ! Glib::find_program_in_path( "mkfs.xfs" ) .empty() ) 	
 		fs .create = GParted::FS::EXTERNAL ;
@@ -126,6 +130,29 @@ bool xfs::write_label( const Partition & partition, OperationDetail & operationd
 	return ! execute_command( cmd, operationdetail ) ;
 }
 
+void xfs::read_uuid( Partition & partition )
+{
+	if ( ! Utils::execute_command( "xfs_admin -u " + partition .get_path(), output, error, true ) )
+	{
+		partition .uuid = Utils::regexp_label( output, "^UUID[[:blank:]]*=[[:blank:]]*([^[:space:]]*)" ) ;
+		if (partition .uuid == "00000000-0000-0000-0000-000000000000")
+			partition .uuid .clear() ;
+	}
+	else
+	{
+		if ( ! output .empty() )
+			partition .messages .push_back( output ) ;
+
+		if ( ! error .empty() )
+			partition .messages .push_back( error ) ;
+	}
+}
+
+bool xfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+	return ! execute_command( "xfs_admin -U generate " + partition .get_path(), operationdetail ) ;
+}
+
 bool xfs::create( const Partition & new_partition, OperationDetail & operationdetail )
 {
 	//mkfs.xfs will not create file system if label is longer than 12 characters, hence truncation.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]