[gparted] Refactor GParted internal file system signature detection (#741430)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Refactor GParted internal file system signature detection (#741430)
- Date: Mon, 9 Mar 2015 16:36:20 +0000 (UTC)
commit cb645b16cf6cb6f0d04b693440e88c8d994aac52
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Tue Dec 23 18:22:04 2014 +0000
Refactor GParted internal file system signature detection (#741430)
Refactor GParted internal file system signature detection to remove code
duplication. There were 5 separate copies of code to: allocate a
buffer, open, read and close the device, free the buffer and compare the
signature.
Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
drive
include/GParted_Core.h | 1 +
src/GParted_Core.cc | 195 ++++++++++++++++++++---------------------------
2 files changed, 84 insertions(+), 112 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index 819cfdf..1f497c3 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -78,6 +78,7 @@ private:
static void read_mountpoints_from_mount_command( std::map< Glib::ustring, std::vector<Glib::ustring>
& map ) ;
Glib::ustring get_partition_path( PedPartition * lp_partition ) ;
void set_device_partitions( Device & device, PedDevice* lp_device, PedDisk* lp_disk ) ;
+ static FILESYSTEM recognise_filesystem_signature( PedDevice * lp_device, PedPartition * lp_partition
);
GParted::FILESYSTEM get_filesystem( PedDevice* lp_device, PedPartition* lp_partition,
std::vector<Glib::ustring>& messages ) ;
void read_label( Partition & partition ) ;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 650960c..dee3d34 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1245,11 +1245,86 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
insert_unallocated( device .get_path(), device .partitions, 0, device .length -1, device
.sector_size, false ) ;
}
+// GParted simple internal file system signature detection. Use sparingly. Only when
+// (old versions of) blkid and libparted don't recognise a signature.
+FILESYSTEM GParted_Core::recognise_filesystem_signature( PedDevice * lp_device, PedPartition * lp_partition )
+{
+ char magic1[16]; // Big enough for largest signatures[].sig1 or sig2
+ char magic2[16];
+ FILESYSTEM fstype = FS_UNKNOWN;
+
+ char * buf = static_cast<char *>( malloc( lp_device->sector_size ) );
+ if ( ! buf )
+ return FS_UNKNOWN;
+
+ if ( ! ped_device_open( lp_device ) )
+ {
+ free( buf );
+ return FS_UNKNOWN;
+ }
+
+ struct {
+ Byte_Value offset1;
+ const char * sig1;
+ Byte_Value offset2;
+ const char * sig2;
+ FILESYSTEM fstype;
+ } signatures[] = {
+ //offset1, sig1 , offset2, sig2 , fstype
+ { 65536LL, "ReIsEr4" , 0LL, NULL , FS_REISER4 },
+ { 512LL, "LABELONE" , 536LL, "LVM2", FS_LVM2_PV },
+ { 0LL, "LUKS\xBA\xBE", 0LL, NULL , FS_LUKS },
+ { 65600LL, "_BHRfS_M" , 0LL, NULL , FS_BTRFS },
+ { 3LL, "-FVE-FS-" , 0LL, NULL , FS_BITLOCKER }
+ };
+ // Reference:
+ // Detecting BitLocker
+ // http://blogs.msdn.com/b/si_team/archive/2006/10/26/detecting-bitlocker.aspx
+ // Consider validation of BIOS Parameter Block fields as unnecessary for
+ // simple recognition only of BitLocker.
+
+ for ( unsigned int i = 0 ; i < sizeof( signatures ) / sizeof( signatures[0] ) ; i ++ )
+ {
+ const size_t len1 = std::min( ( signatures[i].sig1 == NULL ) ? 0U : strlen(
signatures[i].sig1 ),
+ sizeof( magic1 ) );
+ const size_t len2 = std::min( ( signatures[i].sig2 == NULL ) ? 0U : strlen(
signatures[i].sig2 ),
+ sizeof( magic2 ) );
+ // NOTE: From this point onwards signatures[].sig1 and .sig2 are treated
+ // as character buffers of known lengths len1 and len2, not NUL terminated
+ // strings.
+ if ( len1 == 0UL || ( signatures[i].sig2 != NULL && len2 == 0UL ) )
+ continue; // Don't allow 0 length signatures to match
+
+ memset( buf, 0, lp_device->sector_size );
+ if ( ped_geometry_read( &lp_partition->geom, buf, signatures[i].offset1 /
lp_device->sector_size, 1 ) != 0 )
+ {
+ memcpy( magic1, buf + signatures[i].offset1 % lp_device->sector_size, len1 );
+
+ // WARNING: This assumes offset2 is in the same sector as offset1
+ if ( signatures[i].sig2 != NULL )
+ {
+ memcpy( magic2, buf + signatures[i].offset2 % lp_device->sector_size, len2 );
+ }
+
+ if ( memcmp( magic1, signatures[i].sig1, len1 ) == 0 &&
+ ( signatures[i].sig2 != NULL ||
+ memcmp( magic2, signatures[i].sig2, len2 ) == 0 ) )
+ {
+ fstype = signatures[i].fstype;
+ break;
+ }
+ }
+ }
+
+ ped_device_close( lp_device );
+ free( buf );
+
+ return fstype;
+}
+
GParted::FILESYSTEM GParted_Core::get_filesystem( PedDevice* lp_device, PedPartition* lp_partition,
std::vector<Glib::ustring>& messages )
{
- char magic1[16] = "";
- char magic2[16] = "";
FS_Info fs_info ;
Glib::ustring fs_type = "" ;
static Glib::ustring luks_unsupported = _("Linux Unified Key Setup encryption is not yet supported.");
@@ -1336,118 +1411,14 @@ GParted::FILESYSTEM GParted_Core::get_filesystem( PedDevice* lp_device, PedParti
return FS_REFS;
}
-
-
- //other file systems libparted couldn't detect (i've send patches for these file systems to the
parted guys)
- // - no patches sent to parted for lvm2, or luks
-
- //reiser4
- char * buf = static_cast<char *>( malloc( lp_device->sector_size ) );
- if ( buf )
- {
- ped_device_open( lp_device );
- ped_geometry_read( & lp_partition ->geom
- , buf
- , (65536 / lp_device ->sector_size)
- , 1
- ) ;
- memcpy(magic1, buf+0, 7) ; //set binary magic data
- ped_device_close( lp_device );
- free( buf ) ;
-
- if ( 0 == memcmp( magic1, "ReIsEr4", 7 ) )
- return GParted::FS_REISER4 ;
- }
-
- //lvm2
- //NOTE: lvm2 is not a file system but we do wish to recognize the Physical Volume
- buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
- if ( buf )
- {
- ped_device_open( lp_device );
- if ( lp_device ->sector_size == 512 )
- {
- ped_geometry_read( & lp_partition ->geom, buf, 1, 1 ) ;
- memcpy(magic1, buf+ 0, 8) ; // set binary magic data
- memcpy(magic2, buf+24, 4) ; // set binary magic data
- }
- else
- {
- ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) ;
- memcpy(magic1, buf+ 0+512, 8) ; // set binary magic data
- memcpy(magic2, buf+24+512, 4) ; // set binary magic data
- }
- ped_device_close( lp_device );
- free( buf ) ;
-
- if ( 0 == memcmp( magic1, "LABELONE", 8 )
- && 0 == memcmp( magic2, "LVM2", 4 ) )
- {
- return GParted::FS_LVM2_PV ;
- }
- }
-
- //LUKS encryption
- buf = static_cast<char *>( malloc( lp_device->sector_size ) );
- if ( buf )
+ // Fallback to GParted simple internal file system detection
+ if ( lp_partition )
{
- ped_device_open( lp_device );
- ped_geometry_read( & lp_partition->geom, buf, 0, 1 );
- memcpy(magic1, buf+0, 6); // set binary magic data
- ped_device_close( lp_device );
- free( buf );
-
- if ( 0 == memcmp( magic1 , "LUKS\xBA\xBE", 6 ) )
- {
+ FILESYSTEM fstype = recognise_filesystem_signature( lp_device, lp_partition );
+ if ( fstype == FS_LUKS )
messages.push_back( luks_unsupported );
- return FS_LUKS;
- }
- }
-
- //btrfs
- const Sector BTRFS_SUPER_INFO_SIZE = 4096 ;
- const Sector BTRFS_SUPER_INFO_OFFSET = (64 * 1024) ;
- const char* const BTRFS_SIGNATURE = "_BHRfS_M" ;
-
- char buf_btrfs[BTRFS_SUPER_INFO_SIZE] ;
-
- ped_device_open( lp_device ) ;
- ped_geometry_read( & lp_partition ->geom
- , buf_btrfs
- , (BTRFS_SUPER_INFO_OFFSET / lp_device ->sector_size)
- , (BTRFS_SUPER_INFO_SIZE / lp_device ->sector_size)
- ) ;
- memcpy(magic1, buf_btrfs+64, strlen(BTRFS_SIGNATURE) ) ; //set binary magic data
- ped_device_close( lp_device ) ;
-
- if ( 0 == memcmp( magic1, BTRFS_SIGNATURE, strlen(BTRFS_SIGNATURE) ) )
- {
- return GParted::FS_BTRFS ;
- }
-
- //bitlocker
- // Detecting BitLocker
- // http://blogs.msdn.com/b/si_team/archive/2006/10/26/detecting-bitlocker.aspx
- // Validation of BIOS Parameter Block fields is unnecessary for recognition only
- const size_t BITLOCKER_SIG_OFFSET = 3UL ;
- const char * const BITLOCKER_SIGNATURE = "-FVE-FS-" ;
- const size_t BITLOCKER_SIG_LEN = strlen( BITLOCKER_SIGNATURE ) ;
- buf = static_cast<char *>( malloc( lp_device ->sector_size ) ) ;
- if ( buf )
- {
- memset( buf, 0, lp_device ->sector_size ) ;
- if ( ped_device_open( lp_device ) )
- {
- if ( ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) != 0 )
- {
- memcpy( magic1, buf + BITLOCKER_SIG_OFFSET, BITLOCKER_SIG_LEN ) ;
- }
- ped_device_close( lp_device );
- }
- free( buf ) ;
-
- if ( 0 == memcmp( magic1, BITLOCKER_SIGNATURE, BITLOCKER_SIG_LEN ) )
- return FS_BITLOCKER ;
+ if ( fstype != FS_UNKNOWN )
+ return fstype;
}
//no file system found....
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]