mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Extraction per image now takes place in a single thread
Previously made one thread per volume.
This commit is contained in:
parent
cd3d1fc4f4
commit
2bb12c1176
@ -55,8 +55,8 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
|
|
||||||
private final List<UnallocStruct> LstUnallocs = new ArrayList<UnallocStruct>();
|
private final List<UnallocStruct> LstUnallocs = new ArrayList<UnallocStruct>();
|
||||||
private static final List<String> lockedVols = new ArrayList<String>();
|
private static final List<String> lockedVols = new ArrayList<String>();
|
||||||
private int numDone = 0;
|
private static final List<Long> lockedImages = new ArrayList<Long>();
|
||||||
private static boolean runningOnImage = false;
|
private long currentImage = 0L;
|
||||||
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
|
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
|
||||||
private boolean isImage = false;
|
private boolean isImage = false;
|
||||||
|
|
||||||
@ -68,6 +68,7 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
public ExtractUnallocAction(String title, Image img) {
|
public ExtractUnallocAction(String title, Image img) {
|
||||||
super(title);
|
super(title);
|
||||||
isImage = true;
|
isImage = true;
|
||||||
|
currentImage = img.getId();
|
||||||
if (hasVolumeSystem(img)) {
|
if (hasVolumeSystem(img)) {
|
||||||
for (Volume v : getVolumes(img)) {
|
for (Volume v : getVolumes(img)) {
|
||||||
UnallocStruct us = new UnallocStruct(v);
|
UnallocStruct us = new UnallocStruct(v);
|
||||||
@ -87,29 +88,36 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (LstUnallocs != null && LstUnallocs.size() > 0) {
|
if (LstUnallocs != null && LstUnallocs.size() > 0) {
|
||||||
if (runningOnImage) {
|
if (lockedImages.contains(currentImage)) {
|
||||||
JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already running on this Image. Please select a different Image.");
|
JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already running on this Image. Please select a different Image.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
List<UnallocStruct> copyList = new ArrayList<UnallocStruct>(){{
|
||||||
|
addAll(LstUnallocs);
|
||||||
|
}};
|
||||||
for (UnallocStruct u : LstUnallocs) {
|
for (UnallocStruct u : LstUnallocs) {
|
||||||
String UnallocName = u.ImageName + "-Unalloc-" + u.ImageId + "-" + u.VolumeId + ".dat";
|
if (u.llf != null && u.llf.size() > 0 && !lockedVols.contains(u.getFileName())) {
|
||||||
if (u.llf != null && u.llf.size() > 0 && !lockedVols.contains(UnallocName)) {
|
|
||||||
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
||||||
File unalloc = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + UnallocName);
|
if (u.FileInstance.exists()) {
|
||||||
if (unalloc.exists()) {
|
int res = JOptionPane.showConfirmDialog(new Frame(), "The Unalloc File for this volume, " + u.getFileName() + " already exists, do you want to replace it?");
|
||||||
int res = JOptionPane.showConfirmDialog(new Frame(), "The Unalloc File for this volume, " + UnallocName + " already exists, do you want to replace it?");
|
|
||||||
if (res == JOptionPane.YES_OPTION) {
|
if (res == JOptionPane.YES_OPTION) {
|
||||||
unalloc.delete();
|
u.FileInstance.delete();
|
||||||
} else {
|
} else {
|
||||||
return;
|
copyList.remove(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExtractUnallocWorker uw = new ExtractUnallocWorker(unalloc, u);
|
if (!isImage) {
|
||||||
|
ExtractUnallocWorker uw = new ExtractUnallocWorker(u);
|
||||||
uw.execute();
|
uw.execute();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, "Tried to get unallocated content from volume ID " + u.VolumeId + ", but its list of unallocated files was empty or null");
|
logger.log(Level.WARNING, "Tried to get unallocated content from volume ID " + u.VolumeId + ", but its list of unallocated files was empty or null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isImage) {
|
||||||
|
ExtractUnallocWorker uw = new ExtractUnallocWorker(copyList);
|
||||||
|
uw.execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -135,61 +143,99 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
*/
|
*/
|
||||||
private class ExtractUnallocWorker extends SwingWorker<Integer, Integer> {
|
private class ExtractUnallocWorker extends SwingWorker<Integer, Integer> {
|
||||||
|
|
||||||
private File path;
|
|
||||||
private ProgressHandle progress;
|
private ProgressHandle progress;
|
||||||
private boolean canceled = false;
|
private boolean canceled = false;
|
||||||
private UnallocStruct us;
|
private List<UnallocStruct> lus = new ArrayList<UnallocStruct>();
|
||||||
|
private File currentlyProcessing;
|
||||||
|
private int totalSizeinMegs;
|
||||||
|
|
||||||
|
ExtractUnallocWorker(UnallocStruct us) {
|
||||||
ExtractUnallocWorker(File path, UnallocStruct us) {
|
this.lus.add(us);
|
||||||
this.path = path;
|
//Getting the total megs this worker is going to be doing
|
||||||
if(isImage){
|
if (!lockedVols.contains(us.getFileName())) {
|
||||||
runningOnImage = true;
|
totalSizeinMegs = toMb(us.sizeInBytes());
|
||||||
|
lockedVols.add(us.getFileName());
|
||||||
}
|
}
|
||||||
lockedVols.add(path.getName());
|
|
||||||
this.us = us;
|
}
|
||||||
|
|
||||||
|
ExtractUnallocWorker(List<UnallocStruct> lst) {
|
||||||
|
//Getting the total megs this worker is going to be doing
|
||||||
|
long totalBytes = 0;
|
||||||
|
for (UnallocStruct lu : lst) {
|
||||||
|
if (!lockedVols.contains(lu.getFileName())) {
|
||||||
|
totalBytes += lu.sizeInBytes();
|
||||||
|
lockedVols.add(lu.getFileName());
|
||||||
|
this.lus.add(lu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalSizeinMegs = toMb(totalBytes);
|
||||||
|
lockedImages.add(currentImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int toMb(long bytes) {
|
||||||
|
if (bytes > 1024 && (bytes / 1024.0) <= Double.MAX_VALUE) {
|
||||||
|
double Mb = ((bytes / 1024.0)/1024.0);//Bytes -> Megabytes
|
||||||
|
if (((bytes / 1024.0)/1024.0) <= Integer.MAX_VALUE) {
|
||||||
|
return (int) Math.floor(Mb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Integer doInBackground() {
|
protected Integer doInBackground() {
|
||||||
try {
|
try {
|
||||||
progress = ProgressHandleFactory.createHandle("Extracting " + path.getName(), new Cancellable() {
|
progress = ProgressHandleFactory.createHandle("Extracting Unallocated Space", new Cancellable() {
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel() {
|
public boolean cancel() {
|
||||||
logger.log(Level.INFO, "Canceling extraction of Unalloc file " + path.getName());
|
logger.log(Level.INFO, "Canceling extraction of unallocated space");
|
||||||
canceled = true;
|
canceled = true;
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.setDisplayName(path.getName() + " (Cancelling...)");
|
progress.setDisplayName("Extracting Unallocated Space" + " (Cancelling...)");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
FileOutputStream fos = new FileOutputStream(path);
|
|
||||||
int MAX_BYTES = 8192;
|
int MAX_BYTES = 8192;
|
||||||
byte[] buf = new byte[MAX_BYTES]; //read 8kb at a time
|
byte[] buf = new byte[MAX_BYTES]; //read 8kb at a time
|
||||||
logger.log(Level.INFO, "Writing Unalloc file to " + path.getPath());
|
|
||||||
|
|
||||||
progress.start(us.size());
|
|
||||||
int count = 0;
|
//Begin the actual File IO
|
||||||
for (LayoutFile f : us.getLayouts()) {
|
progress.start(totalSizeinMegs);
|
||||||
|
int kbs = 0; //Each completion of the while loop adds one to kbs. 8kb * 128 = 1mb.
|
||||||
|
int mbs = 0; //Increments every 128 kbs
|
||||||
|
for (UnallocStruct u : this.lus) {
|
||||||
|
currentlyProcessing = u.getFile();
|
||||||
|
logger.log(Level.INFO, "Writing Unalloc file to " + currentlyProcessing.getPath());
|
||||||
|
FileOutputStream fos = new FileOutputStream(currentlyProcessing);
|
||||||
|
int count = 1;
|
||||||
|
for (LayoutFile f : u.getLayouts()) {
|
||||||
long offset = 0L;
|
long offset = 0L;
|
||||||
while (offset != f.getSize() && !canceled) {
|
while (offset != f.getSize() && !canceled) {
|
||||||
offset += f.read(buf, offset, MAX_BYTES); //Offset + Bytes read
|
offset += f.read(buf, offset, MAX_BYTES); //Offset + Bytes read
|
||||||
fos.write(buf);
|
fos.write(buf);
|
||||||
|
if (++kbs % 128 == 0) {
|
||||||
|
mbs++;
|
||||||
|
progress.progress("processing " + mbs + " of " + totalSizeinMegs + " MBs", mbs);
|
||||||
}
|
}
|
||||||
progress.progress("processing block " + ++count + "of " + us.size(), count);
|
|
||||||
}
|
}
|
||||||
progress.finish();
|
count++;
|
||||||
|
}
|
||||||
fos.flush();
|
fos.flush();
|
||||||
fos.close();
|
fos.close();
|
||||||
|
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
path.delete();
|
u.getFile().delete();
|
||||||
logger.log(Level.INFO, "Canceled extraction of " + path.getName() + " and deleted file");
|
logger.log(Level.INFO, "Canceled extraction of " + u.getFile().getName() + " and deleted file");
|
||||||
|
} else {
|
||||||
|
logger.log(Level.INFO, "Finished writing unalloc file " + u.getFile().getPath());
|
||||||
}
|
}
|
||||||
else{
|
lockedVols.remove(u.FileName);
|
||||||
logger.log(Level.INFO, "Finished writing unalloc file " + path.getPath());
|
|
||||||
}
|
}
|
||||||
|
progress.finish();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ioe);
|
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ioe);
|
||||||
return -1;
|
return -1;
|
||||||
@ -202,10 +248,8 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done(){
|
protected void done(){
|
||||||
lockedVols.remove(path.getName());
|
if(isImage){
|
||||||
if(++numDone == LstUnallocs.size()){
|
lockedImages.remove(currentImage);
|
||||||
runningOnImage = false;
|
|
||||||
numDone = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,6 +402,9 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
private long VolumeId;
|
private long VolumeId;
|
||||||
private long ImageId;
|
private long ImageId;
|
||||||
private String ImageName;
|
private String ImageName;
|
||||||
|
private String FileName;
|
||||||
|
private File FileInstance;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contingency constructor in event no VolumeSystem exists on an Image.
|
* Contingency constructor in event no VolumeSystem exists on an Image.
|
||||||
@ -368,6 +415,8 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
this.VolumeId = 0;
|
this.VolumeId = 0;
|
||||||
this.ImageId = img.getId();
|
this.ImageId = img.getId();
|
||||||
this.ImageName = img.getName();
|
this.ImageName = img.getName();
|
||||||
|
this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + 0 + ".dat";
|
||||||
|
this.FileInstance = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + this.FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -384,6 +433,8 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
this.ImageName = "";
|
this.ImageName = "";
|
||||||
this.ImageId = 0;
|
this.ImageId = 0;
|
||||||
}
|
}
|
||||||
|
this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + VolumeId + ".dat";
|
||||||
|
this.FileInstance = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + this.FileName);
|
||||||
this.llf = getUnallocFiles(volu);
|
this.llf = getUnallocFiles(volu);
|
||||||
Collections.sort(llf, new SortObjId());
|
Collections.sort(llf, new SortObjId());
|
||||||
}
|
}
|
||||||
@ -392,6 +443,14 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
int size() {
|
int size() {
|
||||||
return llf.size();
|
return llf.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sizeInBytes(){
|
||||||
|
long size = 0L;
|
||||||
|
for(LayoutFile f : llf){
|
||||||
|
size+= f.getSize();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
long getVolumeId(){
|
long getVolumeId(){
|
||||||
return this.VolumeId;
|
return this.VolumeId;
|
||||||
}
|
}
|
||||||
@ -405,6 +464,14 @@ public final class ExtractUnallocAction extends AbstractAction {
|
|||||||
return this.llf;
|
return this.llf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getFileName(){
|
||||||
|
return this.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
File getFile(){
|
||||||
|
return this.FileInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user