mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge pull request #7551 from gdicristofaro/8299-fileExtraction
8299 file extraction
This commit is contained in:
commit
d8241caa60
@ -392,85 +392,69 @@ public final class ContentUtils {
|
|||||||
public static <T, V> void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker) {
|
public static <T, V> void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker) {
|
||||||
cntnt.accept(new ExtractFscContentVisitor<>(dest, progress, worker, true));
|
cntnt.accept(new ExtractFscContentVisitor<>(dest, progress, worker, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base method writing a file to disk.
|
||||||
|
*
|
||||||
|
* @param file The TSK content file.
|
||||||
|
* @param dest The disk location where the content will be written.
|
||||||
|
* @param progress progress bar handle to update, if available. null
|
||||||
|
* otherwise
|
||||||
|
* @param worker the swing worker background thread the process runs
|
||||||
|
* within, or null, if in the main thread, used to
|
||||||
|
* handle task cancellation
|
||||||
|
* @param source true if source file
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected void writeFile(Content file, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker, boolean source) throws IOException {
|
||||||
|
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Void visit(File file) {
|
* Visits a TSK content file and writes that file to disk.
|
||||||
|
* @param file The file to be written.
|
||||||
|
* @param fileType The file type (i.e. "derived file") for error logging.
|
||||||
|
* @return null.
|
||||||
|
*/
|
||||||
|
protected Void visitFile(Content file, String fileType) {
|
||||||
try {
|
try {
|
||||||
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
writeFile(file, dest, progress, worker, source);
|
||||||
} catch (ReadContentInputStreamException ex) {
|
} catch (ReadContentInputStreamException ex) {
|
||||||
logger.log(Level.WARNING,
|
logger.log(Level.WARNING,
|
||||||
String.format("Error reading file '%s' (id=%d).",
|
String.format("Error reading file '%s' (id=%d).",
|
||||||
file.getName(), file.getId()), ex); //NON-NLS
|
file.getName(), file.getId()), ex); //NON-NLS
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE,
|
logger.log(Level.SEVERE,
|
||||||
String.format("Error extracting file '%s' (id=%d) to '%s'.",
|
String.format("Error extracting %s '%s' (id=%d) to '%s'.",
|
||||||
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
fileType, file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(File file) {
|
||||||
|
return visitFile(file, "file");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(LayoutFile file) {
|
public Void visit(LayoutFile file) {
|
||||||
try {
|
return visitFile(file, "unallocated content file");
|
||||||
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
|
||||||
} catch (ReadContentInputStreamException ex) {
|
|
||||||
logger.log(Level.WARNING,
|
|
||||||
String.format("Error reading file '%s' (id=%d).",
|
|
||||||
file.getName(), file.getId()), ex); //NON-NLS
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.log(Level.SEVERE,
|
|
||||||
String.format("Error extracting unallocated content file '%s' (id=%d) to '%s'.",
|
|
||||||
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(DerivedFile file) {
|
public Void visit(DerivedFile file) {
|
||||||
try {
|
return visitFile(file, "derived file");
|
||||||
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
|
||||||
} catch (ReadContentInputStreamException ex) {
|
|
||||||
logger.log(Level.WARNING,
|
|
||||||
String.format("Error reading file '%s' (id=%d).",
|
|
||||||
file.getName(), file.getId()), ex); //NON-NLS
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.log(Level.SEVERE,
|
|
||||||
String.format("Error extracting derived file '%s' (id=%d) to '%s'.",
|
|
||||||
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(LocalFile file) {
|
public Void visit(LocalFile file) {
|
||||||
try {
|
return visitFile(file, "local file");
|
||||||
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
|
||||||
} catch (ReadContentInputStreamException ex) {
|
|
||||||
logger.log(Level.WARNING,
|
|
||||||
String.format("Error reading file '%s' (id=%d).",
|
|
||||||
file.getName(), file.getId()), ex); //NON-NLS
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.log(Level.SEVERE,
|
|
||||||
String.format("Error extracting local file '%s' (id=%d) to '%s'.",
|
|
||||||
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(SlackFile file) {
|
public Void visit(SlackFile file) {
|
||||||
try {
|
return visitFile(file, "slack file");
|
||||||
ContentUtils.writeToFile(file, dest, progress, worker, source);
|
|
||||||
} catch (ReadContentInputStreamException ex) {
|
|
||||||
logger.log(Level.WARNING,
|
|
||||||
String.format("Error reading file '%s' (id=%d).",
|
|
||||||
file.getName(), file.getId()), ex); //NON-NLS
|
|
||||||
} catch (IOException ex) {
|
|
||||||
logger.log(Level.SEVERE,
|
|
||||||
String.format("Error extracting slack file '%s' (id=%d) to '%s'.",
|
|
||||||
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -493,6 +477,20 @@ public final class ContentUtils {
|
|||||||
+ content.getName();
|
+ content.getName();
|
||||||
return new java.io.File(path);
|
return new java.io.File(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a visitor to visit any child content.
|
||||||
|
* @param childFile The disk location where the content will be written.
|
||||||
|
* @param progress progress bar handle to update, if available. null
|
||||||
|
* otherwise
|
||||||
|
* @param worker the swing worker background thread the process runs
|
||||||
|
* within, or null, if in the main thread, used to
|
||||||
|
* handle task cancellation
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected ExtractFscContentVisitor<T, V> getChildVisitor(java.io.File childFile, ProgressHandle progress, SwingWorker<T, V> worker) {
|
||||||
|
return new ExtractFscContentVisitor<>(childFile, progress, worker, false);
|
||||||
|
}
|
||||||
|
|
||||||
public Void visitDir(AbstractFile dir) {
|
public Void visitDir(AbstractFile dir) {
|
||||||
|
|
||||||
@ -509,8 +507,7 @@ public final class ContentUtils {
|
|||||||
for (Content child : dir.getChildren()) {
|
for (Content child : dir.getChildren()) {
|
||||||
if (child instanceof AbstractFile) { //ensure the directory's artifact children are ignored
|
if (child instanceof AbstractFile) { //ensure the directory's artifact children are ignored
|
||||||
java.io.File childFile = getFsContentDest(child);
|
java.io.File childFile = getFsContentDest(child);
|
||||||
ExtractFscContentVisitor<T, V> childVisitor
|
ExtractFscContentVisitor<T, V> childVisitor = getChildVisitor(childFile, progress, worker);
|
||||||
= new ExtractFscContentVisitor<>(childFile, progress, worker, false);
|
|
||||||
// If this is the source directory of an extract it
|
// If this is the source directory of an extract it
|
||||||
// will have a progress and worker, and will keep track
|
// will have a progress and worker, and will keep track
|
||||||
// of the progress bar's progress
|
// of the progress bar's progress
|
||||||
|
@ -43,6 +43,8 @@ public final class ExtractAction extends AbstractAction {
|
|||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ExtractActionHelper extractor = new ExtractActionHelper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor for the action.
|
* Private constructor for the action.
|
||||||
@ -61,7 +63,6 @@ public final class ExtractAction extends AbstractAction {
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Lookup lookup = Utilities.actionsGlobalContext();
|
Lookup lookup = Utilities.actionsGlobalContext();
|
||||||
Collection<? extends AbstractFile> selectedFiles =lookup.lookupAll(AbstractFile.class);
|
Collection<? extends AbstractFile> selectedFiles =lookup.lookupAll(AbstractFile.class);
|
||||||
ExtractActionHelper extractor = new ExtractActionHelper();
|
|
||||||
extractor.extract(e, selectedFiles);
|
extractor.extract(e, selectedFiles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.directorytree.actionhelpers;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -42,8 +44,10 @@ import org.sleuthkit.autopsy.coreutils.FileUtil;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
|
||||||
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
|
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for methods needed by actions which extract files.
|
* Helper class for methods needed by actions which extract files.
|
||||||
@ -52,7 +56,7 @@ public class ExtractActionHelper {
|
|||||||
|
|
||||||
private final Logger logger = Logger.getLogger(ExtractActionHelper.class.getName());
|
private final Logger logger = Logger.getLogger(ExtractActionHelper.class.getName());
|
||||||
private String userDefinedExportPath;
|
private String userDefinedExportPath;
|
||||||
|
|
||||||
private final JFileChooserFactory extractFileHelper = new JFileChooserFactory();
|
private final JFileChooserFactory extractFileHelper = new JFileChooserFactory();
|
||||||
private final JFileChooserFactory extractFilesHelper = new JFileChooserFactory();
|
private final JFileChooserFactory extractFilesHelper = new JFileChooserFactory();
|
||||||
|
|
||||||
@ -68,12 +72,7 @@ public class ExtractActionHelper {
|
|||||||
if (selectedFiles.size() > 1) {
|
if (selectedFiles.size() > 1) {
|
||||||
extractFiles(event, selectedFiles);
|
extractFiles(event, selectedFiles);
|
||||||
} else if (selectedFiles.size() == 1) {
|
} else if (selectedFiles.size() == 1) {
|
||||||
AbstractFile source = selectedFiles.iterator().next();
|
extractFile(event, selectedFiles.iterator().next());
|
||||||
if (source.isDir()) {
|
|
||||||
extractFiles(event, selectedFiles);
|
|
||||||
} else {
|
|
||||||
extractFile(event, selectedFiles.iterator().next());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +82,11 @@ public class ExtractActionHelper {
|
|||||||
* @param event
|
* @param event
|
||||||
* @param selectedFile Selected file
|
* @param selectedFile Selected file
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"ExtractActionHelper.noOpenCase.errMsg=No open case available."})
|
@NbBundle.Messages({"ExtractActionHelper.noOpenCase.errMsg=No open case available.",
|
||||||
|
"ExtractActionHelper.extractOverwrite.title=Export to csv file",
|
||||||
|
"# {0} - fileName",
|
||||||
|
"ExtractActionHelper.extractOverwrite.msg=A file already exists at {0}. Do you want to overwrite the existing file?"
|
||||||
|
})
|
||||||
private void extractFile(ActionEvent event, AbstractFile selectedFile) {
|
private void extractFile(ActionEvent event, AbstractFile selectedFile) {
|
||||||
Case openCase;
|
Case openCase;
|
||||||
try {
|
try {
|
||||||
@ -269,6 +272,68 @@ public class ExtractActionHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file content extraction visitor that handles for the UI designed to
|
||||||
|
* handle file name conflicts by appending the object id to the file name.
|
||||||
|
*/
|
||||||
|
private static class UIExtractionVisitor<T, V> extends ExtractFscContentVisitor<T, V> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param file The TSK content file.
|
||||||
|
* @param dest The disk location where the content will be written.
|
||||||
|
* @param progress progress bar handle to update, if available. null
|
||||||
|
* otherwise
|
||||||
|
* @param worker the swing worker background thread the process runs
|
||||||
|
* within, or null, if in the main thread, used to
|
||||||
|
* handle task cancellation
|
||||||
|
* @param source true if source file
|
||||||
|
*/
|
||||||
|
UIExtractionVisitor(File dest, ProgressHandle progress, SwingWorker<T, V> worker, boolean source) {
|
||||||
|
super(dest, progress, worker, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes content and children to disk.
|
||||||
|
*
|
||||||
|
* @param content The root content.
|
||||||
|
* @param file The TSK content file.
|
||||||
|
* @param dest The disk location where the content will be written.
|
||||||
|
* @param progress progress bar handle to update, if available. null
|
||||||
|
* otherwise
|
||||||
|
* @param worker the swing worker background thread the process runs
|
||||||
|
* within, or null, if in the main thread, used to
|
||||||
|
* handle task cancellation
|
||||||
|
* @param source true if source file
|
||||||
|
*/
|
||||||
|
static <T,V> void writeContent(Content content, File dest, ProgressHandle progress, SwingWorker<T, V> worker) {
|
||||||
|
content.accept(new UIExtractionVisitor<>(dest, progress, worker, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeFile(Content file, File dest, ProgressHandle progress, SwingWorker<T, V> worker, boolean source) throws IOException {
|
||||||
|
File destFile;
|
||||||
|
if (dest.exists()) {
|
||||||
|
String parent = dest.getParent();
|
||||||
|
String fileName = dest.getName();
|
||||||
|
String objIdFileName = MessageFormat.format("{0}-{1}", file.getId(), fileName);
|
||||||
|
destFile = new File(parent, objIdFileName);
|
||||||
|
} else {
|
||||||
|
destFile = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.writeFile(file, destFile, progress, worker, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExtractFscContentVisitor<T, V> getChildVisitor(File childFile, ProgressHandle progress, SwingWorker<T, V> worker) {
|
||||||
|
return new UIExtractionVisitor(childFile, progress, worker, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread that does the actual extraction work
|
* Thread that does the actual extraction work
|
||||||
*/
|
*/
|
||||||
@ -321,8 +386,7 @@ public class ExtractActionHelper {
|
|||||||
// Do the extraction tasks.
|
// Do the extraction tasks.
|
||||||
for (FileExtractionTask task : this.extractionTasks) {
|
for (FileExtractionTask task : this.extractionTasks) {
|
||||||
progress.progress(Bundle.ExtractActionHelper_progress_fileExtracting(task.destination.getName()));
|
progress.progress(Bundle.ExtractActionHelper_progress_fileExtracting(task.destination.getName()));
|
||||||
|
UIExtractionVisitor.writeContent(task.source, task.destination, null, this);
|
||||||
ContentUtils.ExtractFscContentVisitor.extract(task.source, task.destination, null, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user