mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
This commit is contained in:
commit
7e81142c50
@ -68,9 +68,5 @@ abstract class ContentTypePanel extends JPanel {
|
|||||||
*/
|
*/
|
||||||
abstract public void select();
|
abstract public void select();
|
||||||
|
|
||||||
@Override
|
|
||||||
abstract public void addPropertyChangeListener(PropertyChangeListener pcl);
|
|
||||||
@Override
|
|
||||||
abstract public void removePropertyChangeListener(PropertyChangeListener pcl);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ import javax.swing.event.DocumentListener;
|
|||||||
* ImageTypePanel for adding an image file such as .img, .E0x, .00x, etc.
|
* ImageTypePanel for adding an image file such as .img, .E0x, .00x, etc.
|
||||||
*/
|
*/
|
||||||
public class ImageFilePanel extends ContentTypePanel implements DocumentListener {
|
public class ImageFilePanel extends ContentTypePanel implements DocumentListener {
|
||||||
private static ImageFilePanel instance;
|
private static ImageFilePanel instance = null;
|
||||||
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private PropertyChangeSupport pcs = null;
|
||||||
private JFileChooser fc = new JFileChooser();
|
private JFileChooser fc = new JFileChooser();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,19 +47,27 @@ public class ImageFilePanel extends ContentTypePanel implements DocumentListener
|
|||||||
fc.addChoosableFileFilter(AddImageVisualPanel1.rawFilter);
|
fc.addChoosableFileFilter(AddImageVisualPanel1.rawFilter);
|
||||||
fc.addChoosableFileFilter(AddImageVisualPanel1.encaseFilter);
|
fc.addChoosableFileFilter(AddImageVisualPanel1.encaseFilter);
|
||||||
fc.setFileFilter(AddImageVisualPanel1.allFilter);
|
fc.setFileFilter(AddImageVisualPanel1.allFilter);
|
||||||
pathTextField.getDocument().addDocumentListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default instance of a ImageFilePanel.
|
* Returns the default instance of a ImageFilePanel.
|
||||||
*/
|
*/
|
||||||
public static ImageFilePanel getDefault() {
|
public static synchronized ImageFilePanel getDefault() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new ImageFilePanel();
|
instance = new ImageFilePanel();
|
||||||
|
instance.postInit();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//post-constructor initialization to properly initialize listener support
|
||||||
|
//without leaking references of uninitialized objects
|
||||||
|
private void postInit() {
|
||||||
|
pathTextField.getDocument().addDocumentListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@ -217,12 +225,20 @@ public class ImageFilePanel extends ContentTypePanel implements DocumentListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.addPropertyChangeListener(pcl);
|
||||||
|
|
||||||
|
if (pcs == null) {
|
||||||
|
pcs = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
pcs.addPropertyChangeListener(pcl);
|
pcs.addPropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.removePropertyChangeListener(pcl);
|
||||||
|
|
||||||
pcs.removePropertyChangeListener(pcl);
|
pcs.removePropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
|||||||
*/
|
*/
|
||||||
public class LocalDiskPanel extends ContentTypePanel {
|
public class LocalDiskPanel extends ContentTypePanel {
|
||||||
private static LocalDiskPanel instance;
|
private static LocalDiskPanel instance;
|
||||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private PropertyChangeSupport pcs = null;
|
||||||
private List<LocalDisk> disks = new ArrayList<LocalDisk>();
|
private List<LocalDisk> disks = new ArrayList<LocalDisk>();
|
||||||
private LocalDiskModel model;
|
private LocalDiskModel model;
|
||||||
private boolean enableNext = false;
|
private boolean enableNext = false;
|
||||||
@ -61,13 +61,14 @@ public class LocalDiskPanel extends ContentTypePanel {
|
|||||||
/**
|
/**
|
||||||
* Get the default instance of this panel.
|
* Get the default instance of this panel.
|
||||||
*/
|
*/
|
||||||
public static LocalDiskPanel getDefault() {
|
public static synchronized LocalDiskPanel getDefault() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new LocalDiskPanel();
|
instance = new LocalDiskPanel();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void customInit() {
|
private void customInit() {
|
||||||
model = new LocalDiskModel();
|
model = new LocalDiskModel();
|
||||||
diskComboBox.setModel(model);
|
diskComboBox.setModel(model);
|
||||||
@ -189,12 +190,20 @@ public class LocalDiskPanel extends ContentTypePanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.addPropertyChangeListener(pcl);
|
||||||
|
|
||||||
|
if (pcs == null) {
|
||||||
|
pcs = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
pcs.addPropertyChangeListener(pcl);
|
pcs.addPropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.removePropertyChangeListener(pcl);
|
||||||
|
|
||||||
pcs.removePropertyChangeListener(pcl);
|
pcs.removePropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ import javax.swing.JFileChooser;
|
|||||||
*/
|
*/
|
||||||
public class LocalFilesPanel extends ContentTypePanel {
|
public class LocalFilesPanel extends ContentTypePanel {
|
||||||
|
|
||||||
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private PropertyChangeSupport pcs = null;
|
||||||
private Set<File> currentFiles = new TreeSet<File>(); //keep currents in a set to disallow duplicates per add
|
private Set<File> currentFiles = new TreeSet<File>(); //keep currents in a set to disallow duplicates per add
|
||||||
private boolean enableNext = false;
|
private boolean enableNext = false;
|
||||||
private static LocalFilesPanel instance;
|
private static LocalFilesPanel instance;
|
||||||
@ -55,7 +55,6 @@ public class LocalFilesPanel extends ContentTypePanel {
|
|||||||
localFileChooser.setMultiSelectionEnabled(true);
|
localFileChooser.setMultiSelectionEnabled(true);
|
||||||
selectedPaths.setText("");
|
selectedPaths.setText("");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,16 +101,25 @@ public class LocalFilesPanel extends ContentTypePanel {
|
|||||||
pcs.firePropertyChange(AddImageVisualPanel1.EVENT.UPDATE_UI.toString(), false, true);
|
pcs.firePropertyChange(AddImageVisualPanel1.EVENT.UPDATE_UI.toString(), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.addPropertyChangeListener(pcl);
|
||||||
|
|
||||||
|
if (pcs == null) {
|
||||||
|
pcs = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
pcs.addPropertyChangeListener(pcl);
|
pcs.addPropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
super.removePropertyChangeListener(pcl);
|
||||||
|
|
||||||
pcs.removePropertyChangeListener(pcl);
|
pcs.removePropertyChangeListener(pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Logical Files";
|
return "Logical Files";
|
||||||
|
@ -41,6 +41,7 @@ import org.apache.solr.common.SolrException.ErrorCode;
|
|||||||
import org.apache.solr.common.util.ContentStream;
|
import org.apache.solr.common.util.ContentStream;
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.keywordsearch.Server.SolrServerNoPortException;
|
import org.sleuthkit.autopsy.keywordsearch.Server.SolrServerNoPortException;
|
||||||
@ -52,10 +53,10 @@ import org.sleuthkit.datamodel.DerivedFile;
|
|||||||
import org.sleuthkit.datamodel.Directory;
|
import org.sleuthkit.datamodel.Directory;
|
||||||
import org.sleuthkit.datamodel.File;
|
import org.sleuthkit.datamodel.File;
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
import org.sleuthkit.datamodel.Image;
|
|
||||||
import org.sleuthkit.datamodel.LayoutFile;
|
import org.sleuthkit.datamodel.LayoutFile;
|
||||||
import org.sleuthkit.datamodel.LocalFile;
|
import org.sleuthkit.datamodel.LocalFile;
|
||||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,6 +185,12 @@ public class Ingester {
|
|||||||
|
|
||||||
private class GetContentFieldsV extends ContentVisitor.Default<Map<String, String>> {
|
private class GetContentFieldsV extends ContentVisitor.Default<Map<String, String>> {
|
||||||
|
|
||||||
|
private SleuthkitCase curCase = null;
|
||||||
|
|
||||||
|
GetContentFieldsV() {
|
||||||
|
curCase = Case.getCurrentCase().getSleuthkitCase();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, String> defaultVisit(Content cntnt) {
|
protected Map<String, String> defaultVisit(Content cntnt) {
|
||||||
return new HashMap<String, String>();
|
return new HashMap<String, String>();
|
||||||
@ -217,11 +224,7 @@ public class Ingester {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> visit(LocalFile lf) {
|
public Map<String, String> visit(LocalFile lf) {
|
||||||
final Map<String, String> params = new HashMap<String, String>();
|
return getCommonFields(lf);
|
||||||
params.put(Server.Schema.ID.toString(), Long.toString(lf.getId()));
|
|
||||||
params.put(Server.Schema.FILE_NAME.toString(), lf.getName());
|
|
||||||
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(-1));
|
|
||||||
return params;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getCommonFsContentFields(Map<String, String> params, FsContent fsContent) {
|
private Map<String, String> getCommonFsContentFields(Map<String, String> params, FsContent fsContent) {
|
||||||
@ -235,15 +238,13 @@ public class Ingester {
|
|||||||
private Map<String, String> getCommonFields(AbstractFile af) {
|
private Map<String, String> getCommonFields(AbstractFile af) {
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
params.put(Server.Schema.ID.toString(), Long.toString(af.getId()));
|
params.put(Server.Schema.ID.toString(), Long.toString(af.getId()));
|
||||||
long imageId = -1;
|
long dataSourceId = -1;
|
||||||
try {
|
try {
|
||||||
Image image = af.getImage();
|
dataSourceId = curCase.getFileDataSource(af);
|
||||||
if (image != null) {
|
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(dataSourceId));
|
||||||
imageId = image.getId();
|
|
||||||
}
|
|
||||||
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(imageId));
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Could not get image id to properly index the file " + af.getId());
|
logger.log(Level.SEVERE, "Could not get data source id to properly index the file " + af.getId());
|
||||||
|
params.put(Server.Schema.IMAGE_ID.toString(), Long.toString(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
params.put(Server.Schema.FILE_NAME.toString(), af.getName());
|
params.put(Server.Schema.FILE_NAME.toString(), af.getName());
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.keywordsearch;
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Filter to restrict query only specific files, chunks, images
|
* Filter to restrict query only specific files, chunks, images
|
||||||
@ -27,23 +31,23 @@ public class KeywordQueryFilter {
|
|||||||
|
|
||||||
public static enum FilterType {
|
public static enum FilterType {
|
||||||
|
|
||||||
FILE, CHUNK, IMAGE
|
FILE, CHUNK, DATA_SOURCE
|
||||||
};
|
};
|
||||||
private long[] idFilters;
|
private Set<Long>idFilters;
|
||||||
private FilterType filterType;
|
private FilterType filterType;
|
||||||
|
|
||||||
public KeywordQueryFilter(FilterType filterType, long id) {
|
public KeywordQueryFilter(FilterType filterType, long id) {
|
||||||
this.filterType = filterType;
|
this.filterType = filterType;
|
||||||
this.idFilters = new long[1];
|
this.idFilters = new HashSet<Long>();
|
||||||
this.idFilters[0] = id;
|
this.idFilters.add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeywordQueryFilter(FilterType filterType, long[] ids) {
|
public KeywordQueryFilter(FilterType filterType, Set<Long>ids) {
|
||||||
this.filterType = filterType;
|
this.filterType = filterType;
|
||||||
this.idFilters = ids;
|
this.idFilters = ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] getIdFilters() {
|
public Set<Long> getIdFilters() {
|
||||||
return idFilters;
|
return idFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,12 +59,14 @@ public class KeywordQueryFilter {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String id = null;
|
String id = null;
|
||||||
for (int i = 0; i < idFilters.length; ++i) {
|
|
||||||
|
Iterator<Long>it = idFilters.iterator();
|
||||||
|
for (int i = 0; it.hasNext(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sb.append(" "); //OR
|
sb.append(" "); //OR
|
||||||
}
|
}
|
||||||
long idVal = idFilters[i];
|
long idVal = it.next();
|
||||||
if (filterType == FilterType.IMAGE) {
|
if (filterType == FilterType.DATA_SOURCE) {
|
||||||
id = Server.Schema.IMAGE_ID.toString();
|
id = Server.Schema.IMAGE_ID.toString();
|
||||||
} else {
|
} else {
|
||||||
id = Server.Schema.ID.toString();
|
id = Server.Schema.ID.toString();
|
||||||
|
@ -44,6 +44,7 @@ import org.netbeans.api.progress.aggregate.AggregateProgressFactory;
|
|||||||
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
|
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
|
||||||
import org.netbeans.api.progress.aggregate.ProgressContributor;
|
import org.netbeans.api.progress.aggregate.ProgressContributor;
|
||||||
import org.openide.util.Cancellable;
|
import org.openide.util.Cancellable;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.StopWatch;
|
import org.sleuthkit.autopsy.coreutils.StopWatch;
|
||||||
@ -60,6 +61,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
|||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
@ -115,7 +117,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
private Map<Keyword, List<Long>> currentResults;
|
private Map<Keyword, List<Long>> currentResults;
|
||||||
//only search images from current ingest, not images previously ingested/indexed
|
//only search images from current ingest, not images previously ingested/indexed
|
||||||
//accessed read-only by searcher thread
|
//accessed read-only by searcher thread
|
||||||
private Set<Long> curImageIds;
|
private Set<Long> curDataSourceIds;
|
||||||
private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy
|
private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy
|
||||||
private static final Lock searcherLock = rwLock.writeLock();
|
private static final Lock searcherLock = rwLock.writeLock();
|
||||||
private volatile int messageID = 0;
|
private volatile int messageID = 0;
|
||||||
@ -129,6 +131,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
private KeywordSearchConfigurationPanel panel;
|
private KeywordSearchConfigurationPanel panel;
|
||||||
private Tika tikaFormatDetector;
|
private Tika tikaFormatDetector;
|
||||||
|
|
||||||
|
|
||||||
private enum IngestStatus {
|
private enum IngestStatus {
|
||||||
|
|
||||||
INGESTED, EXTRACTED_INGESTED, SKIPPED, INGESTED_META
|
INGESTED, EXTRACTED_INGESTED, SKIPPED, INGESTED_META
|
||||||
@ -160,12 +163,10 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
return ProcessResult.OK;
|
return ProcessResult.OK;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
//add image id of the file to the set, keeping track of images being ingested
|
//add data source id of the file to the set, keeping track of images being ingested
|
||||||
final Image fileImage = abstractFile.getImage();
|
final long fileSourceId = caseHandle.getFileDataSource(abstractFile);
|
||||||
if (fileImage != null) {
|
curDataSourceIds.add(fileSourceId);
|
||||||
//not all Content objects have an image associated (e.g. LocalFiles)
|
|
||||||
curImageIds.add(fileImage.getId());
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting image id of file processed by keyword search: " + abstractFile.getName(), ex);
|
logger.log(Level.SEVERE, "Error getting image id of file processed by keyword search: " + abstractFile.getName(), ex);
|
||||||
}
|
}
|
||||||
@ -288,7 +289,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
ingestStatus.clear();
|
ingestStatus.clear();
|
||||||
currentResults.clear();
|
currentResults.clear();
|
||||||
curImageIds.clear();
|
curDataSourceIds.clear();
|
||||||
currentSearcher = null;
|
currentSearcher = null;
|
||||||
//finalSearcher = null; //do not collect, might be finalizing
|
//finalSearcher = null; //do not collect, might be finalizing
|
||||||
|
|
||||||
@ -399,7 +400,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
//keeps track of all results per run not to repeat reporting the same hits
|
//keeps track of all results per run not to repeat reporting the same hits
|
||||||
currentResults = new HashMap<Keyword, List<Long>>();
|
currentResults = new HashMap<Keyword, List<Long>>();
|
||||||
|
|
||||||
curImageIds = new HashSet<Long>();
|
curDataSourceIds = new HashSet<Long>();
|
||||||
|
|
||||||
indexer = new Indexer();
|
indexer = new Indexer();
|
||||||
|
|
||||||
@ -930,15 +931,10 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
|||||||
del = new TermComponentQuery(keywordQuery);
|
del = new TermComponentQuery(keywordQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
//limit search to currently ingested images
|
//limit search to currently ingested data sources
|
||||||
final long imageIds[] = new long[curImageIds.size()];
|
|
||||||
final Iterator<Long> it = curImageIds.iterator();
|
|
||||||
for (int imageI = 0; it.hasNext(); ++imageI) {
|
|
||||||
imageIds[imageI] = it.next();
|
|
||||||
}
|
|
||||||
//set up a filter with 1 or more image ids OR'ed
|
//set up a filter with 1 or more image ids OR'ed
|
||||||
final KeywordQueryFilter imageFilter = new KeywordQueryFilter(KeywordQueryFilter.FilterType.IMAGE, imageIds);
|
final KeywordQueryFilter dataSourceFilter = new KeywordQueryFilter(KeywordQueryFilter.FilterType.DATA_SOURCE, curDataSourceIds);
|
||||||
del.addFilter(imageFilter);
|
del.addFilter(dataSourceFilter);
|
||||||
|
|
||||||
Map<String, List<ContentHit>> queryResult = null;
|
Map<String, List<ContentHit>> queryResult = null;
|
||||||
|
|
||||||
|
2
NEWS.txt
2
NEWS.txt
@ -3,6 +3,7 @@
|
|||||||
New features:
|
New features:
|
||||||
- Logical files and folders support
|
- Logical files and folders support
|
||||||
- New file views in directory tree to view: deleted, executable, archive files and files by size
|
- New file views in directory tree to view: deleted, executable, archive files and files by size
|
||||||
|
- ext4 and yaffs2 support (via TSK 4.1.0)
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
- Improvements to tagging of files and keyword search results
|
- Improvements to tagging of files and keyword search results
|
||||||
@ -14,6 +15,7 @@ Bugfixes:
|
|||||||
- fixed result viewer for "File Search by MD5 Hash"
|
- fixed result viewer for "File Search by MD5 Hash"
|
||||||
- fix Solr, Timeline and RecentActivity issues with java 7.0.21
|
- fix Solr, Timeline and RecentActivity issues with java 7.0.21
|
||||||
- Views->Recent Files showing inconsistent results when clicked many times
|
- Views->Recent Files showing inconsistent results when clicked many times
|
||||||
|
- reduced memory usage in Timeline
|
||||||
|
|
||||||
|
|
||||||
---------------- VERSION 3.0.5 --------------
|
---------------- VERSION 3.0.5 --------------
|
||||||
|
@ -77,13 +77,13 @@ import org.openide.awt.ActionReferences;
|
|||||||
import org.openide.awt.ActionRegistration;
|
import org.openide.awt.ActionRegistration;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
import org.openide.modules.ModuleInstall;
|
import org.openide.modules.ModuleInstall;
|
||||||
import org.openide.nodes.ChildFactory;
|
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
||||||
@ -98,14 +98,20 @@ import org.sleuthkit.autopsy.datamodel.FileNode;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
|
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
|
||||||
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy=false)
|
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false)
|
||||||
@ActionReferences(value = {
|
@ActionReferences(value = {
|
||||||
@ActionReference(path = "Menu/Tools", position = 100)})
|
@ActionReference(path = "Menu/Tools", position = 100)})
|
||||||
@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
|
@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
|
||||||
|
/**
|
||||||
|
* The Timeline Action entry point. Collects data and pushes data to javafx
|
||||||
|
* widgets
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class Timeline extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener {
|
public class Timeline extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Timeline.class.getName());
|
private static final Logger logger = Logger.getLogger(Timeline.class.getName());
|
||||||
@ -116,14 +122,14 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
|
private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
|
||||||
private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
|
private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
|
||||||
private JFXPanel fxPanelCharts; //FX panel to hold the group
|
private JFXPanel fxPanelCharts; //FX panel to hold the group
|
||||||
private BarChart<String,Number> fxChartEvents; //Yearly/Monthly events - Bar chart
|
private BarChart<String, Number> fxChartEvents; //Yearly/Monthly events - Bar chart
|
||||||
private ScrollPane fxScrollEvents; //Scroll Panes for dealing with oversized an oversized chart
|
private ScrollPane fxScrollEvents; //Scroll Panes for dealing with oversized an oversized chart
|
||||||
private static final int FRAME_HEIGHT = 700; //Sizing constants
|
private static final int FRAME_HEIGHT = 700; //Sizing constants
|
||||||
private static final int FRAME_WIDTH = 1200;
|
private static final int FRAME_WIDTH = 1200;
|
||||||
private Button fxZoomOutButton; //Navigation buttons
|
private Button fxZoomOutButton; //Navigation buttons
|
||||||
private ComboBox<String> fxDropdownSelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
|
private ComboBox<String> fxDropdownSelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
|
||||||
private final Stack<BarChart<String,Number>> fxStackPrevCharts = new Stack<BarChart<String,Number>>(); //Stack for storing drill-up information.
|
private final Stack<BarChart<String, Number>> fxStackPrevCharts = new Stack<BarChart<String, Number>>(); //Stack for storing drill-up information.
|
||||||
private BarChart<String,Number> fxChartTopLevel; //the topmost chart, used for resetting to default view.
|
private BarChart<String, Number> fxChartTopLevel; //the topmost chart, used for resetting to default view.
|
||||||
private DataResultPanel dataResultPanel;
|
private DataResultPanel dataResultPanel;
|
||||||
private DataContentPanel dataContentPanel;
|
private DataContentPanel dataContentPanel;
|
||||||
private ProgressHandle progress;
|
private ProgressHandle progress;
|
||||||
@ -272,7 +278,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
|
fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent e) {
|
public void handle(ActionEvent e) {
|
||||||
BarChart<String,Number> bc;
|
BarChart<String, Number> bc;
|
||||||
if (fxStackPrevCharts.size() == 0) {
|
if (fxStackPrevCharts.size() == 0) {
|
||||||
bc = fxChartTopLevel;
|
bc = fxChartTopLevel;
|
||||||
} else {
|
} else {
|
||||||
@ -339,7 +345,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
* @param allYears The list of years that have barData from the mactime file
|
* @param allYears The list of years that have barData from the mactime file
|
||||||
* @return BarChart scaled to the year level
|
* @return BarChart scaled to the year level
|
||||||
*/
|
*/
|
||||||
private BarChart<String,Number> createYearChartWithDrill(final List<YearEpoch> allYears) {
|
private BarChart<String, Number> createYearChartWithDrill(final List<YearEpoch> allYears) {
|
||||||
final CategoryAxis xAxis = new CategoryAxis(); //Axes are very specific types. Categorys are strings.
|
final CategoryAxis xAxis = new CategoryAxis(); //Axes are very specific types. Categorys are strings.
|
||||||
final NumberAxis yAxis = new NumberAxis();
|
final NumberAxis yAxis = new NumberAxis();
|
||||||
final Label l = new Label("");
|
final Label l = new Label("");
|
||||||
@ -354,7 +360,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
|
BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
|
||||||
if (allYears != null) {
|
if (allYears != null) {
|
||||||
for (final YearEpoch ye : allYears) {
|
for (final YearEpoch ye : allYears) {
|
||||||
se.getData().add(new BarChart.Data<String, Number>(String.valueOf(ye.year), ye.getNumFiles()));
|
se.getData().add(new BarChart.Data<String, Number>(String.valueOf(ye.year), ye.getNumFiles()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcData.add(se);
|
bcData.add(se);
|
||||||
@ -367,7 +373,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
// But it is for this reason that the chart generating functions have two forloops. I do not believe they can be condensed into a single loop due to the nodes being null until
|
// But it is for this reason that the chart generating functions have two forloops. I do not believe they can be condensed into a single loop due to the nodes being null until
|
||||||
// an undetermined point in time.
|
// an undetermined point in time.
|
||||||
BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
||||||
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
|
for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
|
||||||
barData.getNode().setScaleX(.5);
|
barData.getNode().setScaleX(.5);
|
||||||
|
|
||||||
final javafx.scene.Node barNode = barData.getNode();
|
final javafx.scene.Node barNode = barData.getNode();
|
||||||
@ -385,7 +391,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
Platform.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
BarChart<String,Number> b =
|
BarChart<String, Number> b =
|
||||||
createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
|
createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
|
||||||
fxChartEvents = b;
|
fxChartEvents = b;
|
||||||
fxScrollEvents.setContent(fxChartEvents);
|
fxScrollEvents.setContent(fxChartEvents);
|
||||||
@ -408,7 +414,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
* Displays a chart with events from one year only, separated into 1-month chunks.
|
* Displays a chart with events from one year only, separated into 1-month chunks.
|
||||||
* Always 12 per year, empty months are represented by no bar.
|
* Always 12 per year, empty months are represented by no bar.
|
||||||
*/
|
*/
|
||||||
private BarChart<String,Number> createMonthsWithDrill(final YearEpoch ye) {
|
private BarChart<String, Number> createMonthsWithDrill(final YearEpoch ye) {
|
||||||
|
|
||||||
final CategoryAxis xAxis = new CategoryAxis();
|
final CategoryAxis xAxis = new CategoryAxis();
|
||||||
final NumberAxis yAxis = new NumberAxis();
|
final NumberAxis yAxis = new NumberAxis();
|
||||||
@ -427,7 +433,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
||||||
|
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
|
for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
|
||||||
//Note:
|
//Note:
|
||||||
// All the charts of this package have a problem where when the chart gets below a certain pixel ratio, the barData stops drawing. The axes and the labels remain,
|
// All the charts of this package have a problem where when the chart gets below a certain pixel ratio, the barData stops drawing. The axes and the labels remain,
|
||||||
// But the actual chart barData is invisible, unclickable, and unrendered. To partially compensate for that, barData.getNode() can be manually scaled up to increase visibility.
|
// But the actual chart barData is invisible, unclickable, and unrendered. To partially compensate for that, barData.getNode() can be manually scaled up to increase visibility.
|
||||||
@ -473,14 +479,13 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
* Displays a chart with events from one month only.
|
* Displays a chart with events from one month only.
|
||||||
* Up to 31 days per month, as low as 28 as determined by the specific MonthEpoch
|
* Up to 31 days per month, as low as 28 as determined by the specific MonthEpoch
|
||||||
*/
|
*/
|
||||||
private BarChart<String,Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
|
private BarChart<String, Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
|
||||||
final CategoryAxis xAxis = new CategoryAxis();
|
final CategoryAxis xAxis = new CategoryAxis();
|
||||||
final NumberAxis yAxis = new NumberAxis();
|
final NumberAxis yAxis = new NumberAxis();
|
||||||
xAxis.setLabel("Day of Month");
|
xAxis.setLabel("Day of Month");
|
||||||
yAxis.setLabel("Number of Events");
|
yAxis.setLabel("Number of Events");
|
||||||
ObservableList<BarChart.Data<String,Number>> bcData
|
ObservableList<BarChart.Data<String, Number>> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
|
||||||
= makeObservableListByMonthAllDays(me, ye.getYear());
|
BarChart.Series<String, Number> series = new BarChart.Series<String, Number>(bcData);
|
||||||
BarChart.Series<String, Number> series = new BarChart.Series<String,Number>(bcData);
|
|
||||||
series.setName(me.getMonthName() + " " + ye.getYear());
|
series.setName(me.getMonthName() + " " + ye.getYear());
|
||||||
|
|
||||||
|
|
||||||
@ -488,7 +493,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
|
FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
|
||||||
|
|
||||||
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
|
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
|
||||||
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
|
for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
|
||||||
//data.getNode().setScaleX(2);
|
//data.getNode().setScaleX(2);
|
||||||
|
|
||||||
final javafx.scene.Node barNode = barData.getNode();
|
final javafx.scene.Node barNode = barData.getNode();
|
||||||
@ -503,9 +508,18 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(MouseEvent e) {
|
public void handle(MouseEvent e) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//reset the view and free the current nodes before loading new ones
|
||||||
|
final FileRootNode d = new FileRootNode("Empty Root", new ArrayList<Long>());
|
||||||
|
dataResultPanel.setNode(d);
|
||||||
|
dataResultPanel.setPath("Loading...");
|
||||||
|
}
|
||||||
|
});
|
||||||
final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
|
final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
|
||||||
final DayEpoch de = myme.getDay(day);
|
final DayEpoch de = myme.getDay(day);
|
||||||
final List<AbstractFile> afs;
|
final List<Long> afs;
|
||||||
if (de != null) {
|
if (de != null) {
|
||||||
afs = de.getEvents();
|
afs = de.getEvents();
|
||||||
} else {
|
} else {
|
||||||
@ -516,7 +530,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final FileRootNode d = new FileRootNode("Test Root", afs);
|
final FileRootNode d = new FileRootNode("Root", afs);
|
||||||
dataResultPanel.setNode(d);
|
dataResultPanel.setNode(d);
|
||||||
//set result viewer title path with the current date
|
//set result viewer title path with the current date
|
||||||
String dateString = ye.getYear() + "-" + (1 + me.getMonthInt()) + "-" + +de.dayNum;
|
String dateString = ye.getYear() + "-" + (1 + me.getMonthInt()) + "-" + +de.dayNum;
|
||||||
@ -533,13 +547,13 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObservableList<BarChart.Data<String,Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
|
private static ObservableList<BarChart.Data<String, Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
|
||||||
ObservableList<BarChart.Data<String,Number>> bcData = FXCollections.observableArrayList();
|
ObservableList<BarChart.Data<String, Number>> bcData = FXCollections.observableArrayList();
|
||||||
int totalDays = me.getTotalNumDays(year);
|
int totalDays = me.getTotalNumDays(year);
|
||||||
for (int i = 1; i <= totalDays; ++i) {
|
for (int i = 1; i <= totalDays; ++i) {
|
||||||
DayEpoch day = me.getDay(i);
|
DayEpoch day = me.getDay(i);
|
||||||
int numFiles = day == null ? 0 : day.getNumFiles();
|
int numFiles = day == null ? 0 : day.getNumFiles();
|
||||||
BarChart.Data<String,Number> d = new BarChart.Data<String,Number>(me.month + 1 + "-" + i, numFiles);
|
BarChart.Data<String, Number> d = new BarChart.Data<String, Number>(me.month + 1 + "-" + i, numFiles);
|
||||||
d.setExtraValue(me);
|
d.setExtraValue(me);
|
||||||
bcData.add(d);
|
bcData.add(d);
|
||||||
}
|
}
|
||||||
@ -693,7 +707,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
return month;
|
return month;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(AbstractFile af, int month, int day) {
|
public void add(long fileId, int month, int day) {
|
||||||
// see if this month is in the list
|
// see if this month is in the list
|
||||||
MonthEpoch monthEpoch = null;
|
MonthEpoch monthEpoch = null;
|
||||||
for (MonthEpoch me : months) {
|
for (MonthEpoch me : months) {
|
||||||
@ -709,7 +723,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add the file the the MonthEpoch object
|
// add the file the the MonthEpoch object
|
||||||
monthEpoch.add(af, day);
|
monthEpoch.add(fileId, day);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +766,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
return de;
|
return de;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(AbstractFile af, int day) {
|
public void add(long fileId, int day) {
|
||||||
DayEpoch dayEpoch = null;
|
DayEpoch dayEpoch = null;
|
||||||
for (DayEpoch de : days) {
|
for (DayEpoch de : days) {
|
||||||
if (de.getDayInt() == day) {
|
if (de.getDayInt() == day) {
|
||||||
@ -766,7 +780,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
days.add(dayEpoch);
|
days.add(dayEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
dayEpoch.add(af);
|
dayEpoch.add(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -786,7 +800,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
|
|
||||||
private class DayEpoch extends Epoch {
|
private class DayEpoch extends Epoch {
|
||||||
|
|
||||||
private List<AbstractFile> files = new ArrayList<>();
|
private final List<Long> fileIds = new ArrayList<>();
|
||||||
int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28.
|
int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28.
|
||||||
|
|
||||||
DayEpoch(int dayOfMonth) {
|
DayEpoch(int dayOfMonth) {
|
||||||
@ -799,40 +813,68 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumFiles() {
|
public int getNumFiles() {
|
||||||
return files.size();
|
return fileIds.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(AbstractFile af) {
|
public void add(long fileId) {
|
||||||
files.add(af);
|
fileIds.add(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AbstractFile> getEvents() {
|
List<Long> getEvents() {
|
||||||
return this.files;
|
return this.fileIds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The node factories used to make lists of files to send to the result viewer
|
// The node factories used to make lists of files to send to the result viewer
|
||||||
private class FileNodeChildFactory extends ChildFactory<AbstractFile> {
|
// using the lazy loading (rather than background) loading option to facilitate
|
||||||
|
// loading a huge number of nodes for the given day
|
||||||
|
private class FileNodeChildFactory extends Children.Keys<Long> {
|
||||||
|
|
||||||
List<AbstractFile> l;
|
private List<Long> fileIds;
|
||||||
|
|
||||||
FileNodeChildFactory(List<AbstractFile> l) {
|
FileNodeChildFactory(List<Long> fileIds) {
|
||||||
this.l = l;
|
super(true);
|
||||||
|
this.fileIds = fileIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean createKeys(List<AbstractFile> list) {
|
protected void addNotify() {
|
||||||
list.addAll(l);
|
super.addNotify();
|
||||||
return true;
|
setKeys(fileIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node createNodeForKey(AbstractFile file) {
|
protected void removeNotify() {
|
||||||
|
super.removeNotify();
|
||||||
|
setKeys(new ArrayList<Long>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Node[] createNodes(Long t) {
|
||||||
|
return new Node[]{createNodeForKey(t)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// protected boolean createKeys(List<Long> list) {
|
||||||
|
// list.addAll(fileIds);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//@Override
|
||||||
|
protected Node createNodeForKey(Long fileId) {
|
||||||
|
AbstractFile af = null;
|
||||||
|
try {
|
||||||
|
af = skCase.getAbstractFileById(fileId);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error getting file by id and creating a node in Timeline: " + fileId, ex);
|
||||||
|
//no node will be shown for this object
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Node wrapped;
|
Node wrapped;
|
||||||
if (file.isDir()) {
|
if (af.isDir()) {
|
||||||
wrapped = new DirectoryNode(file, false);
|
wrapped = new DirectoryNode(af, false);
|
||||||
} else {
|
} else {
|
||||||
wrapped = new FileNode(file, false);
|
wrapped = new FileNode(af, false);
|
||||||
}
|
}
|
||||||
return new FilterNodeLeaf(wrapped);
|
return new FilterNodeLeaf(wrapped);
|
||||||
}
|
}
|
||||||
@ -840,8 +882,9 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
|
|
||||||
private class FileRootNode extends DisplayableItemNode {
|
private class FileRootNode extends DisplayableItemNode {
|
||||||
|
|
||||||
FileRootNode(String NAME, List<AbstractFile> l) {
|
FileRootNode(String NAME, List<Long> fileIds) {
|
||||||
super(Children.create(new FileNodeChildFactory(l), true));
|
//super(Children.create(new FileNodeChildFactory(fileIds), true));
|
||||||
|
super(new FileNodeChildFactory(fileIds), Lookups.singleton(fileIds));
|
||||||
super.setName(NAME);
|
super.setName(NAME);
|
||||||
super.setDisplayName(NAME);
|
super.setDisplayName(NAME);
|
||||||
}
|
}
|
||||||
@ -887,16 +930,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
prevYear = year;
|
prevYear = year;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and add the file
|
|
||||||
AbstractFile file;
|
|
||||||
try {
|
|
||||||
file = skCase.getAbstractFileById(ObjId);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Could not find a file with ID " + ObjId, ex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ye != null) {
|
if (ye != null) {
|
||||||
ye.add(file, month, day);
|
ye.add(ObjId, month, day);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,11 +958,11 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
+ java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt";
|
+ java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt";
|
||||||
|
|
||||||
// Run query to get all files
|
// Run query to get all files
|
||||||
String filesAndDirs = "name != '.' "
|
final String filesAndDirs = "name != '.' "
|
||||||
+ "AND name != '..'";
|
+ "AND name != '..'";
|
||||||
List<AbstractFile> files = null;
|
List<Long> fileIds = null;
|
||||||
try {
|
try {
|
||||||
files = skCase.findAllFilesWhere(filesAndDirs);
|
fileIds = skCase.findAllFileIdsWhere(filesAndDirs);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error querying image files to make a body file: " + bodyFilePath, ex);
|
logger.log(Level.SEVERE, "Error querying image files to make a body file: " + bodyFilePath, ex);
|
||||||
return null;
|
return null;
|
||||||
@ -945,7 +980,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
BufferedWriter out = null;
|
BufferedWriter out = null;
|
||||||
try {
|
try {
|
||||||
out = new BufferedWriter(fileWriter);
|
out = new BufferedWriter(fileWriter);
|
||||||
for (AbstractFile file : files) {
|
for (long fileId : fileIds) {
|
||||||
|
AbstractFile file = skCase.getAbstractFileById(fileId);
|
||||||
// try {
|
// try {
|
||||||
// MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime
|
// MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime
|
||||||
if (file.getMd5Hash() != null) {
|
if (file.getMd5Hash() != null) {
|
||||||
@ -985,6 +1021,10 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
out.write(Long.toString(file.getCrtime()));
|
out.write(Long.toString(file.getCrtime()));
|
||||||
out.write("\n");
|
out.write("\n");
|
||||||
}
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error querying file by id", ex);
|
||||||
|
return null;
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.WARNING, "Error while trying to write data to the body file.", ex);
|
logger.log(Level.WARNING, "Error while trying to write data to the body file.", ex);
|
||||||
return null;
|
return null;
|
||||||
@ -1030,8 +1070,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
logger.log(Level.SEVERE, "Could not create mactime file, encountered error ", ioe);
|
logger.log(Level.SEVERE, "Could not create mactime file, encountered error ", ioe);
|
||||||
return null;
|
return null;
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
try {
|
try {
|
||||||
writer.close();
|
writer.close();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<p align="center" style="font-size: 145%;"><strong>Autopsy 3 Quick Start Guide</strong></p>
|
<p align="center" style="font-size: 145%;"><strong>Autopsy 3 Quick Start Guide</strong></p>
|
||||||
<p align="center" style="font-size: 120%;">June 2012</p>
|
<p align="center" style="font-size: 120%;">June 2013</p>
|
||||||
<p align="center"><a href="http://www.sleuthkit.org/autopsy/">www.sleuthkit.org/autopsy/</a></p>
|
<p align="center"><a href="http://www.sleuthkit.org/autopsy/">www.sleuthkit.org/autopsy/</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user