mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'sleuthkit:develop' into develop
This commit is contained in:
commit
aa9d2031fb
@ -17,6 +17,8 @@ ContactsViewer_columnHeader_Phone=Phone
|
|||||||
ContactsViewer_noContacts_message=<No contacts found for selected account>
|
ContactsViewer_noContacts_message=<No contacts found for selected account>
|
||||||
ContactsViewer_tabTitle=Contacts
|
ContactsViewer_tabTitle=Contacts
|
||||||
MediaViewer_Name=Media Attachments
|
MediaViewer_Name=Media Attachments
|
||||||
|
MediaViewer_selection_failure_msg=Failed to get media attachments for selected accounts.
|
||||||
|
MediaViewer_selection_failure_title=Selection Failed
|
||||||
MessageNode_Node_Property_Attms=Attachment Count
|
MessageNode_Node_Property_Attms=Attachment Count
|
||||||
MessageNode_Node_Property_Date=Date
|
MessageNode_Node_Property_Date=Date
|
||||||
MessageNode_Node_Property_From=From
|
MessageNode_Node_Property_From=From
|
||||||
|
@ -19,14 +19,19 @@
|
|||||||
package org.sleuthkit.autopsy.communications.relationships;
|
package org.sleuthkit.autopsy.communications.relationships;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Cursor;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
import static org.openide.explorer.ExplorerUtils.createLookup;
|
import static org.openide.explorer.ExplorerUtils.createLookup;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
@ -39,6 +44,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||||
import org.sleuthkit.datamodel.AbstractContent;
|
import org.sleuthkit.datamodel.AbstractContent;
|
||||||
|
import org.sleuthkit.datamodel.Account;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
@ -58,6 +64,8 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
|
|||||||
|
|
||||||
private final MessageDataContent contentViewer;
|
private final MessageDataContent contentViewer;
|
||||||
|
|
||||||
|
private MediaViewerWorker worker;
|
||||||
|
|
||||||
@Messages({
|
@Messages({
|
||||||
"MediaViewer_Name=Media Attachments"
|
"MediaViewer_Name=Media Attachments"
|
||||||
})
|
})
|
||||||
@ -97,24 +105,17 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSelectionInfo(SelectionInfo info) {
|
public void setSelectionInfo(SelectionInfo info) {
|
||||||
Set<Content> relationshipSources;
|
|
||||||
Set<BlackboardArtifact> artifactList = new HashSet<>();
|
|
||||||
contentViewer.setNode(null);
|
contentViewer.setNode(null);
|
||||||
if (info != null) {
|
|
||||||
try {
|
|
||||||
relationshipSources = info.getRelationshipSources();
|
|
||||||
|
|
||||||
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
|
||||||
artifactList.add((BlackboardArtifact) content);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to update selection.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thumbnailViewer.resetComponent();
|
thumbnailViewer.resetComponent();
|
||||||
|
|
||||||
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName()));
|
if (worker != null) {
|
||||||
|
worker.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
worker = new MediaViewerWorker(info);
|
||||||
|
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
worker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -198,6 +199,56 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing worker for gathering the data needed to populate the media viewer.
|
||||||
|
*/
|
||||||
|
private class MediaViewerWorker extends SwingWorker<TableFilterNode, Void> {
|
||||||
|
|
||||||
|
private final SelectionInfo selectionInfo;
|
||||||
|
|
||||||
|
MediaViewerWorker(SelectionInfo info) {
|
||||||
|
selectionInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TableFilterNode doInBackground() throws Exception {
|
||||||
|
Set<Content> relationshipSources;
|
||||||
|
Set<BlackboardArtifact> artifactList = new HashSet<>();
|
||||||
|
|
||||||
|
if (selectionInfo != null) {
|
||||||
|
relationshipSources = selectionInfo.getRelationshipSources();
|
||||||
|
|
||||||
|
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
||||||
|
artifactList.add((BlackboardArtifact) content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"MediaViewer_selection_failure_msg=Failed to get media attachments for selected accounts.",
|
||||||
|
"MediaViewer_selection_failure_title=Selection Failed"
|
||||||
|
})
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
try {
|
||||||
|
if (isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thumbnailViewer.setNode(get());
|
||||||
|
} catch (ExecutionException | InterruptedException ex) {
|
||||||
|
String accounts = selectionInfo.getAccounts().stream().map(Account::getTypeSpecificID).collect(Collectors.joining(","));
|
||||||
|
logger.log(Level.WARNING, "Unable to update cvt media viewer for " + accounts, ex);
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(MediaViewer.this, Bundle.MediaViewer_selection_failure_msg(), Bundle.MediaViewer_selection_failure_title(), JOptionPane.ERROR_MESSAGE);
|
||||||
|
} finally {
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
@ -23,14 +23,12 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.Utilities;
|
import org.openide.util.Utilities;
|
||||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||||
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
@ -43,11 +41,10 @@ import org.sleuthkit.datamodel.LocalFile;
|
|||||||
import org.sleuthkit.datamodel.LocalDirectory;
|
import org.sleuthkit.datamodel.LocalDirectory;
|
||||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
import org.sleuthkit.datamodel.Volume;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
|
|
||||||
public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? extends Action>> {
|
public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? extends Action>> {
|
||||||
|
|
||||||
private static ExplorerNodeActionVisitor instance = new ExplorerNodeActionVisitor();
|
private final static ExplorerNodeActionVisitor instance = new ExplorerNodeActionVisitor();
|
||||||
|
|
||||||
public static List<Action> getActions(Content c) {
|
public static List<Action> getActions(Content c) {
|
||||||
List<Action> actions = new ArrayList<>();
|
List<Action> actions = new ArrayList<>();
|
||||||
@ -73,13 +70,8 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
|
|||||||
@Override
|
@Override
|
||||||
public List<? extends Action> visit(final Image img) {
|
public List<? extends Action> visit(final Image img) {
|
||||||
List<Action> lst = new ArrayList<>();
|
List<Action> lst = new ArrayList<>();
|
||||||
//TODO lst.add(new ExtractAction("Extract Image", img));
|
|
||||||
try {
|
|
||||||
lst.add(new ExtractUnallocAction(
|
lst.add(new ExtractUnallocAction(
|
||||||
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.extUnallocToSingleFiles"), img));
|
NbBundle.getMessage(this.getClass(), "ExplorerNodeActionVisitor.action.extUnallocToSingleFiles"), img));
|
||||||
} catch (NoCurrentCaseException ex) {
|
|
||||||
Logger.getLogger(ExplorerNodeActionVisitor.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -32,10 +33,15 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
|
import static javax.swing.JFileChooser.SAVE_DIALOG;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.openide.util.Cancellable;
|
import org.openide.util.Cancellable;
|
||||||
@ -63,13 +69,18 @@ import org.sleuthkit.datamodel.VolumeSystem;
|
|||||||
final class ExtractUnallocAction extends AbstractAction {
|
final class ExtractUnallocAction extends AbstractAction {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
|
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final List<OutputFileData> filesToExtract = new ArrayList<>();
|
|
||||||
private static final Set<String> volumesInProgress = new HashSet<>();
|
private static final Set<String> volumesInProgress = new HashSet<>();
|
||||||
private static final Set<Long> imagesInProgress = new HashSet<>();
|
private static final Set<Long> imagesInProgress = new HashSet<>();
|
||||||
private static String userDefinedExportPath;
|
private static String userDefinedExportPath;
|
||||||
private long currentImage = 0L;
|
|
||||||
private final boolean isImage;
|
private final Volume volume;
|
||||||
|
private final Image image;
|
||||||
|
|
||||||
|
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(CustomFileChooser::new);
|
||||||
|
|
||||||
|
private JFileChooser fileChooser = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of ExtractUnallocAction with a volume.
|
* Create an instance of ExtractUnallocAction with a volume.
|
||||||
@ -77,16 +88,8 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
* @param title The title
|
* @param title The title
|
||||||
* @param volume The volume set for extraction.
|
* @param volume The volume set for extraction.
|
||||||
*/
|
*/
|
||||||
public ExtractUnallocAction(String title, Volume volume) {
|
ExtractUnallocAction(String title, Volume volume) {
|
||||||
super(title);
|
this(title, null, volume);
|
||||||
isImage = false;
|
|
||||||
try {
|
|
||||||
OutputFileData outputFileData = new OutputFileData(volume);
|
|
||||||
filesToExtract.add(outputFileData);
|
|
||||||
} catch (NoCurrentCaseException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Exception while getting open case.", ex);
|
|
||||||
setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,21 +98,21 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
*
|
*
|
||||||
* @param title The title.
|
* @param title The title.
|
||||||
* @param image The image set for extraction.
|
* @param image The image set for extraction.
|
||||||
|
*
|
||||||
* @throws NoCurrentCaseException If no case is open.
|
* @throws NoCurrentCaseException If no case is open.
|
||||||
*/
|
*/
|
||||||
public ExtractUnallocAction(String title, Image image) throws NoCurrentCaseException {
|
ExtractUnallocAction(String title, Image image) {
|
||||||
|
this(title, image, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtractUnallocAction(String title, Image image, Volume volume) {
|
||||||
super(title);
|
super(title);
|
||||||
isImage = true;
|
|
||||||
currentImage = image.getId();
|
this.volume = null;
|
||||||
if (hasVolumeSystem(image)) {
|
this.image = image;
|
||||||
for (Volume v : getVolumes(image)) {
|
|
||||||
OutputFileData outputFileData = new OutputFileData(v);
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
filesToExtract.add(outputFileData);
|
executor.execute(futureFileChooser);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OutputFileData outputFileData = new OutputFileData(image);
|
|
||||||
filesToExtract.add(outputFileData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,14 +129,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
"ExtractUnallocAction.noOpenCase.errMsg=No open case available."})
|
"ExtractUnallocAction.noOpenCase.errMsg=No open case available."})
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
if (filesToExtract != null && filesToExtract.isEmpty() == false) {
|
|
||||||
// This check doesn't absolutely guarantee that the image won't be in progress when we make the worker,
|
|
||||||
// but in general it will suffice.
|
|
||||||
if (isImage && isImageInProgress(currentImage)) {
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.notifyMsg.unallocAlreadyBeingExtr.msg"));
|
|
||||||
//JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already being extracted on this Image. Please select a different Image.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Case openCase;
|
Case openCase;
|
||||||
try {
|
try {
|
||||||
openCase = Case.getCurrentCaseThrows();
|
openCase = Case.getCurrentCaseThrows();
|
||||||
@ -141,97 +137,31 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
MessageNotifyUtil.Message.info(Bundle.ExtractUnallocAction_noOpenCase_errMsg());
|
MessageNotifyUtil.Message.info(Bundle.ExtractUnallocAction_noOpenCase_errMsg());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<OutputFileData> copyList = new ArrayList<OutputFileData>() {
|
|
||||||
{
|
|
||||||
addAll(filesToExtract);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
JFileChooser fileChooser = new JFileChooser() {
|
if (fileChooser == null) {
|
||||||
@Override
|
try {
|
||||||
public void approveSelection() {
|
fileChooser = futureFileChooser.get();
|
||||||
File f = getSelectedFile();
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
if (!f.exists() && getDialogType() == SAVE_DIALOG || !f.canWrite()) {
|
fileChooser = new CustomFileChooser();
|
||||||
JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractUnallocAction.msgDlg.folderDoesntExist.msg"));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
super.approveSelection();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
fileChooser.setCurrentDirectory(new File(getExportDirectory(openCase)));
|
fileChooser.setCurrentDirectory(new File(getExportDirectory(openCase)));
|
||||||
fileChooser.setDialogTitle(
|
if (JFileChooser.APPROVE_OPTION != fileChooser.showSaveDialog((Component) event.getSource())) {
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.dlgTitle.selectDirToSaveTo.msg"));
|
return;
|
||||||
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
}
|
||||||
fileChooser.setAcceptAllFileFilterUsed(false);
|
|
||||||
int returnValue = fileChooser.showSaveDialog((Component) event.getSource());
|
|
||||||
if (returnValue == JFileChooser.APPROVE_OPTION) {
|
|
||||||
String destination = fileChooser.getSelectedFile().getPath();
|
|
||||||
|
|
||||||
|
String destination = fileChooser.getSelectedFile().getPath();
|
||||||
updateExportDirectory(destination, openCase);
|
updateExportDirectory(destination, openCase);
|
||||||
|
|
||||||
for (OutputFileData outputFileData : filesToExtract) {
|
if (image != null && isImageInProgress(image.getId())) {
|
||||||
outputFileData.setPath(destination);
|
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.notifyMsg.unallocAlreadyBeingExtr.msg"));
|
||||||
|
JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already being extracted on this Image. Please select a different Image.");
|
||||||
if (outputFileData.layoutFiles != null && outputFileData.layoutFiles.size() > 0 && (!isVolumeInProgress(outputFileData.getFileName()))) {
|
return;
|
||||||
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
|
||||||
|
|
||||||
// Check if there is already a file with this name
|
|
||||||
if (outputFileData.fileInstance.exists()) {
|
|
||||||
int res = JOptionPane.showConfirmDialog(new Frame(), NbBundle.getMessage(this.getClass(),
|
|
||||||
"ExtractUnallocAction.confDlg.unallocFileAlreadyExist.msg",
|
|
||||||
outputFileData.getFileName()));
|
|
||||||
if (res == JOptionPane.YES_OPTION) {
|
|
||||||
// If the user wants to overwrite, delete the exising output file
|
|
||||||
outputFileData.fileInstance.delete();
|
|
||||||
} else {
|
|
||||||
// Otherwise remove it from the list of output files
|
|
||||||
copyList.remove(outputFileData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isImage & !copyList.isEmpty()) {
|
ExtractUnallocWorker worker = new ExtractUnallocWorker(openCase, destination);
|
||||||
try {
|
|
||||||
ExtractUnallocWorker worker = new ExtractUnallocWorker(outputFileData);
|
|
||||||
worker.execute();
|
worker.execute();
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Already extracting unallocated space into {0}", outputFileData.getFileName());
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeInProgress", outputFileData.getFileName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// The output file for this volume could not be created for one of the following reasons
|
|
||||||
if (outputFileData.layoutFiles == null) {
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeError"));
|
|
||||||
logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS
|
|
||||||
} else if (outputFileData.layoutFiles.isEmpty()) {
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.noFiles"));
|
|
||||||
logger.log(Level.WARNING, "No unallocated files found in volume"); //NON-NLS
|
|
||||||
copyList.remove(outputFileData);
|
|
||||||
} else {
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeInProgress", outputFileData.getFileName()));
|
|
||||||
logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS
|
|
||||||
copyList.remove(outputFileData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This needs refactoring. The idea seems to be that we'll take advantage of the loop above to
|
|
||||||
// check whether each output file exists but wait until this point to make a worker
|
|
||||||
// to extract everything (the worker in the above loop doesn't get created because isImage is true)
|
|
||||||
// It's also unclear to me why we need the two separate worker types.
|
|
||||||
if (isImage && !copyList.isEmpty()) {
|
|
||||||
try {
|
|
||||||
ExtractUnallocWorker worker = new ExtractUnallocWorker(copyList);
|
|
||||||
worker.execute();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
logger.log(Level.WARNING, "Error creating ExtractUnallocWorker", ex);
|
|
||||||
MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.imageError"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -333,38 +263,14 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
private boolean canceled = false;
|
private boolean canceled = false;
|
||||||
private final List<OutputFileData> outputFileDataList = new ArrayList<>();
|
private final List<OutputFileData> outputFileDataList = new ArrayList<>();
|
||||||
private File currentlyProcessing;
|
private File currentlyProcessing;
|
||||||
private final int totalSizeinMegs;
|
private int totalSizeinMegs;
|
||||||
long totalBytes = 0;
|
long totalBytes = 0;
|
||||||
|
private final String destination;
|
||||||
|
private Case openCase;
|
||||||
|
|
||||||
ExtractUnallocWorker(OutputFileData outputFileData) throws TskCoreException {
|
ExtractUnallocWorker(Case openCase, String destination) {
|
||||||
//Getting the total megs this worker is going to be doing
|
this.destination = destination;
|
||||||
addVolumeInProgress(outputFileData.getFileName());
|
this.openCase = openCase;
|
||||||
outputFileDataList.add(outputFileData);
|
|
||||||
totalBytes = outputFileData.getSizeInBytes();
|
|
||||||
totalSizeinMegs = toMb(totalBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtractUnallocWorker(List<OutputFileData> outputFileDataList) throws TskCoreException {
|
|
||||||
addImageInProgress(currentImage);
|
|
||||||
|
|
||||||
//Getting the total megs this worker is going to be doing
|
|
||||||
for (OutputFileData outputFileData : outputFileDataList) {
|
|
||||||
try {
|
|
||||||
// If a volume is locked, skip it but continue trying to process any other requested volumes
|
|
||||||
addVolumeInProgress(outputFileData.getFileName());
|
|
||||||
totalBytes += outputFileData.getSizeInBytes();
|
|
||||||
this.outputFileDataList.add(outputFileData);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Already extracting data into {0}", outputFileData.getFileName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't have anything to output (because of locking), throw an exception
|
|
||||||
if (this.outputFileDataList.isEmpty()) {
|
|
||||||
throw new TskCoreException("No unallocated files can be extracted");
|
|
||||||
}
|
|
||||||
|
|
||||||
totalSizeinMegs = toMb(totalBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toMb(long bytes) {
|
private int toMb(long bytes) {
|
||||||
@ -380,6 +286,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
@Override
|
@Override
|
||||||
protected Integer doInBackground() {
|
protected Integer doInBackground() {
|
||||||
try {
|
try {
|
||||||
|
initalizeFilesToExtract();
|
||||||
progress = ProgressHandle.createHandle(
|
progress = ProgressHandle.createHandle(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.progress.extractUnalloc.title"), new Cancellable() {
|
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.progress.extractUnalloc.title"), new Cancellable() {
|
||||||
@Override
|
@Override
|
||||||
@ -403,7 +310,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
for (OutputFileData outputFileData : this.outputFileDataList) {
|
for (OutputFileData outputFileData : this.outputFileDataList) {
|
||||||
currentlyProcessing = outputFileData.getFile();
|
currentlyProcessing = outputFileData.getFile();
|
||||||
logger.log(Level.INFO, "Writing Unalloc file to {0}", currentlyProcessing.getPath()); //NON-NLS
|
logger.log(Level.INFO, "Writing Unalloc file to {0}", currentlyProcessing.getPath()); //NON-NLS
|
||||||
OutputStream outputStream = new FileOutputStream(currentlyProcessing);
|
try (OutputStream outputStream = new FileOutputStream(currentlyProcessing)) {
|
||||||
long bytes = 0;
|
long bytes = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < outputFileData.getLayouts().size() && bytes != outputFileData.getSizeInBytes()) {
|
while (i < outputFileData.getLayouts().size() && bytes != outputFileData.getSizeInBytes()) {
|
||||||
@ -425,7 +332,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
outputStream.close();
|
}
|
||||||
|
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
outputFileData.getFile().delete();
|
outputFileData.getFile().delete();
|
||||||
@ -448,8 +355,8 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
if (isImage) {
|
if (image != null) {
|
||||||
removeImageInProgress(currentImage);
|
removeImageInProgress(image.getId());
|
||||||
}
|
}
|
||||||
for (OutputFileData u : outputFileDataList) {
|
for (OutputFileData u : outputFileDataList) {
|
||||||
removeVolumeInProgress(u.getFileName());
|
removeVolumeInProgress(u.getFileName());
|
||||||
@ -468,10 +375,115 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
MessageNotifyUtil.Notify.error(
|
MessageNotifyUtil.Notify.error(
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.done.errMsg.title"),
|
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.done.errMsg.title"),
|
||||||
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.done.errMsg.msg", ex.getMessage()));
|
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.done.errMsg.msg", ex.getMessage()));
|
||||||
|
logger.log(Level.SEVERE, "Failed to extract unallocated space", ex);
|
||||||
} // catch and ignore if we were cancelled
|
} // catch and ignore if we were cancelled
|
||||||
catch (java.util.concurrent.CancellationException ex) {
|
catch (java.util.concurrent.CancellationException ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initalizeFilesToExtract() throws TskCoreException {
|
||||||
|
List<OutputFileData> filesToExtract = new ArrayList<>();
|
||||||
|
|
||||||
|
if (volume != null) {
|
||||||
|
OutputFileData outputFileData = new OutputFileData(volume, openCase);
|
||||||
|
filesToExtract.add(outputFileData);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (hasVolumeSystem(image)) {
|
||||||
|
for (Volume v : getVolumes(image)) {
|
||||||
|
OutputFileData outputFileData = new OutputFileData(v, openCase);
|
||||||
|
filesToExtract.add(outputFileData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OutputFileData outputFileData = new OutputFileData(image, openCase);
|
||||||
|
filesToExtract.add(outputFileData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filesToExtract.isEmpty() == false) {
|
||||||
|
|
||||||
|
List<OutputFileData> copyList = new ArrayList<OutputFileData>() {
|
||||||
|
{
|
||||||
|
addAll(filesToExtract);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (OutputFileData outputFileData : filesToExtract) {
|
||||||
|
outputFileData.setPath(destination);
|
||||||
|
if (outputFileData.getLayouts() != null && !outputFileData.getLayouts().isEmpty() && (!isVolumeInProgress(outputFileData.getFileName()))) {
|
||||||
|
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
||||||
|
|
||||||
|
// Check if there is already a file with this name
|
||||||
|
if (outputFileData.getFile().exists()) {
|
||||||
|
final Result dialogResult = new Result();
|
||||||
|
try {
|
||||||
|
SwingUtilities.invokeAndWait(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
dialogResult.set(JOptionPane.showConfirmDialog(new Frame(), NbBundle.getMessage(this.getClass(),
|
||||||
|
"ExtractUnallocAction.confDlg.unallocFileAlreadyExist.msg",
|
||||||
|
outputFileData.getFileName())));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (InterruptedException | InvocationTargetException ex) {
|
||||||
|
logger.log(Level.SEVERE, "An error occured launching confirmation dialog for extract unalloc actions", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogResult.value == JOptionPane.YES_OPTION) {
|
||||||
|
// If the user wants to overwrite, delete the exising output file
|
||||||
|
outputFileData.getFile().delete();
|
||||||
|
} else {
|
||||||
|
// Otherwise remove it from the list of output files
|
||||||
|
copyList.remove(outputFileData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The output file for this volume could not be created for one of the following reasons
|
||||||
|
if (outputFileData.getLayouts() == null) {
|
||||||
|
logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS
|
||||||
|
} else if (outputFileData.getLayouts().isEmpty()) {
|
||||||
|
logger.log(Level.WARNING, "No unallocated files found in volume"); //NON-NLS
|
||||||
|
copyList.remove(outputFileData);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS
|
||||||
|
copyList.remove(outputFileData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!copyList.isEmpty()) {
|
||||||
|
|
||||||
|
setDataFileList(copyList);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDataFileList(List<OutputFileData> outputFileDataList) throws TskCoreException {
|
||||||
|
|
||||||
|
if (image != null) {
|
||||||
|
addImageInProgress(image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Getting the total megs this worker is going to be doing
|
||||||
|
for (OutputFileData outputFileData : outputFileDataList) {
|
||||||
|
try {
|
||||||
|
// If a volume is locked, skip it but continue trying to process any other requested volumes
|
||||||
|
addVolumeInProgress(outputFileData.getFileName());
|
||||||
|
totalBytes += outputFileData.getSizeInBytes();
|
||||||
|
this.outputFileDataList.add(outputFileData);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Already extracting data into {0}", outputFileData.getFileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have anything to output (because of locking), throw an exception
|
||||||
|
if (this.outputFileDataList.isEmpty()) {
|
||||||
|
throw new TskCoreException("No unallocated files can be extracted");
|
||||||
|
}
|
||||||
|
|
||||||
|
totalSizeinMegs = toMb(totalBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -659,14 +671,14 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
*
|
*
|
||||||
* @throws NoCurrentCaseException if there is no open case.
|
* @throws NoCurrentCaseException if there is no open case.
|
||||||
*/
|
*/
|
||||||
OutputFileData(Image img) throws NoCurrentCaseException {
|
OutputFileData(Image img, Case openCase) {
|
||||||
this.layoutFiles = getUnallocFiles(img);
|
this.layoutFiles = getUnallocFiles(img);
|
||||||
Collections.sort(layoutFiles, new SortObjId());
|
Collections.sort(layoutFiles, new SortObjId());
|
||||||
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"; //NON-NLS
|
this.fileName = this.imageName + "-Unalloc-" + this.imageId + "-" + 0 + ".dat"; //NON-NLS
|
||||||
this.fileInstance = new File(Case.getCurrentCaseThrows().getExportDirectory() + File.separator + this.fileName);
|
this.fileInstance = new File(openCase.getExportDirectory() + File.separator + this.fileName);
|
||||||
this.sizeInBytes = calcSizeInBytes();
|
this.sizeInBytes = calcSizeInBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +689,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
*
|
*
|
||||||
* @throws NoCurrentCaseException if there is no open case.
|
* @throws NoCurrentCaseException if there is no open case.
|
||||||
*/
|
*/
|
||||||
OutputFileData(Volume volume) throws NoCurrentCaseException {
|
OutputFileData(Volume volume, Case openCase) {
|
||||||
try {
|
try {
|
||||||
this.imageName = volume.getDataSource().getName();
|
this.imageName = volume.getDataSource().getName();
|
||||||
this.imageId = volume.getDataSource().getId();
|
this.imageId = volume.getDataSource().getId();
|
||||||
@ -688,7 +700,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
this.imageId = 0;
|
this.imageId = 0;
|
||||||
}
|
}
|
||||||
this.fileName = this.imageName + "-Unalloc-" + this.imageId + "-" + volumeId + ".dat"; //NON-NLS
|
this.fileName = this.imageName + "-Unalloc-" + this.imageId + "-" + volumeId + ".dat"; //NON-NLS
|
||||||
this.fileInstance = new File(Case.getCurrentCaseThrows().getExportDirectory() + File.separator + this.fileName);
|
this.fileInstance = new File(openCase.getExportDirectory() + File.separator + this.fileName);
|
||||||
this.layoutFiles = getUnallocFiles(volume);
|
this.layoutFiles = getUnallocFiles(volume);
|
||||||
Collections.sort(layoutFiles, new SortObjId());
|
Collections.sort(layoutFiles, new SortObjId());
|
||||||
this.sizeInBytes = calcSizeInBytes();
|
this.sizeInBytes = calcSizeInBytes();
|
||||||
@ -739,4 +751,46 @@ final class ExtractUnallocAction extends AbstractAction {
|
|||||||
this.fileInstance = new File(path + File.separator + this.fileName);
|
this.fileInstance = new File(path + File.separator + this.fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Custome JFileChooser for this Action Class.
|
||||||
|
private class CustomFileChooser extends JFileChooser {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
CustomFileChooser() {
|
||||||
|
initalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initalize() {
|
||||||
|
setDialogTitle(
|
||||||
|
NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.dlgTitle.selectDirToSaveTo.msg"));
|
||||||
|
setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
setAcceptAllFileFilterUsed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void approveSelection() {
|
||||||
|
File f = getSelectedFile();
|
||||||
|
if (!f.exists() && getDialogType() == SAVE_DIALOG || !f.canWrite()) {
|
||||||
|
JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(),
|
||||||
|
"ExtractUnallocAction.msgDlg.folderDoesntExist.msg"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.approveSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small helper class for use with SwingUtilities involkAndWait to get
|
||||||
|
// the result from the launching of the JOptionPane.
|
||||||
|
private class Result {
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
void set(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,12 @@ import java.nio.file.Paths;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import org.apache.poi.EmptyFileException;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
||||||
import org.apache.poi.poifs.filesystem.Entry;
|
import org.apache.poi.poifs.filesystem.Entry;
|
||||||
|
import org.apache.poi.poifs.filesystem.NotOLE2FileException;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
@ -62,7 +64,6 @@ final class ExtractJumpLists extends Extract {
|
|||||||
|
|
||||||
private static final String JUMPLIST_TSK_COMMENT = "Jumplist File";
|
private static final String JUMPLIST_TSK_COMMENT = "Jumplist File";
|
||||||
private static final String RA_DIR_NAME = "RecentActivity"; //NON-NLS
|
private static final String RA_DIR_NAME = "RecentActivity"; //NON-NLS
|
||||||
private static final String MODULE_OUTPUT_DIR = "ModuleOutput"; //NON-NLS
|
|
||||||
private static final String AUTOMATIC_DESTINATIONS_FILE_DIRECTORY = "%/AppData/Roaming/Microsoft/Windows/Recent/AutomaticDestinations/";
|
private static final String AUTOMATIC_DESTINATIONS_FILE_DIRECTORY = "%/AppData/Roaming/Microsoft/Windows/Recent/AutomaticDestinations/";
|
||||||
private static final String JUMPLIST_DIR_NAME = "jumplists"; //NON-NLS
|
private static final String JUMPLIST_DIR_NAME = "jumplists"; //NON-NLS
|
||||||
private static final String VERSION_NUMBER = "1.0.0"; //NON-NLS
|
private static final String VERSION_NUMBER = "1.0.0"; //NON-NLS
|
||||||
@ -86,7 +87,8 @@ final class ExtractJumpLists extends Extract {
|
|||||||
fileManager = currentCase.getServices().getFileManager();
|
fileManager = currentCase.getServices().getFileManager();
|
||||||
long ingestJobId = context.getJobId();
|
long ingestJobId = context.getJobId();
|
||||||
|
|
||||||
List<AbstractFile> jumpListFiles = extractJumplistFiles(dataSource, ingestJobId);
|
String baseRaTempPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), JUMPLIST_DIR_NAME , ingestJobId);
|
||||||
|
List<AbstractFile> jumpListFiles = extractJumplistFiles(dataSource, ingestJobId, baseRaTempPath);
|
||||||
|
|
||||||
if (jumpListFiles.isEmpty()) {
|
if (jumpListFiles.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -98,13 +100,13 @@ final class ExtractJumpLists extends Extract {
|
|||||||
|
|
||||||
List<AbstractFile> derivedFiles = new ArrayList<>();
|
List<AbstractFile> derivedFiles = new ArrayList<>();
|
||||||
String derivedPath = null;
|
String derivedPath = null;
|
||||||
String baseRaTempPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), JUMPLIST_DIR_NAME + "_" + dataSource.getId(), ingestJobId);
|
String baseRaModPath = RAImageIngestModule.getRAOutputPath(Case.getCurrentCase(), JUMPLIST_DIR_NAME, ingestJobId);
|
||||||
for (AbstractFile jumplistFile : jumpListFiles) {
|
for (AbstractFile jumplistFile : jumpListFiles) {
|
||||||
if (!jumplistFile.getName().toLowerCase().contains("-slack") && !jumplistFile.getName().equals("..") &&
|
if (!jumplistFile.getName().toLowerCase().contains("-slack") && !jumplistFile.getName().equals("..") &&
|
||||||
!jumplistFile.getName().equals(".") && jumplistFile.getSize() > 0) {
|
!jumplistFile.getName().equals(".") && jumplistFile.getSize() > 0) {
|
||||||
String jlFile = Paths.get(baseRaTempPath, jumplistFile.getName() + "_" + jumplistFile.getId()).toString();
|
String jlFile = Paths.get(baseRaTempPath, jumplistFile.getName() + "_" + jumplistFile.getId()).toString();
|
||||||
String moduleOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + RA_DIR_NAME + File.separator + JUMPLIST_DIR_NAME + "_" + dataSource.getId() + File.separator + jumplistFile.getName() + "_" + jumplistFile.getId();
|
String moduleOutPath = baseRaModPath + File.separator + jumplistFile.getName() + "_" + jumplistFile.getId();
|
||||||
derivedPath = RA_DIR_NAME + File.separator + JUMPLIST_DIR_NAME + "_" + dataSource.getId() + File.separator + jumplistFile.getName() + "_" + jumplistFile.getId();
|
derivedPath = RA_DIR_NAME + File.separator + JUMPLIST_DIR_NAME + "_" + ingestJobId + File.separator + jumplistFile.getName() + "_" + jumplistFile.getId();
|
||||||
File jlDir = new File(moduleOutPath);
|
File jlDir = new File(moduleOutPath);
|
||||||
if (jlDir.exists() == false) {
|
if (jlDir.exists() == false) {
|
||||||
boolean dirMade = jlDir.mkdirs();
|
boolean dirMade = jlDir.mkdirs();
|
||||||
@ -129,7 +131,7 @@ final class ExtractJumpLists extends Extract {
|
|||||||
*
|
*
|
||||||
* @return - list of jumplist abstractfiles or empty list
|
* @return - list of jumplist abstractfiles or empty list
|
||||||
*/
|
*/
|
||||||
private List<AbstractFile> extractJumplistFiles(Content dataSource, Long ingestJobId) {
|
private List<AbstractFile> extractJumplistFiles(Content dataSource, Long ingestJobId, String baseRaTempPath) {
|
||||||
List<AbstractFile> jumpListFiles = new ArrayList<>();;
|
List<AbstractFile> jumpListFiles = new ArrayList<>();;
|
||||||
List<AbstractFile> tempJumpListFiles = new ArrayList<>();;
|
List<AbstractFile> tempJumpListFiles = new ArrayList<>();;
|
||||||
|
|
||||||
@ -154,7 +156,6 @@ final class ExtractJumpLists extends Extract {
|
|||||||
if (!jumpListFile.getName().toLowerCase().contains("-slack") && !jumpListFile.getName().equals("..") &&
|
if (!jumpListFile.getName().toLowerCase().contains("-slack") && !jumpListFile.getName().equals("..") &&
|
||||||
!jumpListFile.getName().equals(".") && jumpListFile.getSize() > 0) {
|
!jumpListFile.getName().equals(".") && jumpListFile.getSize() > 0) {
|
||||||
String fileName = jumpListFile.getName() + "_" + jumpListFile.getId();
|
String fileName = jumpListFile.getName() + "_" + jumpListFile.getId();
|
||||||
String baseRaTempPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), JUMPLIST_DIR_NAME+ "_" + dataSource.getId(), ingestJobId);
|
|
||||||
String jlFile = Paths.get(baseRaTempPath, fileName).toString();
|
String jlFile = Paths.get(baseRaTempPath, fileName).toString();
|
||||||
try {
|
try {
|
||||||
ContentUtils.writeToFile(jumpListFile, new File(jlFile));
|
ContentUtils.writeToFile(jumpListFile, new File(jlFile));
|
||||||
@ -196,7 +197,8 @@ final class ExtractJumpLists extends Extract {
|
|||||||
JLNK lnk = lnkParser.parse();
|
JLNK lnk = lnkParser.parse();
|
||||||
lnkFileName = lnk.getBestName() + ".lnk";
|
lnkFileName = lnk.getBestName() + ".lnk";
|
||||||
File targetFile = new File(moduleOutPath + File.separator + entry.getName() + "-" + lnkFileName);
|
File targetFile = new File(moduleOutPath + File.separator + entry.getName() + "-" + lnkFileName);
|
||||||
String derivedFileName = MODULE_OUTPUT_DIR + File.separator + derivedPath + File.separator + entry.getName() + "-" + lnkFileName;
|
String relativePath = Case.getCurrentCase().getModuleOutputDirectoryRelativePath();
|
||||||
|
String derivedFileName = Case.getCurrentCase().getModuleOutputDirectoryRelativePath() + File.separator + derivedPath + File.separator + entry.getName() + "-" + lnkFileName;
|
||||||
OutputStream outStream = new FileOutputStream(targetFile);
|
OutputStream outStream = new FileOutputStream(targetFile);
|
||||||
outStream.write(buffer);
|
outStream.write(buffer);
|
||||||
outStream.close();
|
outStream.close();
|
||||||
@ -226,6 +228,8 @@ final class ExtractJumpLists extends Extract {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NotOLE2FileException | EmptyFileException ex1) {
|
||||||
|
logger.log(Level.WARNING, String.format("Error file not a valid OLE2 Document $s", jumpListFile)); //NON-NLS
|
||||||
} catch (IOException | TskCoreException ex) {
|
} catch (IOException | TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, String.format("Error lnk parsing the file to get recent files $s", jumpListFile), ex); //NON-NLS
|
logger.log(Level.WARNING, String.format("Error lnk parsing the file to get recent files $s", jumpListFile), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -235,3 +239,4 @@ final class ExtractJumpLists extends Extract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,9 @@ This is the User's Guide for the <a href="http://www.sleuthkit.org/autopsy/">ope
|
|||||||
|
|
||||||
Note: For those users running Autopsy on Mac devices, the functionality available through the "Tools" -> "Options" dialog as described in this documentation can be accessed through the system menu bar under "Preferences" or through the Cmd + , (command-comma) shortcut.
|
Note: For those users running Autopsy on Mac devices, the functionality available through the "Tools" -> "Options" dialog as described in this documentation can be accessed through the system menu bar under "Preferences" or through the Cmd + , (command-comma) shortcut.
|
||||||
|
|
||||||
|
Translated versions of this guide:
|
||||||
|
- <a href="https://sleuthkit.org/autopsy/docs/user-docs_fr/4.19.0/">Français (4.19.0)</a>
|
||||||
|
|
||||||
Help Topics
|
Help Topics
|
||||||
-------
|
-------
|
||||||
The following topics are available here:
|
The following topics are available here:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user