diff --git a/Core/manifest.mf b/Core/manifest.mf
index 4eb28aaa23..45cb2dbed0 100644
--- a/Core/manifest.mf
+++ b/Core/manifest.mf
@@ -1,8 +1,8 @@
Manifest-Version: 1.0
-OpenIDE-Module: org.sleuthkit.autopsy.core/4
+OpenIDE-Module: org.sleuthkit.autopsy.core/5
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Requires: org.openide.windows.WindowManager, org.netbeans.api.javahelp.Help
AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index 713c9fbdc6..977c65838c 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -5,5 +5,5 @@ license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/
nbm.module.author=Brian Carrier
nbm.needs.restart=true
-spec.version.base=2.0
+spec.version.base=3.0
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index a599372982..2e44b24d71 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -27,6 +27,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
@@ -572,6 +573,10 @@ public class Case {
Set ids = getImagePaths(db).keySet();
return ids.toArray(new Long[ids.size()]);
}
+
+ public List getImages() throws TskCoreException {
+ return db.getImages();
+ }
/**
* Count the root objects.
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java
index 56dff078ec..48f21bab5d 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java
@@ -43,7 +43,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.datamodel.FsContent;
/**
- * ImageTypePanel for adding a local disk or partition such as \\.\PhysicalDrive0 or \\.\C:.
+ * ImageTypePanel for adding a local disk or partition such as PhysicalDrive0 or C:.
*/
public class LocalDiskPanel extends ImageTypePanel {
private static LocalDiskPanel instance;
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html b/Core/src/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html
index cd90748e39..e825d1642f 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html
@@ -29,6 +29,7 @@
EnCase: An EnCase hashset file.
MD5sum: Output from running the md5, md5sum, or md5deep program on a set of files.
NSRL: The format of the NSRL database.
+
HashKeeper: Hashset file conforming to the HashKeeper standard.
NIST NSRL
@@ -49,7 +50,8 @@
Autopsy needs an index of the hashset to actualy use a hash database.
It can create the index if you import only the hashset.
When you select the database from within this window, it will tell you if the index needs to be created.
- Autopsy uses the hash database management system from The Sleuth Kit. You can manually create an index using the 'hfind' command line tool or use can use Autopsy.
+ Autopsy uses the hash database management system from The Sleuth Kit. You can manually create an index using the 'hfind' command line tool or you can use Autopsy.
+ If you attempt proceed without indexing a database, Autopsy will offer to automatically produce an index for you.
You can also specify only the index file and not use the full hashset - the index file is sufficient to identify known files.
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java
index 4a34625bb4..c5499b118b 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/FileManager.java
@@ -42,6 +42,7 @@ public class FileManager implements Closeable {
}
/**
+ * @param image image where to find files
* @param fileName the name of the file or directory to match
* @return a list of FsContent for files/directories whose name matches the
* given fileName
@@ -54,6 +55,7 @@ public class FileManager implements Closeable {
}
/**
+ * @param image image where to find files
* @param fileName the name of the file or directory to match
* @param dirName the name of a parent directory of fileName
* @return a list of FsContent for files/directories whose name matches
@@ -67,6 +69,7 @@ public class FileManager implements Closeable {
}
/**
+ * @param image image where to find files
* @param fileName the name of the file or directory to match
* @param parentFsContent
* @return a list of FsContent for files/directories whose name matches
@@ -80,6 +83,7 @@ public class FileManager implements Closeable {
}
/**
+ * @param image image where to find files
* @param filePath The full path to the file(s) of interest. This can
* optionally include the image and volume names.
* @return a list of FsContent that have the given file path.
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.dox b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.dox
index e8da825fcf..51cbc93198 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.dox
+++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.dox
@@ -3,6 +3,6 @@
This package contains the interface classes that define the core components in Autopsy. These components are used in the different zones of the GUI.
-See \ref design_page for examples of the modules and such that it defines.
+See \ref design_data_flow for examples of the modules and such that it defines.
*/
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java
index 2a1f93e7a6..1d9d3c640b 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java
@@ -48,11 +48,10 @@ public abstract class AbstractDataResultViewer extends JPanel implements
//property listener to send nodes to content viewer
nodeSelListener = new PropertyChangeListener() {
+
/**
* Propagates changes in the current select node from the
* DataResultViewer to the DataContentTopComponent
- *
- * @param evt
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index a12d343f7a..23067adf05 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -96,3 +96,5 @@ DataResultViewerThumbnail.imagesLabel.text=Images:
DataResultViewerThumbnail.imagesRangeLabel.text=-
DataResultViewerThumbnail.pageNumLabel.text=-
DataResultViewerThumbnail.filePathLabel.text=\ \ \
+DataResultViewerThumbnail.goToPageLabel.text=Go to Page:
+DataResultViewerThumbnail.goToPageField.text=
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java
index b5d0cdc13c..6afbc66aae 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java
@@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.File;
-import org.sleuthkit.datamodel.TskData;
+import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
/**
*
@@ -332,7 +332,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
return false;
}
- if (File.dirFlagToValue(file.getDir_flags()).equals(TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.toString())) {
+ if (file.getDirFlag() == TSK_FS_NAME_FLAG_ENUM.UNALLOC) {
return false;
}
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form
index 9063cdd442..48d26daaa7 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form
@@ -20,6 +20,7 @@
+
@@ -30,12 +31,15 @@
-
+
+
+
+
+
-
@@ -55,9 +59,11 @@
+
+
-
+
@@ -173,5 +179,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java
index 4011222e88..b3e50a81fd 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java
@@ -23,6 +23,7 @@ import java.awt.Cursor;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.util.logging.Level;
+import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
@@ -94,6 +95,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
imagesRangeLabel = new javax.swing.JLabel();
pageNumLabel = new javax.swing.JLabel();
filePathLabel = new javax.swing.JLabel();
+ goToPageLabel = new javax.swing.JLabel();
+ goToPageField = new javax.swing.JTextField();
thumbnailScrollPanel.setPreferredSize(new java.awt.Dimension(582, 348));
@@ -134,6 +137,15 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
filePathLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerThumbnail.class, "DataResultViewerThumbnail.filePathLabel.text")); // NOI18N
+ goToPageLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerThumbnail.class, "DataResultViewerThumbnail.goToPageLabel.text")); // NOI18N
+
+ goToPageField.setText(org.openide.util.NbBundle.getMessage(DataResultViewerThumbnail.class, "DataResultViewerThumbnail.goToPageField.text")); // NOI18N
+ goToPageField.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ goToPageFieldActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -142,6 +154,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(filePathLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(pageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -152,11 +165,14 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
.addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(33, 33, 33)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(goToPageLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(goToPageField, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(12, 12, 12)
.addComponent(imagesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(imagesRangeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(filePathLabel))
+ .addComponent(imagesRangeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.setVerticalGroup(
@@ -171,8 +187,10 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
.addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(imagesLabel)
- .addComponent(imagesRangeLabel)))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(imagesRangeLabel)
+ .addComponent(goToPageLabel)
+ .addComponent(goToPageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGap(0, 0, 0)
.addComponent(thumbnailScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filePathLabel))
@@ -186,8 +204,15 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
private void pageNextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pageNextButtonActionPerformed
nextPage();
}//GEN-LAST:event_pageNextButtonActionPerformed
+
+ private void goToPageFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageFieldActionPerformed
+ goToPage(goToPageField.getText());
+ }//GEN-LAST:event_goToPageFieldActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel filePathLabel;
+ private javax.swing.JTextField goToPageField;
+ private javax.swing.JLabel goToPageLabel;
private javax.swing.JLabel imagesLabel;
private javax.swing.JLabel imagesRangeLabel;
private javax.swing.JLabel pageLabel;
@@ -309,6 +334,26 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
switchPage();
}
}
+
+ private void goToPage(String pageNumText) {
+ int newPage;
+ try {
+ newPage = Integer.parseInt(pageNumText);
+ }
+ catch (NumberFormatException e) {
+ //ignore input
+ return;
+ }
+
+ if (newPage > totalPages || newPage < 1) {
+ JOptionPane.showMessageDialog(this, "Please enter a valid page number between 1 and " + totalPages,
+ "Invalid page number", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ curPage = newPage;
+ switchPage();
+ }
private void switchPage() {
@@ -327,6 +372,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
protected Object doInBackground() throws Exception {
pagePrevButton.setEnabled(false);
pageNextButton.setEnabled(false);
+ goToPageField.setEnabled(false);
progress = ProgressHandleFactory.createHandle("Generating Thumbnails...");
progress.start();
progress.switchToIndeterminate();
@@ -352,6 +398,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
if (totalPages == 0) {
pagePrevButton.setEnabled(false);
pageNextButton.setEnabled(false);
+ goToPageField.setEnabled(false);
pageNumLabel.setText("");
imagesRangeLabel.setText("");
} else {
@@ -362,6 +409,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
pageNextButton.setEnabled(!(curPage == totalPages));
pagePrevButton.setEnabled(!(curPage == 1));
+ goToPageField.setEnabled(totalPages>1);
}
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml
index e428c40e70..350f02129b 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml
@@ -14,6 +14,7 @@ and open the template in the editor.
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml
index deb30aa9e6..23534a81d2 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml
@@ -9,6 +9,7 @@ and open the template in the editor.
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml
index a3746f29f3..f204c293c3 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml
@@ -8,6 +8,7 @@
+
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/StringExtract.java b/Core/src/org/sleuthkit/autopsy/coreutils/StringExtract.java
index 014a26c794..bb8890d8a3 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/StringExtract.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/StringExtract.java
@@ -111,7 +111,7 @@ public class StringExtract {
/**
* Sets the enabled script to one provided, resets previous setting
*
- * @param scripts script to consider for when extracting strings
+ * @param script script to consider for when extracting strings
*/
public final void setEnabledScript(SCRIPT script) {
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java
index 329348167f..eab0f6cf60 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/XMLUtil.java
@@ -62,7 +62,8 @@ public class XMLUtil {
* The schema files are extracted automatically when this function is called, the XML being validated is not.
* Be sure the XML file is already extracted otherwise it will return false.
* @param xmlfile The XML file to validate, in DOMSource format
- * @param type The file name of the schema to validate against, must exist as a resource in the same package as where this function is being called.
+ * @param clazz class frm package to extract schema file from
+ * @param schemaFile The file name of the schema to validate against, must exist as a resource in the same package as where this function is being called.
*
* For example usages, please see KeywordSearchListsXML, HashDbXML, or IngestModuleLoader.
*
@@ -95,7 +96,8 @@ public class XMLUtil {
*
* The schema files are extracted automatically when this function is called, the XML being validated is not.
* Be sure the XML file is already extracted otherwise it will return false.
- * @param xmlfile The XML file to validate
+ * @param doc The XML DOM to validate
+ * @param clazz class from package to extract schema from
* @param type The file name of the schema to validate against, must exist as a resource in the same package as where this function is being called
*
* For example usages, please see KeywordSearchListsXML, HashDbXML, or IngestModuleLoader.
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java
index 16940e30c9..3f7de13f83 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java
@@ -26,7 +26,7 @@ import org.sleuthkit.autopsy.datamodel.KeywordHits.KeywordHitsRootNode;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.Image;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.SleuthkitVisitableItem;
import org.sleuthkit.datamodel.SleuthkitItemVisitor;
import org.sleuthkit.datamodel.TskException;
@@ -92,8 +92,8 @@ abstract class AbstractContentChildren extends Keys {
}
@Override
- public AbstractContentNode visit(LayoutDirectory ld) {
- return new LayoutDirectoryNode(ld);
+ public AbstractContentNode visit(VirtualDirectory ld) {
+ return new VirtualDirectoryNode(ld);
}
@Override
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
index cba598e6e4..73233bfe91 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
@@ -18,11 +18,11 @@
*/
package org.sleuthkit.autopsy.datamodel;
-import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import org.openide.nodes.Sheet;
import org.sleuthkit.datamodel.FsContent;
+import org.sleuthkit.datamodel.TskData.TSK_FS_META_MODE_ENUM;
/**
* Abstract class that implements the commonality between File and Directory
@@ -236,15 +236,15 @@ public abstract class AbstractFsContentNode extends Abstrac
map.put(FsContentPropertyType.ACCESS_TIME.toString(), ContentUtils.getStringTime(content.getAtime(), content));
map.put(FsContentPropertyType.CREATED_TIME.toString(), ContentUtils.getStringTime(content.getCrtime(), content));
map.put(FsContentPropertyType.SIZE.toString(), content.getSize());
- map.put(FsContentPropertyType.FLAGS_DIR.toString(), content.getDirFlagsAsString());
- map.put(FsContentPropertyType.FLAGS_META.toString(), content.getMetaFlagsAsString());
- map.put(FsContentPropertyType.MODE.toString(), content.getModeAsString());
+ map.put(FsContentPropertyType.FLAGS_DIR.toString(), content.getDirFlag().toString());
+ map.put(FsContentPropertyType.FLAGS_META.toString(), Integer.toString(content.getMetaFlagsInt()));
+ map.put(FsContentPropertyType.MODE.toString(), TSK_FS_META_MODE_ENUM.toString(content.getModes(), content.getMetaType()));
map.put(FsContentPropertyType.USER_ID.toString(), content.getUid());
map.put(FsContentPropertyType.GROUP_ID.toString(), content.getGid());
- map.put(FsContentPropertyType.META_ADDR.toString(), content.getMeta_addr());
- map.put(FsContentPropertyType.ATTR_ADDR.toString(), Long.toString(content.getAttr_type()) + "-" + Long.toString(content.getAttr_id()));
- map.put(FsContentPropertyType.TYPE_DIR.toString(), content.getDirTypeAsString());
- map.put(FsContentPropertyType.TYPE_META.toString(), content.getMetaTypeAsString());
+ map.put(FsContentPropertyType.META_ADDR.toString(), content.getMetaAddr());
+ map.put(FsContentPropertyType.ATTR_ADDR.toString(), Long.toString(content.getAttrType().getValue()) + "-" + Long.toString(content.getAttrId()));
+ map.put(FsContentPropertyType.TYPE_DIR.toString(), content.getDirType().getLabel());
+ map.put(FsContentPropertyType.TYPE_META.toString(), content.getMetaType().toString());
map.put(FsContentPropertyType.KNOWN.toString(), content.getKnown().getName());
map.put(FsContentPropertyType.MD5HASH.toString(), content.getMd5Hash() == null ? "" : content.getMd5Hash());
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
index 5354dd0c50..ecb955911c 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
@@ -89,8 +89,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
Map map = new LinkedHashMap();
fillPropertyMap(map, artifact);
- ss.put(new NodeProperty("File Name",
- "File Name",
+ ss.put(new NodeProperty("Source File",
+ "Source File",
NO_DESCR,
associated.getName()));
@@ -124,7 +124,10 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
try {
for (BlackboardAttribute attribute : artifact.getAttributes()) {
final int attributeTypeID= attribute.getAttributeTypeID();
- if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
+ //skip some internal attributes that user shouldn't see
+ if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
+ || attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID())
+ {
continue;
} else {
switch (attribute.getValueType()) {
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentHierarchyVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentHierarchyVisitor.java
index d70f95cc49..21d421b1fb 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentHierarchyVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentHierarchyVisitor.java
@@ -28,7 +28,7 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.FileSystem;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.VolumeSystem;
@@ -93,7 +93,7 @@ public class ContentHierarchyVisitor extends ContentVisitor.Default visit(LayoutDirectory ldir) {
+ public List extends Content> visit(VirtualDirectory ldir) {
//return getChildren(ldir);
return Collections.singletonList(ldir);
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentIdHierarchyVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentIdHierarchyVisitor.java
index d5b866ca1b..72ded24b36 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentIdHierarchyVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentIdHierarchyVisitor.java
@@ -28,7 +28,7 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.FileSystem;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.VolumeSystem;
@@ -93,7 +93,7 @@ public class ContentIdHierarchyVisitor extends ContentVisitor.Default visit(LayoutDirectory ldir) {
+ public List extends Long> visit(VirtualDirectory ldir) {
//return getChildren(ldir);
return Collections.singletonList(ldir.getId());
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java
index ce8fa29ba0..03931e9591 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java
@@ -34,7 +34,7 @@ public interface ContentNodeVisitor {
T visit(LayoutFileNode lcn);
- T visit(LayoutDirectoryNode lcn);
+ T visit(VirtualDirectoryNode lcn);
/**
* Visitor with an implementable default behavior for all types. Override
@@ -76,7 +76,7 @@ public interface ContentNodeVisitor {
}
@Override
- public T visit(LayoutDirectoryNode ldn) {
+ public T visit(VirtualDirectoryNode ldn) {
return defaultVisit(ldn);
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java
index e136a4e2fa..21d4432cf9 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java
@@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.Image;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.TskException;
@@ -155,7 +155,7 @@ public final class ContentUtils {
}
@Override
- public List visit(LayoutDirectory ld) {
+ public List visit(VirtualDirectory ld) {
List path = ld.getParent().accept(this);
path.add(toString.visit(ld));
return path;
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java
index 74a278272d..d52d477176 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java
@@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.datamodel;
import javax.swing.Action;
import org.sleuthkit.datamodel.Directory;
-import org.sleuthkit.datamodel.TskData;
+import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
/**
* This class is used to represent the "Node" for the directory.
@@ -39,7 +39,7 @@ public class DirectoryNode extends AbstractFsContentNode {
super(dir, directoryBrowseMode);
// set name, display name, and icon
- if (Directory.dirFlagToValue(dir.getDir_flags()).equals(TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.toString())) {
+ if (dir.getDirFlag() == TSK_FS_NAME_FLAG_ENUM.UNALLOC) {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-deleted.png");
} else {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png");
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
index 9453ffbb7d..789c7094ab 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java
@@ -59,7 +59,7 @@ public interface DisplayableItemNodeVisitor {
T visit(ResultsNode rn);
T visit(ImagesNode in);
T visit(LayoutFileNode lcn);
- T visit(LayoutDirectoryNode ldn);
+ T visit(VirtualDirectoryNode ldn);
/**
* Visitor with an implementable default behavior for all types. Override
@@ -191,7 +191,7 @@ public interface DisplayableItemNodeVisitor {
}
@Override
- public T visit(LayoutDirectoryNode ldn) {
+ public T visit(VirtualDirectoryNode ldn) {
return defaultVisit(ldn);
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java
index 0beb0ae483..7ba667cb99 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java
@@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.datamodel;
import javax.swing.Action;
import org.sleuthkit.datamodel.File;
-import org.sleuthkit.datamodel.TskData;
+import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
/**
* This class is used to represent the "Node" for the file. It has no children.
@@ -39,7 +39,7 @@ public class FileNode extends AbstractFsContentNode {
super(file, directoryBrowseMode);
// set name, display name, and icon
- if (file.getDir_flags() == (TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.getDirFlag())) {
+ if (file.getDirFlag() == TSK_FS_NAME_FLAG_ENUM.UNALLOC) {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon-deleted.png");
} else {
this.setIconBaseWithExtension(getIconForFileType(file));
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
similarity index 68%
rename from Core/src/org/sleuthkit/autopsy/datamodel/LayoutDirectoryNode.java
rename to Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
index d558a3c33f..5e9ab5dc8c 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutDirectoryNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
@@ -22,19 +22,19 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.datamodel.LayoutFileNode.LayoutContentPropertyType;
-import org.sleuthkit.datamodel.LayoutDirectory;
-import org.sleuthkit.datamodel.LayoutFile;
+import org.sleuthkit.datamodel.VirtualDirectory;
+import org.sleuthkit.datamodel.TskData;
/**
* Node for layout dir
*/
-public class LayoutDirectoryNode extends AbstractAbstractFileNode {
+public class VirtualDirectoryNode extends AbstractAbstractFileNode {
- public static String nameForLayoutFile(LayoutDirectory ld) {
+ public static String nameForLayoutFile(VirtualDirectory ld) {
return ld.getName();
}
- public LayoutDirectoryNode(LayoutDirectory ld) {
+ public VirtualDirectoryNode(VirtualDirectory ld) {
super(ld);
this.setDisplayName(nameForLayoutFile(ld));
@@ -83,12 +83,10 @@ public class LayoutDirectoryNode extends AbstractAbstractFileNode map, LayoutDirectory content) {
+ private static void fillPropertyMap(Map map, VirtualDirectory content) {
map.put(LayoutContentPropertyType.NAME.toString(), content.getName());
map.put(LayoutContentPropertyType.SIZE.toString(), content.getSize());
@@ -97,9 +95,38 @@ public class LayoutDirectoryNode extends AbstractAbstractFileNode visit(LayoutDirectoryNode ld) {
+ public List visit(VirtualDirectoryNode ld) {
List actions = new ArrayList();
actions.add(new BookmarkAction("Bookmark Directory", ld));
@@ -416,7 +416,7 @@ public class DataResultFilterNode extends FilterNode {
}
@Override
- public AbstractAction visit(LayoutDirectoryNode ldn) {
+ public AbstractAction visit(VirtualDirectoryNode ldn) {
return openChild(ldn);
}
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java
index 2bb0c15d9c..7670d21106 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java
@@ -284,14 +284,14 @@ class ExplorerNodeActionVisitor extends ContentVisitor.Default LstUnallocs = new ArrayList();
private static final List lockedVols = new ArrayList();
- private int numDone = 0;
- private static boolean runningOnImage = false;
+ private static final List lockedImages = new ArrayList();
+ private long currentImage = 0L;
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
private boolean isImage = false;
-
- public ExtractUnallocAction(String title, Volume volu){
+
+ public ExtractUnallocAction(String title, Volume volu) {
super(title);
UnallocStruct us = new UnallocStruct(volu);
LstUnallocs.add(us);
- }
+ }
+
public ExtractUnallocAction(String title, Image img) {
super(title);
isImage = true;
+ currentImage = img.getId();
if (hasVolumeSystem(img)) {
for (Volume v : getVolumes(img)) {
UnallocStruct us = new UnallocStruct(v);
@@ -78,36 +82,59 @@ public final class ExtractUnallocAction extends AbstractAction {
LstUnallocs.add(us);
}
}
-
/**
- * Writes the unallocated files to $CaseDir/Export/ImgName-Unalloc-ImgObjectID-VolumeID.dat
- * @param e
+ * Writes the unallocated files to
+ * $CaseDir/Export/ImgName-Unalloc-ImgObjectID-VolumeID.dat
+ *
+ * @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
if (LstUnallocs != null && LstUnallocs.size() > 0) {
- if (runningOnImage) {
- JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already running on this Image. Please select a different Image.");
+ if (lockedImages.contains(currentImage)) {
+ JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already being extracted on this Image. Please select a different Image.");
return;
}
- for (UnallocStruct u : LstUnallocs) {
- String UnallocName = u.ImageName + "-Unalloc-" + u.ImageId + "-" + u.VolumeId + ".dat";
- if (u.llf != null && u.llf.size() > 0 && !lockedVols.contains(UnallocName)) {
- //Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
- File unalloc = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + UnallocName);
- if (unalloc.exists()) {
- int res = JOptionPane.showConfirmDialog(new Frame(), "The Unalloc File for this volume, " + UnallocName + " already exists, do you want to replace it?");
- if (res == JOptionPane.YES_OPTION) {
- unalloc.delete();
- } else {
- return;
+ List copyList = new ArrayList() {
+ {
+ addAll(LstUnallocs);
+ }
+ };
+
+
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Case.getCurrentCase().getCaseDirectory()));
+ fc.setDialogTitle("Select directory to save to");
+ fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ fc.setAcceptAllFileFilterUsed(false);
+ int returnValue = fc.showSaveDialog((Component) e.getSource());
+ if (returnValue == JFileChooser.APPROVE_OPTION) {
+ String destination = fc.getSelectedFile().getPath();
+
+ for (UnallocStruct u : LstUnallocs) {
+ u.setPath(destination);
+ if (u.llf != null && u.llf.size() > 0 && !lockedVols.contains(u.getFileName())) {
+ //Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
+ if (u.FileInstance.exists()) {
+ int res = JOptionPane.showConfirmDialog(new Frame(), "The Unalloc File for this volume, " + u.getFileName() + " already exists, do you want to replace it?");
+ if (res == JOptionPane.YES_OPTION) {
+ u.FileInstance.delete();
+ } else {
+ copyList.remove(u);
+ }
}
+ if (!isImage & !copyList.isEmpty()) {
+ ExtractUnallocWorker uw = new ExtractUnallocWorker(u);
+ uw.execute();
+ }
+ } else {
+ logger.log(Level.WARNING, "Tried to get unallocated content from volume ID but " + u.VolumeId + u.llf == null ? "its list of unallocated files was null" : "the volume is locked" );
}
- ExtractUnallocWorker uw = new ExtractUnallocWorker(unalloc, u);
+ }
+ if (isImage && !copyList.isEmpty()) {
+ ExtractUnallocWorker uw = new ExtractUnallocWorker(copyList);
uw.execute();
- } else {
- logger.log(Level.WARNING, "Tried to get unallocated content from volume ID " + u.VolumeId + ", but its list of unallocated files was empty or null");
}
}
}
@@ -115,9 +142,11 @@ public final class ExtractUnallocAction extends AbstractAction {
}
/**
- * Gets all the unallocated files in a given Content.
- * @param c Content to get Unallocated Files from
- * @return A list if it didn't crash List may be empty. Returns null on failure.
+ * Gets all the unallocated files in a given Content.
+ *
+ * @param c Content to get Unallocated Files from
+ * @return A list if it didn't crash List may be empty. Returns
+ * null on failure.
*/
private List getUnallocFiles(Content c) {
UnallocVisitor uv = new UnallocVisitor();
@@ -128,68 +157,103 @@ public final class ExtractUnallocAction extends AbstractAction {
}
return null;
}
-
-
+
/**
* Private class for dispatching the file IO in a background thread.
*/
private class ExtractUnallocWorker extends SwingWorker {
-
- private File path;
+
private ProgressHandle progress;
private boolean canceled = false;
- private UnallocStruct us;
-
+ private List lus = new ArrayList();
+ private File currentlyProcessing;
+ private int totalSizeinMegs;
- ExtractUnallocWorker(File path, UnallocStruct us) {
- this.path = path;
- if(isImage){
- runningOnImage = true;
+ ExtractUnallocWorker(UnallocStruct us) {
+ this.lus.add(us);
+ //Getting the total megs this worker is going to be doing
+ if (!lockedVols.contains(us.getFileName())) {
+ totalSizeinMegs = toMb(us.sizeInBytes());
+ lockedVols.add(us.getFileName());
}
- lockedVols.add(path.getName());
- this.us = us;
+ }
+
+ ExtractUnallocWorker(List lst) {
+ //Getting the total megs this worker is going to be doing
+ long totalBytes = 0;
+ for (UnallocStruct lu : lst) {
+ if (!lockedVols.contains(lu.getFileName())) {
+ totalBytes += lu.sizeInBytes();
+ lockedVols.add(lu.getFileName());
+ this.lus.add(lu);
+ }
+ }
+ totalSizeinMegs = toMb(totalBytes);
+ lockedImages.add(currentImage);
+ }
+
+ private int toMb(long bytes) {
+ if (bytes > 1024 && (bytes / 1024.0) <= Double.MAX_VALUE) {
+ double Mb = ((bytes / 1024.0) / 1024.0);//Bytes -> Megabytes
+ if (Mb <= Integer.MAX_VALUE) {
+ return (int) Math.floor(Mb);
+ }
+ }
+ return 0;
}
@Override
protected Integer doInBackground() {
try {
- progress = ProgressHandleFactory.createHandle("Extracting " + path.getName(), new Cancellable() {
+ progress = ProgressHandleFactory.createHandle("Extracting Unallocated Space", new Cancellable() {
@Override
public boolean cancel() {
- logger.log(Level.INFO, "Canceling extraction of Unalloc file " + path.getName());
+ logger.log(Level.INFO, "Canceling extraction of unallocated space");
canceled = true;
if (progress != null) {
- progress.setDisplayName(path.getName() + " (Cancelling...)");
+ progress.setDisplayName("Extracting Unallocated Space" + " (Cancelling...)");
}
return true;
}
});
- FileOutputStream fos = new FileOutputStream(path);
int MAX_BYTES = 8192;
- byte[] buf = new byte[MAX_BYTES]; //read 8kb at a time
- logger.log(Level.INFO, "Writing Unalloc file to " + path.getPath());
-
- progress.start(us.size());
- int count = 0;
- for (LayoutFile f : us.getLayouts()) {
+ byte[] buf = new byte[MAX_BYTES]; //read 8kb at a time
+
+
+ //Begin the actual File IO
+ progress.start(totalSizeinMegs);
+ int kbs = 0; //Each completion of the while loop adds one to kbs. 8kb * 128 = 1mb.
+ int mbs = 0; //Increments every 128th tick of kbs
+ for (UnallocStruct u : this.lus) {
+ currentlyProcessing = u.getFile();
+ logger.log(Level.INFO, "Writing Unalloc file to " + currentlyProcessing.getPath());
+ FileOutputStream fos = new FileOutputStream(currentlyProcessing);
+ int count = 1;
+ for (LayoutFile f : u.getLayouts()) {
long offset = 0L;
while (offset != f.getSize() && !canceled) {
offset += f.read(buf, offset, MAX_BYTES); //Offset + Bytes read
fos.write(buf);
+ if (++kbs % 128 == 0) {
+ mbs++;
+ progress.progress("processing " + mbs + " of " + totalSizeinMegs + " MBs", mbs);
+ }
}
- progress.progress("processing block " + ++count + "of " + us.size(), count);
+ count++;
}
+ fos.flush();
+ fos.close();
+
+ if (canceled) {
+ u.getFile().delete();
+ logger.log(Level.INFO, "Canceled extraction of " + u.getFileName() + " and deleted file");
+ } else {
+ logger.log(Level.INFO, "Finished writing unalloc file " + u.getFile().getPath());
+ }
+ }
progress.finish();
- fos.flush();
- fos.close();
-
- if(canceled){
- path.delete();
- logger.log(Level.INFO, "Canceled extraction of " + path.getName() + " and deleted file");
- }
- else{
- logger.log(Level.INFO, "Finished writing unalloc file " + path.getPath());
- }
+
+
} catch (IOException ioe) {
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ioe);
return -1;
@@ -199,42 +263,49 @@ public final class ExtractUnallocAction extends AbstractAction {
}
return 1;
}
-
+
@Override
- protected void done(){
- lockedVols.remove(path.getName());
- if(++numDone == LstUnallocs.size()){
- runningOnImage = false;
- numDone = 0;
+ protected void done() {
+ if (isImage) {
+ lockedImages.remove(currentImage);
}
- }
+ for (UnallocStruct u : lus) {
+ lockedVols.remove(u.getFileName());
+ }
+ if (!canceled && !lus.isEmpty()) {
+ JOptionPane.showMessageDialog(new Frame(), "Completed extraction of unallocated space. Files were extracted to " + lus.get(0).getFile().getParent());
+ }
+ }
}
-
+
/**
* Determines if an image has a volume system or not.
+ *
* @param img The Image to analyze
* @return True if there are Volume Systems present
*/
- private boolean hasVolumeSystem(Image img){
- try{
- return (img.getChildren().get(0) instanceof VolumeSystem);
- } catch(TskCoreException tce){
+ private boolean hasVolumeSystem(Image img) {
+ try {
+ return (img.getChildren().get(0) instanceof VolumeSystem);
+ } catch (TskCoreException tce) {
logger.log(Level.WARNING, "Unable to determine if image has a volume system, extraction may be incomplete", tce);
return false;
}
}
-
+
/**
* Gets the volumes on an given image.
+ *
* @param img The image to analyze
- * @return A list of volumes from the image. Returns an empty list if no matches.
+ * @return A list of volumes from the image. Returns an empty list if no
+ * matches.
*/
private List getVolumes(Image img) {
List lstVol = new ArrayList();
try {
for (Content v : img.getChildren().get(0).getChildren()) {
- if(v instanceof Volume){
- lstVol.add((Volume)v);
+ if (v instanceof Volume) {
+ lstVol.add((Volume) v);
}
}
} catch (TskCoreException tce) {
@@ -242,17 +313,17 @@ public final class ExtractUnallocAction extends AbstractAction {
}
return lstVol;
}
-
-
-
/**
- * Private visitor class for going through a Content file and grabbing unallocated files.
+ * Private visitor class for going through a Content file and grabbing
+ * unallocated files.
*/
private static class UnallocVisitor extends ContentVisitor.Default> {
/**
- * If the volume has no FileSystem, then it will call this method to return the single instance of unallocated space.
+ * If the volume has no FileSystem, then it will call this method to
+ * return the single instance of unallocated space.
+ *
* @param lf the LayoutFile the visitor encountered
* @return A list of size 1, returns null if it fails
*/
@@ -266,16 +337,19 @@ public final class ExtractUnallocAction extends AbstractAction {
}
/**
- * If the visitor finds a FileSystem, it will filter the results for directories and return on the Root Dir.
+ * If the visitor finds a FileSystem, it will filter the results for
+ * directories and return on the Root Dir.
+ *
* @param fs the FileSystem the visitor encountered
- * @return A list containing the layout files from subsequent Visits(), returns null if it fails
+ * @return A list containing the layout files from
+ * subsequent Visits(), returns null if it fails
*/
@Override
public List visit(FileSystem fs) {
try {
- for (Content c : fs.getChildren()){
- if(((AbstractFile)c).isRoot()){
- return c.accept(this);
+ for (Content c : fs.getChildren()) {
+ if (((AbstractFile) c).isRoot()) {
+ return c.accept(this);
}
}
} catch (TskCoreException tce) {
@@ -283,40 +357,45 @@ public final class ExtractUnallocAction extends AbstractAction {
}
return null;
}
-
+
/**
* LayoutDirectory has all the Layout(Unallocated) files
+ *
* @param ld LayoutDirectory the visitor encountered
- * @return A list containing all the LayoutFile in ld, returns null if it fails
+ * @return A list containing all the LayoutFile in ld,
+ * returns null if it fails
*/
@Override
- public List visit(LayoutDirectory ld){
- try{
+ public List visit(VirtualDirectory vd) {
+ try {
List lflst = new ArrayList();
- for(Content layout : ld.getChildren()){
- lflst.add((LayoutFile)layout);
+ for (Content layout : vd.getChildren()) {
+ lflst.add((LayoutFile) layout);
}
return lflst;
- } catch(TskCoreException tce){
+ } catch (TskCoreException tce) {
logger.log(Level.WARNING, "Could not get list of Layout Files, failed at visiting Layout Directory", tce);
}
return null;
}
/**
- * The only time this visitor should ever encounter a directory is when parsing over Root
+ * The only time this visitor should ever encounter a directory is when
+ * parsing over Root
+ *
* @param dir the directory this visitor encountered
- * @return A list containing LayoutFiles encountered during subsequent Visits(), returns null if it fails
+ * @return A list containing LayoutFiles encountered during
+ * subsequent Visits(), returns null if it fails
*/
@Override
public List visit(Directory dir) {
try {
for (Content c : dir.getChildren()) {
- if(c instanceof LayoutDirectory){
+ if (c instanceof VirtualDirectory) {
return c.accept(this);
}
}
- }catch (TskCoreException tce) {
+ } catch (TskCoreException tce) {
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), tce);
}
return null;
@@ -327,51 +406,58 @@ public final class ExtractUnallocAction extends AbstractAction {
return null;
}
}
-
-
+
/**
* Comparator for sorting lists of LayoutFiles based on their Object ID
- * Ensures that the single Unalloc File is in proper order, and that the bytes
- * are continuous.
+ * Ensures that the single Unalloc File is in proper order, and that the
+ * bytes are continuous.
*/
- private class SortObjId implements Comparator{
-
+ private class SortObjId implements Comparator {
+
@Override
public int compare(LayoutFile o1, LayoutFile o2) {
- if(o1.getId() == o2.getId()){
+ if (o1.getId() == o2.getId()) {
return 0;
- }
- if(o1.getId() > o2.getId()){
- return -1;
}
- else{
+ if (o1.getId() > o2.getId()) {
+ return -1;
+ } else {
return 1;
}
}
}
-
+
/**
- * Private class for assisting in the running the action over an image with multiple volumes.
+ * Private class for assisting in the running the action over an image with
+ * multiple volumes.
*/
- private class UnallocStruct{
+ private class UnallocStruct {
+
private List llf;
private long VolumeId;
private long ImageId;
private String ImageName;
-
+ private String FileName;
+ private File FileInstance;
+
/**
* Contingency constructor in event no VolumeSystem exists on an Image.
+ *
* @param img Image file to be analyzed
*/
- UnallocStruct(Image img){
+ UnallocStruct(Image img) {
this.llf = getUnallocFiles(img);
+ Collections.sort(llf, new SortObjId());
this.VolumeId = 0;
this.ImageId = img.getId();
this.ImageName = img.getName();
+ this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + 0 + ".dat";
+ this.FileInstance = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + this.FileName);
}
/**
* Default constructor for extracting info from Volumes.
+ *
* @param volu Volume file to be analyzed
*/
UnallocStruct(Volume volu) {
@@ -384,6 +470,8 @@ public final class ExtractUnallocAction extends AbstractAction {
this.ImageName = "";
this.ImageId = 0;
}
+ this.FileName = this.ImageName + "-Unalloc-" + this.ImageId + "-" + VolumeId + ".dat";
+ this.FileInstance = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + this.FileName);
this.llf = getUnallocFiles(volu);
Collections.sort(llf, new SortObjId());
}
@@ -392,21 +480,41 @@ public final class ExtractUnallocAction extends AbstractAction {
int size() {
return llf.size();
}
- long getVolumeId(){
+
+ long sizeInBytes() {
+ long size = 0L;
+ for (LayoutFile f : llf) {
+ size += f.getSize();
+ }
+ return size;
+ }
+
+ long getVolumeId() {
return this.VolumeId;
}
- long getImageId(){
+
+ long getImageId() {
return this.ImageId;
}
- String getImageName(){
+
+ String getImageName() {
return this.ImageName;
}
- List getLayouts(){
+
+ List getLayouts() {
return this.llf;
}
-
-
-
- }
+ String getFileName() {
+ return this.FileName;
+ }
+
+ File getFile() {
+ return this.FileInstance;
+ }
+
+ void setPath(String path) {
+ this.FileInstance = new File(path + File.separator + this.FileName);
+ }
+ }
}
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java
index 7e50019abc..80360f1595 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java
@@ -43,7 +43,7 @@ import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.Image;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.Volume;
@@ -209,7 +209,7 @@ class ViewContextAction extends AbstractAction {
}
@Override
- public List visit(LayoutDirectory ld) {
+ public List visit(VirtualDirectory ld) {
ret.add(ld);
ret.addAll(ld.getParent().accept(this));
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/docs/ExtractUnallocImage.png b/Core/src/org/sleuthkit/autopsy/directorytree/docs/ExtractUnallocImage.png
new file mode 100644
index 0000000000..3fc12e59d1
Binary files /dev/null and b/Core/src/org/sleuthkit/autopsy/directorytree/docs/ExtractUnallocImage.png differ
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml b/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml
index 7d897a7c0d..02ea31466a 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml
@@ -9,4 +9,5 @@ and open the template in the editor.
+
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml b/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml
index 64eefae2b2..b87ebd13f8 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml
@@ -9,5 +9,6 @@ and open the template in the editor.
-
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/docs/unallocated-space.html b/Core/src/org/sleuthkit/autopsy/directorytree/docs/unallocated-space.html
new file mode 100644
index 0000000000..d8d03299cd
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/docs/unallocated-space.html
@@ -0,0 +1,53 @@
+
+
+
+ Extracting Unallocated Space
+
+
+
+
+
Extracting Unallocated Space
+
+ Unallocated space are chunks of the file system that is currently not being used for anything.
+ Unallocated space can store deleted files and other interesting artifacts. On the actual image,
+ Unallocated space is stored in blocks with distinct locations on the system. However, because
+ of the way various carving tools work, it is more ideal to feed them a single, large unallocated
+ file.
+
+ Autopsy provides access to both methods of looking at unallocated space.
+
+
+
Individual Blocks
+ Underneath a volume, there is a folder named Unalloc. This folder contains all the individual unallocated blocks as the image is storing them.
+ You can right click and extract them the same way you can extract any other type of file in the Directory Tree.
+
+
Single Files
+ There are two ways to extract unallocated space as a single file. Right clicking on a volume and selecting "Extract Unallocated Space as Single File"
+ will concatenate all the unallocated files into a single, continuous file for the volume.
+ The second way is to right click on an image, and select "Extract Unallocated Space to Single Files". This option will extract one single file for each
+ volume in the image.
+
+ Progress on extraction is sent to the progress bar in the bottom right. Progress is based on number of files concatenated.
+
+ These files are stored in the Export folder under the case directory.
+ Files are named according to ImageName-Unalloc-ImageObjectID-VolumeID.dat
+ This naming scheme ensures that no duplicate file names will occur even if an there are two images with the same name in a case.
+
+
+
+
Below is where to find the single file extraction option
+
+
+
+
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/ingest/GetFilesContentVisitor.java b/Core/src/org/sleuthkit/autopsy/ingest/GetFilesContentVisitor.java
index b101db0c52..fad32d6cc4 100644
--- a/Core/src/org/sleuthkit/autopsy/ingest/GetFilesContentVisitor.java
+++ b/Core/src/org/sleuthkit/autopsy/ingest/GetFilesContentVisitor.java
@@ -29,7 +29,7 @@ import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Image;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.datamodel.VolumeSystem;
@@ -53,7 +53,7 @@ public abstract class GetFilesContentVisitor implements ContentVisitor visit(LayoutFile lc);
@Override
- public Collection visit(LayoutDirectory ld) {
+ public Collection visit(VirtualDirectory ld) {
return getAllFromChildren(ld);
}
diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java
index 5ad1970843..482fdd9762 100644
--- a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java
+++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java
@@ -22,7 +22,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
@@ -42,15 +41,13 @@ import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FileSystem;
-import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.Image;
-import org.sleuthkit.datamodel.LayoutDirectory;
+import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
-import org.sleuthkit.datamodel.Volume;
-import org.sleuthkit.datamodel.VolumeSystem;
+import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
/**
* Schedules images and files with their associated modules for ingest, and
@@ -313,7 +310,7 @@ class IngestScheduler {
* @return
*/
private static List createFromScheduledTask(ScheduledTask scheduledTask) {
- Collection rootObjects = new GetRootDirVisitor().visit(scheduledTask.image);
+ Collection rootObjects = scheduledTask.image.accept(new GetRootDirVisitor());
List firstLevelFiles = new ArrayList();
for (AbstractFile root : rootObjects) {
//TODO use more specific get AbstractFile children method
@@ -609,7 +606,7 @@ class IngestScheduler {
//skip files in root dir, starting with $, containing : (not default attributes)
//with meta address < 32, i.e. some special large NTFS and FAT files
- final TskData.TSK_FS_TYPE_ENUM fsType = f.getFileSystem().getFs_type();
+ final TskData.TSK_FS_TYPE_ENUM fsType = f.getFileSystem().getFsType();
if ((fsType.getValue() & FAT_NTFS_FLAGS) == 0) {
//not fat or ntfs, accept all files
@@ -623,7 +620,7 @@ class IngestScheduler {
logger.log(Level.WARNING, "Could not check if should enqueue the file: " + f.getName(), ex);
}
- if (isInRootDir && f.getMeta_addr() < 32) {
+ if (isInRootDir && f.getMetaAddr() < 32) {
String name = f.getName();
if (name.length() > 0
@@ -745,8 +742,8 @@ class IngestScheduler {
queryB.append("SELECT COUNT(*) FROM tsk_files WHERE ( (fs_obj_id = ").append(fs.getId());
//queryB.append(") OR (fs_obj_id = NULL) )");
queryB.append(") )");
- queryB.append(" AND ( (meta_type = ").append(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getMetaType());
- queryB.append(") OR (meta_type = ").append(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getMetaType());
+ queryB.append(" AND ( (meta_type = ").append(TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue());
+ queryB.append(") OR (meta_type = ").append(TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue());
queryB.append(" AND (name != '.') AND (name != '..')");
queryB.append(") )");
@@ -815,7 +812,7 @@ class IngestScheduler {
static class GetRootDirVisitor extends GetFilesContentVisitor {
@Override
- public Collection visit(LayoutDirectory ld) {
+ public Collection visit(VirtualDirectory ld) {
//case when we hit a layout directory, not under a real FS
Collection ret = new ArrayList();
ret.add(ld);
diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java b/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java
index 6cb5e022a8..c9620a4269 100644
--- a/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java
+++ b/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java
@@ -42,6 +42,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.*;
+import org.sleuthkit.datamodel.TskData.TSK_FS_META_MODE_ENUM;
/**
* ReportBodyFile generates a report in the body file format specified on
@@ -120,10 +121,11 @@ public class ReportBodyFile implements ReportModule {
out.write(file.getUniquePath());
}
out.write("|");
- out.write(Long.toString(file.getMeta_addr()));
+ out.write(Long.toString(file.getMetaAddr()));
out.write("|");
- if(file.getModeAsString()!=null) {
- out.write(file.getModeAsString());
+ String modeString = TSK_FS_META_MODE_ENUM.toString(file.getModes(), file.getMetaType());
+ if(modeString != null) {
+ out.write(modeString);
}
out.write("|");
out.write(Long.toString(file.getUid()));
@@ -168,7 +170,7 @@ public class ReportBodyFile implements ReportModule {
@Override
public String getName() {
- String name = "Body File";
+ String name = "Body File (Timeline Report)";
return name;
}
diff --git a/ExifParser/manifest.mf b/ExifParser/manifest.mf
index 61c3730eaa..e613aa76c2 100644
--- a/ExifParser/manifest.mf
+++ b/ExifParser/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true
OpenIDE-Module: org.sleuthkit.autopsy.exifparser/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Layer: org/sleuthkit/autopsy/exifparser/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/exifparser/Bundle.properties
diff --git a/ExifParser/nbproject/project.xml b/ExifParser/nbproject/project.xml
index ec520cd8f4..9542df9bcf 100644
--- a/ExifParser/nbproject/project.xml
+++ b/ExifParser/nbproject/project.xml
@@ -11,8 +11,8 @@
- 4
- 2.0
+ 5
+ 3.0
diff --git a/HashDatabase/manifest.mf b/HashDatabase/manifest.mf
index d177146724..0b3c75a34a 100644
--- a/HashDatabase/manifest.mf
+++ b/HashDatabase/manifest.mf
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true
OpenIDE-Module: org.sleuthkit.autopsy.hashdatabase/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Layer: org/sleuthkit/autopsy/hashdatabase/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/hashdatabase/Bundle.properties
diff --git a/HashDatabase/nbproject/project.properties b/HashDatabase/nbproject/project.properties
index 5e95dbce94..9dcdea211c 100644
--- a/HashDatabase/nbproject/project.properties
+++ b/HashDatabase/nbproject/project.properties
@@ -3,4 +3,4 @@ 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
+spec.version.base=1.1
diff --git a/HashDatabase/nbproject/project.xml b/HashDatabase/nbproject/project.xml
index db79488f5c..1a3d2b30a5 100644
--- a/HashDatabase/nbproject/project.xml
+++ b/HashDatabase/nbproject/project.xml
@@ -77,8 +77,8 @@
- 4
- 2.0
+ 5
+ 3.0
diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java
index cce3086c4c..9a08234eab 100644
--- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java
+++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java
@@ -281,7 +281,7 @@ public class HashDb implements Comparable {
/** We need proper cancel support in TSK to make the task cancellable
new Cancellable() {
- @Override
+ Override
public boolean cancel() {
return CreateIndex.this.cancel(true);
}
diff --git a/KeywordSearch/manifest.mf b/KeywordSearch/manifest.mf
index f8cfb2cab6..91df9c8471 100644
--- a/KeywordSearch/manifest.mf
+++ b/KeywordSearch/manifest.mf
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true
-OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/4
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class
OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties
diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties
index 9dcdea211c..71755d2104 100644
--- a/KeywordSearch/nbproject/project.properties
+++ b/KeywordSearch/nbproject/project.properties
@@ -3,4 +3,4 @@ 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.1
+spec.version.base=2.0
diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml
index a49c7e4c11..72869c4a41 100644
--- a/KeywordSearch/nbproject/project.xml
+++ b/KeywordSearch/nbproject/project.xml
@@ -95,8 +95,8 @@
- 4
- 2.0
+ 5
+ 3.0
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
index dac751b3bd..366c5e08e4 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
@@ -320,7 +320,6 @@ public final class KeywordSearchIngestModule implements IngestModuleAbstractFile
* Initializes the module for new ingest run Sets up threads, timers,
* retrieves settings, keyword lists to run on
*
- * @param services
*/
@Override
public void init(IngestModuleInit initContext) {
diff --git a/NEWS.txt b/NEWS.txt
index b6d7eeec90..80438d494a 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,18 +1,30 @@
----------------- VERSION Current (development) --------------
-
+---------------- VERSION Current (dev) --------------
New features:
-- Added Hashkeeper hash database support
+
Improvements:
-- File Ingest: minimized file queuing time and memory usage
-- Add Image Wizard - better work-flow, better device size reporting, info on currently processed directory
-- Added extraction of all unallocated blocks (from volume, image) as a single file
-- Reporting improvements: reorganized columns, sorted by 1st column, added logo to html report
+
Bugfixes:
-- fixed periodic keyword search during ingest, when it'd run max. 2 times only
+
+---------------- VERSION 3.0.2 --------------
+
+New features:
+- Extraction of all unallocated blocks as a single file
+- Results bookmarks with comments and basic bookmark reporting
+- Hashkeeper hash database support
+
+Improvements:
+- File Ingest: minimized file queuing time and memory usage, also improving ingest stability
+- Jump to arbitrary page in Thumbnail View
+- Add Image Wizard - better work-flow, better device size reporting, info on currently processed directory
+- Reporting: reorganized columns, sorted by 1st column, added logo, better styling
+
+Bugfixes:
+- fixed periodic keyword search during ingest, when it would only search max. 2 times
- fixed Downloads "target" in Recent Activity
- fixed missing hash and keyword search hits in reports
+- fixed deselecting NSRL database for hash ingest
---------------- VERSION 3.0.1 --------------
diff --git a/RecentActivity/manifest.mf b/RecentActivity/manifest.mf
index 48e3171c78..aeb6503d27 100644
--- a/RecentActivity/manifest.mf
+++ b/RecentActivity/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
-OpenIDE-Module: org.sleuthkit.autopsy.recentactivity/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module: org.sleuthkit.autopsy.recentactivity/4
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Layer: org/sleuthkit/autopsy/recentactivity/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties
OpenIDE-Module-Requires:
diff --git a/RecentActivity/nbproject/project.properties b/RecentActivity/nbproject/project.properties
index ffdd87b7d0..eae0cc9761 100644
--- a/RecentActivity/nbproject/project.properties
+++ b/RecentActivity/nbproject/project.properties
@@ -4,4 +4,4 @@ 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.1
+spec.version.base=2.0
diff --git a/RecentActivity/nbproject/project.xml b/RecentActivity/nbproject/project.xml
index 222c9f7b57..1a7c1f9578 100644
--- a/RecentActivity/nbproject/project.xml
+++ b/RecentActivity/nbproject/project.xml
@@ -35,8 +35,8 @@
- 4
- 2.0
+ 5
+ 3.0
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
index 3432d17ea8..ea0d994650 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
@@ -36,6 +36,7 @@ import javax.xml.parsers.ParserConfigurationException;
import org.openide.modules.InstalledFileLocator;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
@@ -88,7 +89,12 @@ public class ExtractRegistry extends Extract implements IngestModuleImage {
final String rrHome = rrRoot.getAbsolutePath();
logger.log(Level.INFO, "RegRipper home: " + rrHome);
- RR_PATH = rrHome + File.separator + "rip.exe";
+ if (PlatformUtil.isWindowsOS()) {
+ RR_PATH = rrHome + File.separator + "rip.exe";
+ }
+ else {
+ RR_PATH = "perl " + rrHome + File.separator + "rip.pl";
+ }
}
@Override
diff --git a/Testing/manifest.mf b/Testing/manifest.mf
index 0a7372fd55..1c4e9da69f 100644
--- a/Testing/manifest.mf
+++ b/Testing/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: false
OpenIDE-Module: org.sleuthkit.autopsy.testing/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/testing/Bundle.properties
diff --git a/Testing/nbproject/project.properties b/Testing/nbproject/project.properties
index 5e95dbce94..9dcdea211c 100644
--- a/Testing/nbproject/project.properties
+++ b/Testing/nbproject/project.properties
@@ -3,4 +3,4 @@ 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
+spec.version.base=1.1
diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml
index 4526a6b590..aed542547c 100644
--- a/Testing/nbproject/project.xml
+++ b/Testing/nbproject/project.xml
@@ -11,8 +11,8 @@
- 4
- 2.0
+ 5
+ 3.0
diff --git a/docs/doxygen/modDev.dox b/docs/doxygen/modDev.dox
index a3dfa1fdd8..7ce7cfc4eb 100644
--- a/docs/doxygen/modDev.dox
+++ b/docs/doxygen/modDev.dox
@@ -101,11 +101,19 @@ TODO we should outline the process of adding a JAR file dependency for an extern
E.g. adding jar directly to the module project, or (preferred) wrapping set of jars in another module
e.g. NewModuleName-Libs and adding a dependency on the libs module. Add info how to bundle OS-specific dlls in the jar (work in progress).
+\section mod_dev_services Services
-\section mod_dev_services Getting Access to Services
+A Services class is provided to give developers access to the services provided by the Autopsy framework. Currently, the following
+services are provided:
-Autopsy-Core module contains the core Autopsy application, and also the framework the application is built upon that other modules can use.
-Among the Core APIs there are general services available to the Autopsy modules. The relevant packages include:
+- FileManager: the org.sleuthkit.autopsy.casemodule.services.FileManager service provides an API for easy access to files and directories for a given image.
+You can access the org.sleuthkit.autopsy.casemodule.services.FileManager service by calling the getFileManager() method of the
+org.sleuthkit.autopsy.casemodule.services.Services class.
+
+\section mod_dev_utilities Utilities
+
+Autopsy-Core module contains the core Autopsy application and also the framework the application is built upon that other modules can use.
+Among the Core APIs there are general utilities available to the Autopsy modules. The relevant packages include:
- org.sleuthkit.autopsy.casemodule.Case class - for the module to access Case data (TSK database) and subscribe to Case change events
- org.sleuthkit.autopsy.coreutils package has classes providing utilities for getting access to Autopsy loggers, configuration persistance API,
@@ -115,11 +123,11 @@ Relevant service classes are org.sleuthkit.autopsy.coreutils.Version,
org.sleuthkit.autopsy.coreutils.PlatformUtil, org.sleuthkit.autopsy.coreutils.ModuleSettings,
org.sleuthkit.autopsy.coreutils.Logger and org.sleuthkit.autopsy.coreutils.FileUtil.
-TODO: Add additional info about service classes (log, Case, database, etc.) Similar to the C++ section about services (http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_devpage.html)
+TODO: Add additional info about utility classes (log, Case, database, etc.) Similar to the C++ section about services (http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_devpage.html)
TODO: Move the log content from the wiki (http://wiki.sleuthkit.org/index.php?title=Autopsy_3_Logging_and_Error_Checking) to here.
-Note: \ref IngestModuleServices provides services specifically for the ingest modules.
+Note: org.sleuthkit.autopsy.ingest.IngestServices provides services specifically for the ingest modules.
\section mod_dev_configuration Making a Configuration Panel
@@ -155,7 +163,7 @@ First, use NetBeans' GUI builder to design the panel. Be sure to include all opt
Second, in the source code of the panel, there are two important methods: \c load() and \c store(). When the options panel is opened via Tools > Options in Autopsy, the \c load() method will be called. Conversely, when the user presses OK after editing the options, the \c store() method will be called.
-If one wishes to make any additional panels within the original options panel, or panels which the original opens, Autopsy provides the \ref OptionsPanel interface to help. This interface requires the \c store() and \c load() functions also be provided in the separate panels, allowing for easier child storing and loading.
+If one wishes to make any additional panels within the original options panel, or panels which the original opens, Autopsy provides the org.sleuthkit.autopsy.corecomponents.OptionsPanel interface to help. This interface requires the \c store() and \c load() functions also be provided in the separate panels, allowing for easier child storing and loading.
Any storing or loading of settings or properties should be done in the \c store() and \c load() methods. Continue to \ref mod_dev_properties for more details.
diff --git a/docs/doxygen/platformConcepts.dox b/docs/doxygen/platformConcepts.dox
index f33fa5f460..7e51941a82 100644
--- a/docs/doxygen/platformConcepts.dox
+++ b/docs/doxygen/platformConcepts.dox
@@ -3,7 +3,8 @@
\section platform_basics Basic Concepts
- Central Database: All data except for the disk image is stored in a SQLite database. This includes information about what files exist in the disk image and the output from modules. Access to this database can be found from the SleuthKitCase class.
-- Services: There are core services that the platform provides to modules. See the \ref mod_dev_services section for more details.
+- Utilities: There are core utilities that the platform provides to modules. See the \ref mod_dev_utilities section for more details.
+- Services: There are services provided by the platform. See the \ref mod_dev_services section for more details.
- Pipelines and Plug-in Modules: The platform has several places where plug-in modules can be incorporated. This modular approach allows other developers to extend the functionality of the system. See the \ref platform_frameworks section for more details.
- Blackboard: The platform uses the blackboard to enable modules to communicate with each other and to display data in the GUI. See the \ref platform_blackboard section for more details.
- Single tree: Results from the various modules can generally be found in a single tree. This makes it easy for users to find their results.
diff --git a/docs/doxygen/workflow.dox b/docs/doxygen/workflow.dox
index 09a30f8abf..13de18a5bc 100644
--- a/docs/doxygen/workflow.dox
+++ b/docs/doxygen/workflow.dox
@@ -36,10 +36,13 @@ See \ref mod_ingest_page for more details on making an ingest module.
The UI has three main areas. The tree on the left-hand side, the result viewers in the upper right, and the content viewers in the lower right. Data passes between these areas by encapsulating them in Netbeans Node objects (see org.openide.nodes.Node). These allow Autopsy to generically handle all types of data. The org.sleuthkit.autopsy.datamodel package details with wrapping the org.sleuthkit.datamodel objects as Netbeans Nodes.
-
Nodes are modeled in a parent-child hierarchy with other nodes. All data within a Case is represented in a hierarchy with the disk images being one level below the case and volumes and such below the image.
-The tree on the left hand-side shows the analysis results. Its contents are populated from the central database. This is where you can browse the file system contents and see the results from the blackboard (see \ref blackboard_page). The tree is implemented in the org.sleuthkit.autopsy.directorytree package.
+The tree on the left hand-side shows the analysis results.
+Its contents are populated from the central database.
+This is where you can browse the file system contents and see the results from the blackboard.
+
+The tree is implemented in the org.sleuthkit.autopsy.directorytree package.
The area in the upper right is the result viewer area. When a node is selected from the tree, the node and its children are sent to this area. This area is used to view a set of nodes. The viewer is itself a framework with modules that display the data in different layouts. For example, the standard version comes with a table viewer and a thumbnail viewer. Refer to \ref mod_result_page for details on building a module.
@@ -50,12 +53,13 @@ See \ref mod_content_page for details on building new content viewers.
\section design_report Report generation
-When ingest is complete, the user can generate reports. There is a reporting framework to enable many different formats. Autopsy currently comes with generic html, xml and Excel reports. See the org.sleuthkit.autopsy.report package for details on the framework and
-\ref report_making for details on building a new report module.
+When ingest is complete, the user can generate reports.
+There is a reporting framework to enable many different formats. Autopsy currently comes with generic html, xml and Excel reports. See the org.sleuthkit.autopsy.report package for details on the framework and
+\ref mod_report_page for details on building a new report module.
-
The component is by default registered with the ingest manager as an ingest event listener.
The viewer first loads all the viewer-supported data currently in the blackboard when Autopsy starts.
@@ -66,9 +70,10 @@ and performs a final refresh of all viewer-supported data in the blackboard.
Node content support capabilities are registered in the node's Lookup.
--->
-
\section design_data_flow Data Flow
@@ -88,6 +93,6 @@ DataResult can send data back to its DataExplorer by making a custom action that
A default DataContent viewer is created when a case is opened. To display the contents of a node, it must be passed to a DataContent instance. The default single-click behavior of the DataResultViewers is to lookup the default DataContent TopComponent and pass the selected node to it. See org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer.propertyChange(PropertyChangeEvent) for details.
--->
+
*/
diff --git a/nbproject/project.properties b/nbproject/project.properties
index bb17c836a3..8b3a6d6092 100644
--- a/nbproject/project.properties
+++ b/nbproject/project.properties
@@ -4,7 +4,7 @@ app.title=Autopsy
### lowercase version of above
app.name=autopsy
### if left unset, version will default to today's date
-#app.version=3.0.0
+#app.version=3.0.2
### Build type isn't used at this point, but it may be useful
### Must be one of: DEVELOPMENT, RELEASE
#build.type=RELEASE
diff --git a/thunderbirdparser/manifest.mf b/thunderbirdparser/manifest.mf
index 265703b61a..d3cf213ff2 100644
--- a/thunderbirdparser/manifest.mf
+++ b/thunderbirdparser/manifest.mf
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true
OpenIDE-Module: org.sleuthkit.autopsy.thunderbirdparser/3
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Layer: org/sleuthkit/autopsy/thunderbirdparser/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/thunderbirdparser/Bundle.properties
diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml
index 515dccc008..8215e4c344 100644
--- a/thunderbirdparser/nbproject/project.xml
+++ b/thunderbirdparser/nbproject/project.xml
@@ -11,8 +11,8 @@
- 4
- 2.0
+ 5
+ 3.0