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:
parent
2febe04665
commit
8ce9074ac6
5
README
5
README
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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() ;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue