Remove Attempt Data Rescue and use of gpart (!118)

gpart scans a drive trying to guess the location of partitions when an
MBR partition table is lost [1].  However the tool is unmaintained,
takes hours or days of 100% CPU time to scan a drive and provides no
progress indication [2][3][4].  We keep recommending killing the gpart
process and using TestDisk [5] instead.

Therefore remove Device > Attempt Data Rescue and the use of gpart from
GParted.

[1] Gpart
    https://github.com/baruch/gpart
[2] Have you had a good or bad experience with Dev->Attempt Data Rescue?
    http://gparted-forum.surf4.info/viewtopic.php?id=17992
    No good, only bad experiences using gpart were reported.
[3] Gparted does not say anything
    http://gparted-forum.surf4.info/viewtopic.php?id=17749
    Forum user reported waiting 48 hours with no progress indication.
    We recommended using TestDisk.
[4] How cancel Data Rescue process?
    http://gparted-forum.surf4.info/viewtopic.php?id=18143
    Forum user reported it will take 3 days to scan their external 480GB
    drive.  We recommended using TestDisk instead.
[5] TestDisk, Data Recovery
    https://www.cgsecurity.org/wiki/TestDisk

Closes !118 - Remove Attempt Data Rescue and use of gpart
This commit is contained in:
Mike Fleetwood 2023-09-25 20:56:55 +01:00 committed by Curtis Gedak
parent 2febe04665
commit 8ce9074ac6
12 changed files with 0 additions and 679 deletions

5
README
View File

@ -308,11 +308,6 @@ For LUKS support the following commands are required:
dmsetup - Device-mapper administration tool dmsetup - Device-mapper administration tool
For attempt data rescue for lost partitions, the following package
is required:
gpart - guesses PC-type hard disk partitions
Several more commands are optionally used by GParted if found on the Several more commands are optionally used by GParted if found on the
system. These commands include: system. These commands include:

View File

@ -1,76 +0,0 @@
/* Copyright (C) 2010 Joan Lledó
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* The dialog for mount old data
* Reads the output of gpart and build the dialog
* */
#ifndef GPARTED_DIALOG_RESCUE_DATA_H
#define GPARTED_DIALOG_RESCUE_DATA_H
#include "Device.h"
#include "Partition.h"
#include "PartitionVector.h"
#include <gtkmm/dialog.h>
#include <gtkmm/frame.h>
#include <vector>
namespace GParted
{
class Dialog_Rescue_Data : public Gtk::Dialog
{
public:
Dialog_Rescue_Data();
void init_partitions(Device *parentDevice, const Glib::ustring &buff);
bool found_partitions();
private:
void draw_dialog();
void create_list_of_fs();
bool is_overlaping(int nPart);
void read_partitions_from_buffer();
void check_overlaps(int nPart);
void open_ro_view(Glib::ustring mountPoint);
bool is_inconsistent(const Partition &part);
Device *device; //Parent device
PartitionVector partitions; //Partitions read from the buffer
std::vector<int> overlappedPartitions;//List of guessed partitions that
//overlap active partitions
Glib::ustring device_path;
Sector device_length;
bool inconsistencies; //If some of the guessed partitions is inconsistent
int sector_size;
std::vector<int>inconsistencies_list; //List of inconsistent partitions
// Output of gpart command
std::istringstream *buffer;
//GUI stuff
Gtk::Frame *frm;
//Callback
void on_view_clicked(int nPart);
};
} //GParted
#endif /* GPARTED_DIALOG_RESCUE_DATA_H */

View File

@ -54,7 +54,6 @@ public:
void set_user_devices( const std::vector<Glib::ustring> & user_devices ) ; void set_user_devices( const std::vector<Glib::ustring> & user_devices ) ;
void set_devices( std::vector<Device> & devices ) ; void set_devices( std::vector<Device> & devices ) ;
void set_devices_thread( std::vector<Device> * pdevices ); void set_devices_thread( std::vector<Device> * pdevices );
void guess_partition_table(const Device & device, Glib::ustring &buff);
bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error); bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error);
bool apply_operation_to_disk( Operation * operation ); bool apply_operation_to_disk( Operation * operation );
@ -241,7 +240,6 @@ private:
std::vector<Glib::ustring> device_paths ; std::vector<Glib::ustring> device_paths ;
bool probe_devices ; bool probe_devices ;
Glib::ustring thread_status_message; //Used to pass data to show_pulsebar method Glib::ustring thread_status_message; //Used to pass data to show_pulsebar method
Glib::RefPtr<Glib::IOChannel> iocInput, iocOutput; // Used to send data to gpart command
static SupportedFileSystems* supported_filesystems; static SupportedFileSystems* supported_filesystems;
}; };

View File

@ -18,7 +18,6 @@ noinst_HEADERS = \
Dialog_Partition_New.h \ Dialog_Partition_New.h \
Dialog_Partition_Resize_Move.h \ Dialog_Partition_Resize_Move.h \
Dialog_Progress.h \ Dialog_Progress.h \
Dialog_Rescue_Data.h \
DrawingAreaVisualDisk.h \ DrawingAreaVisualDisk.h \
FS_Info.h \ FS_Info.h \
FileSystem.h \ FileSystem.h \

View File

@ -179,7 +179,6 @@ public:
static void split( const Glib::ustring& str, static void split( const Glib::ustring& str,
std::vector<Glib::ustring>& result, std::vector<Glib::ustring>& result,
const Glib::ustring& delimiters ) ; const Glib::ustring& delimiters ) ;
static int convert_to_int(const Glib::ustring & src);
static Glib::ustring generate_uuid(void); static Glib::ustring generate_uuid(void);
static int get_mounted_filesystem_usage( const Glib::ustring & mountpoint, static int get_mounted_filesystem_usage( const Glib::ustring & mountpoint,
Byte_Value & fs_size, Byte_Value & fs_free, Byte_Value & fs_size, Byte_Value & fs_free,

View File

@ -191,7 +191,6 @@ private:
void toggle_fs_busy_state(); void toggle_fs_busy_state();
void activate_mount_partition( unsigned int index ) ; void activate_mount_partition( unsigned int index ) ;
void activate_disklabel() ; void activate_disklabel() ;
void activate_attempt_rescue_data();
void activate_manage_flags() ; void activate_manage_flags() ;
void activate_check() ; void activate_check() ;
void activate_change_uuid() ; void activate_change_uuid() ;

View File

@ -19,7 +19,6 @@ src/Dialog_Partition_Resize_Move.cc
src/Dialog_Progress.cc src/Dialog_Progress.cc
src/DialogFeatures.cc src/DialogFeatures.cc
src/DialogManageFlags.cc src/DialogManageFlags.cc
src/Dialog_Rescue_Data.cc
src/DMRaid.cc src/DMRaid.cc
src/FileSystem.cc src/FileSystem.cc
src/GParted_Core.cc src/GParted_Core.cc

View File

@ -1,502 +0,0 @@
/* Copyright (C) 2010 Joan Lledó
* Copyright (C) 2011 Curtis Gedak
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "Utils.h"
#include "Dialog_Rescue_Data.h"
#include "Partition.h"
#include <glibmm/stringutils.h>
#include <glibmm/shell.h>
#include <gtk/gtk.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/stock.h>
#include <gtkmm/checkbutton.h>
#include <sstream>
#include <cerrno>
namespace GParted
{
#define tmp_prefix P_tmpdir "/gparted-roview-XXXXXX"
//The constructor creates a empty dialog
Dialog_Rescue_Data::Dialog_Rescue_Data()
{
this ->set_title( _("Search disk for file systems") );
this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE );
}
//getters
bool Dialog_Rescue_Data::found_partitions()
{
return this->partitions.size() > 0;
}
// Draws the dialog
void Dialog_Rescue_Data::draw_dialog()
{
Glib::ustring *message;
/*TO TRANSLATORS: looks like File systems found on /dev/sdb */
this ->set_title( Glib::ustring::compose( _("File systems found on %1"), this->device_path ) );
message=new Glib::ustring("<big><b>");
if(!this->inconsistencies)
{
message->append(_("Data found"));
}
else
{
message->append(_("Data found with inconsistencies"));
Glib::ustring msg_label=_("WARNING!: The file systems marked with (!) are inconsistent.");
msg_label.append("\n");
msg_label.append(_("You might encounter errors trying to view these file systems."));
Gtk::Label *inconsis_label=manage(Utils::mk_label(msg_label));
inconsis_label->override_color(Gdk::RGBA("red"), Gtk::STATE_FLAG_NORMAL);
this->get_content_area()->pack_end(*inconsis_label, Gtk::PACK_SHRINK, 5);
}
message->append("</b></big>");
this->get_content_area()->set_spacing(5);
Gtk::Label *msgLbl=Utils::mk_label(*message);
this->get_content_area()->pack_start(*msgLbl, Gtk::PACK_SHRINK);
this->create_list_of_fs();
Glib::ustring info_txt=_("The 'View' buttons create read-only views of each file system.");
info_txt+="\n";
info_txt+=_("All mounted views will be unmounted when you close this dialog.");
Gtk::Box *infoBox = manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
Gtk::Image *infoImg = Utils::mk_image(Gtk::Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG);
Gtk::Label *infoLabel= manage(new Gtk::Label (info_txt));
infoBox->pack_start(*infoImg, Gtk::PACK_SHRINK, 5);
infoBox->pack_start(*infoLabel, Gtk::PACK_SHRINK);
this->get_content_area()->pack_start(*infoBox, Gtk::PACK_SHRINK);
this->show_all_children();
delete message;
}
/*
* Create the list of the filesystems found */
void Dialog_Rescue_Data::create_list_of_fs()
{
Gtk::Box *vb = manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
vb->set_border_width(5);
vb->set_spacing(5);
this->frm=Gtk::manage(new Gtk::Frame(_("File systems")));
this->frm->add(*vb);
for(unsigned int i=0;i<this->partitions.size();i++)
{
if (this->partitions[i].fstype == FS_UNALLOCATED ||
this->partitions[i].fstype == FS_UNKNOWN ||
this->partitions[i].fstype == FS_UNFORMATTED ||
this->partitions[i].fstype == FS_EXTENDED ||
this->partitions[i].type == TYPE_EXTENDED ||
this->partitions[i].type == TYPE_UNALLOCATED )
{
continue;
}
std::string fs_name = Utils::get_filesystem_string(this->partitions[i].fstype);
if (this->partitions[i].fstype == FS_EXT2)
{
fs_name+="/3/4, ReiserFs or XFS";
}
/*TO TRANSLATORS: looks like 1: ntfs (10240 MiB)*/
Gtk::Label *fsLbl= manage(new Gtk::Label( Glib::ustring::compose(_("#%1: %2 (%3 MiB)"), i+1, fs_name, (this->partitions[i].get_byte_length()/1024/1024))));
if(this->is_inconsistent(this->partitions[i]))
{
fsLbl->set_label(fsLbl->get_label().append(" (!)"));
}
Gtk::Box *hb = manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
Gtk::Button *btn=manage(new Gtk::Button(_("View")));
btn->signal_clicked().connect(sigc::bind(sigc::mem_fun(this, &Dialog_Rescue_Data::on_view_clicked), i));
hb->pack_start(*fsLbl, Gtk::PACK_SHRINK);
hb->pack_end(*btn, Gtk::PACK_SHRINK);
vb->pack_start(*hb, Gtk::PACK_SHRINK);
}
this->get_content_area()->pack_start(*this->frm, Gtk::PACK_SHRINK);
}
/*
* Callback function for "View" button */
void Dialog_Rescue_Data::on_view_clicked(int nPart)
{
const Partition & part = this->partitions[nPart];
Byte_Value initOffset=this->sector_size*part.sector_start;
Sector numSectors=part.sector_end-part.sector_start+1;
Byte_Value totalSize=this->sector_size*numSectors;
this->check_overlaps(nPart);
char tmpDir[32]=tmp_prefix;
char * tmpDirResult = mkdtemp(tmpDir);
if (tmpDirResult == nullptr)
{
Glib::ustring error_txt = _("An error occurred while creating a temporary directory for use as a mount point.");
error_txt += "\n";
error_txt += _("Error");
error_txt += ":\n";
error_txt += Glib::strerror( errno );
//Dialog information
Gtk::MessageDialog errorDialog(*this, "", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
errorDialog.set_message(_("Failed creating temporary directory"));
errorDialog.set_secondary_text(error_txt);
errorDialog.run();
return;
}
Glib::ustring mountPoint=tmpDir;
Glib::ustring commandLine = "mount -o ro,loop,offset=" + Utils::num_to_str(initOffset) +
",sizelimit=" + Utils::num_to_str(totalSize) +
" " + Glib::shell_quote(this->device_path) +
" " + Glib::shell_quote(mountPoint);
int mountResult=Utils::execute_command(commandLine);
if(mountResult!=0)
{
Glib::ustring error_txt=_("An error occurred while creating the read-only view.");
error_txt+="\n";
error_txt+=_("Either the file system can not be mounted (like swap), or there are inconsistencies or errors in the file system.");
//Dialog information
Gtk::MessageDialog errorDialog(*this, "", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
errorDialog.set_message(_("Failed creating read-only view"));
errorDialog.set_secondary_text(error_txt);
errorDialog.run();
return;
}
this->open_ro_view(mountPoint);
}
/* Opens the default browser in a directory */
void Dialog_Rescue_Data::open_ro_view(Glib::ustring mountPoint)
{
GError* error = nullptr;
GdkScreen* gscreen = nullptr;
Glib::ustring uri = "file:" + mountPoint ;
gscreen = gdk_screen_get_default() ;
gtk_show_uri( gscreen, uri .c_str(), gtk_get_current_event_time(), &error ) ;
if (error != nullptr)
{
Glib::ustring sec_text(_("Error:"));
sec_text.append("\n");
sec_text.append(error ->message);
sec_text.append("\n");
sec_text.append("\n");
/*TO TRANSLATORS: looks like
* The file system is mounted on:
* /tmp/gparted-roview-Nlhb3R. */
sec_text.append(_("The file system is mounted on:"));
sec_text.append("\n");
sec_text.append("<b>"+mountPoint+"</b>");
Gtk::MessageDialog dialog( *this
, _( "Unable to open the default file manager" )
, false
, Gtk::MESSAGE_ERROR
, Gtk::BUTTONS_OK
, true
) ;
dialog .set_secondary_text( sec_text, true ) ;
dialog .run() ;
}
}
/*
* Checks if a guessed filesystem is overlapping other one and
* shows the dialog to umount it */
void Dialog_Rescue_Data::check_overlaps(int nPart)
{
if(is_overlaping(nPart))
{
Gtk::MessageDialog overlapDialog(*this, "", true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
overlapDialog.set_message(_("Warning: The detected file system area overlaps with at least one existing partition"));
Glib::ustring sec_text=_("It is recommended that you do not use any overlapping file systems to avoid disturbing existing data.");
sec_text+="\n";
sec_text+=_("Do you want to try to deactivate the following mount points?");
for(unsigned int i=0;i<this->overlappedPartitions.size(); i++)
{
const Glib::ustring& ovrDevPath = this->device->partitions[i].get_path();
const Glib::ustring& ovrDevMountPoint = this->device->partitions[i].get_mountpoint();
sec_text+="\n"+ovrDevPath+" mounted on "+ovrDevMountPoint;
}
overlapDialog.set_secondary_text(sec_text);
if(overlapDialog.run()==Gtk::RESPONSE_YES)
{
for(unsigned int i=0;i<this->overlappedPartitions.size(); i++)
{
const Glib::ustring& mountP=this->device->partitions[i].get_mountpoint();
Glib::ustring commandUmount = "umount " + Glib::shell_quote(mountP);
Utils::execute_command(commandUmount);
}
}
}
}
/*
* Reads the output of gpart and sets some private variables */
void Dialog_Rescue_Data::init_partitions(Device *parentDevice, const Glib::ustring & buff)
{
this->device=parentDevice;
this->device_path=parentDevice->get_path();
this->device_length=parentDevice->length;
this->sector_size=parentDevice->sector_size;
this->buffer=new std::istringstream(buff);
this->inconsistencies=false;
std::string line;
while(getline(*this->buffer, line))
{
//If gpart finds inconsistencies, might not be able to mount some partitions
if(line.find("Number of inconsistencies found")!=Glib::ustring::npos)
{
this->inconsistencies=true;
}
//Read the primary partition table
// (gpart only finds primary partitions)
if(line.find("Guessed primary partition table:")!=Glib::ustring::npos)
{
this->read_partitions_from_buffer();
}
}
this->draw_dialog();
}
/* Reads the output of gpart and builds the vector of guessed partitions */
void Dialog_Rescue_Data::read_partitions_from_buffer()
{
this->partitions.clear();
std::string line;
while(getline(*this->buffer, line))
{
if(line.find("Primary partition")!=line.npos)
{
// Parameters of Partition::Set
Glib::ustring dev_path=this->device_path;
Glib::ustring part_path;
int part_num;
PartitionType type = TYPE_PRIMARY;
FSType fs = FS_UNALLOCATED;
Sector sec_start=0;
Sector sec_end=0;
Byte_Value sec_size=this->sector_size;
// Get the part_num
Glib::ustring num=Utils::regexp_label(line, "^Primary partition\\(+([0-9])+\\)$");
part_num=Utils::convert_to_int(num);
//Get the part_path
part_path=Glib::ustring::compose( "%1%2", this->device_path, num );
while(getline(*this->buffer, line))
{
if(line=="")
{
break;
}
if(line.find("type:")!=Glib::ustring::npos)
{
//Get the filesystem (needed for set the color of the visual partition)
int code=Utils::convert_to_int(Utils::regexp_label(line, "^[\t ]+type: +([0-9]+)+\\(+[a-zA-Z0-9]+\\)\\(+.+\\)$"));
switch (code)
{
case 0x83: //FS code for ext2, reiserfs and xfs
{
fs = FS_EXT2;
break;
}
case 0x18:
case 0x82:
case 0xB8: //SWAP partition
{
fs = FS_LINUX_SWAP;
break;
}
case 0x04:
case 0x14:
case 0x86:
case 0xE4: //FAT16
{
fs = FS_FAT16;
break;
}
case 0x0B:
case 0x0C: //FAT32
{
fs = FS_FAT32;
break;
}
case 0x07: //NTFS, HPFS, exFAT and UDF
{
fs = FS_NTFS;
break;
}
case 0x05:
case 0x0F:
case 0x85: //Extended
{
fs = FS_EXTENDED;
type = TYPE_EXTENDED;
break;
}
default:
{
fs = FS_UNKNOWN;
}
}
}
if(line.find("size:")!=Glib::ustring::npos)
{
// Get the start sector
sec_start=Utils::convert_to_int(Utils::regexp_label(line, "^[\t ]+size: [0-9]+mb #s\\(+[0-9]+\\) s\\(+([0-9]+)+\\-+[0-9]+\\)$"));
// Get the end sector
sec_end=Utils::convert_to_int(Utils::regexp_label(line, "^[\t ]+size: [0-9]+mb #s\\(+[0-9]+\\) s\\(+[0-9]+\\-+([0-9]+)+\\)$"));
}
}
//No part found
if(sec_start==0 && sec_end==0)
{
continue;
}
//Swap partitions don't contain data
if (fs == FS_LINUX_SWAP)
{
continue;
}
Partition * part = new Partition();
part->Set( dev_path, part_path, part_num,
type, fs, sec_start, sec_end, sec_size, false, false );
this->partitions.push_back_adopt( part );
}
}
}
/*
* Checks if the guessed partition is overlapping some active partition
*/
bool Dialog_Rescue_Data::is_overlaping(int nPart)
{
bool result=false;
Sector start_sector=this->partitions[nPart].sector_start;
Sector end_sector=this->partitions[nPart].sector_end;
for(unsigned int j=0;j<this->device->partitions.size();j++)
{
//only check if the partition if mounted
if(this->device->partitions[j].get_mountpoint()=="")
{
continue;
}
//If the start sector is inside other partition
if(start_sector>this->device->partitions[j].sector_start &&
start_sector<this->device->partitions[j].sector_end)
{
this->overlappedPartitions.push_back(j);
result=true;
continue;
}
//If the end sector is inside other partition
if(end_sector>this->device->partitions[j].sector_start &&
end_sector<this->device->partitions[j].sector_end)
{
this->overlappedPartitions.push_back(j);
result=true;
continue;
}
//There is a partition between the sectors start and end
//If the end sector is inside other partition
if(this->device->partitions[j].sector_start>start_sector &&
this->device->partitions[j].sector_end<end_sector)
{
this->overlappedPartitions.push_back(j);
result=true;
continue;
}
}
return result;
}
/* Check if a partition is inconsistent */
bool Dialog_Rescue_Data::is_inconsistent(const Partition &part)
{
for(unsigned int i=0;i<this->inconsistencies_list.size();i++)
{
if (part.partition_number==this->inconsistencies_list[i])
{
return true;
}
}
return false;
}
}//GParted

View File

@ -275,14 +275,6 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
g_idle_add((GSourceFunc)_mainquit, nullptr); g_idle_add((GSourceFunc)_mainquit, nullptr);
} }
// runs gpart on the specified parameter
void GParted_Core::guess_partition_table(const Device & device, Glib::ustring &buff)
{
Glib::ustring error;
Glib::ustring cmd = "gpart -s " + Utils::num_to_str( device.sector_size ) +
" " + Glib::shell_quote( device.get_path() );
Utils::execute_command( cmd, buff, error, true );
}
void GParted_Core::set_thread_status_message( Glib::ustring msg ) void GParted_Core::set_thread_status_message( Glib::ustring msg )
{ {

View File

@ -28,7 +28,6 @@ gpartedbin_SOURCES = \
Dialog_Partition_New.cc \ Dialog_Partition_New.cc \
Dialog_Partition_Resize_Move.cc \ Dialog_Partition_Resize_Move.cc \
Dialog_Progress.cc \ Dialog_Progress.cc \
Dialog_Rescue_Data.cc \
DrawingAreaVisualDisk.cc \ DrawingAreaVisualDisk.cc \
FS_Info.cc \ FS_Info.cc \
FileSystem.cc \ FileSystem.cc \

View File

@ -895,15 +895,6 @@ void Utils::split( const Glib::ustring& str,
result. push_back( word ) ; result. push_back( word ) ;
} }
// Converts a Glib::ustring into a int
int Utils::convert_to_int(const Glib::ustring & src)
{
int ret_val;
std::istringstream stream(src);
stream >> ret_val;
return ret_val;
}
// Create a new UUID // Create a new UUID
Glib::ustring Utils::generate_uuid(void) Glib::ustring Utils::generate_uuid(void)

View File

@ -21,7 +21,6 @@
#include "DialogFeatures.h" #include "DialogFeatures.h"
#include "DialogPasswordEntry.h" #include "DialogPasswordEntry.h"
#include "Dialog_Disklabel.h" #include "Dialog_Disklabel.h"
#include "Dialog_Rescue_Data.h"
#include "Dialog_Partition_Resize_Move.h" #include "Dialog_Partition_Resize_Move.h"
#include "Dialog_Partition_Copy.h" #include "Dialog_Partition_Copy.h"
#include "Dialog_Partition_New.h" #include "Dialog_Partition_New.h"
@ -254,11 +253,6 @@ void Win_GParted::init_menubar()
sigc::mem_fun(*this, &Win_GParted::activate_disklabel))); sigc::mem_fun(*this, &Win_GParted::activate_disklabel)));
menu->append(*item); menu->append(*item);
item = manage(new GParted::Menu_Helpers::MenuElem(
Glib::ustring(_("_Attempt Data Rescue") ) + "...",
sigc::mem_fun(*this, &Win_GParted::activate_attempt_rescue_data)));
menu->append(*item);
item = manage(new GParted::Menu_Helpers::MenuElem( item = manage(new GParted::Menu_Helpers::MenuElem(
_("_Device"), *menu)); _("_Device"), *menu));
menubar_main.append(*item); menubar_main.append(*item);
@ -3193,72 +3187,6 @@ void Win_GParted::activate_disklabel()
} }
} }
//Runs when the Device->Attempt Rescue Data is clicked
void Win_GParted::activate_attempt_rescue_data()
{
if(Glib::find_program_in_path( "gpart" ) .empty()) //Gpart must be installed to continue
{
Gtk::MessageDialog errorDialog(*this, "", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
errorDialog.set_message(_("Command gpart was not found"));
errorDialog.set_secondary_text(_("This feature uses gpart. Please install gpart and try again."));
errorDialog.run();
return;
}
//Dialog information
Glib::ustring sec_text = _( "A full disk scan is needed to find file systems." ) ;
sec_text += "\n" ;
sec_text +=_("The scan might take a very long time.");
sec_text += "\n" ;
sec_text += _("After the scan you can mount any discovered file systems and copy the data to other media.") ;
sec_text += "\n" ;
sec_text += _("Do you want to continue?");
Gtk::MessageDialog messageDialog(*this, "", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true);
/*TO TRANSLATORS: looks like Search for file systems on /deb/sdb */
messageDialog.set_message(Glib::ustring::compose(_("Search for file systems on %1"), devices[ current_device ] .get_path()));
messageDialog.set_secondary_text(sec_text);
if(messageDialog.run()!=Gtk::RESPONSE_OK)
{
return;
}
messageDialog.hide();
/*TO TRANSLATORS: looks like Searching for file systems on /deb/sdb */
show_pulsebar(Glib::ustring::compose( _("Searching for file systems on %1"), devices[ current_device ] .get_path()));
Glib::ustring gpart_output;
gparted_core.guess_partition_table(devices[ current_device ], gpart_output);
hide_pulsebar();
Dialog_Rescue_Data dialog;
dialog .set_transient_for( *this );
//Reads the output of gpart
dialog.init_partitions( &devices[current_device], gpart_output );
if ( ! dialog.found_partitions() )
{
//Dialog information
Gtk::MessageDialog errorDialog(*this, "", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
/*TO TRANSLATORS: looks like No file systems found on /deb/sdb */
errorDialog.set_message(Glib::ustring::compose(_("No file systems found on %1"), devices[ current_device ] .get_path()));
errorDialog.set_secondary_text(_("The disk scan by gpart did not find any recognizable file systems on this disk."));
errorDialog.run();
return;
}
dialog.run();
dialog.hide();
Utils::execute_command( "umount /tmp/gparted-roview*" );
menu_gparted_refresh_devices() ;
}
void Win_GParted::activate_manage_flags() void Win_GParted::activate_manage_flags()
{ {