@ -105,10 +105,10 @@ public class AddImageLoadingPanel extends javax.swing.JPanel {
|
||||
void setErrors(final String errors, boolean critical) {
|
||||
crDbProgressBar.setValue(100); //always invoked when process completed
|
||||
if (critical) {
|
||||
progressLabel.setText("*Failed to add image (critical errors encountered). Click below to view the Add Image Log.");
|
||||
progressLabel.setText("*Failed to add image (critical errors encountered). Click below to view the log.");
|
||||
}
|
||||
else {
|
||||
progressLabel.setText("*Image added (non-critical image errors encountered). Click below to view the Add Image Log.");
|
||||
progressLabel.setText("*Data Source added (non-critical errors encountered). Click below to view the log.");
|
||||
}
|
||||
errorButton = new JButton();
|
||||
errorButton.setText("View Log");
|
||||
|
@ -103,6 +103,9 @@
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="noFatOrphansCheckbox">
|
||||
<Properties>
|
||||
@ -200,6 +203,9 @@
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<ContentTypePanel>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
|
@ -57,7 +57,7 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
private AddImageWizardPanel1 wizPanel;
|
||||
private ContentTypeModel model;
|
||||
|
||||
ContentTypePanel currentPanel;
|
||||
private ContentTypePanel currentPanel;
|
||||
|
||||
/**
|
||||
* Creates new form AddImageVisualPanel1
|
||||
@ -231,13 +231,13 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
nextLabel = new javax.swing.JLabel();
|
||||
timeZoneLabel = new javax.swing.JLabel();
|
||||
timeZoneComboBox = new javax.swing.JComboBox();
|
||||
timeZoneComboBox = new javax.swing.JComboBox<String>();
|
||||
noFatOrphansCheckbox = new javax.swing.JCheckBox();
|
||||
descLabel = new javax.swing.JLabel();
|
||||
inputPanel = new javax.swing.JPanel();
|
||||
typeTabel = new javax.swing.JLabel();
|
||||
typePanel = new javax.swing.JPanel();
|
||||
typeComboBox = new javax.swing.JComboBox();
|
||||
typeComboBox = new javax.swing.JComboBox<ContentTypePanel>();
|
||||
imgInfoLabel = new javax.swing.JLabel();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.jLabel2.text")); // NOI18N
|
||||
@ -355,9 +355,9 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel nextLabel;
|
||||
private javax.swing.JCheckBox noFatOrphansCheckbox;
|
||||
private javax.swing.JComboBox timeZoneComboBox;
|
||||
private javax.swing.JComboBox<String> timeZoneComboBox;
|
||||
private javax.swing.JLabel timeZoneLabel;
|
||||
private javax.swing.JComboBox typeComboBox;
|
||||
private javax.swing.JComboBox<ContentTypePanel> typeComboBox;
|
||||
private javax.swing.JPanel typePanel;
|
||||
private javax.swing.JLabel typeTabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
@ -377,9 +377,10 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
/**
|
||||
* ComboBoxModel to control typeComboBox and supply ImageTypePanels.
|
||||
*/
|
||||
private class ContentTypeModel implements ComboBoxModel {
|
||||
ContentTypePanel selected;
|
||||
ContentTypePanel[] types = ContentTypePanel.getPanels();
|
||||
private class ContentTypeModel implements ComboBoxModel<ContentTypePanel> {
|
||||
private ContentTypePanel selected;
|
||||
private ContentTypePanel[] types = ContentTypePanel.getPanels();
|
||||
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object anItem) {
|
||||
@ -398,7 +399,7 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
public ContentTypePanel getElementAt(int index) {
|
||||
return types[index];
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ import java.awt.BorderLayout;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* Image added, ingest configure wizard visual panel 3
|
||||
* Data Source added, ingest configure wizard visual panel 3
|
||||
*/
|
||||
public class AddImageVisualPanel3 extends javax.swing.JPanel {
|
||||
private JPanel ingestPanel = null;
|
||||
|
@ -29,7 +29,7 @@ import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
|
||||
/**
|
||||
* The "Add Image" wizard panel2. Handles processing the image in a worker
|
||||
* The "Add Data Source" wizard panel2. Handles processing the image in a worker
|
||||
* thread, and any errors that may occur during the add process.
|
||||
*/
|
||||
class AddImageWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
@ -90,7 +90,7 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
*/
|
||||
void setStateStarted() {
|
||||
component.getCrDbProgressBar().setIndeterminate(true);
|
||||
component.changeProgressBarTextAndColor("*Adding the image may take some time for large images.", 0, Color.black);
|
||||
component.changeProgressBarTextAndColor("*This process take some time for large data sources.", 0, Color.black);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -570,7 +570,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
cleanupImage.enable();
|
||||
|
||||
if (errorString == null) { // complete progress bar
|
||||
wizPanel.getComponent().changeProgressBarTextAndColor("*Image added.", 100, Color.black);
|
||||
wizPanel.getComponent().changeProgressBarTextAndColor("*Data Source added.", 100, Color.black);
|
||||
}
|
||||
|
||||
// Get attention for the process finish
|
||||
|
@ -94,9 +94,6 @@ NewJPanel.jFormattedTextField1.text=jFormattedTextField1
|
||||
NewJPanel.jButton1.text=Rename
|
||||
NewJPanel.jLabel4.text=Database:
|
||||
AddImageVisualPanel2.indexImageCheckBox.text=Index image for keyword search
|
||||
AddImageVisualPanel4.jLabel1.text=Image was successfully added to the case and is being processed.
|
||||
AddImageVisualPanel4.crDbLabel.text=Image Added and Being Processed
|
||||
AddImageVisualPanel4.addImgButton.text=Add Another Image
|
||||
AddImageVisualPanel3.titleLabel.text=Configure Ingest Modules
|
||||
AddImageVisualPanel3.subtitleLabel.text=Configure the ingest modules you would like to run on this data source.
|
||||
CasePropertiesForm.caseNumberLabel.text=Case Number:
|
||||
@ -132,12 +129,12 @@ MissingImageDialog.cancelButton.text=Cancel
|
||||
LocalDiskPanel.errorLabel.text=Error Label
|
||||
AddImageVisualPanel1.typeTabel.text=Select source type to add:
|
||||
AddImageVisualPanel1.imgInfoLabel.text=Enter Data Source Information:
|
||||
AddImageLoadingPanel.crDbLabel.text=Adding Image
|
||||
AddImageLoadingPanel.crDbLabel.text=Adding Data Source
|
||||
AddImageLoadingPanel.Label_CurrentDirectory_Static.text=Currently Processing:
|
||||
AddImageLoadingPanel.jLabel5.text=Processing Image and Adding to Database
|
||||
AddImageLoadingPanel.jLabel5.text=Processing Data Source and Adding to Database
|
||||
AddImageLoadingPanel.jLabel1.text=File system information is being added to a local database. File analysis will start when this finishes.
|
||||
AddImageDonePanel.statusLabel.text=File system has been added to the local database. Files are being analyzed.
|
||||
AddImageDonePanel.crDbLabel.text=Adding Image - Complete
|
||||
AddImageDonePanel.crDbLabel.text=Adding Data Source - Complete
|
||||
LocalFilesPanel.infoLabel.text=Add local files and folders:
|
||||
LocalFilesPanel.selectButton.text=Add
|
||||
LocalFilesPanel.localFileChooser.dialogTitle=Select Local Files or Folders
|
||||
|
@ -75,7 +75,7 @@ public final class CasePropertiesAction extends CallableSystemAction {
|
||||
int totalImage = currentCase.getRootObjectsCount();
|
||||
|
||||
// put the image paths information into hashmap
|
||||
Map<Long, String> imgPaths = currentCase.getImagePaths(currentCase.getSleuthkitCase());
|
||||
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
|
||||
|
||||
// create the case properties form
|
||||
CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);
|
||||
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 40 KiB |
@ -1,35 +1,51 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Disk Image Basics</title>
|
||||
<title>Data Source Basics</title>
|
||||
<link rel="stylesheet" href="nbdocs:/org/sleuthkit/autopsy/core/docs/ide.css" type="text/css">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<h2>About Disk Images</h2>
|
||||
<h2>About Data Sources</h2>
|
||||
|
||||
<p>
|
||||
In Autopsy, an "image" refers to a byte-for-byte copy of a hard drive or other storage media.
|
||||
To analyze an image, you must use the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Image Wizard</a>
|
||||
Autopsy supports 3 types of data sources that can be added to the Case:</p>
|
||||
<ul>
|
||||
<li>Disk Image (raw, Encase, etc).
|
||||
"Image" refers to a byte-for-byte copy of a hard drive or other storage media.
|
||||
</li>
|
||||
<li>Disk Device (physical or logical disk partition, plugged in the user machine and detected by Autopsy).
|
||||
Note: to correctly detect all devices, Autopsy needs to run as Administrator.
|
||||
</li>
|
||||
<li>Logical Files (files and folders on the user machine file system)</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
User needs to select the data source type from the pull down menu in the Add Data Source wizard.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To analyze a Data Source, user should use the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Data Source Wizard</a>
|
||||
to add it to a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.
|
||||
</p>
|
||||
<p>
|
||||
Autopsy populates an embedded database for each image that it imports.
|
||||
This database is a SQLite database and it contains all of the file system metadata from the image.
|
||||
The database is stored in the case directory, but the image will stay in its original location.
|
||||
The image must remain accessible for the duration of the analysis because the database contains only basic file system information.
|
||||
The image is needed to retrieve file content.
|
||||
Autopsy populates an embedded database for each data source (image, disk device, logical files) that it imports.
|
||||
This database is a SQLite database and it contains all of the file system metadata from the input data source.
|
||||
The database is stored in the case directory, but the data source will stay in its original location.
|
||||
The data source must remain accessible for the duration of the analysis because the database contains only basic file system information (meta-data, not the actual content).
|
||||
The image / files are needed to retrieve file content.
|
||||
</p>
|
||||
|
||||
<h2>Supported Formats</h2>
|
||||
<h2>Supported Image Formats</h2>
|
||||
<p>Currently, Autopsy supports these image formats:</p>
|
||||
<ul>
|
||||
<li>Raw Single (For example: *.img, *.dd, etc)</li>
|
||||
<li>Raw Single (For example: *.img, *.dd, *.raw, etc)</li>
|
||||
<li>Raw Split (For example: *.001, *.002, *.aa, *.ab, etc)</li>
|
||||
<li>EnCase (For example: *.e01, *e02, etc)</li>
|
||||
</ul>
|
||||
|
||||
<h2>Removing an Image</h2>
|
||||
<p>You cannot currently remove an image from a case.</p>
|
||||
<h2>Removing a Data Source</h2>
|
||||
<p>You cannot currently remove an data source from a case.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,23 +1,27 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Adding Image Wizard</title>
|
||||
<title>Adding Data Source (Image, Disk, Files) Wizard</title>
|
||||
<link rel="stylesheet" href="nbdocs:/org/sleuthkit/autopsy/core/docs/ide.css" type="text/css">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<h2>Adding An Image</h2>
|
||||
<p>There are two ways to add an image to the currently opened case:</p>
|
||||
<h2>Adding a Data Source</h2>
|
||||
|
||||
<p>There are two ways to add an data source to the currently opened case:</p>
|
||||
<ul>
|
||||
<li>Go to "File" and select "Add Image..." </li>
|
||||
<li>Go to "File" and select "Add Data Source..." </li>
|
||||
<li>Select the <img src="addImage-icon.png" alt="Add Image Icon" /> icon on the toolbar</li>
|
||||
</ul>
|
||||
<p>This will bring up the Add Image wizard. It will guide you through the process.</p>
|
||||
<p>This will bring up the Add Data Source wizard. It will guide you through the process.</p>
|
||||
<p>Here are some notes on what is going on during the process:</p>
|
||||
<ul>
|
||||
<li>
|
||||
The first panel will ask you to browse for the image on your machine.
|
||||
You will also need to specify the timezone that the disk image came from so that the dates and times can be properly displayed and converted.
|
||||
The first panel will ask you to select the data source type and
|
||||
browse for the data source (image or files located on the computer, or select the device detected).
|
||||
|
||||
In case of adding a disk image, you will also need to specify the timezone that the disk image came from
|
||||
so that the dates and times can be properly displayed and converted.
|
||||
As soon as you click 'Next >', Autopsy will begin analyzing the disk image and populating the database in the background.
|
||||
<br />
|
||||
<img src="AddImageWizard1_Help.png" alt="Add Image Wizard Panel 1 Help" />
|
||||
@ -29,21 +33,21 @@
|
||||
<img src="AddImageWizard2_Help.png" alt="Add Image Wizard Panel 3 Help" />
|
||||
</li>
|
||||
<li>
|
||||
The third panel provides a progress bar and information about the image Autopsy is currently processing.
|
||||
If small enough, the image may have already finished processing, allowing you to continue past this panel.
|
||||
The third panel provides a progress bar and information about the data source Autopsy is currently processing.
|
||||
If small enough, the input may have already finished processing, allowing you to continue past this panel.
|
||||
However, it may be necessary to wait for a short time while the database is populated.
|
||||
<br />
|
||||
<img src="AddImageWizard3_Help.png" alt="Add Image Wizard Panel 2 Help" />
|
||||
</li>
|
||||
<li>
|
||||
Once the image finishes adding, the ingest modules you selected will automatically run in the background.
|
||||
If the image is processed before you select ingest modules, Autopsy will wait until you have done so.
|
||||
Once the input data source finishes adding, the ingest modules you selected will automatically run in the background.
|
||||
If the data source is processed before you select ingest modules, Autopsy will wait until you have done so.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that Autopsy will store the path to the image in its configuration file.
|
||||
If the image moves, then Autopsy will give an error because it can't find the image file.
|
||||
Note that in case of image, Autopsy will store the path to the image in its configuration file.
|
||||
If the image moves, then Autopsy will give an error because it can't find the image file and it will prompt user to point to the new image location.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -8,8 +8,8 @@
|
||||
<body>
|
||||
<h2>About Cases</h2>
|
||||
<p>
|
||||
In Autopsy, a "case" is a container concept for a set of <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a>.
|
||||
The set of images could be from multiple drives in a single computer or from multiple computers.
|
||||
In Autopsy, a "case" is a container concept for a set of <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">input data sources (disk images, disk devices, logical files)</a>.
|
||||
The set of data could be from multiple drives in a single computer or from multiple computers.
|
||||
When you make a case, it will create a directory to hold all of the information.
|
||||
The directory will contain the main Autopsy configuration file, other module's configuration files,
|
||||
some databases, generated reports, and some other information (temporary files, cache files).
|
||||
|
@ -9,8 +9,8 @@ and open the template in the editor.
|
||||
<indexitem text="Quick Start" target="org.sleuthkit.autopsy.casemodule.quickstart"/>
|
||||
<indexitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
|
||||
<indexitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
|
||||
<indexitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
|
||||
<indexitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
|
||||
<indexitem text="About Data Sources" target="org.sleuthkit.autopsy.casemodule.image-about"/>
|
||||
<indexitem text="Adding a Data Source" target="org.sleuthkit.autopsy.casemodule.add-image"/>
|
||||
<indexitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
|
||||
<indexitem text="Hash Database Management" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>
|
||||
</index>
|
||||
|
@ -12,9 +12,9 @@ and open the template in the editor.
|
||||
<tocitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
|
||||
<tocitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
|
||||
</tocitem>
|
||||
<tocitem text="Image">
|
||||
<tocitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
|
||||
<tocitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
|
||||
<tocitem text="Data Source">
|
||||
<tocitem text="About Data Source" target="org.sleuthkit.autopsy.casemodule.image-about"/>
|
||||
<tocitem text="Adding a Data Source" target="org.sleuthkit.autopsy.casemodule.add-image"/>
|
||||
</tocitem>
|
||||
<tocitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
|
||||
<tocitem text="Hash Database Management Window" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>
|
||||
|
@ -14,7 +14,7 @@
|
||||
The remainder of the help guide is organized around these concepts.
|
||||
</p>
|
||||
<p>
|
||||
The main Autopsy features include: importing and image and exploring its file systems,
|
||||
The main Autopsy features include: importing a Data Source (image, disk, files) and exploring its file systems,
|
||||
running analysis modules (ingest), viewing ingest results, viewing content and generating reports.
|
||||
</p>
|
||||
<p>
|
||||
@ -24,7 +24,7 @@
|
||||
</p>
|
||||
<p>
|
||||
All data is organized around the concept of a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.
|
||||
A case can have one or more disk <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a> loaded into it.
|
||||
A case can have one or more data <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">sources</a> loaded into it.
|
||||
</p>
|
||||
<p>The main window has three major areas:</p>
|
||||
<ul>
|
||||
|
@ -177,20 +177,22 @@ public class FileManager implements Closeable {
|
||||
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume
|
||||
* or file system given by systemId.
|
||||
*
|
||||
* @param name the name of the carved file (containing appropriate
|
||||
* @param carvedFileName the name of the carved file (containing appropriate
|
||||
* extension)
|
||||
* @param carvedFileSize size of the carved file to add
|
||||
* @param systemId the ID of the parent volume or file system
|
||||
* @param sectors a list of SectorGroups giving this sectors that make up
|
||||
* this carved file.
|
||||
* @throws TskCoreException exception thrown when critical tsk error occurred and carved file could not be added
|
||||
*/
|
||||
public synchronized LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize,
|
||||
long systemId, List<TskFileRange> data) throws TskCoreException {
|
||||
long systemId, List<TskFileRange> sectors) throws TskCoreException {
|
||||
|
||||
if (tskCase == null) {
|
||||
throw new TskCoreException("Attempted to use FileManager after it was closed.");
|
||||
}
|
||||
|
||||
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, data);
|
||||
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, sectors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -418,7 +418,7 @@ public class PlatformUtil {
|
||||
/**
|
||||
* Query and get PID of another java process
|
||||
*
|
||||
* @sigarSubQuery a sigar subquery to identify a unique java process among
|
||||
* @param sigarSubQuery a sigar subquery to identify a unique java process among
|
||||
* other java processes, for example, by class name, use:
|
||||
* Args.*.eq=org.jboss.Main more examples here:
|
||||
* http://support.hyperic.com/display/SIGAR/PTQL
|
||||
@ -448,7 +448,7 @@ public class PlatformUtil {
|
||||
/**
|
||||
* Query and get PIDs of another java processes matching a query
|
||||
*
|
||||
* @sigarSubQuery a sigar subquery to identify a java processes among other
|
||||
* @param sigarSubQuery a sigar subquery to identify a java processes among other
|
||||
* java processes, for example, by class name, use: Args.*.eq=org.jboss.Main
|
||||
* more examples here: http://support.hyperic.com/display/SIGAR/PTQL
|
||||
*
|
||||
|
@ -16,7 +16,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.openide.nodes.AbstractNode;
|
||||
@ -39,14 +38,14 @@ import org.sleuthkit.datamodel.Volume;
|
||||
/**
|
||||
* Abstract subclass for ContentChildren and RootContentChildren implementations
|
||||
* that handles creating Nodes from Content objects.
|
||||
*/
|
||||
*/
|
||||
abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
|
||||
private final CreateSleuthkitNodeVisitor createSleuthkitNodeVisitor = new CreateSleuthkitNodeVisitor();
|
||||
private final CreateAutopsyNodeVisitor createAutopsyNodeVisitor = new CreateAutopsyNodeVisitor();
|
||||
|
||||
|
||||
/**
|
||||
* Uses lazy Content.Keys
|
||||
* Uses lazy Content.Keys
|
||||
*/
|
||||
AbstractContentChildren() {
|
||||
super(true); // use lazy behavior
|
||||
@ -54,21 +53,18 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
|
||||
@Override
|
||||
protected Node[] createNodes(T key) {
|
||||
if(key instanceof SleuthkitVisitableItem) {
|
||||
if (key instanceof SleuthkitVisitableItem) {
|
||||
return new Node[]{((SleuthkitVisitableItem) key).accept(createSleuthkitNodeVisitor)};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new Node[]{((AutopsyVisitableItem) key).accept(createAutopsyNodeVisitor)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates appropriate Node for each sub-class of Content
|
||||
*/
|
||||
public static class CreateSleuthkitNodeVisitor extends SleuthkitItemVisitor.Default<AbstractContentNode> {
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractContentNode visit(Directory drctr) {
|
||||
return new DirectoryNode(drctr);
|
||||
@ -88,22 +84,22 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
public AbstractContentNode visit(Volume volume) {
|
||||
return new VolumeNode(volume);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractContentNode visit(LayoutFile lf) {
|
||||
return new LayoutFileNode(lf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractContentNode visit(DerivedFile df) {
|
||||
return new LocalFileNode(df);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractContentNode visit(LocalFile lf) {
|
||||
return new LocalFileNode(lf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractContentNode visit(VirtualDirectory ld) {
|
||||
return new VirtualDirectoryNode(ld);
|
||||
@ -114,53 +110,57 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
throw new UnsupportedOperationException("No Node defined for the given SleuthkitItem");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates appropriate Node for each supported artifact category / grouping
|
||||
*/
|
||||
static class CreateAutopsyNodeVisitor extends AutopsyItemVisitor.Default<AbstractNode> {
|
||||
|
||||
|
||||
@Override
|
||||
public ExtractedContentNode visit(ExtractedContent ec) {
|
||||
return new ExtractedContentNode(ec.getSleuthkitCase());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(SearchFilters sf) {
|
||||
return new SearchFiltersNode(sf.getSleuthkitCase(), true);
|
||||
return new SearchFiltersNode(sf.getSleuthkitCase(), null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(RecentFiles rf) {
|
||||
return new RecentFilesNode(rf.getSleuthkitCase());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(DeletedContent dc) {
|
||||
return new DeletedContent.DeletedContentsNode(dc.getSleuthkitCase());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(FileSize dc) {
|
||||
return new FileSize.FileSizeRootNode(dc.getSleuthkitCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(KeywordHits kh) {
|
||||
return kh.new KeywordHitsRootNode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(HashsetHits hh) {
|
||||
return hh.new HashsetHitsRootNode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(EmailExtracted ee) {
|
||||
return ee.new EmailExtractedRootNode();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(Tags t) {
|
||||
return t.new TagsRootNode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(DataSources i) {
|
||||
try {
|
||||
@ -169,12 +169,12 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
return defaultVisit(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(Views v) {
|
||||
return new ViewsNode(v.getSleuthkitCase());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractNode visit(Results r) {
|
||||
return new ResultsNode(r.getSleuthkitCase());
|
||||
@ -185,5 +185,4 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
throw new UnsupportedOperationException("No Node defined for the given DisplayableItem");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,98 +23,132 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
* @author dfickling
|
||||
*/
|
||||
public interface AutopsyItemVisitor<T> {
|
||||
|
||||
|
||||
T visit(ExtractedContent ec);
|
||||
|
||||
T visit(SearchFilters sf);
|
||||
|
||||
T visit(SearchFilters.FileSearchFilter fsf);
|
||||
|
||||
T visit(SearchFilters.DocumentFilter df);
|
||||
|
||||
T visit(SearchFilters.ExecutableFilter ef);
|
||||
|
||||
T visit(RecentFiles rf);
|
||||
|
||||
T visit(RecentFiles.RecentFilesFilter rff);
|
||||
|
||||
T visit(DeletedContent dc);
|
||||
|
||||
T visit(DeletedContent.DeletedContentFilter dcf);
|
||||
|
||||
T visit(FileSize fs);
|
||||
|
||||
T visit(FileSize.FileSizeFilter fsf);
|
||||
|
||||
T visit(KeywordHits kh);
|
||||
|
||||
T visit(HashsetHits hh);
|
||||
|
||||
T visit(EmailExtracted ee);
|
||||
|
||||
T visit(Tags t);
|
||||
|
||||
T visit(DataSources i);
|
||||
|
||||
T visit(Views v);
|
||||
|
||||
T visit(Results r);
|
||||
|
||||
|
||||
static abstract public class Default<T> implements AutopsyItemVisitor<T> {
|
||||
|
||||
protected abstract T defaultVisit(AutopsyVisitableItem ec);
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(ExtractedContent ec) {
|
||||
return defaultVisit(ec);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(SearchFilters sf) {
|
||||
return defaultVisit(sf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(SearchFilters.FileSearchFilter fsf) {
|
||||
return defaultVisit(fsf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(SearchFilters.DocumentFilter df) {
|
||||
return defaultVisit(df);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public T visit(SearchFilters.ExecutableFilter ef) {
|
||||
return defaultVisit(ef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(DeletedContent dc) {
|
||||
return defaultVisit(dc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(DeletedContent.DeletedContentFilter dcf) {
|
||||
return defaultVisit(dcf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(FileSize fs) {
|
||||
return defaultVisit(fs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(FileSize.FileSizeFilter fsf) {
|
||||
return defaultVisit(fsf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(RecentFiles rf) {
|
||||
return defaultVisit(rf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(RecentFiles.RecentFilesFilter rff) {
|
||||
return defaultVisit(rff);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(KeywordHits kh) {
|
||||
return defaultVisit(kh);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(HashsetHits hh) {
|
||||
return defaultVisit(hh);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(EmailExtracted ee) {
|
||||
return defaultVisit(ee);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(Tags t) {
|
||||
return defaultVisit(t);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(DataSources i) {
|
||||
return defaultVisit(i);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(Views v) {
|
||||
return defaultVisit(v);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(Results r) {
|
||||
return defaultVisit(r);
|
||||
|
@ -162,13 +162,17 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
DeletedContentNode(SleuthkitCase skCase, DeletedContent.DeletedContentFilter filter) {
|
||||
super(Children.create(new DeletedContentChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
|
||||
super.setName(filter.getName());
|
||||
super.setDisplayName(filter.getDisplayName());
|
||||
this.skCase = skCase;
|
||||
this.filter = filter;
|
||||
|
||||
String tooltip = filter.getDisplayName();
|
||||
this.setShortDescription(tooltip);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon-deleted.png");
|
||||
|
||||
//get count of children without preloading all children nodes
|
||||
final long count = new DeletedContentChildren(filter, skCase).calculateItems();
|
||||
//final long count = getChildren().getNodesCount(true);
|
||||
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,30 +229,30 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
String query = "";
|
||||
switch (filter) {
|
||||
case FS_DELETED_FILTER:
|
||||
query = "dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||
query = "dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||
+ " AND meta_flags != " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
|
||||
+ " AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType();
|
||||
|
||||
|
||||
break;
|
||||
case ALL_DELETED_FILTER:
|
||||
query = " ( "
|
||||
query = " ( "
|
||||
+ "( "
|
||||
+ "(dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
|
||||
+ " OR "
|
||||
+ "meta_flags = " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
|
||||
+ "meta_flags = " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
|
||||
+ ")"
|
||||
+ " AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType()
|
||||
+ " )"
|
||||
+ " OR type = " + TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()
|
||||
+ " )";
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()
|
||||
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
logger.log(Level.SEVERE, "Unsupported filter type to get deleted content: " + filter);
|
||||
|
||||
@ -271,6 +275,20 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children count without actually loading all nodes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
long calculateItems() {
|
||||
try {
|
||||
return skCase.countFilesWhere(makeQuery());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting deleted files search view count", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(AbstractFile key) {
|
||||
return key.accept(new ContentVisitor.Default<AbstractNode>() {
|
||||
|
@ -23,6 +23,8 @@ import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode;
|
||||
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedAccountNode;
|
||||
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedFolderNode;
|
||||
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsSetNode;
|
||||
import org.sleuthkit.autopsy.datamodel.KeywordHits.KeywordHitsKeywordNode;
|
||||
@ -38,45 +40,80 @@ import org.sleuthkit.autopsy.datamodel.Tags.TagsRootNode;
|
||||
public interface DisplayableItemNodeVisitor<T> {
|
||||
|
||||
T visit(DirectoryNode dn);
|
||||
|
||||
T visit(FileNode fn);
|
||||
|
||||
T visit(ImageNode in);
|
||||
|
||||
T visit(VolumeNode vn);
|
||||
|
||||
T visit(BlackboardArtifactNode ban);
|
||||
|
||||
T visit(ArtifactTypeNode atn);
|
||||
|
||||
T visit(ExtractedContentNode ecn);
|
||||
|
||||
T visit(FileSearchFilterNode fsfn);
|
||||
|
||||
T visit(DeletedContentNode dcn);
|
||||
|
||||
T visit(DeletedContentsNode dcn);
|
||||
|
||||
T visit(FileSizeRootNode fsrn);
|
||||
|
||||
T visit(FileSizeNode fsn);
|
||||
|
||||
T visit(SearchFiltersNode sfn);
|
||||
|
||||
T visit(RecentFilesNode rfn);
|
||||
|
||||
T visit(RecentFilesFilterNode rffn);
|
||||
|
||||
T visit(KeywordHitsRootNode khrn);
|
||||
|
||||
T visit(KeywordHitsListNode khsn);
|
||||
|
||||
T visit(KeywordHitsKeywordNode khmln);
|
||||
|
||||
T visit(HashsetHitsRootNode hhrn);
|
||||
|
||||
T visit(HashsetHitsSetNode hhsn);
|
||||
|
||||
T visit(EmailExtractedRootNode eern);
|
||||
|
||||
T visit(EmailExtractedAccountNode eean);
|
||||
|
||||
T visit(EmailExtractedFolderNode eefn);
|
||||
|
||||
T visit(TagsRootNode bksrn);
|
||||
|
||||
T visit(TagsNodeRoot bksrn);
|
||||
|
||||
T visit(TagNodeRoot tnr);
|
||||
|
||||
T visit(ViewsNode vn);
|
||||
|
||||
T visit(ResultsNode rn);
|
||||
|
||||
T visit(DataSourcesNode in);
|
||||
|
||||
T visit(LayoutFileNode lfn);
|
||||
|
||||
T visit(LocalFileNode dfn);
|
||||
|
||||
T visit(VirtualDirectoryNode ldn);
|
||||
|
||||
/**
|
||||
* Visitor with an implementable default behavior for all types. Override
|
||||
* specific visit types to not use the default behavior.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
static abstract class Default<T> implements DisplayableItemNodeVisitor<T> {
|
||||
|
||||
/**
|
||||
* Default visit for all types
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
@ -103,126 +140,135 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(BlackboardArtifactNode ban){
|
||||
public T visit(BlackboardArtifactNode ban) {
|
||||
return defaultVisit(ban);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(ArtifactTypeNode atn){
|
||||
public T visit(ArtifactTypeNode atn) {
|
||||
return defaultVisit(atn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(ExtractedContentNode ecn){
|
||||
public T visit(ExtractedContentNode ecn) {
|
||||
return defaultVisit(ecn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(FileSearchFilterNode fsfn){
|
||||
public T visit(FileSearchFilterNode fsfn) {
|
||||
return defaultVisit(fsfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(DeletedContentNode dcn){
|
||||
return defaultVisit(dcn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(DeletedContentsNode dcn){
|
||||
public T visit(DeletedContentNode dcn) {
|
||||
return defaultVisit(dcn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(SearchFiltersNode sfn){
|
||||
public T visit(DeletedContentsNode dcn) {
|
||||
return defaultVisit(dcn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(FileSizeRootNode fsrn) {
|
||||
return defaultVisit(fsrn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(FileSizeNode fsn) {
|
||||
return defaultVisit(fsn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(SearchFiltersNode sfn) {
|
||||
return defaultVisit(sfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(RecentFilesNode rfn) {
|
||||
return defaultVisit(rfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(RecentFilesFilterNode rffn) {
|
||||
return defaultVisit(rffn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(KeywordHitsRootNode khrn) {
|
||||
return defaultVisit(khrn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(KeywordHitsListNode khsn) {
|
||||
return defaultVisit(khsn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(KeywordHitsKeywordNode khmln) {
|
||||
return defaultVisit(khmln);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(ViewsNode vn) {
|
||||
return defaultVisit(vn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(ResultsNode rn) {
|
||||
return defaultVisit(rn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(DataSourcesNode in) {
|
||||
return defaultVisit(in);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(HashsetHitsRootNode hhrn) {
|
||||
return defaultVisit(hhrn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(HashsetHitsSetNode hhsn) {
|
||||
return defaultVisit(hhsn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(EmailExtractedRootNode eern) {
|
||||
return defaultVisit(eern);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(EmailExtractedAccountNode eean) {
|
||||
return defaultVisit(eean);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(EmailExtractedFolderNode eefn) {
|
||||
return defaultVisit(eefn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(LayoutFileNode lfn) {
|
||||
return defaultVisit(lfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(LocalFileNode dfn) {
|
||||
return defaultVisit(dfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(VirtualDirectoryNode ldn) {
|
||||
return defaultVisit(ldn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(TagsRootNode bksrn) {
|
||||
return defaultVisit(bksrn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T visit(TagsNodeRoot bksnr) {
|
||||
return defaultVisit(bksnr);
|
||||
@ -232,7 +278,5 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
public T visit(TagNodeRoot tnr) {
|
||||
return defaultVisit(tnr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,13 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
import org.sleuthkit.datamodel.DerivedFile;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.LocalFile;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Children factory for the file by type view in dir tree
|
||||
@ -59,7 +60,8 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
|
||||
|
||||
|
||||
private String createQuery(){
|
||||
String query = "(known IS NULL OR known != 1) AND (0";
|
||||
String query = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
|
||||
+ " AND (known IS NULL OR known != 1) AND (0";
|
||||
for(String s : filter.getFilter()){
|
||||
query += " OR name LIKE '%" + s + "'";
|
||||
}
|
||||
@ -74,17 +76,28 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
|
||||
try {
|
||||
List<AbstractFile> res = skCase.findAllFilesWhere(createQuery());
|
||||
for(AbstractFile c : res){
|
||||
if(c.isFile()){
|
||||
list.add(c);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't get search results", ex);
|
||||
logger.log(Level.SEVERE, "Couldn't get search results", ex);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children count without actually loading all nodes
|
||||
* @return
|
||||
*/
|
||||
long calculateItems() {
|
||||
try {
|
||||
return skCase.countFilesWhere(createQuery());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting file search view count", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(Content key) {
|
||||
@ -94,6 +107,11 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectoryNode visit(Directory d) {
|
||||
return new DirectoryNode(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutFileNode visit(LayoutFile lf) {
|
||||
return new LayoutFileNode(lf);
|
||||
|
@ -18,11 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.datamodel.SearchFilters.FileSearchFilter;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
@ -35,10 +33,17 @@ public class FileSearchFilterNode extends DisplayableItemNode {
|
||||
|
||||
FileSearchFilterNode(SearchFilters.SearchFilterInterface filter, SleuthkitCase skCase) {
|
||||
super(Children.create(new FileSearchFilterChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
|
||||
super.setName(filter.getName());
|
||||
super.setDisplayName(filter.getDisplayName());
|
||||
|
||||
this.filter = filter;
|
||||
this.skCase = skCase;
|
||||
|
||||
super.setName(filter.getName());
|
||||
|
||||
//get count of children without preloading all children nodes
|
||||
final long count = new FileSearchFilterChildren(filter, skCase).calculateItems();
|
||||
//final long count = getChildren().getNodesCount(true);
|
||||
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
|
||||
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png");
|
||||
}
|
||||
|
||||
|
314
Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Files by Size View node and related child nodes
|
||||
*/
|
||||
public class FileSize implements AutopsyVisitableItem {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
public enum FileSizeFilter implements AutopsyVisitableItem {
|
||||
|
||||
SIZE_50_200(0, "SIZE_50_200", "50 - 200MB"),
|
||||
SIZE_200_1000(1, "SIZE_200_1GB", "200MB - 1GB"),
|
||||
SIZE_1000_(2, "SIZE_1000+", "1GB+");
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
|
||||
private FileSizeFilter(int id, String name, String displayName) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(AutopsyItemVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public FileSize(SleuthkitCase skCase) {
|
||||
this.skCase = skCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(AutopsyItemVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
|
||||
public SleuthkitCase getSleuthkitCase() {
|
||||
return this.skCase;
|
||||
}
|
||||
|
||||
public static class FileSizeRootNode extends DisplayableItemNode {
|
||||
|
||||
private static final String NAME = "File Size";
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
FileSizeRootNode(SleuthkitCase skCase) {
|
||||
super(Children.create(new FileSizeRootChildren(skCase), true), Lookups.singleton(NAME));
|
||||
super.setName(NAME);
|
||||
super.setDisplayName(NAME);
|
||||
this.skCase = skCase;
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
|
||||
return DisplayableItemNode.TYPE.META;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sheet createSheet() {
|
||||
Sheet s = super.createSheet();
|
||||
Sheet.Set ss = s.get(Sheet.PROPERTIES);
|
||||
if (ss == null) {
|
||||
ss = Sheet.createPropertiesSet();
|
||||
s.put(ss);
|
||||
}
|
||||
|
||||
ss.put(new NodeProperty("Name",
|
||||
"Name",
|
||||
"no description",
|
||||
NAME));
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileSizeRootChildren extends ChildFactory<org.sleuthkit.autopsy.datamodel.FileSize.FileSizeFilter> {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
public FileSizeRootChildren(SleuthkitCase skCase) {
|
||||
this.skCase = skCase;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<FileSizeFilter> list) {
|
||||
list.addAll(Arrays.asList(FileSizeFilter.values()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(FileSizeFilter key) {
|
||||
return new FileSizeNode(skCase, key);
|
||||
}
|
||||
|
||||
public class FileSizeNode extends DisplayableItemNode {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
private FileSizeFilter filter;
|
||||
private final Logger logger = Logger.getLogger(FileSizeNode.class.getName());
|
||||
|
||||
FileSizeNode(SleuthkitCase skCase, FileSizeFilter filter) {
|
||||
super(Children.create(new FileSizeChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
|
||||
super.setName(filter.getName());
|
||||
this.skCase = skCase;
|
||||
this.filter = filter;
|
||||
|
||||
String tooltip = filter.getDisplayName();
|
||||
this.setShortDescription(tooltip);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png");
|
||||
|
||||
//get count of children without preloading all children nodes
|
||||
final long count = new FileSizeChildren(filter, skCase).calculateItems();
|
||||
//final long count = getChildren().getNodesCount(true);
|
||||
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sheet createSheet() {
|
||||
Sheet s = super.createSheet();
|
||||
Sheet.Set ss = s.get(Sheet.PROPERTIES);
|
||||
if (ss == null) {
|
||||
ss = Sheet.createPropertiesSet();
|
||||
s.put(ss);
|
||||
}
|
||||
|
||||
ss.put(new NodeProperty("Filter Type",
|
||||
"Filter Type",
|
||||
"no description",
|
||||
filter.getDisplayName()));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
|
||||
return DisplayableItemNode.TYPE.META;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FileSizeChildren extends ChildFactory<AbstractFile> {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
private FileSizeFilter filter;
|
||||
private final Logger logger = Logger.getLogger(FileSizeChildren.class.getName());
|
||||
|
||||
FileSizeChildren(FileSizeFilter filter, SleuthkitCase skCase) {
|
||||
this.skCase = skCase;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<AbstractFile> list) {
|
||||
list.addAll(runFsQuery());
|
||||
return true;
|
||||
}
|
||||
|
||||
private String makeQuery() {
|
||||
String query = "";
|
||||
switch (filter) {
|
||||
case SIZE_50_200:
|
||||
query = "size >= 50000000 AND size < 200000000";
|
||||
|
||||
break;
|
||||
case SIZE_200_1000:
|
||||
query = "size >= 200000000 AND size < 1000000000";
|
||||
|
||||
break;
|
||||
|
||||
case SIZE_1000_:
|
||||
query = "size >= 1000000000";
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.log(Level.SEVERE, "Unsupported filter type to get files by size: " + filter);
|
||||
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private List<AbstractFile> runFsQuery() {
|
||||
List<AbstractFile> ret = new ArrayList<AbstractFile>();
|
||||
|
||||
String query = makeQuery();
|
||||
try {
|
||||
ret = skCase.findAllFilesWhere(query);
|
||||
} catch (TskCoreException e) {
|
||||
logger.log(Level.SEVERE, "Error getting files for the file size view using: " + query, e);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children count without actually loading all nodes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
long calculateItems() {
|
||||
try {
|
||||
return skCase.countFilesWhere(makeQuery());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting files by size search view count", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(AbstractFile key) {
|
||||
return key.accept(new ContentVisitor.Default<AbstractNode>() {
|
||||
public FileNode visit(AbstractFile f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
public FileNode visit(FsContent f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileNode visit(LayoutFile f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileNode visit(File f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileNode visit(Directory f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractNode defaultVisit(Content di) {
|
||||
throw new UnsupportedOperationException("Not supported for this type of Displayable Item: " + di.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -36,8 +36,8 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
*/
|
||||
public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFilter> {
|
||||
|
||||
SleuthkitCase skCase;
|
||||
Calendar lastDay;
|
||||
private SleuthkitCase skCase;
|
||||
private Calendar lastDay;
|
||||
private final static Logger logger = Logger.getLogger(RecentFilesChildren.class.getName());
|
||||
|
||||
public RecentFilesChildren(SleuthkitCase skCase) {
|
||||
@ -74,8 +74,9 @@ public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFil
|
||||
return Math.max(maxcr, Math.max(maxc, maxm));
|
||||
}
|
||||
|
||||
//TODO add a generic query to SleuthkitCase
|
||||
private String createMaxQuery(String attr) {
|
||||
return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis() / 1000;
|
||||
return "SELECT MAX(" + attr + ") from tsk_files WHERE " + attr + " < " + System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -27,12 +27,16 @@ import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
import org.sleuthkit.datamodel.DerivedFile;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.LocalFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -40,9 +44,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
*/
|
||||
public class RecentFilesFilterChildren extends ChildFactory<Content> {
|
||||
|
||||
SleuthkitCase skCase;
|
||||
RecentFilesFilter filter;
|
||||
Calendar prevDay;
|
||||
private SleuthkitCase skCase;
|
||||
private RecentFilesFilter filter;
|
||||
private Calendar prevDay;
|
||||
private final static Logger logger = Logger.getLogger(RecentFilesFilterChildren.class.getName());
|
||||
//private final static int MAX_OBJECTS = 1000000;
|
||||
|
||||
@ -55,16 +59,18 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<Content> list) {
|
||||
list.addAll(runFsQuery());
|
||||
list.addAll(runQuery());
|
||||
return true;
|
||||
}
|
||||
|
||||
private String createQuery() {
|
||||
String query = "(known IS NULL OR known != 1) AND (";
|
||||
long lowerLimit = prevDay.getTimeInMillis() / 1000;
|
||||
prevDay.add(Calendar.DATE, 1);
|
||||
prevDay.add(Calendar.MILLISECOND, -1);
|
||||
long upperLimit = prevDay.getTimeInMillis() / 1000;
|
||||
Calendar prevDayQuery = (Calendar) prevDay.clone();
|
||||
String query = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
|
||||
+ " AND (known IS NULL OR known != 1) AND (";
|
||||
long lowerLimit = prevDayQuery.getTimeInMillis() / 1000;
|
||||
prevDayQuery.add(Calendar.DATE, 1);
|
||||
prevDayQuery.add(Calendar.MILLISECOND, -1);
|
||||
long upperLimit = prevDayQuery.getTimeInMillis() / 1000;
|
||||
query += "(crtime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
|
||||
query += "(ctime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
|
||||
//query += "(atime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
|
||||
@ -73,14 +79,12 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
|
||||
return query;
|
||||
}
|
||||
|
||||
private List<FsContent> runFsQuery() {
|
||||
List<FsContent> ret = new ArrayList<FsContent>();
|
||||
private List<AbstractFile> runQuery() {
|
||||
List<AbstractFile> ret = new ArrayList<AbstractFile>();
|
||||
try {
|
||||
List<FsContent> found = skCase.findFilesWhere(createQuery());
|
||||
for (FsContent c : found) {
|
||||
if (c.isFile()) {
|
||||
List<AbstractFile> found = skCase.findAllFilesWhere(createQuery());
|
||||
for (AbstractFile c : found) {
|
||||
ret.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
@ -89,6 +93,21 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children count without actually loading all nodes
|
||||
* @return
|
||||
*/
|
||||
long calculateItems() {
|
||||
try {
|
||||
return skCase.countFilesWhere(createQuery());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting recent files search view count", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(Content key) {
|
||||
@ -97,7 +116,23 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
|
||||
public FileNode visit(File f) {
|
||||
return new FileNode(f, false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DirectoryNode visit(Directory d) {
|
||||
return new DirectoryNode(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalFileNode visit(DerivedFile f) {
|
||||
return new LocalFileNode(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalFileNode visit(LocalFile f) {
|
||||
return new LocalFileNode(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected AbstractNode defaultVisit(Content di) {
|
||||
|
@ -40,7 +40,7 @@ public class RecentFilesFilterNode extends DisplayableItemNode {
|
||||
RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter, Calendar lastDay) {
|
||||
super(Children.create(new RecentFilesFilterChildren(filter, skCase, lastDay), true), Lookups.singleton(filter.getDisplayName()));
|
||||
super.setName(filter.getName());
|
||||
super.setDisplayName(filter.getDisplayName());
|
||||
//super.setDisplayName(filter.getDisplayName());
|
||||
this.skCase = skCase;
|
||||
this.filter = filter;
|
||||
Calendar prevDay = (Calendar) lastDay.clone();
|
||||
@ -50,6 +50,11 @@ public class RecentFilesFilterNode extends DisplayableItemNode {
|
||||
+ prevDay.get(Calendar.YEAR);
|
||||
this.setShortDescription(tooltip);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent_files.png");
|
||||
|
||||
//get count of children without preloading all children nodes
|
||||
final long count = new RecentFilesFilterChildren(filter, skCase, lastDay).calculateItems();
|
||||
//final long count = getChildren().getNodesCount(true);
|
||||
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,7 +30,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
public class RecentFilesNode extends DisplayableItemNode {
|
||||
|
||||
private static final String NAME = "Recent Files";
|
||||
SleuthkitCase skCase;
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
RecentFilesNode(SleuthkitCase skCase) {
|
||||
super(Children.create(new RecentFilesChildren(skCase), true), Lookups.singleton(NAME));
|
||||
@ -38,6 +38,7 @@ public class RecentFilesNode extends DisplayableItemNode {
|
||||
super.setDisplayName(NAME);
|
||||
this.skCase = skCase;
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent_files.png");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +33,9 @@ public class SearchFilters implements AutopsyVisitableItem {
|
||||
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", FileTypeExtensions.getImageExtensions()),
|
||||
TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos", FileTypeExtensions.getVideoExtensions()),
|
||||
TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio", FileTypeExtensions.getAudioExtensions()),
|
||||
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt"));
|
||||
TSK_ARCHIVE_FILTER(3, "TSK_ARCHIVE_FILTER", "Archives", FileTypeExtensions.getArchiveExtensions()),
|
||||
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt")),
|
||||
TSK_EXECUTABLE_FILTER(3, "TSK_EXECUTABLE_FILTER", "Executable", Arrays.asList(".exe", ".dll", ".bat", ".cmd", ".com"));
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
@ -81,10 +83,10 @@ public class SearchFilters implements AutopsyVisitableItem {
|
||||
AUT_DOC_TXT(3, "AUT_DOC_TXT", "Plain Text", Arrays.asList(".txt")),
|
||||
AUT_DOC_RTF(4, "AUT_DOC_RTF", "Rich Text", Arrays.asList(".rtf"));
|
||||
|
||||
int id;
|
||||
String name;
|
||||
String displayName;
|
||||
List<String> filter;
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private List<String> filter;
|
||||
|
||||
private DocumentFilter(int id, String name, String displayName, List<String> filter){
|
||||
this.id = id;
|
||||
@ -118,6 +120,52 @@ public class SearchFilters implements AutopsyVisitableItem {
|
||||
return this.filter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum ExecutableFilter implements AutopsyVisitableItem,SearchFilterInterface {
|
||||
ExecutableFilter_EXE(0, "ExecutableFilter_EXE", ".exe", Arrays.asList(".exe")),
|
||||
ExecutableFilter_DLL(1, "ExecutableFilter_DLL", ".dll", Arrays.asList(".dll")),
|
||||
ExecutableFilter_BAT(2, "ExecutableFilter_BAT", ".bat", Arrays.asList(".bat")),
|
||||
ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")),
|
||||
ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com"));
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private List<String> filter;
|
||||
|
||||
private ExecutableFilter(int id, String name, String displayName, List<String> filter){
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(AutopsyItemVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName(){
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFilter(){
|
||||
return this.filter;
|
||||
}
|
||||
}
|
||||
|
||||
public SearchFilters(SleuthkitCase skCase){
|
||||
this.skCase = skCase;
|
||||
|
@ -31,28 +31,38 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
class SearchFiltersChildren extends ChildFactory<SearchFilters.SearchFilterInterface> {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
private boolean root;
|
||||
private SearchFilters.FileSearchFilter filter;
|
||||
|
||||
public SearchFiltersChildren(SleuthkitCase skCase, boolean root) {
|
||||
public SearchFiltersChildren(SleuthkitCase skCase, SearchFilters.FileSearchFilter filter) {
|
||||
this.skCase = skCase;
|
||||
this.root = root;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<SearchFilters.SearchFilterInterface> list) {
|
||||
if(root)
|
||||
if (filter == null) {
|
||||
list.addAll(Arrays.asList(FileSearchFilter.values()));
|
||||
else
|
||||
}
|
||||
else if (filter.equals(FileSearchFilter.TSK_DOCUMENT_FILTER) ){
|
||||
list.addAll(Arrays.asList(SearchFilters.DocumentFilter.values()));
|
||||
}
|
||||
else if (filter.equals(FileSearchFilter.TSK_EXECUTABLE_FILTER) ){
|
||||
list.addAll(Arrays.asList(SearchFilters.ExecutableFilter.values()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(SearchFilters.SearchFilterInterface key){
|
||||
if(key.getName().equals(SearchFilters.FileSearchFilter.TSK_DOCUMENT_FILTER.getName())){
|
||||
return new SearchFiltersNode(skCase, false);
|
||||
return new SearchFiltersNode(skCase, SearchFilters.FileSearchFilter.TSK_DOCUMENT_FILTER);
|
||||
}
|
||||
else if(key.getName().equals(SearchFilters.FileSearchFilter.TSK_EXECUTABLE_FILTER.getName())){
|
||||
return new SearchFiltersNode(skCase, SearchFilters.FileSearchFilter.TSK_EXECUTABLE_FILTER);
|
||||
}
|
||||
else {
|
||||
return new FileSearchFilterNode(key, skCase);
|
||||
}
|
||||
return new FileSearchFilterNode(key, skCase);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
@ -30,17 +29,16 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
public class SearchFiltersNode extends DisplayableItemNode {
|
||||
|
||||
private static final String FNAME = "File Types";
|
||||
private static final String DNAME = "Documents";
|
||||
SleuthkitCase skCase;
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
SearchFiltersNode(SleuthkitCase skCase, boolean root) {
|
||||
super(Children.create(new SearchFiltersChildren(skCase, root), true), Lookups.singleton(root ? FNAME : DNAME));
|
||||
if (root) {
|
||||
SearchFiltersNode(SleuthkitCase skCase, SearchFilters.FileSearchFilter filter) {
|
||||
super(Children.create(new SearchFiltersChildren(skCase, filter), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
|
||||
if (filter == null) {
|
||||
super.setName(FNAME);
|
||||
super.setDisplayName(FNAME);
|
||||
} else {
|
||||
super.setName(DNAME);
|
||||
super.setDisplayName(DNAME);
|
||||
super.setName(filter.getName());
|
||||
super.setDisplayName(filter.getDisplayName());
|
||||
}
|
||||
this.skCase = skCase;
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");
|
||||
|
@ -19,7 +19,6 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -34,7 +33,13 @@ public class ViewsNode extends DisplayableItemNode {
|
||||
public static final String NAME = "Views";
|
||||
|
||||
public ViewsNode(SleuthkitCase sleuthkitCase) {
|
||||
super(new RootContentChildren(Arrays.asList(new SearchFilters(sleuthkitCase), new RecentFiles(sleuthkitCase), new DeletedContent(sleuthkitCase))), Lookups.singleton(NAME));
|
||||
super(new RootContentChildren(Arrays.asList(
|
||||
new SearchFilters(sleuthkitCase),
|
||||
new RecentFiles(sleuthkitCase),
|
||||
new DeletedContent(sleuthkitCase),
|
||||
new FileSize(sleuthkitCase)
|
||||
)),
|
||||
Lookups.singleton(NAME));
|
||||
setName(NAME);
|
||||
setDisplayName(NAME);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/views.png");
|
||||
|
@ -48,6 +48,8 @@ import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.ExtractedContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSearchFilterNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsSetNode;
|
||||
import org.sleuthkit.autopsy.datamodel.ImageNode;
|
||||
@ -365,17 +367,27 @@ public class DataResultFilterNode extends FilterNode {
|
||||
public AbstractAction visit(RecentFilesNode rfn) {
|
||||
return openChild(rfn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(DeletedContentsNode dcn) {
|
||||
return openChild(dcn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(DeletedContentNode dcn) {
|
||||
return openChild(dcn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(FileSizeRootNode fsrn) {
|
||||
return openChild(fsrn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(FileSizeNode fsn) {
|
||||
return openChild(fsn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(BlackboardArtifactNode ban) {
|
||||
return new ViewContextAction("View in Directory", ban);
|
||||
|
BIN
Core/src/org/sleuthkit/autopsy/images/file-size-16.png
Normal file
After Width: | Height: | Size: 572 B |
@ -325,7 +325,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
|
||||
}
|
||||
});
|
||||
save(); // save the simple panel
|
||||
dialog.display(currentModule.getAdvancedConfiguration());
|
||||
dialog.display(currentModule.getAdvancedConfiguration(null));
|
||||
}//GEN-LAST:event_advancedButtonActionPerformed
|
||||
|
||||
private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed
|
||||
@ -452,7 +452,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
|
||||
if(this.modulesTable.getSelectedRow() != -1) {
|
||||
simplePanel.removeAll();
|
||||
if (currentModule.hasSimpleConfiguration()) {
|
||||
simplePanel.add(currentModule.getSimpleConfiguration());
|
||||
simplePanel.add(currentModule.getSimpleConfiguration(null));
|
||||
}
|
||||
simplePanel.revalidate();
|
||||
simplePanel.repaint();
|
||||
|
@ -101,7 +101,7 @@ public abstract class IngestModuleAbstract {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the arguments as set in XML
|
||||
* Gets the module arguments as set in pipeline/module configuration
|
||||
* @return arguments string
|
||||
*/
|
||||
public String getArguments() {
|
||||
@ -109,11 +109,11 @@ public abstract class IngestModuleAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the arguments from XML
|
||||
* @param args arguments string in XML
|
||||
* Sets the module arguments (e.g. from pipeline/module configuration)
|
||||
* @param moduleArgs arguments string
|
||||
*/
|
||||
public void setArguments(String a_args) {
|
||||
args = a_args;
|
||||
public void setArguments(String moduleArgs) {
|
||||
args = moduleArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,27 +162,34 @@ public abstract class IngestModuleAbstract {
|
||||
public void saveAdvancedConfiguration() {}
|
||||
|
||||
/**
|
||||
* Returns a panel that displays the simple (run-time) configuration.
|
||||
* Returns a panel that displays the simple (run-time) configuration
|
||||
* for the given configuration context (such as pipeline instance).
|
||||
* This is presented to the user before ingest starts and only basic
|
||||
* settings should be given here. use the advanced (general) configuration
|
||||
* settings should be given here. Use the advanced (general) configuration
|
||||
* panel for more in-depth interfaces.
|
||||
* The module is responsible for preserving / saving its configuration state
|
||||
* In addition, saveSimpleConfiguration() can be used
|
||||
* The module (or its configuration controller object) is responsible for preserving / saving its configuration state
|
||||
* In addition, saveSimpleConfiguration() can be used as the trigger.
|
||||
*
|
||||
* @param context the configuration context to use in the panel
|
||||
* @return JPanel containing basic configuration widgets or null if simple configuration is not available
|
||||
*/
|
||||
public javax.swing.JPanel getSimpleConfiguration() {
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements advanced module conf iguration exposed to the user before ingest starts
|
||||
* The module is responsible for preserving / saving its configuration state
|
||||
* In addition, saveAdvancedConfiguration() can be used
|
||||
* Returns a panel that displays the advanced (run-time) configuration
|
||||
* for the given configuration context (such as pipeline instance).
|
||||
* Implements advanced module configuration exposed to the user before ingest starts.
|
||||
*
|
||||
* The module (or its configuration controller object)
|
||||
* is responsible for preserving / saving its configuration state
|
||||
* In addition, saveAdvancedConfiguration() can be used as the trigger.
|
||||
*
|
||||
* @param context the configuration context to use in the panel
|
||||
* @return JPanel containing advanced configuration widgets or null if advanced configuration is not available
|
||||
*/
|
||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
||||
public javax.swing.JPanel getAdvancedConfiguration(String context) {
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
and even for very large images to be processed there can be initial results available minutes, sometimes seconds after the analysis has started.
|
||||
</p>
|
||||
<p>
|
||||
You can start image ingest in two ways. When you add an image with the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Image wizard</a>,
|
||||
You can start image ingest in two ways. When you add an image with the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Data Source wizard</a>,
|
||||
you will be shown the list of ingest modules and you can choose which you want to run.
|
||||
You can also launch the Ingest Manager run ingest by right clicking on an image in the explorer tree and choosing "Restart Image Ingest".
|
||||
</p>
|
||||
|
@ -222,13 +222,13 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getSimpleConfiguration() {
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
HashDbXML.getCurrent().reload();
|
||||
return new HashDbSimplePanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
||||
public javax.swing.JPanel getAdvancedConfiguration(String context) {
|
||||
//return HashDbManagementPanel.getDefault();
|
||||
getPanel().load();
|
||||
return getPanel();
|
||||
|
@ -427,13 +427,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getSimpleConfiguration() {
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
return new KeywordSearchIngestSimplePanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
||||
public javax.swing.JPanel getAdvancedConfiguration(String context) {
|
||||
//return KeywordSearchConfigurationPanel.getDefault();
|
||||
getPanel().load();
|
||||
return getPanel();
|
||||
|
@ -359,7 +359,7 @@ public class Server {
|
||||
} else {
|
||||
loggingPropertiesFilePath += "logging-release.properties";
|
||||
}
|
||||
//loggingPropertiesFilePath = PlatformUtil.getOSFilePath(loggingPropertiesFilePath);
|
||||
|
||||
final String loggingProperties = loggingPropertiesOpt + loggingPropertiesFilePath;
|
||||
|
||||
final String [] SOLR_START_CMD = {
|
||||
@ -371,7 +371,13 @@ public class Server {
|
||||
loggingProperties,
|
||||
"-jar",
|
||||
"start.jar"};
|
||||
logger.log(Level.INFO, "Starting Solr using: " + SOLR_START_CMD);
|
||||
|
||||
StringBuilder cmdSb = new StringBuilder();
|
||||
for (int i = 0; i<SOLR_START_CMD.length; ++i ) {
|
||||
cmdSb.append(SOLR_START_CMD[i]).append(" ");
|
||||
}
|
||||
|
||||
logger.log(Level.INFO, "Starting Solr using: " + cmdSb.toString());
|
||||
curSolrProcess = Runtime.getRuntime().exec(SOLR_START_CMD, null, solrFolder);
|
||||
logger.log(Level.INFO, "Finished starting Solr");
|
||||
|
||||
|
5
NEWS.txt
@ -1,8 +1,8 @@
|
||||
---------------- VERSION Current (development) --------------
|
||||
|
||||
New features:
|
||||
- Local files and folders support
|
||||
- Deleted files view in directory tree
|
||||
- Logical files and folders support
|
||||
- New file views in directory tree to view: deleted, executable, archive files and files by size
|
||||
|
||||
Improvements:
|
||||
- Improvements to tagging of files and keyword search results
|
||||
@ -13,6 +13,7 @@ Bugfixes:
|
||||
- fix for "Process Unallocated Space" option doesn't do anything
|
||||
- fixed result viewer for "File Search by MD5 Hash"
|
||||
- fix Solr, Timeline and RecentActivity issues with java 7.0.21
|
||||
- Views->Recent Files showing inconsistent results when clicked many times
|
||||
|
||||
|
||||
---------------- VERSION 3.0.5 --------------
|
||||
|
@ -311,12 +311,12 @@ public class ScalpelCarverIngestModule { // disable autodiscovery for now // imp
|
||||
public void saveAdvancedConfiguration() { }
|
||||
|
||||
// @Override
|
||||
public JPanel getSimpleConfiguration() {
|
||||
public JPanel getSimpleConfiguration(String context) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
// @Override
|
||||
public JPanel getAdvancedConfiguration() {
|
||||
public JPanel getAdvancedConfiguration(String context) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ public class ScalpelCarver {
|
||||
File outputFile = new File(outputFolderPath, SCALPEL_OUTPUT_FILE_NAME);
|
||||
|
||||
// parse the output
|
||||
List<CarvedFileMeta> output = Collections.EMPTY_LIST;
|
||||
List<CarvedFileMeta> output = Collections.<CarvedFileMeta>emptyList();
|
||||
try {
|
||||
output = ScalpelOutputParser.parse(outputFile);
|
||||
} catch (FileNotFoundException ex) {
|
||||
|
@ -2,5 +2,5 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.sevenzip/1
|
||||
OpenIDE-Module-Implementation-Version: 1
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/sevenzip/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
|
||||
|
||||
|
@ -4,3 +4,5 @@ license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/autopsy/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
spec.version.base=1.0.0
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.timeline
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.timeline/1
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/timeline/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/timeline/Bundle.properties
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
OpenIDE-Module-Implementation-Version: 1
|
||||
|
||||
|
@ -1,2 +1,6 @@
|
||||
javac.source=1.7
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/autopsy/
|
||||
nbm.needs.restart=true
|
||||
spec.version.base=1.0.0
|
||||
|
@ -80,7 +80,6 @@ import org.openide.modules.ModuleInstall;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
@ -99,15 +98,11 @@ import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
|
||||
@ActionRegistration(displayName = "#CTL_MakeTimeline")
|
||||
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy=false)
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 100)})
|
||||
@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
|
||||
@ -121,14 +116,14 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
|
||||
private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
|
||||
private JFXPanel fxPanelCharts; //FX panel to hold the group
|
||||
private BarChart 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 static final int FRAME_HEIGHT = 700; //Sizing constants
|
||||
private static final int FRAME_WIDTH = 1200;
|
||||
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 final Stack<BarChart> fxStackPrevCharts = new Stack<BarChart>(); //Stack for storing drill-up information.
|
||||
private BarChart fxChartTopLevel; //the topmost chart, used for resetting to default view.
|
||||
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 DataResultPanel dataResultPanel;
|
||||
private DataContentPanel dataContentPanel;
|
||||
private ProgressHandle progress;
|
||||
@ -138,8 +133,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
private boolean listeningToAddImage = false;
|
||||
private long lastObjectId = -1;
|
||||
private TimelineProgressDialog progressDialog;
|
||||
private EventHandler fxMouseEnteredListener;
|
||||
private EventHandler fxMouseExitedListener;
|
||||
private EventHandler<MouseEvent> fxMouseEnteredListener;
|
||||
private EventHandler<MouseEvent> fxMouseExitedListener;
|
||||
private SleuthkitCase skCase;
|
||||
private boolean fxInited = false;
|
||||
|
||||
@ -270,14 +265,14 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
lsi.add(ye.year + " : " + ye.getNumFiles());
|
||||
}
|
||||
ObservableList<String> listSelect = FXCollections.observableArrayList(lsi);
|
||||
fxDropdownSelectYears = new ComboBox(listSelect);
|
||||
fxDropdownSelectYears = new ComboBox<String>(listSelect);
|
||||
|
||||
//Buttons for navigating up and down the timeline
|
||||
fxZoomOutButton = new Button("Zoom Out");
|
||||
fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent e) {
|
||||
BarChart bc;
|
||||
BarChart<String,Number> bc;
|
||||
if (fxStackPrevCharts.size() == 0) {
|
||||
bc = fxChartTopLevel;
|
||||
} else {
|
||||
@ -344,7 +339,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
* @param allYears The list of years that have barData from the mactime file
|
||||
* @return BarChart scaled to the year level
|
||||
*/
|
||||
private BarChart 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 NumberAxis yAxis = new NumberAxis();
|
||||
final Label l = new Label("");
|
||||
@ -372,7 +367,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
|
||||
// an undetermined point in time.
|
||||
BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
||||
for (final BarChart.Data 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);
|
||||
|
||||
final javafx.scene.Node barNode = barData.getNode();
|
||||
@ -390,7 +385,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
BarChart b = createMonthsWithDrill((YearEpoch) findYear(allYears, Integer.valueOf((String) barData.getXValue())));
|
||||
BarChart<String,Number> b =
|
||||
createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
|
||||
fxChartEvents = b;
|
||||
fxScrollEvents.setContent(fxChartEvents);
|
||||
}
|
||||
@ -412,7 +408,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
* 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.
|
||||
*/
|
||||
private BarChart createMonthsWithDrill(final YearEpoch ye) {
|
||||
private BarChart<String,Number> createMonthsWithDrill(final YearEpoch ye) {
|
||||
|
||||
final CategoryAxis xAxis = new CategoryAxis();
|
||||
final NumberAxis yAxis = new NumberAxis();
|
||||
@ -431,7 +427,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
for (final BarChart.Data barData : bc.getData().get(0).getData()) {
|
||||
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
|
||||
//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,
|
||||
// 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.
|
||||
@ -454,7 +450,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt((String) barData.getXValue())), ye);
|
||||
fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt(barData.getXValue())), ye);
|
||||
fxScrollEvents.setContent(fxChartEvents);
|
||||
}
|
||||
});
|
||||
@ -477,20 +473,22 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
* 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
|
||||
*/
|
||||
private BarChart createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
|
||||
private BarChart<String,Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
|
||||
final CategoryAxis xAxis = new CategoryAxis();
|
||||
final NumberAxis yAxis = new NumberAxis();
|
||||
xAxis.setLabel("Day of Month");
|
||||
yAxis.setLabel("Number of Events");
|
||||
ObservableList<BarChart.Data> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
|
||||
BarChart.Series<String, Number> series = new BarChart.Series(bcData);
|
||||
ObservableList<BarChart.Data<String,Number>> bcData
|
||||
= makeObservableListByMonthAllDays(me, ye.getYear());
|
||||
BarChart.Series<String, Number> series = new BarChart.Series<String,Number>(bcData);
|
||||
series.setName(me.getMonthName() + " " + ye.getYear());
|
||||
|
||||
|
||||
ObservableList<BarChart.Series<String, Number>> ol = FXCollections.observableArrayList(series);
|
||||
ObservableList<BarChart.Series<String, Number>> ol =
|
||||
FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
|
||||
|
||||
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
|
||||
for (final BarChart.Data barData : bc.getData().get(0).getData()) {
|
||||
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
|
||||
//data.getNode().setScaleX(2);
|
||||
|
||||
final javafx.scene.Node barNode = barData.getNode();
|
||||
@ -505,7 +503,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent e) {
|
||||
final int day = (Integer.valueOf(((String) barData.getXValue()).split("-")[1]));
|
||||
final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
|
||||
final DayEpoch de = myme.getDay(day);
|
||||
final List<AbstractFile> afs;
|
||||
if (de != null) {
|
||||
@ -535,13 +533,13 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
||||
return bc;
|
||||
}
|
||||
|
||||
private static ObservableList<BarChart.Data> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
|
||||
ObservableList<BarChart.Data> bcData = FXCollections.observableArrayList();
|
||||
private static ObservableList<BarChart.Data<String,Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
|
||||
ObservableList<BarChart.Data<String,Number>> bcData = FXCollections.observableArrayList();
|
||||
int totalDays = me.getTotalNumDays(year);
|
||||
for (int i = 1; i <= totalDays; ++i) {
|
||||
DayEpoch day = me.getDay(i);
|
||||
int numFiles = day == null ? 0 : day.getNumFiles();
|
||||
BarChart.Data d = new BarChart.Data(me.month + 1 + "-" + i, numFiles);
|
||||
BarChart.Data<String,Number> d = new BarChart.Data<String,Number>(me.month + 1 + "-" + i, numFiles);
|
||||
d.setExtraValue(me);
|
||||
bcData.add(d);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#Updated by build script
|
||||
#Thu, 23 May 2013 00:04:58 -0400
|
||||
#Sun, 02 Jun 2013 00:12:29 -0400
|
||||
LBL_splash_window_title=Starting Autopsy
|
||||
SPLASH_HEIGHT=288
|
||||
SPLASH_WIDTH=538
|
||||
SplashProgressBarBounds=3,236,533,6
|
||||
SplashRunningTextBounds=5,212,530,17
|
||||
SplashProgressBarBounds=3,282,533,6
|
||||
SplashRunningTextBounds=5,266,530,17
|
||||
SplashRunningTextColor=0x0
|
||||
SplashRunningTextFontSize=18
|
||||
|
||||
currentVersion=Autopsy 20130523
|
||||
currentVersion=Autopsy 20130602
|
||||
|
@ -26,10 +26,10 @@
|
||||
</p>
|
||||
<p>Note that Autopsy 3 is a complete rewrite from Autopsy 2 and none of this document is relevant to Autopsy 2.</p>
|
||||
|
||||
<h1>Adding a Disk Image</h1>
|
||||
<h1>Adding a Data Source (image, local disk, logical files)</h1>
|
||||
<p>
|
||||
Disk images are added to a <strong>case</strong>. A case can have a single image or it can have multiple images if they are related.
|
||||
Currently, a single report is generated for an entire case, so if you need to report on individual images, then you should use one image per case.
|
||||
Data sources are added to a <strong>case</strong>. A case can have a single data source or it can have multiple data source if they are related.
|
||||
Currently, a single report is generated for an entire case, so if you need to report on individual data sources, then you should use one data source per case.
|
||||
</p>
|
||||
|
||||
<h2>Creating a Case</h2>
|
||||
@ -40,16 +40,32 @@
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Adding an Image</h2>
|
||||
<h2>Adding a Data Source</h2>
|
||||
<p>
|
||||
The next step is to add a disk image to the case.
|
||||
The <strong>Add Image Wizard</strong> will start automatically after the case is created or you can manually start it from the "File" menu or toolbar.
|
||||
You will need to supply it with the location of the disk image to add. Autopsy currently supports E01 and raw (dd) files.
|
||||
You need to specify only the first file in an image set (i.e. the E01 file) and Autopsy will find the rest of the files.
|
||||
The next step is to add input data source to the case.
|
||||
The <strong>Add Data Source Wizard</strong> will start automatically after the case is created or you can manually start it from the "File" menu or toolbar.
|
||||
You will need to choose the type of input data source to add (image, local disk or logical files and folders).
|
||||
Next, supply it with the location of the source to add.
|
||||
</p>
|
||||
<ul>
|
||||
<li>For image, point to location of disk image on your system. Autopsy currently supports E01 and raw (dd) files.
|
||||
For multi-part/split images, you will need to specify only the first file in an image set (i.e. the E01 file) and Autopsy will find the rest of the files.
|
||||
</li>
|
||||
<li>
|
||||
For local disk, select one of the detected disks.
|
||||
Autopsy will add the current view of the disk to the case (i.e. snapshot of the meta-data).
|
||||
However, the individual file content (not meta-data) does get updated with the changes made to the disk.
|
||||
|
||||
|
||||
Note, you may need run Autopsy as an Administrator to detect all disks.
|
||||
</li>
|
||||
<li>For logical files, add one or more local files or folders on your system.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
It may take a few minutes to add the disk image.
|
||||
It may take a few minutes to add the data source to the case.
|
||||
During this time, an internal database is being created of the file system contents.
|
||||
</p>
|
||||
|
||||
@ -105,7 +121,9 @@
|
||||
<img src="screenshot.png" alt="Autopsy Screenshot" />
|
||||
<p>You will start all of your analysis techniques from the tree on the left.</p>
|
||||
<ul>
|
||||
<li>The Images node shows the file system structure of the disk images.</li>
|
||||
<li>The Data Sources root node shows all data in the case.</li>
|
||||
<li>The individual image nodes show the file system structure of the disk images or local disks in the case.</li>
|
||||
<li>The LogicalFileSet nodes show the logical files in the case.</li>
|
||||
<li>The Views node shows the same data from a file type or timeline perspective.</li>
|
||||
<li>The Results node shows the output from the ingest modules.</li>
|
||||
</ul>
|
||||
@ -157,7 +175,7 @@
|
||||
|
||||
<h2>Known Bad Hash Files</h2>
|
||||
<p>
|
||||
If you want to see if the image had known bad files, make sure that the Hash Lookup ingest module was enabled.
|
||||
If you want to see if the data source had known bad files, make sure that the Hash Lookup ingest module was enabled.
|
||||
You can then view the "Hashset Hits" section in the "Results" area of the tree on the left.
|
||||
Note that hash lookup can take a long time, so this section will be updated as long as the ingest process is occurring.
|
||||
Use the Ingest Inbox to keep track of what known bad files were recently found.
|
||||
@ -167,7 +185,7 @@
|
||||
You may find additional files that are relevant and stored in the same folder as this file.
|
||||
</p>
|
||||
|
||||
<h2>Images and Videos</h2>
|
||||
<h2>Media: Images and Videos</h2>
|
||||
<p>
|
||||
If you want to see all images and video on the disk image, then go to the "Views" section in the tree on the left and then "File Types".
|
||||
Select either "Images" or "Videos".
|
||||
|
@ -12,7 +12,7 @@ build.type=DEVELOPMENT
|
||||
update_versions=false
|
||||
#custom JVM options
|
||||
#Note: can be higher on 64 bit systems, should be in sync with build.xml
|
||||
run.args.extra=-J-Xms24m -J-Xmx768m -J-XX:MaxPermSize=256M -J-Xverify:none
|
||||
run.args.extra=-J-Xms24m -J-Xmx512m -J-XX:MaxPermSize=128M -J-Xverify:none
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
|
||||
@ -30,6 +30,7 @@ modules=\
|
||||
${project.org.sleuthkit.autopsy.core}:\
|
||||
${project.org.sleuthkit.autopsy.corelibs}:\
|
||||
${project.org.sleuthkit.autopsy.sevenzip}:\
|
||||
${project.org.sleuthkit.autopsy.scalpel}:\
|
||||
${project.org.sleuthkit.autopsy.timeline}
|
||||
project.org.sleuthkit.autopsy.core=Core
|
||||
project.org.sleuthkit.autopsy.corelibs=CoreLibs
|
||||
@ -40,5 +41,6 @@ project.org.sleuthkit.autopsy.testing=Testing
|
||||
project.org.sleuthkit.autopsy.thunderbirdparser=thunderbirdparser
|
||||
project.org.sleuthkit.autopsy.exifparser=ExifParser
|
||||
project.org.sleuthkit.autopsy.sevenzip=SevenZip
|
||||
project.org.sleuthkit.autopsy.scalpel=ScalpelCarver
|
||||
project.org.sleuthkit.autopsy.timeline=Timeline
|
||||
|
||||
|