19 package org.sleuthkit.datamodel;
21 import com.mchange.v2.c3p0.ComboPooledDataSource;
22 import com.mchange.v2.c3p0.DataSources;
23 import com.mchange.v2.c3p0.PooledDataSource;
24 import java.beans.PropertyVetoException;
25 import java.io.BufferedInputStream;
26 import java.io.BufferedOutputStream;
28 import java.io.FileInputStream;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.io.UnsupportedEncodingException;
34 import java.net.InetAddress;
35 import java.net.URLEncoder;
36 import java.nio.charset.StandardCharsets;
37 import java.nio.file.Paths;
38 import java.sql.Connection;
39 import java.sql.DriverManager;
40 import java.sql.PreparedStatement;
41 import java.sql.ResultSet;
42 import java.sql.SQLException;
43 import java.sql.Statement;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collection;
48 import java.util.Collections;
49 import java.util.Date;
50 import java.util.EnumMap;
51 import java.util.HashMap;
52 import java.util.HashSet;
53 import java.util.LinkedHashMap;
54 import java.util.List;
56 import java.util.MissingResourceException;
57 import java.util.ResourceBundle;
59 import java.util.UUID;
60 import java.util.concurrent.ConcurrentHashMap;
61 import java.util.concurrent.locks.ReentrantReadWriteLock;
62 import java.util.logging.Level;
63 import java.util.logging.Logger;
64 import org.postgresql.util.PSQLException;
65 import org.postgresql.util.PSQLState;
80 import org.sqlite.SQLiteConfig;
81 import org.sqlite.SQLiteDataSource;
82 import org.sqlite.SQLiteJDBCLoader;
90 private static final int MAX_DB_NAME_LEN_BEFORE_TIMESTAMP = 47;
99 private static final long BASE_ARTIFACT_ID = Long.MIN_VALUE;
100 private static final Logger logger = Logger.getLogger(
SleuthkitCase.class.getName());
101 private static final ResourceBundle bundle = ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle");
102 private static final int IS_REACHABLE_TIMEOUT_MS = 1000;
103 private static final String SQL_ERROR_CONNECTION_GROUP =
"08";
104 private static final String SQL_ERROR_AUTHENTICATION_GROUP =
"28";
105 private static final String SQL_ERROR_PRIVILEGE_GROUP =
"42";
106 private static final String SQL_ERROR_RESOURCE_GROUP =
"53";
107 private static final String SQL_ERROR_LIMIT_GROUP =
"54";
108 private static final String SQL_ERROR_INTERNAL_GROUP =
"xx";
109 private static final int MIN_USER_DEFINED_TYPE_ID = 10000;
110 private final ConnectionPool connections;
111 private final Map<Long, VirtualDirectory> rootIdsToCarvedFileDirs =
new HashMap<Long, VirtualDirectory>();
112 private final Map<Long, FileSystem> fileSystemIdMap =
new HashMap<Long, FileSystem>();
113 private final ArrayList<ErrorObserver> sleuthkitCaseErrorObservers =
new ArrayList<ErrorObserver>();
114 private final String databaseName;
115 private final String dbPath;
116 private final DbType dbType;
117 private final String caseDirPath;
119 private String dbBackupPath;
125 private long nextArtifactId;
130 private final ReentrantReadWriteLock rwLock =
new ReentrantReadWriteLock(
true);
134 private final Map<String, Set<Long>> deviceIdToDatasourceObjIdMap =
new HashMap<String, Set<Long>>();
152 if (info.getHost() == null || info.getHost().isEmpty()) {
153 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingHostname"));
154 }
else if (info.getPort() == null || info.getPort().isEmpty()) {
155 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPort"));
156 }
else if (info.getUserName() == null || info.getUserName().isEmpty()) {
157 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingUsername"));
158 }
else if (info.getPassword() == null || info.getPassword().isEmpty()) {
159 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPassword"));
163 Class.forName(
"org.postgresql.Driver");
164 Connection conn = DriverManager.getConnection(
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres", info.getUserName(), info.getPassword());
168 }
catch (SQLException ex) {
170 String sqlState = ex.getSQLState().toLowerCase();
171 if (sqlState.startsWith(SQL_ERROR_CONNECTION_GROUP)) {
173 if (InetAddress.getByName(info.getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) {
175 result = bundle.getString(
"DatabaseConnectionCheck.Port");
177 result = bundle.getString(
"DatabaseConnectionCheck.HostnameOrPort");
179 }
catch (IOException any) {
181 result = bundle.getString(
"DatabaseConnectionCheck.Everything");
182 }
catch (MissingResourceException any) {
184 result = bundle.getString(
"DatabaseConnectionCheck.Everything");
186 }
else if (sqlState.startsWith(SQL_ERROR_AUTHENTICATION_GROUP)) {
187 result = bundle.getString(
"DatabaseConnectionCheck.Authentication");
188 }
else if (sqlState.startsWith(SQL_ERROR_PRIVILEGE_GROUP)) {
189 result = bundle.getString(
"DatabaseConnectionCheck.Access");
190 }
else if (sqlState.startsWith(SQL_ERROR_RESOURCE_GROUP)) {
191 result = bundle.getString(
"DatabaseConnectionCheck.ServerDiskSpace");
192 }
else if (sqlState.startsWith(SQL_ERROR_LIMIT_GROUP)) {
193 result = bundle.getString(
"DatabaseConnectionCheck.ServerRestart");
194 }
else if (sqlState.startsWith(SQL_ERROR_INTERNAL_GROUP)) {
195 result = bundle.getString(
"DatabaseConnectionCheck.InternalServerIssue");
197 result = bundle.getString(
"DatabaseConnectionCheck.Connection");
200 }
catch (ClassNotFoundException ex) {
201 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.Installation"));
217 Class.forName(
"org.sqlite.JDBC");
218 this.dbPath = dbPath;
219 this.dbType = dbType;
221 this.caseDirPath = dbFile.getParentFile().getAbsolutePath();
222 this.databaseName = dbFile.
getName();
223 this.connections =
new SQLiteConnections(dbPath);
224 this.caseHandle = caseHandle;
226 logSQLiteJDBCDriverInfo();
246 private SleuthkitCase(String host,
int port, String dbName, String userName, String password, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, DbType dbType)
throws Exception {
248 this.databaseName = dbName;
249 this.dbType = dbType;
250 this.caseDirPath = caseDirPath;
251 this.connections =
new PostgreSQLConnections(host, port, dbName, userName, password);
252 this.caseHandle = caseHandle;
256 private void init() throws Exception {
257 typeIdToArtifactTypeMap =
new ConcurrentHashMap<Integer, BlackboardArtifact.Type>();
258 typeIdToAttributeTypeMap =
new ConcurrentHashMap<Integer, BlackboardAttribute.Type>();
259 typeNameToArtifactTypeMap =
new ConcurrentHashMap<String, BlackboardArtifact.Type>();
260 typeNameToAttributeTypeMap =
new ConcurrentHashMap<String, BlackboardAttribute.Type>();
266 initBlackboardArtifactTypes();
267 initBlackboardAttributeTypes();
268 initNextArtifactId();
270 updateDatabaseSchema(null);
272 CaseDbConnection connection = connections.getConnection();
273 initIngestModuleTypes(connection);
274 initIngestStatusTypes(connection);
275 initReviewStatuses(connection);
276 initEncodingTypes(connection);
286 if (null == communicationsMgrInstance) {
289 return communicationsMgrInstance;
298 private void initBlackboardArtifactTypes() throws SQLException,
TskCoreException {
299 CaseDbConnection connection = connections.getConnection();
300 Statement statement = null;
301 ResultSet resultSet = null;
304 statement = connection.createStatement();
307 statement.execute(
"INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES (" + type.getTypeID() +
" , '" + type.getLabel() +
"', '" + type.getDisplayName() +
"')");
308 }
catch (SQLException ex) {
309 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) AS count FROM blackboard_artifact_types WHERE artifact_type_id = '" + type.getTypeID() +
"'");
311 if (resultSet.getLong(
"count") == 0) {
317 this.typeIdToArtifactTypeMap.put(type.getTypeID(),
new BlackboardArtifact.Type(type));
318 this.typeNameToArtifactTypeMap.put(type.getLabel(),
new BlackboardArtifact.Type(type));
321 int newPrimaryKeyIndex = Collections.max(Arrays.asList(ARTIFACT_TYPE.values())).getTypeID() + 1;
322 statement.execute(
"ALTER SEQUENCE blackboard_artifact_types_artifact_type_id_seq RESTART WITH " + newPrimaryKeyIndex);
325 closeResultSet(resultSet);
326 closeStatement(statement);
339 private void initBlackboardAttributeTypes() throws SQLException, TskCoreException {
340 CaseDbConnection connection = connections.getConnection();
341 Statement statement = null;
342 ResultSet resultSet = null;
345 statement = connection.createStatement();
346 for (ATTRIBUTE_TYPE type : ATTRIBUTE_TYPE.values()) {
348 statement.execute(
"INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name, value_type) VALUES (" + type.getTypeID() +
", '" + type.getLabel() +
"', '" + type.getDisplayName() +
"', '" + type.getValueType().getType() +
"')");
349 }
catch (SQLException ex) {
350 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) AS count FROM blackboard_attribute_types WHERE attribute_type_id = '" + type.getTypeID() +
"'");
352 if (resultSet.getLong(
"count") == 0) {
358 this.typeIdToAttributeTypeMap.put(type.getTypeID(),
new BlackboardAttribute.Type(type));
359 this.typeNameToAttributeTypeMap.put(type.getLabel(),
new BlackboardAttribute.Type(type));
362 int newPrimaryKeyIndex = Collections.max(Arrays.asList(ATTRIBUTE_TYPE.values())).getTypeID() + 1;
363 statement.execute(
"ALTER SEQUENCE blackboard_attribute_types_attribute_type_id_seq RESTART WITH " + newPrimaryKeyIndex);
366 closeResultSet(resultSet);
367 closeStatement(statement);
382 private void initNextArtifactId() throws SQLException, TskCoreException {
383 CaseDbConnection connection = connections.getConnection();
384 Statement statement = null;
385 ResultSet resultSet = null;
388 statement = connection.createStatement();
389 resultSet = connection.executeQuery(statement,
"SELECT MAX(artifact_id) AS max_artifact_id FROM blackboard_artifacts");
391 this.nextArtifactId = resultSet.getLong(
"max_artifact_id") + 1;
392 if (this.nextArtifactId == 1) {
393 this.nextArtifactId = BASE_ARTIFACT_ID;
396 closeResultSet(resultSet);
397 closeStatement(statement);
410 private void initIngestModuleTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
411 Statement statement = null;
412 ResultSet resultSet = null;
415 statement = connection.createStatement();
416 for (IngestModuleType type : IngestModuleType.values()) {
418 statement.execute(
"INSERT INTO ingest_module_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"');");
419 }
catch (SQLException ex) {
420 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_module_types WHERE type_id = " + type.ordinal() +
";");
422 if (resultSet.getLong(
"count") == 0) {
430 closeResultSet(resultSet);
431 closeStatement(statement);
443 private void initIngestStatusTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
444 Statement statement = null;
445 ResultSet resultSet = null;
448 statement = connection.createStatement();
449 for (IngestJobStatusType type : IngestJobStatusType.values()) {
451 statement.execute(
"INSERT INTO ingest_job_status_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"');");
452 }
catch (SQLException ex) {
453 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_job_status_types WHERE type_id = " + type.ordinal() +
";");
455 if (resultSet.getLong(
"count") == 0) {
463 closeResultSet(resultSet);
464 closeStatement(statement);
475 private void initReviewStatuses(CaseDbConnection connection)
throws SQLException, TskCoreException {
476 Statement statement = null;
477 ResultSet resultSet = null;
480 statement = connection.createStatement();
481 for (BlackboardArtifact.ReviewStatus status : BlackboardArtifact.ReviewStatus.values()) {
483 statement.execute(
"INSERT INTO review_statuses (review_status_id, review_status_name, display_name) "
484 +
"VALUES (" + status.getID() +
",'" + status.getName() +
"','" + status.getDisplayName() +
"')");
485 }
catch (SQLException ex) {
486 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM review_statuses WHERE review_status_id = " + status.getID());
488 if (resultSet.getLong(
"count") == 0) {
496 closeResultSet(resultSet);
497 closeStatement(statement);
509 private void initEncodingTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
510 Statement statement = null;
511 ResultSet resultSet = null;
514 statement = connection.createStatement();
515 for (TskData.EncodingType type : TskData.EncodingType.values()) {
517 statement.execute(
"INSERT INTO file_encoding_types (encoding_type, name) VALUES (" + type.getType() +
" , '" + type.name() +
"')");
518 }
catch (SQLException ex) {
519 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM file_encoding_types WHERE encoding_type = " + type.getType());
521 if (resultSet.getLong(
"count") == 0) {
529 closeResultSet(resultSet);
530 closeStatement(statement);
544 private void updateDatabaseSchema(String dbPath)
throws Exception {
545 CaseDbConnection connection = connections.getConnection();
546 ResultSet resultSet = null;
547 Statement statement = null;
550 connection.beginTransaction();
552 boolean hasMinorVersion =
false;
553 ResultSet columns = connection.getConnection().getMetaData().getColumns(null, null,
"tsk_db_info",
"schema%");
554 while (columns.next()) {
555 if (columns.getString(
"COLUMN_NAME").equals(
"schema_minor_ver")) {
556 hasMinorVersion =
true;
561 int dbSchemaMajorVersion;
562 int dbSchemaMinorVersion = 0;
564 statement = connection.createStatement();
565 resultSet = connection.executeQuery(statement,
"SELECT schema_ver"
566 + (hasMinorVersion ?
", schema_minor_ver" :
"")
567 +
" FROM tsk_db_info");
568 if (resultSet.next()) {
569 dbSchemaMajorVersion = resultSet.getInt(
"schema_ver");
570 if (hasMinorVersion) {
572 dbSchemaMinorVersion = resultSet.getInt(
"schema_minor_ver");
575 throw new TskCoreException();
577 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(dbSchemaMajorVersion, dbSchemaMinorVersion);
585 if (
false == CURRENT_DB_SCHEMA_VERSION.
isCompatible(dbSchemaVersion)) {
587 throw new TskUnsupportedSchemaVersionException(
588 "Unsupported DB schema version " + dbSchemaVersion +
", the highest supported schema version is " + CURRENT_DB_SCHEMA_VERSION.
getMajor() +
".X");
589 }
else if (dbSchemaVersion.compareTo(CURRENT_DB_SCHEMA_VERSION) < 0) {
592 if (null != dbPath) {
595 String backupFilePath = dbPath +
".schemaVer" + dbSchemaVersion.toString() +
".backup";
597 dbBackupPath = backupFilePath;
604 dbSchemaVersion = updateFromSchema2toSchema3(dbSchemaVersion, connection);
605 dbSchemaVersion = updateFromSchema3toSchema4(dbSchemaVersion, connection);
606 dbSchemaVersion = updateFromSchema4toSchema5(dbSchemaVersion, connection);
607 dbSchemaVersion = updateFromSchema5toSchema6(dbSchemaVersion, connection);
608 dbSchemaVersion = updateFromSchema6toSchema7(dbSchemaVersion, connection);
609 dbSchemaVersion = updateFromSchema7toSchema7dot1(dbSchemaVersion, connection);
610 dbSchemaVersion = updateFromSchema7dot1toSchema7dot2(dbSchemaVersion, connection);
611 statement = connection.createStatement();
612 connection.executeUpdate(statement,
"UPDATE tsk_db_info SET schema_ver = " + dbSchemaVersion.getMajor() +
", schema_minor_ver = " + dbSchemaVersion.getMinor());
617 connection.commitTransaction();
618 }
catch (Exception ex) {
619 connection.rollbackTransaction();
622 closeResultSet(resultSet);
623 closeStatement(statement);
638 public void copyCaseDB(String newDBPath)
throws IOException {
639 if (dbPath.isEmpty()) {
640 throw new IOException(
"Copying case database files is not supported for this type of case database");
642 InputStream in = null;
643 OutputStream out = null;
646 InputStream inFile =
new FileInputStream(dbPath);
647 in =
new BufferedInputStream(inFile);
648 OutputStream outFile =
new FileOutputStream(newDBPath);
649 out =
new BufferedOutputStream(outFile);
650 int bytesRead = in.read();
651 while (bytesRead != -1) {
652 out.write(bytesRead);
653 bytesRead = in.read();
664 }
catch (IOException e) {
665 logger.log(Level.WARNING,
"Could not close streams after db copy", e);
674 private void logSQLiteJDBCDriverInfo() {
676 SleuthkitCase.logger.info(String.format(
"sqlite-jdbc version %s loaded in %s mode",
677 SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
678 ?
"native" :
"pure-java"));
679 }
catch (Exception ex) {
680 SleuthkitCase.logger.log(Level.SEVERE,
"Error querying case database mode", ex);
697 @SuppressWarnings(
"deprecation")
698 private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection) throws SQLException, TskCoreException {
699 if (schemaVersion.getMajor() != 2) {
700 return schemaVersion;
702 Statement statement = null;
703 Statement updateStatement = null;
704 ResultSet resultSet = null;
707 statement = connection.createStatement();
710 statement.execute(
"CREATE TABLE tag_names (tag_name_id INTEGER PRIMARY KEY, display_name TEXT UNIQUE, description TEXT NOT NULL, color TEXT NOT NULL)");
711 statement.execute(
"CREATE TABLE content_tags (tag_id INTEGER PRIMARY KEY, obj_id INTEGER NOT NULL, tag_name_id INTEGER NOT NULL, comment TEXT NOT NULL, begin_byte_offset INTEGER NOT NULL, end_byte_offset INTEGER NOT NULL)");
712 statement.execute(
"CREATE TABLE blackboard_artifact_tags (tag_id INTEGER PRIMARY KEY, artifact_id INTEGER NOT NULL, tag_name_id INTEGER NOT NULL, comment TEXT NOT NULL)");
715 statement.execute(
"CREATE TABLE reports (report_id INTEGER PRIMARY KEY, path TEXT NOT NULL, crtime INTEGER NOT NULL, src_module_name TEXT NOT NULL, report_name TEXT NOT NULL)");
718 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN size INTEGER;");
719 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN md5 TEXT;");
720 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN display_name TEXT;");
723 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN display_name TEXT;");
726 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN meta_seq INTEGER;");
731 statement.execute(
"ALTER TABLE blackboard_attributes ADD COLUMN artifact_type_id INTEGER NULL NOT NULL DEFAULT -1;");
732 statement.execute(
"CREATE INDEX attribute_artifactTypeId ON blackboard_attributes(artifact_type_id);");
733 statement.execute(
"CREATE INDEX attribute_valueText ON blackboard_attributes(value_text);");
734 statement.execute(
"CREATE INDEX attribute_valueInt32 ON blackboard_attributes(value_int32);");
735 statement.execute(
"CREATE INDEX attribute_valueInt64 ON blackboard_attributes(value_int64);");
736 statement.execute(
"CREATE INDEX attribute_valueDouble ON blackboard_attributes(value_double);");
737 resultSet = statement.executeQuery(
"SELECT attrs.artifact_id AS artifact_id, "
738 +
"arts.artifact_type_id AS artifact_type_id "
739 +
"FROM blackboard_attributes AS attrs "
740 +
"INNER JOIN blackboard_artifacts AS arts "
741 +
"WHERE attrs.artifact_id = arts.artifact_id;");
742 updateStatement = connection.createStatement();
743 while (resultSet.next()) {
744 long artifactId = resultSet.getLong(
"artifact_id");
745 int artifactTypeId = resultSet.getInt(
"artifact_type_id");
746 updateStatement.executeUpdate(
747 "UPDATE blackboard_attributes "
748 +
"SET artifact_type_id = " + artifactTypeId
749 +
" WHERE blackboard_attributes.artifact_id = " + artifactId +
";");
758 HashMap<String, TagName> tagNames =
new HashMap<String, TagName>();
764 for (BlackboardAttribute attribute : attributes) {
765 if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) {
766 name = attribute.getValueString();
767 }
else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()) {
768 comment = attribute.getValueString();
771 if (!name.isEmpty()) {
773 if (tagNames.containsKey(name)) {
774 tagName = tagNames.get(name);
776 tagName =
addTagName(name,
"", TagName.HTML_COLOR.NONE);
777 tagNames.put(name, tagName);
779 addContentTag(content, tagName, comment, 0, content.getSize() - 1);
783 long taggedArtifactId = -1;
787 for (BlackboardAttribute attribute : attributes) {
788 if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) {
789 name = attribute.getValueString();
790 }
else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()) {
791 comment = attribute.getValueString();
792 }
else if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()) {
793 taggedArtifactId = attribute.getValueLong();
796 if (taggedArtifactId != -1 && !name.isEmpty()) {
798 if (tagNames.containsKey(name)) {
799 tagName = tagNames.get(name);
801 tagName =
addTagName(name,
"", TagName.HTML_COLOR.NONE);
802 tagNames.put(name, tagName);
808 "DELETE FROM blackboard_attributes WHERE artifact_id IN "
809 +
"(SELECT artifact_id FROM blackboard_artifacts WHERE artifact_type_id = "
810 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
811 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
");");
813 "DELETE FROM blackboard_artifacts WHERE artifact_type_id = "
814 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
815 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
";");
817 return new CaseDbSchemaVersionNumber(3, 0);
819 closeStatement(updateStatement);
820 closeResultSet(resultSet);
821 closeStatement(statement);
840 private CaseDbSchemaVersionNumber updateFromSchema3toSchema4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
841 if (schemaVersion.getMajor() != 3) {
842 return schemaVersion;
845 Statement statement = null;
846 ResultSet resultSet = null;
847 Statement queryStatement = null;
848 ResultSet queryResultSet = null;
849 Statement updateStatement = null;
854 statement = connection.createStatement();
855 updateStatement = connection.createStatement();
856 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN mime_type TEXT;");
857 resultSet = statement.executeQuery(
"SELECT files.obj_id AS obj_id, attrs.value_text AS value_text "
858 +
"FROM tsk_files AS files, blackboard_attributes AS attrs, blackboard_artifacts AS arts "
859 +
"WHERE files.obj_id = arts.obj_id AND "
860 +
"arts.artifact_id = attrs.artifact_id AND "
861 +
"arts.artifact_type_id = 1 AND "
862 +
"attrs.attribute_type_id = 62");
863 while (resultSet.next()) {
864 updateStatement.executeUpdate(
866 +
"SET mime_type = '" + resultSet.getString(
"value_text") +
"' "
867 +
"WHERE tsk_files.obj_id = " + resultSet.getInt(
"obj_id") +
";");
872 statement.execute(
"ALTER TABLE blackboard_attribute_types ADD COLUMN value_type INTEGER NOT NULL DEFAULT -1;");
873 resultSet = statement.executeQuery(
"SELECT * FROM blackboard_attribute_types AS types");
874 while (resultSet.next()) {
875 int attributeTypeId = resultSet.getInt(
"attribute_type_id");
876 String attributeLabel = resultSet.getString(
"type_name");
877 if (attributeTypeId < MIN_USER_DEFINED_TYPE_ID) {
878 updateStatement.executeUpdate(
879 "UPDATE blackboard_attribute_types "
880 +
"SET value_type = " + ATTRIBUTE_TYPE.fromLabel(attributeLabel).getValueType().getType() +
" "
881 +
"WHERE blackboard_attribute_types.attribute_type_id = " + attributeTypeId +
";");
887 queryStatement = connection.createStatement();
888 statement.execute(
"CREATE TABLE data_source_info (obj_id INTEGER PRIMARY KEY, device_id TEXT NOT NULL, time_zone TEXT NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id));");
889 resultSet = statement.executeQuery(
"SELECT * FROM tsk_objects WHERE par_obj_id IS NULL");
890 while (resultSet.next()) {
891 long objectId = resultSet.getLong(
"obj_id");
892 String timeZone =
"";
893 queryResultSet = queryStatement.executeQuery(
"SELECT tzone FROM tsk_image_info WHERE obj_id = " + objectId);
894 if (queryResultSet.next()) {
895 timeZone = queryResultSet.getString(
"tzone");
897 queryResultSet.close();
898 updateStatement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone) "
899 +
"VALUES(" + objectId +
", '" + UUID.randomUUID().toString() +
"' , '" + timeZone +
"');");
913 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN data_source_obj_id BIGINT NOT NULL DEFAULT -1;");
914 resultSet = statement.executeQuery(
"SELECT tsk_files.obj_id AS obj_id, par_obj_id FROM tsk_files, tsk_objects WHERE tsk_files.obj_id = tsk_objects.obj_id");
915 while (resultSet.next()) {
916 long fileId = resultSet.getLong(
"obj_id");
917 long dataSourceId = getDataSourceObjectId(connection, fileId);
918 updateStatement.executeUpdate(
"UPDATE tsk_files SET data_source_obj_id = " + dataSourceId +
" WHERE obj_id = " + fileId +
";");
921 statement.execute(
"CREATE TABLE ingest_module_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
922 statement.execute(
"CREATE TABLE ingest_job_status_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
923 if (this.dbType.equals(DbType.SQLITE)) {
924 statement.execute(
"CREATE TABLE ingest_modules (ingest_module_id INTEGER PRIMARY KEY, display_name TEXT NOT NULL, unique_name TEXT UNIQUE NOT NULL, type_id INTEGER NOT NULL, version TEXT NOT NULL, FOREIGN KEY(type_id) REFERENCES ingest_module_types(type_id));");
925 statement.execute(
"CREATE TABLE ingest_jobs (ingest_job_id INTEGER PRIMARY KEY, obj_id BIGINT NOT NULL, host_name TEXT NOT NULL, start_date_time BIGINT NOT NULL, end_date_time BIGINT NOT NULL, status_id INTEGER NOT NULL, settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id));");
927 statement.execute(
"CREATE TABLE ingest_modules (ingest_module_id BIGSERIAL PRIMARY KEY, display_name TEXT NOT NULL, unique_name TEXT UNIQUE NOT NULL, type_id INTEGER NOT NULL, version TEXT NOT NULL, FOREIGN KEY(type_id) REFERENCES ingest_module_types(type_id));");
928 statement.execute(
"CREATE TABLE ingest_jobs (ingest_job_id BIGSERIAL PRIMARY KEY, obj_id BIGINT NOT NULL, host_name TEXT NOT NULL, start_date_time BIGINT NOT NULL, end_date_time BIGINT NOT NULL, status_id INTEGER NOT NULL, settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id));");
931 statement.execute(
"CREATE TABLE ingest_job_modules (ingest_job_id INTEGER, ingest_module_id INTEGER, pipeline_position INTEGER, PRIMARY KEY(ingest_job_id, ingest_module_id), FOREIGN KEY(ingest_job_id) REFERENCES ingest_jobs(ingest_job_id), FOREIGN KEY(ingest_module_id) REFERENCES ingest_modules(ingest_module_id));");
932 initIngestModuleTypes(connection);
933 initIngestStatusTypes(connection);
935 return new CaseDbSchemaVersionNumber(4, 0);
938 closeResultSet(queryResultSet);
939 closeStatement(queryStatement);
940 closeStatement(updateStatement);
941 closeResultSet(resultSet);
942 closeStatement(statement);
960 private CaseDbSchemaVersionNumber updateFromSchema4toSchema5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
961 if (schemaVersion.getMajor() != 4) {
962 return schemaVersion;
965 Statement statement = null;
969 statement = connection.createStatement();
970 statement.execute(
"CREATE TABLE review_statuses (review_status_id INTEGER PRIMARY KEY, review_status_name TEXT NOT NULL, display_name TEXT NOT NULL)");
980 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
983 statement.execute(
"CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL);");
984 initEncodingTypes(connection);
991 initReviewStatuses(connection);
996 statement.execute(
"ALTER TABLE tsk_files_path ADD COLUMN encoding_type INTEGER NOT NULL DEFAULT 0;");
998 return new CaseDbSchemaVersionNumber(5, 0);
1001 closeStatement(statement);
1019 private CaseDbSchemaVersionNumber updateFromSchema5toSchema6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1020 if (schemaVersion.getMajor() != 5) {
1021 return schemaVersion;
1028 Statement statement = null;
1029 ResultSet resultSet = null;
1035 statement = connection.createStatement();
1036 statement.execute(
"CREATE TABLE IF NOT EXISTS review_statuses (review_status_id INTEGER PRIMARY KEY, review_status_name TEXT NOT NULL, display_name TEXT NOT NULL)");
1038 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) AS count FROM review_statuses");
1040 if (resultSet.getLong(
"count") == 0) {
1049 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
1052 return new CaseDbSchemaVersionNumber(6, 0);
1055 closeResultSet(resultSet);
1056 closeStatement(statement);
1074 private CaseDbSchemaVersionNumber updateFromSchema6toSchema7(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1075 if (schemaVersion.getMajor() != 6) {
1076 return schemaVersion;
1082 Statement statement = null;
1083 Statement updstatement = null;
1084 ResultSet resultSet = null;
1087 statement = connection.createStatement();
1088 updstatement = connection.createStatement();
1089 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN extension TEXT");
1091 resultSet = connection.executeQuery(statement,
"SELECT obj_id,name FROM tsk_files");
1092 while (resultSet.next()) {
1093 long objID = resultSet.getLong(
"obj_id");
1094 String name = resultSet.getString(
"name");
1095 updstatement.executeUpdate(
"UPDATE tsk_files SET extension = '" +
escapeSingleQuotes(extractExtension(name)) +
"' "
1096 +
"WHERE obj_id = " + objID);
1099 statement.execute(
"CREATE INDEX file_extension ON tsk_files ( extension )");
1102 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN artifact_obj_id INTEGER NOT NULL DEFAULT -1");
1104 return new CaseDbSchemaVersionNumber(7, 0);
1107 closeResultSet(resultSet);
1108 closeStatement(statement);
1109 closeStatement(updstatement);
1127 private CaseDbSchemaVersionNumber updateFromSchema7toSchema7dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1128 if (schemaVersion.getMajor() != 7) {
1129 return schemaVersion;
1132 if (schemaVersion.getMinor() != 0) {
1133 return schemaVersion;
1139 Statement statement = null;
1140 ResultSet resultSet = null;
1143 statement = connection.createStatement();
1146 if (schemaVersion.getMinor() == 0) {
1148 statement.execute(
"ALTER TABLE tsk_db_info ADD COLUMN schema_minor_ver INTEGER DEFAULT 1");
1150 return new CaseDbSchemaVersionNumber(7, 1);
1153 closeResultSet(resultSet);
1154 closeStatement(statement);
1172 private CaseDbSchemaVersionNumber updateFromSchema7dot1toSchema7dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1173 if (schemaVersion.getMajor() != 7) {
1174 return schemaVersion;
1177 if (schemaVersion.getMinor() != 1) {
1178 return schemaVersion;
1181 Statement statement = null;
1182 Statement updstatement = null;
1183 ResultSet resultSet = null;
1187 statement = connection.createStatement();
1188 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN data_source_obj_id INTEGER NOT NULL DEFAULT -1");
1191 updstatement = connection.createStatement();
1192 resultSet = connection.executeQuery(statement,
"SELECT artifact_id, obj_id FROM blackboard_artifacts");
1193 while (resultSet.next()) {
1194 long artifact_id = resultSet.getLong(
"artifact_id");
1195 long obj_id = resultSet.getLong(
"obj_id");
1196 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
1197 updstatement.executeUpdate(
"UPDATE blackboard_artifacts SET data_source_obj_id = " + data_source_obj_id +
" "
1198 +
"WHERE artifact_id = " + artifact_id);
1200 closeResultSet(resultSet);
1201 closeStatement(statement);
1202 closeStatement(updstatement);
1207 statement = connection.createStatement();
1208 statement.execute(
"ALTER TABLE tag_names ADD COLUMN knownStatus INTEGER NOT NULL DEFAULT " + TskData.FileKnown.UNKNOWN.getFileKnownValue());
1211 if (this.dbType.equals(DbType.SQLITE)) {
1212 statement.execute(
"CREATE TABLE account_types (account_type_id INTEGER PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1213 statement.execute(
"CREATE TABLE accounts (account_id INTEGER PRIMARY KEY, account_type_id INTEGER NOT NULL, account_unique_identifier TEXT NOT NULL, UNIQUE(account_type_id, account_unique_identifier) , FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
1214 statement.execute(
"CREATE TABLE account_relationships (relationship_id INTEGER PRIMARY KEY, account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, relationship_source_obj_id INTEGER NOT NULL, date_time INTEGER, relationship_type INTEGER NOT NULL, data_source_obj_id INTEGER NOT NULL, UNIQUE(account1_id, account2_id, relationship_source_obj_id), FOREIGN KEY(account1_id) REFERENCES accounts(account_id), FOREIGN KEY(account2_id) REFERENCES accounts(account_id), FOREIGN KEY(relationship_source_obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id))");
1217 statement.execute(
"CREATE TABLE account_types (account_type_id BIGSERIAL PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1218 statement.execute(
"CREATE TABLE accounts (account_id BIGSERIAL PRIMARY KEY, account_type_id INTEGER NOT NULL, account_unique_identifier TEXT NOT NULL, UNIQUE(account_type_id, account_unique_identifier) , FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
1219 statement.execute(
"CREATE TABLE account_relationships (relationship_id BIGSERIAL PRIMARY KEY, account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, relationship_source_obj_id INTEGER NOT NULL, date_time BIGINT, relationship_type INTEGER NOT NULL, data_source_obj_id INTEGER NOT NULL, UNIQUE(account1_id, account2_id, relationship_source_obj_id), FOREIGN KEY(account1_id) REFERENCES accounts(account_id), FOREIGN KEY(account2_id) REFERENCES accounts(account_id), FOREIGN KEY(relationship_source_obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id))");
1223 statement.execute(
"CREATE INDEX artifact_artifact_objID ON blackboard_artifacts(artifact_obj_id)");
1224 statement.execute(
"CREATE INDEX relationships_account1 ON account_relationships(account1_id)");
1225 statement.execute(
"CREATE INDEX relationships_account2 ON account_relationships(account2_id)");
1226 statement.execute(
"CREATE INDEX relationships_relationship_source_obj_id ON account_relationships(relationship_source_obj_id)");
1227 statement.execute(
"CREATE INDEX relationships_date_time ON account_relationships(date_time)");
1228 statement.execute(
"CREATE INDEX relationships_relationship_type ON account_relationships(relationship_type)");
1229 statement.execute(
"CREATE INDEX relationships_data_source_obj_id ON account_relationships(data_source_obj_id)");
1231 return new CaseDbSchemaVersionNumber(7, 2);
1233 closeResultSet(resultSet);
1234 closeStatement(statement);
1235 closeStatement(updstatement);
1247 static String extractExtension(
final String fileName) {
1249 int i = fileName.lastIndexOf(
".");
1251 if ((i > 0) && ((i + 1) < fileName.length())) {
1252 ext = fileName.substring(i + 1);
1263 return ext.toLowerCase();
1287 return CURRENT_DB_SCHEMA_VERSION;
1306 return dbBackupPath;
1329 return databaseName;
1349 rwLock.writeLock().lock();
1360 rwLock.writeLock().unlock();
1371 rwLock.readLock().lock();
1382 rwLock.readLock().unlock();
1402 }
catch (Exception ex) {
1403 throw new TskCoreException(
"Failed to open case database at " + dbPath, ex);
1433 return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()), databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDir, info.getDbType());
1434 }
catch (PropertyVetoException exp) {
1436 throw new TskCoreException(exp.getMessage(), exp);
1440 }
catch (Exception exp) {
1442 throw new TskCoreException(exp.getMessage(), exp);
1459 }
catch (Exception ex) {
1460 throw new TskCoreException(
"Failed to create case database at " + dbPath, ex);
1480 String databaseName = createCaseDataBaseName(caseName);
1495 return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()),
1496 databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDirPath, info.getDbType());
1497 }
catch (PropertyVetoException exp) {
1499 throw new TskCoreException(exp.getMessage(), exp);
1500 }
catch (Exception exp) {
1502 throw new TskCoreException(exp.getMessage(), exp);
1515 private static String createCaseDataBaseName(String candidateDbName) {
1517 if (!candidateDbName.isEmpty()) {
1521 dbName = candidateDbName.replaceAll(
"[^\\p{ASCII}]",
"_");
1526 dbName = dbName.replaceAll(
"[\\p{Cntrl}]",
"_");
1531 dbName = dbName.replaceAll(
"[ /?:'\"\\\\]",
"_");
1536 dbName = dbName.toLowerCase();
1542 if ((dbName.length() > 0 && !(Character.isLetter(dbName.codePointAt(0))) && !(dbName.codePointAt(0) ==
'_'))) {
1543 dbName =
"_" + dbName;
1550 if (dbName.length() > MAX_DB_NAME_LEN_BEFORE_TIMESTAMP) {
1551 dbName = dbName.substring(0, MAX_DB_NAME_LEN_BEFORE_TIMESTAMP);
1563 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
1564 Date date =
new Date();
1565 dbName = dbName +
"_" + dateFormat.format(date);
1588 return this.caseHandle.initAddImageProcess(timeZone, addUnallocSpace, noFatFsOrphans, imageCopyPath);
1600 CaseDbConnection connection = connections.getConnection();
1603 ResultSet rs = null;
1605 s = connection.createStatement();
1606 rs = connection.executeQuery(s,
"SELECT obj_id, type FROM tsk_objects "
1607 +
"WHERE par_obj_id IS NULL");
1608 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
1610 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"),
ObjectType.
valueOf(rs.getShort(
"type"))));
1613 List<Content> rootObjs =
new ArrayList<Content>();
1614 for (ObjectInfo i : infos) {
1615 if (null != i.type) {
1626 throw new TskCoreException(
"Parentless object has wrong type to be a root (ABSTRACTFILE, but not VIRTUAL_DIRECTORY: " + i.type);
1630 throw new TskCoreException(
"Parentless object has wrong type to be a root: " + i.type);
1635 }
catch (SQLException ex) {
1636 throw new TskCoreException(
"Error getting root objects", ex);
1656 List<Long> getDataSourceObjIds(String deviceId)
throws TskCoreException {
1659 synchronized (deviceIdToDatasourceObjIdMap) {
1660 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
1661 return new ArrayList<Long>(deviceIdToDatasourceObjIdMap.get(deviceId));
1664 CaseDbConnection connection = connections.getConnection();
1667 ResultSet rs = null;
1669 s = connection.createStatement();
1670 rs = connection.executeQuery(s,
"SELECT obj_id FROM data_source_info WHERE device_id = '" + deviceId +
"'");
1671 List<Long> dataSourceObjIds =
new ArrayList<Long>();
1673 dataSourceObjIds.add(rs.getLong(
"obj_id"));
1676 long ds_obj_id = rs.getLong(
"obj_id");
1677 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
1678 deviceIdToDatasourceObjIdMap.get(deviceId).add(ds_obj_id);
1680 deviceIdToDatasourceObjIdMap.put(deviceId,
new HashSet<Long>(Arrays.asList(ds_obj_id)));
1683 return dataSourceObjIds;
1684 }
catch (SQLException ex) {
1685 throw new TskCoreException(
"Error getting data sources", ex);
1712 CaseDbConnection connection = connections.getConnection();
1714 Statement statement = null;
1715 ResultSet resultSet = null;
1717 statement = connection.createStatement();
1718 resultSet = connection.executeQuery(statement,
1719 "SELECT ds.obj_id, ds.device_id, ds.time_zone, img.type, img.ssize, img.size, img.md5, img.display_name "
1720 +
"FROM data_source_info AS ds "
1721 +
"LEFT JOIN tsk_image_info AS img "
1722 +
"ON ds.obj_id = img.obj_id");
1723 List<DataSource> dataSourceList =
new ArrayList<DataSource>();
1726 while (resultSet.next()) {
1728 Long objectId = resultSet.getLong(
"obj_id");
1729 String deviceId = resultSet.getString(
"device_id");
1730 String timezone = resultSet.getString(
"time_zone");
1731 String type = resultSet.getString(
"type");
1743 String parentPath =
"/";
1744 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, deviceId, dirType, metaType, dirFlag, metaFlags, timezone, null,
FileKnown.
UNKNOWN, parentPath);
1749 Long ssize = resultSet.getLong(
"ssize");
1750 Long size = resultSet.getLong(
"size");
1751 String md5 = resultSet.getString(
"md5");
1752 String name = resultSet.getString(
"display_name");
1754 List<String> imagePaths = imagePathsMap.get(objectId);
1756 if (imagePaths.size() > 0) {
1757 String path = imagePaths.get(0);
1758 name = (
new java.io.File(path)).getName();
1764 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name, imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, size);
1767 dataSourceList.add(dataSource);
1770 return dataSourceList;
1772 }
catch (SQLException ex) {
1773 throw new TskCoreException(
"Error getting data sources", ex);
1775 closeResultSet(resultSet);
1776 closeStatement(statement);
1803 CaseDbConnection connection = connections.getConnection();
1805 Statement statement = null;
1806 ResultSet resultSet = null;
1808 statement = connection.createStatement();
1809 resultSet = connection.executeQuery(statement,
1810 "SELECT ds.device_id, ds.time_zone, img.type, img.ssize, img.size, img.md5, img.display_name "
1811 +
"FROM data_source_info AS ds "
1812 +
"LEFT JOIN tsk_image_info AS img "
1813 +
"ON ds.obj_id = img.obj_id "
1814 +
"WHERE ds.obj_id = " + objectId);
1815 if (resultSet.next()) {
1816 String deviceId = resultSet.getString(
"device_id");
1817 String timezone = resultSet.getString(
"time_zone");
1818 String type = resultSet.getString(
"type");
1830 String parentPath =
"/";
1831 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, deviceId, dirType, metaType, dirFlag, metaFlags, timezone, null,
FileKnown.
UNKNOWN, parentPath);
1836 Long ssize = resultSet.getLong(
"ssize");
1837 Long size = resultSet.getLong(
"size");
1838 String md5 = resultSet.getString(
"md5");
1839 String name = resultSet.getString(
"display_name");
1841 List<String> imagePaths = getImagePathsById(objectId);
1843 if (imagePaths.size() > 0) {
1844 String path = imagePaths.get(0);
1845 name = (
new java.io.File(path)).getName();
1851 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name, imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, size);
1854 throw new TskDataException(String.format(
"There is no data source with obj_id = %d", objectId));
1856 }
catch (SQLException ex) {
1857 throw new TskCoreException(String.format(
"Error getting data source with obj_id = %d", objectId), ex);
1859 closeResultSet(resultSet);
1860 closeStatement(statement);
1879 return getArtifactsHelper(
"blackboard_artifacts.artifact_type_id = " + artifactTypeID);
1893 CaseDbConnection connection = connections.getConnection();
1895 ResultSet rs = null;
1898 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_FROM_SOURCE);
1899 statement.clearParameters();
1900 statement.setLong(1, objId);
1901 rs = connection.executeQuery(statement);
1904 count = rs.getLong(
"count");
1907 }
catch (SQLException ex) {
1908 throw new TskCoreException(
"Error getting number of blackboard artifacts by content", ex);
1927 CaseDbConnection connection = connections.getConnection();
1929 ResultSet rs = null;
1932 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_OF_TYPE);
1933 statement.clearParameters();
1934 statement.setInt(1, artifactTypeID);
1935 rs = connection.executeQuery(statement);
1938 count = rs.getLong(
"count");
1941 }
catch (SQLException ex) {
1942 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
1965 CaseDbConnection connection = connections.getConnection();
1968 ResultSet rs = null;
1970 s = connection.createStatement();
1971 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
1972 +
"arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
1973 +
"types.type_name AS type_name, types.display_name AS display_name, "
1974 +
" arts.review_status_id AS review_status_id "
1975 +
"FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
1976 +
"WHERE arts.artifact_id = attrs.artifact_id "
1977 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
1978 +
" AND attrs.value_text = '" + value +
"'"
1979 +
" AND types.artifact_type_id=arts.artifact_type_id"
1981 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
1983 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
1984 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
1988 }
catch (SQLException ex) {
1989 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
2016 String valSubStr =
"%" + subString;
2017 if (startsWith ==
false) {
2020 CaseDbConnection connection = connections.getConnection();
2023 ResultSet rs = null;
2025 s = connection.createStatement();
2026 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2027 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2028 +
" types.type_name AS type_name, types.display_name AS display_name, "
2029 +
" arts.review_status_id AS review_status_id "
2030 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2031 +
" WHERE arts.artifact_id = attrs.artifact_id "
2032 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
2033 +
" AND LOWER(attrs.value_text) LIKE LOWER('" + valSubStr +
"')"
2034 +
" AND types.artifact_type_id=arts.artifact_type_id "
2036 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2038 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2039 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2043 }
catch (SQLException ex) {
2044 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
2068 CaseDbConnection connection = connections.getConnection();
2071 ResultSet rs = null;
2073 s = connection.createStatement();
2074 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2075 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2076 +
" types.type_name AS type_name, types.display_name AS display_name, "
2077 +
" arts.review_status_id AS review_status_id "
2078 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2079 +
"WHERE arts.artifact_id = attrs.artifact_id "
2080 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
2081 +
" AND attrs.value_int32 = " + value
2082 +
" AND types.artifact_type_id=arts.artifact_type_id "
2084 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2086 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2087 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2091 }
catch (SQLException ex) {
2092 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
2116 CaseDbConnection connection = connections.getConnection();
2119 ResultSet rs = null;
2121 s = connection.createStatement();
2122 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2123 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2124 +
" types.type_name AS type_name, types.display_name AS display_name, "
2125 +
" arts.review_status_id AS review_status_id "
2126 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2127 +
" WHERE arts.artifact_id = attrs.artifact_id "
2128 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
2129 +
" AND attrs.value_int64 = " + value
2130 +
" AND types.artifact_type_id=arts.artifact_type_id "
2132 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2134 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2135 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2139 }
catch (SQLException ex) {
2140 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
2164 CaseDbConnection connection = connections.getConnection();
2167 ResultSet rs = null;
2169 s = connection.createStatement();
2170 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2171 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2172 +
" types.type_name AS type_name, types.display_name AS display_name, "
2173 +
" arts.review_status_id AS review_status_id "
2174 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2175 +
" WHERE arts.artifact_id = attrs.artifact_id "
2176 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
2177 +
" AND attrs.value_double = " + value
2178 +
" AND types.artifact_type_id=arts.artifact_type_id "
2180 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2182 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2183 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2187 }
catch (SQLException ex) {
2188 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
2212 CaseDbConnection connection = connections.getConnection();
2215 ResultSet rs = null;
2217 s = connection.createStatement();
2218 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2219 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2220 +
" types.type_name AS type_name, types.display_name AS display_name, "
2221 +
" arts.review_status_id AS review_status_id "
2222 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2223 +
" WHERE arts.artifact_id = attrs.artifact_id "
2224 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
2225 +
" AND attrs.value_byte = " + value
2226 +
" AND types.artifact_type_id=arts.artifact_type_id "
2228 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2230 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2231 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2235 }
catch (SQLException ex) {
2236 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
2253 CaseDbConnection connection = connections.getConnection();
2256 ResultSet rs = null;
2258 s = connection.createStatement();
2259 rs = connection.executeQuery(s,
"SELECT artifact_type_id, type_name, display_name FROM blackboard_artifact_types");
2263 rs.getString(
"type_name"), rs.getString(
"display_name")));
2265 return artifactTypes;
2266 }
catch (SQLException ex) {
2267 throw new TskCoreException(
"Error getting artifact types", ex);
2285 String typeIdList =
"";
2292 String query =
"SELECT DISTINCT artifact_type_id FROM blackboard_artifacts "
2293 +
"WHERE artifact_type_id IN (" + typeIdList +
")";
2294 CaseDbConnection connection = connections.getConnection();
2297 ResultSet rs = null;
2299 s = connection.createStatement();
2300 rs = connection.executeQuery(s, query);
2306 }
catch (SQLException ex) {
2307 throw new TskCoreException(
"Error getting artifact types in use", ex);
2327 CaseDbConnection connection = connections.getConnection();
2330 ResultSet rs = null;
2332 s = connection.createStatement();
2333 rs = connection.executeQuery(s,
2334 "SELECT DISTINCT arts.artifact_type_id AS artifact_type_id, "
2335 +
"types.type_name AS type_name, types.display_name AS display_name "
2336 +
"FROM blackboard_artifact_types AS types "
2337 +
"INNER JOIN blackboard_artifacts AS arts "
2338 +
"ON arts.artifact_type_id = types.artifact_type_id");
2342 rs.getString(
"type_name"), rs.getString(
"display_name")));
2344 return uniqueArtifactTypes;
2345 }
catch (SQLException ex) {
2346 throw new TskCoreException(
"Error getting attribute types", ex);
2363 CaseDbConnection connection = connections.getConnection();
2366 ResultSet rs = null;
2368 s = connection.createStatement();
2369 rs = connection.executeQuery(s,
"SELECT attribute_type_id, type_name, display_name, value_type FROM blackboard_attribute_types");
2375 return attribute_types;
2376 }
catch (SQLException ex) {
2377 throw new TskCoreException(
"Error getting attribute types", ex);
2398 CaseDbConnection connection = connections.getConnection();
2401 ResultSet rs = null;
2403 s = connection.createStatement();
2404 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM blackboard_attribute_types");
2407 count = rs.getInt(
"count");
2410 }
catch (SQLException ex) {
2411 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
2432 private ArrayList<BlackboardArtifact> getArtifactsHelper(String whereClause)
throws TskCoreException {
2433 CaseDbConnection connection = connections.getConnection();
2435 ResultSet rs = null;
2437 Statement statement = connection.createStatement();
2438 String query =
"SELECT blackboard_artifacts.artifact_id AS artifact_id, "
2439 +
"blackboard_artifacts.obj_id AS obj_id, "
2440 +
"blackboard_artifacts.artifact_obj_id AS artifact_obj_id, "
2441 +
"blackboard_artifacts.data_source_obj_id AS data_source_obj_id, "
2442 +
"blackboard_artifact_types.artifact_type_id AS artifact_type_id, "
2443 +
"blackboard_artifact_types.type_name AS type_name, "
2444 +
"blackboard_artifact_types.display_name AS display_name, "
2445 +
"blackboard_artifacts.review_status_id AS review_status_id "
2446 +
"FROM blackboard_artifacts, blackboard_artifact_types "
2447 +
"WHERE blackboard_artifacts.artifact_type_id = blackboard_artifact_types.artifact_type_id "
2449 +
" AND " + whereClause;
2450 rs = connection.executeQuery(statement, query);
2451 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2453 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2454 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2458 }
catch (SQLException ex) {
2459 throw new TskCoreException(
"Error getting or creating a blackboard artifact", ex);
2479 private long getArtifactsCountHelper(
int artifactTypeID,
long obj_id)
throws TskCoreException {
2480 CaseDbConnection connection = connections.getConnection();
2482 ResultSet rs = null;
2485 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_BY_SOURCE_AND_TYPE);
2486 statement.clearParameters();
2487 statement.setLong(1, obj_id);
2488 statement.setInt(2, artifactTypeID);
2489 rs = connection.executeQuery(statement);
2492 count = rs.getLong(
"count");
2495 }
catch (SQLException ex) {
2496 throw new TskCoreException(
"Error getting blackboard artifact count", ex);
2517 return getArtifactsHelper(
"blackboard_artifacts.obj_id = " + obj_id +
" AND blackboard_artifact_types.type_name = '" + artifactTypeName +
"';");
2533 return getArtifactsHelper(
"blackboard_artifacts.obj_id = " + obj_id +
" AND blackboard_artifact_types.artifact_type_id = " + artifactTypeID +
";");
2565 int artifactTypeID = this.
getArtifactType(artifactTypeName).getTypeID();
2566 if (artifactTypeID == -1) {
2569 return getArtifactsCountHelper(artifactTypeID, obj_id);
2585 return getArtifactsCountHelper(artifactTypeID, obj_id);
2601 return getArtifactsCountHelper(artifactType.getTypeID(), obj_id);
2616 return getArtifactsHelper(
"blackboard_artifact_types.type_name = '" + artifactTypeName +
"';");
2631 return getArtifactsHelper(
"blackboard_artifact_types.artifact_type_id = " + artifactType.getTypeID() +
";");
2648 CaseDbConnection connection = connections.getConnection();
2651 ResultSet rs = null;
2653 s = connection.createStatement();
2654 rs = connection.executeQuery(s,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
2655 +
"arts.obj_id AS obj_id, arts.artifact_obj_id as artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2656 +
"types.type_name AS type_name, types.display_name AS display_name,"
2657 +
"arts.review_status_id AS review_status_id "
2658 +
"FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
2659 +
"WHERE arts.artifact_id = attrs.artifact_id "
2660 +
"AND attrs.attribute_type_id = " + attrType.getTypeID()
2661 +
" AND arts.artifact_type_id = " + artifactType.getTypeID()
2662 +
" AND attrs.value_text = '" + value +
"'"
2663 +
" AND types.artifact_type_id=arts.artifact_type_id"
2665 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
2667 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2668 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2672 }
catch (SQLException ex) {
2673 throw new TskCoreException(
"Error getting blackboard artifacts by artifact type and attribute. " + ex.getMessage(), ex);
2693 CaseDbConnection connection = connections.getConnection();
2695 ResultSet rs = null;
2698 s = connection.createStatement();
2699 rs = connection.executeQuery(s,
"SELECT arts.artifact_id AS artifact_id, "
2700 +
"arts.obj_id AS obj_id, arts.artifact_obj_id as artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
2701 +
"types.type_name AS type_name, types.display_name AS display_name,"
2702 +
"arts.review_status_id AS review_status_id "
2703 +
"FROM blackboard_artifacts AS arts, blackboard_artifact_types AS types "
2704 +
"WHERE arts.artifact_id = " + artifactID
2705 +
" AND arts.artifact_type_id = types.artifact_type_id");
2707 return new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
2708 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
2716 throw new TskCoreException(
"No blackboard artifact with id " + artifactID);
2718 }
catch (SQLException ex) {
2719 throw new TskCoreException(
"Error getting a blackboard artifact. " + ex.getMessage(), ex);
2736 CaseDbConnection connection = connections.getConnection();
2739 addBlackBoardAttribute(attr, artifactTypeId, connection);
2740 }
catch (SQLException ex) {
2741 throw new TskCoreException(
"Error adding blackboard attribute " + attr.toString(), ex);
2758 CaseDbConnection connection = connections.getConnection();
2761 connection.beginTransaction();
2763 addBlackBoardAttribute(attr, artifactTypeId, connection);
2765 connection.commitTransaction();
2766 }
catch (SQLException ex) {
2767 connection.rollbackTransaction();
2768 throw new TskCoreException(
"Error adding blackboard attributes", ex);
2775 private void addBlackBoardAttribute(
BlackboardAttribute attr,
int artifactTypeId, CaseDbConnection connection)
throws SQLException, TskCoreException {
2776 PreparedStatement statement;
2777 switch (attr.getAttributeType().getValueType()) {
2779 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_STRING_ATTRIBUTE);
2780 statement.clearParameters();
2781 statement.setString(7, attr.getValueString());
2784 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_BYTE_ATTRIBUTE);
2785 statement.clearParameters();
2786 statement.setBytes(7, attr.getValueBytes());
2789 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_INT_ATTRIBUTE);
2790 statement.clearParameters();
2791 statement.setInt(7, attr.getValueInt());
2794 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
2795 statement.clearParameters();
2796 statement.setLong(7, attr.getValueLong());
2799 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_DOUBLE_ATTRIBUTE);
2800 statement.clearParameters();
2801 statement.setDouble(7, attr.getValueDouble());
2804 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
2805 statement.clearParameters();
2806 statement.setLong(7, attr.getValueLong());
2809 throw new TskCoreException(
"Unrecognized artifact attribute value type");
2811 statement.setLong(1, attr.getArtifactID());
2812 statement.setInt(2, artifactTypeId);
2813 statement.setString(3, attr.getSourcesCSV());
2814 statement.setString(4,
"");
2815 statement.setInt(5, attr.getAttributeType().getTypeID());
2816 statement.setLong(6, attr.getAttributeType().getValueType().getType());
2817 connection.executeUpdate(statement);
2830 String addSourceToArtifactAttribute(BlackboardAttribute attr, String source)
throws TskCoreException {
2838 if (null == source || source.isEmpty()) {
2839 throw new TskCoreException(
"Attempt to add null or empty source module name to artifact attribute");
2841 CaseDbConnection connection = connections.getConnection();
2843 Statement queryStmt = null;
2844 Statement updateStmt = null;
2845 ResultSet result = null;
2846 String newSources =
"";
2848 connection.beginTransaction();
2849 String valueClause =
"";
2850 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType = attr.getAttributeType().getValueType();
2851 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
2852 switch (valueType) {
2857 valueClause =
" value_int32 = " + attr.getValueInt();
2861 valueClause =
" value_int64 = " + attr.getValueLong();
2864 valueClause =
" value_double = " + attr.getValueDouble();
2867 throw new TskCoreException(String.format(
"Unrecognized value type for attribute %s", attr.getDisplayString()));
2869 String query =
"SELECT source FROM blackboard_attributes WHERE"
2870 +
" artifact_id = " + attr.getArtifactID()
2871 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
2872 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
2873 +
" AND " + valueClause +
";";
2874 queryStmt = connection.createStatement();
2875 updateStmt = connection.createStatement();
2876 result = connection.executeQuery(queryStmt, query);
2883 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ATTR_BY_VALUE_BYTE);
2884 statement.clearParameters();
2885 statement.setLong(1, attr.getArtifactID());
2886 statement.setLong(2, attr.getAttributeType().getTypeID());
2887 statement.setBytes(3, attr.getValueBytes());
2888 result = connection.executeQuery(statement);
2890 while (result.next()) {
2891 String oldSources = result.getString(
"source");
2892 if (null != oldSources && !oldSources.isEmpty()) {
2893 Set<String> uniqueSources =
new HashSet<String>(Arrays.asList(oldSources.split(
",")));
2894 if (!uniqueSources.contains(source)) {
2895 newSources = oldSources +
"," + source;
2897 newSources = oldSources;
2900 newSources = source;
2902 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
2903 String update =
"UPDATE blackboard_attributes SET source = '" + newSources +
"' WHERE"
2904 +
" artifact_id = " + attr.getArtifactID()
2905 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
2906 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
2907 +
" AND " + valueClause +
";";
2908 connection.executeUpdate(updateStmt, update);
2915 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.UPDATE_ATTR_BY_VALUE_BYTE);
2916 statement.clearParameters();
2917 statement.setString(1, newSources);
2918 statement.setLong(2, attr.getArtifactID());
2919 statement.setLong(3, attr.getAttributeType().getTypeID());
2920 statement.setBytes(4, attr.getValueBytes());
2921 connection.executeUpdate(statement);
2924 connection.commitTransaction();
2926 }
catch (SQLException ex) {
2927 connection.rollbackTransaction();
2928 throw new TskCoreException(String.format(
"Error adding source module to attribute %s", attr.getDisplayString()), ex);
2930 closeResultSet(result);
2931 closeStatement(updateStmt);
2932 closeStatement(queryStmt);
2953 CaseDbConnection connection = connections.getConnection();
2956 ResultSet rs = null;
2958 connection.beginTransaction();
2959 s = connection.createStatement();
2960 rs = connection.executeQuery(s,
"SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = '" + attrTypeString +
"'");
2963 rs = connection.executeQuery(s,
"SELECT MAX(attribute_type_id) AS highest_id FROM blackboard_attribute_types");
2966 maxID = rs.getInt(
"highest_id");
2967 if (maxID < MIN_USER_DEFINED_TYPE_ID) {
2968 maxID = MIN_USER_DEFINED_TYPE_ID;
2973 connection.executeUpdate(s,
"INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name, value_type) VALUES ('" + maxID +
"', '" + attrTypeString +
"', '" + displayName +
"', '" + valueType.getType() +
"')");
2975 this.typeIdToAttributeTypeMap.put(type.getTypeID(), type);
2976 this.typeNameToAttributeTypeMap.put(type.getTypeName(), type);
2977 connection.commitTransaction();
2980 throw new TskDataException(
"The attribute type that was added was already within the system.");
2983 }
catch (SQLException ex) {
2984 connection.rollbackTransaction();
2985 throw new TskCoreException(
"Error adding attribute type", ex);
3005 if (this.typeNameToAttributeTypeMap.containsKey(attrTypeName)) {
3006 return this.typeNameToAttributeTypeMap.get(attrTypeName);
3008 CaseDbConnection connection = connections.getConnection();
3011 ResultSet rs = null;
3013 s = connection.createStatement();
3014 rs = connection.executeQuery(s,
"SELECT attribute_type_id, type_name, display_name, value_type FROM blackboard_attribute_types WHERE type_name = '" + attrTypeName +
"'");
3019 this.typeIdToAttributeTypeMap.put(type.getTypeID(), type);
3020 this.typeNameToAttributeTypeMap.put(attrTypeName, type);
3023 }
catch (SQLException ex) {
3024 throw new TskCoreException(
"Error getting attribute type id", ex);
3044 if (this.typeIdToAttributeTypeMap.containsKey(typeID)) {
3045 return this.typeIdToAttributeTypeMap.get(typeID);
3047 CaseDbConnection connection = connections.getConnection();
3050 ResultSet rs = null;
3052 s = connection.createStatement();
3053 rs = connection.executeQuery(s,
"SELECT attribute_type_id, type_name, display_name, value_type FROM blackboard_attribute_types WHERE attribute_type_id = " + typeID +
"");
3054 BlackboardAttribute.Type type = null;
3056 type =
new BlackboardAttribute.Type(rs.getInt(
"attribute_type_id"), rs.getString(
"type_name"),
3057 rs.getString(
"display_name"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromType(rs.getLong(
"value_type")));
3058 this.typeIdToAttributeTypeMap.put(typeID, type);
3059 this.typeNameToAttributeTypeMap.put(type.getTypeName(), type);
3062 }
catch (SQLException ex) {
3063 throw new TskCoreException(
"Error getting attribute type id", ex);
3083 if (this.typeNameToArtifactTypeMap.containsKey(artTypeName)) {
3084 return this.typeNameToArtifactTypeMap.get(artTypeName);
3086 CaseDbConnection connection = connections.getConnection();
3089 ResultSet rs = null;
3091 s = connection.createStatement();
3092 rs = connection.executeQuery(s,
"SELECT artifact_type_id, type_name, display_name FROM blackboard_artifact_types WHERE type_name = '" + artTypeName +
"'");
3096 rs.getString(
"type_name"), rs.getString(
"display_name"));
3097 this.typeIdToArtifactTypeMap.put(type.getTypeID(), type);
3098 this.typeNameToArtifactTypeMap.put(artTypeName, type);
3101 }
catch (SQLException ex) {
3102 throw new TskCoreException(
"Error getting artifact type from the database", ex);
3122 if (this.typeIdToArtifactTypeMap.containsKey(artTypeId)) {
3123 return typeIdToArtifactTypeMap.get(artTypeId);
3125 CaseDbConnection connection = connections.getConnection();
3128 ResultSet rs = null;
3130 s = connection.createStatement();
3131 rs = connection.executeQuery(s,
"SELECT artifact_type_id, type_name, display_name FROM blackboard_artifact_types WHERE artifact_type_id = " + artTypeId +
"");
3132 BlackboardArtifact.Type type = null;
3134 type =
new BlackboardArtifact.Type(rs.getInt(
"artifact_type_id"),
3135 rs.getString(
"type_name"), rs.getString(
"display_name"));
3136 this.typeIdToArtifactTypeMap.put(artTypeId, type);
3137 this.typeNameToArtifactTypeMap.put(type.getTypeName(), type);
3140 }
catch (SQLException ex) {
3141 throw new TskCoreException(
"Error getting artifact type from the database", ex);
3163 CaseDbConnection connection = connections.getConnection();
3166 ResultSet rs = null;
3168 connection.beginTransaction();
3169 s = connection.createStatement();
3170 rs = connection.executeQuery(s,
"SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = '" + artifactTypeName +
"'");
3173 rs = connection.executeQuery(s,
"SELECT MAX(artifact_type_id) AS highest_id FROM blackboard_artifact_types");
3176 maxID = rs.getInt(
"highest_id");
3177 if (maxID < MIN_USER_DEFINED_TYPE_ID) {
3178 maxID = MIN_USER_DEFINED_TYPE_ID;
3183 connection.executeUpdate(s,
"INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES ('" + maxID +
"', '" + artifactTypeName +
"', '" + displayName +
"')");
3185 this.typeIdToArtifactTypeMap.put(type.getTypeID(), type);
3186 this.typeNameToArtifactTypeMap.put(type.getTypeName(), type);
3187 connection.commitTransaction();
3190 throw new TskDataException(
"The attribute type that was added was already within the system.");
3192 }
catch (SQLException ex) {
3193 connection.rollbackTransaction();
3194 throw new TskCoreException(
"Error adding artifact type", ex);
3204 CaseDbConnection connection = connections.getConnection();
3206 ResultSet rs = null;
3208 Statement statement = connection.createStatement();
3209 rs = connection.executeQuery(statement,
"SELECT attrs.artifact_id AS artifact_id, "
3210 +
"attrs.source AS source, attrs.context AS context, attrs.attribute_type_id AS attribute_type_id, "
3211 +
"attrs.value_type AS value_type, attrs.value_byte AS value_byte, "
3212 +
"attrs.value_text AS value_text, attrs.value_int32 AS value_int32, "
3213 +
"attrs.value_int64 AS value_int64, attrs.value_double AS value_double, "
3214 +
"types.type_name AS type_name, types.display_name AS display_name "
3215 +
"FROM blackboard_attributes AS attrs, blackboard_attribute_types AS types WHERE attrs.artifact_id = " + artifact.getArtifactID()
3216 +
" AND attrs.attribute_type_id = types.attribute_type_id");
3217 ArrayList<BlackboardAttribute> attributes =
new ArrayList<BlackboardAttribute>();
3219 int attributeTypeId = rs.getInt(
"attribute_type_id");
3220 String attributeTypeName = rs.getString(
"type_name");
3222 if (this.typeIdToAttributeTypeMap.containsKey(attributeTypeId)) {
3223 attributeType = this.typeIdToAttributeTypeMap.get(attributeTypeId);
3226 rs.getString(
"display_name"),
3228 this.typeIdToAttributeTypeMap.put(attributeTypeId, attributeType);
3229 this.typeNameToAttributeTypeMap.put(attributeTypeName, attributeType);
3233 rs.getLong(
"artifact_id"),
3235 rs.getString(
"source"),
3236 rs.getString(
"context"),
3237 rs.getInt(
"value_int32"),
3238 rs.getLong(
"value_int64"),
3239 rs.getDouble(
"value_double"),
3240 rs.getString(
"value_text"),
3241 rs.getBytes(
"value_byte"), this
3243 attributes.add(attr);
3246 }
catch (SQLException ex) {
3247 throw new TskCoreException(
"Error getting attributes for artifact, artifact id = " + artifact.getArtifactID(), ex);
3268 CaseDbConnection connection = connections.getConnection();
3271 ResultSet rs = null;
3273 s = connection.createStatement();
3274 rs = connection.executeQuery(s,
"SELECT blackboard_attributes.artifact_id AS artifact_id, "
3275 +
"blackboard_attributes.source AS source, blackboard_attributes.context AS context, "
3276 +
"blackboard_attributes.attribute_type_id AS attribute_type_id, "
3277 +
"blackboard_attributes.value_type AS value_type, blackboard_attributes.value_byte AS value_byte, "
3278 +
"blackboard_attributes.value_text AS value_text, blackboard_attributes.value_int32 AS value_int32, "
3279 +
"blackboard_attributes.value_int64 AS value_int64, blackboard_attributes.value_double AS value_double "
3280 +
"FROM blackboard_attributes " + whereClause);
3281 ArrayList<BlackboardAttribute> matches =
new ArrayList<BlackboardAttribute>();
3287 rs.getLong(
"artifact_id"),
3289 rs.getString(
"source"),
3290 rs.getString(
"context"),
3291 rs.getInt(
"value_int32"),
3292 rs.getLong(
"value_int64"),
3293 rs.getDouble(
"value_double"),
3294 rs.getString(
"value_text"),
3295 rs.getBytes(
"value_byte"), this
3300 }
catch (SQLException ex) {
3301 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
3322 CaseDbConnection connection = connections.getConnection();
3324 ResultSet rs = null;
3327 s = connection.createStatement();
3328 rs = connection.executeQuery(s,
"SELECT blackboard_artifacts.artifact_id AS artifact_id, "
3329 +
"blackboard_artifacts.obj_id AS obj_id, blackboard_artifacts.artifact_obj_id AS artifact_obj_id, blackboard_artifacts.data_source_obj_id AS data_source_obj_id, blackboard_artifacts.artifact_type_id AS artifact_type_id, "
3330 +
"blackboard_artifacts.review_status_id AS review_status_id "
3331 +
"FROM blackboard_artifacts " + whereClause);
3332 ArrayList<BlackboardArtifact> matches =
new ArrayList<BlackboardArtifact>();
3338 type.getTypeID(), type.getTypeName(), type.getDisplayName(),
3340 matches.add(artifact);
3343 }
catch (SQLException ex) {
3344 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
3383 return newBlackboardArtifact(artifactType.getTypeID(), obj_id, artifactType.getLabel(), artifactType.getDisplayName());
3387 CaseDbConnection connection = connections.getConnection();
3389 ResultSet resultSet = null;
3392 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
3393 statement.clearParameters();
3394 statement.setLong(1, obj_id);
3396 connection.executeUpdate(statement);
3397 resultSet = statement.getGeneratedKeys();
3399 long artifact_obj_id = resultSet.getLong(1);
3400 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
3403 statement = connection.getPreparedStatement(PREPARED_STATEMENT.POSTGRESQL_INSERT_ARTIFACT, Statement.RETURN_GENERATED_KEYS);
3404 statement.clearParameters();
3405 statement.setLong(1, obj_id);
3406 statement.setLong(2, artifact_obj_id);
3407 statement.setLong(3, data_source_obj_id);
3408 statement.setInt(4, artifact_type_id);
3411 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_ARTIFACT, Statement.RETURN_GENERATED_KEYS);
3412 statement.clearParameters();
3413 this.nextArtifactId++;
3414 statement.setLong(1, this.nextArtifactId);
3415 statement.setLong(2, obj_id);
3416 statement.setLong(3, artifact_obj_id);
3417 statement.setLong(4, data_source_obj_id);
3418 statement.setInt(5, artifact_type_id);
3421 connection.executeUpdate(statement);
3422 resultSet = statement.getGeneratedKeys();
3424 return new BlackboardArtifact(
this, resultSet.getLong(1),
3425 obj_id, artifact_obj_id, data_source_obj_id, artifact_type_id, artifactTypeName, artifactDisplayName, BlackboardArtifact.ReviewStatus.UNDECIDED,
true);
3426 }
catch (SQLException ex) {
3427 throw new TskCoreException(
"Error creating a blackboard artifact", ex);
3429 closeResultSet(resultSet);
3447 boolean getContentHasChildren(Content content)
throws TskCoreException {
3448 CaseDbConnection connection = connections.getConnection();
3450 ResultSet rs = null;
3453 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_CHILD_OBJECTS_BY_PARENT);
3454 statement.clearParameters();
3455 statement.setLong(1, content.getId());
3456 rs = connection.executeQuery(statement);
3457 boolean hasChildren =
false;
3459 hasChildren = rs.getInt(
"count") > 0;
3462 }
catch (SQLException e) {
3463 throw new TskCoreException(
"Error checking for children of parent " + content, e);
3483 int getContentChildrenCount(Content content)
throws TskCoreException {
3484 CaseDbConnection connection = connections.getConnection();
3486 ResultSet rs = null;
3489 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_CHILD_OBJECTS_BY_PARENT);
3490 statement.clearParameters();
3491 statement.setLong(1, content.getId());
3492 rs = connection.executeQuery(statement);
3493 int countChildren = -1;
3495 countChildren = rs.getInt(
"count");
3497 return countChildren;
3498 }
catch (SQLException e) {
3499 throw new TskCoreException(
"Error checking for children of parent " + content, e);
3518 List<Content> getAbstractFileChildren(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
3519 CaseDbConnection connection = connections.getConnection();
3521 ResultSet rs = null;
3523 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_PARENT_AND_TYPE);
3524 statement.clearParameters();
3525 long parentId = parent.getId();
3526 statement.setLong(1, parentId);
3527 statement.setShort(2, type.getFileType());
3528 rs = connection.executeQuery(statement);
3529 return fileChildren(rs, connection, parentId);
3530 }
catch (SQLException ex) {
3531 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
3548 List<Content> getAbstractFileChildren(Content parent)
throws TskCoreException {
3549 CaseDbConnection connection = connections.getConnection();
3551 ResultSet rs = null;
3553 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_PARENT);
3554 statement.clearParameters();
3555 long parentId = parent.getId();
3556 statement.setLong(1, parentId);
3557 rs = connection.executeQuery(statement);
3558 return fileChildren(rs, connection, parentId);
3559 }
catch (SQLException ex) {
3560 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
3579 List<Long> getAbstractFileChildrenIds(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
3580 CaseDbConnection connection = connections.getConnection();
3582 ResultSet rs = null;
3584 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_IDS_BY_PARENT_AND_TYPE);
3585 statement.clearParameters();
3586 statement.setLong(1, parent.getId());
3587 statement.setShort(2, type.getFileType());
3588 rs = connection.executeQuery(statement);
3589 List<Long> children =
new ArrayList<Long>();
3591 children.add(rs.getLong(
"obj_id"));
3594 }
catch (SQLException ex) {
3595 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
3612 List<Long> getAbstractFileChildrenIds(Content parent)
throws TskCoreException {
3613 CaseDbConnection connection = connections.getConnection();
3615 ResultSet rs = null;
3617 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_IDS_BY_PARENT);
3618 statement.clearParameters();
3619 statement.setLong(1, parent.getId());
3620 rs = connection.executeQuery(statement);
3621 List<Long> children =
new ArrayList<Long>();
3623 children.add(rs.getLong(
"obj_id"));
3626 }
catch (SQLException ex) {
3627 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
3645 List<Long> getBlackboardArtifactChildrenIds(Content parent)
throws TskCoreException {
3646 CaseDbConnection connection = connections.getConnection();
3648 ResultSet rs = null;
3650 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_OBJECTIDS_BY_PARENT);
3651 statement.clearParameters();
3652 statement.setLong(1, parent.getId());
3653 rs = connection.executeQuery(statement);
3654 List<Long> children =
new ArrayList<Long>();
3656 children.add(rs.getLong(
"obj_id"));
3659 }
catch (SQLException ex) {
3660 throw new TskCoreException(
"Error getting children for BlackboardArtifact", ex);
3677 List<Content> getBlackboardArtifactChildren(Content parent)
throws TskCoreException {
3679 long parentId = parent.getId();
3680 ArrayList<BlackboardArtifact> artsArray = getArtifactsHelper(
"blackboard_artifacts.obj_id = " + parentId +
";");
3682 List<Content> lc =
new ArrayList<Content>();
3683 lc.addAll(artsArray);
3695 Collection<ObjectInfo> getChildrenInfo(Content c)
throws TskCoreException {
3696 CaseDbConnection connection = connections.getConnection();
3699 ResultSet rs = null;
3701 s = connection.createStatement();
3702 rs = connection.executeQuery(s,
"SELECT tsk_objects.obj_id AS obj_id, tsk_objects.type AS type "
3703 +
"FROM tsk_objects LEFT JOIN tsk_files "
3704 +
"ON tsk_objects.obj_id = tsk_files.obj_id "
3705 +
"WHERE tsk_objects.par_obj_id = " + c.getId()
3706 +
" ORDER BY tsk_objects.obj_id");
3707 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
3709 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type"))));
3712 }
catch (SQLException ex) {
3713 throw new TskCoreException(
"Error getting Children Info for Content", ex);
3732 ObjectInfo getParentInfo(Content c)
throws TskCoreException {
3735 CaseDbConnection connection = connections.getConnection();
3738 ResultSet rs = null;
3740 s = connection.createStatement();
3741 rs = connection.executeQuery(s,
"SELECT parent.obj_id AS obj_id, parent.type AS type "
3742 +
"FROM tsk_objects AS parent INNER JOIN tsk_objects AS child "
3743 +
"ON child.par_obj_id = parent.obj_id "
3744 +
"WHERE child.obj_id = " + c.getId());
3746 return new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type")));
3748 throw new TskCoreException(
"Given content (id: " + c.getId() +
") has no parent");
3750 }
catch (SQLException ex) {
3751 throw new TskCoreException(
"Error getting Parent Info for Content", ex);
3770 ObjectInfo getParentInfo(
long contentId)
throws TskCoreException {
3773 CaseDbConnection connection = connections.getConnection();
3776 ResultSet rs = null;
3778 s = connection.createStatement();
3779 rs = connection.executeQuery(s,
"SELECT parent.obj_id AS obj_id, parent.type AS type "
3780 +
"FROM tsk_objects AS parent INNER JOIN tsk_objects AS child "
3781 +
"ON child.par_obj_id = parent.obj_id "
3782 +
"WHERE child.obj_id = " + contentId);
3784 return new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type")));
3786 throw new TskCoreException(
"Given content (id: " + contentId +
") has no parent.");
3788 }
catch (SQLException ex) {
3789 throw new TskCoreException(
"Error getting Parent Info for Content: " + contentId, ex);
3808 Directory getParentDirectory(FsContent fsc)
throws TskCoreException {
3812 throw new TskCoreException(
"Given FsContent (id: " + fsc.getId() +
") is a root object (can't have parent directory).");
3814 ObjectInfo parentInfo = getParentInfo(fsc);
3815 Directory parent = null;
3816 if (parentInfo.type == ObjectType.ABSTRACTFILE) {
3817 parent = getDirectoryById(parentInfo.id, fsc.getFileSystem());
3819 throw new TskCoreException(
"Parent of FsContent (id: " + fsc.getId() +
") has wrong type to be directory: " + parentInfo.type);
3837 CaseDbConnection connection = connections.getConnection();
3840 ResultSet rs = null;
3842 s = connection.createStatement();
3843 rs = connection.executeQuery(s,
"SELECT * FROM tsk_objects WHERE obj_id = " +
id +
" LIMIT 1");
3849 long parentId = rs.getLong(
"par_obj_id");
3856 content = getVolumeSystemById(
id, parentId);
3859 content = getVolumeById(
id, parentId);
3862 content = getFileSystemById(
id, parentId);
3871 throw new TskCoreException(
"Could not obtain Content object with ID: " +
id);
3874 }
catch (SQLException ex) {
3875 throw new TskCoreException(
"Error getting Content by ID.", ex);
3891 String getFilePath(
long id) {
3892 CaseDbConnection connection;
3894 connection = connections.getConnection();
3895 }
catch (TskCoreException ex) {
3896 logger.log(Level.SEVERE,
"Error getting file path for file " +
id, ex);
3899 String filePath = null;
3901 ResultSet rs = null;
3903 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_LOCAL_PATH_FOR_FILE);
3904 statement.clearParameters();
3905 statement.setLong(1,
id);
3906 rs = connection.executeQuery(statement);
3908 filePath = rs.getString(
"path");
3910 }
catch (SQLException ex) {
3911 logger.log(Level.SEVERE,
"Error getting file path for file " +
id, ex);
3927 TskData.EncodingType getEncodingType(
long id) {
3928 CaseDbConnection connection;
3930 connection = connections.getConnection();
3931 }
catch (TskCoreException ex) {
3932 logger.log(Level.SEVERE,
"Error getting file path for file " +
id, ex);
3935 TskData.EncodingType type = TskData.EncodingType.NONE;
3937 ResultSet rs = null;
3939 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ENCODING_FOR_FILE);
3940 statement.clearParameters();
3941 statement.setLong(1,
id);
3942 rs = connection.executeQuery(statement);
3944 type = TskData.EncodingType.valueOf(rs.getInt(1));
3946 }
catch (SQLException ex) {
3947 logger.log(Level.SEVERE,
"Error getting encoding type for file " +
id, ex);
3964 String getFileParentPath(
long objectId, CaseDbConnection connection) {
3965 String parentPath = null;
3967 ResultSet rs = null;
3969 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_PATH_FOR_FILE);
3970 statement.clearParameters();
3971 statement.setLong(1, objectId);
3972 rs = connection.executeQuery(statement);
3974 parentPath = rs.getString(
"parent_path");
3976 }
catch (SQLException ex) {
3977 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
3993 String getFileName(
long objectId, CaseDbConnection connection) {
3994 String fileName = null;
3996 ResultSet rs = null;
3998 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_NAME);
3999 statement.clearParameters();
4000 statement.setLong(1, objectId);
4001 rs = connection.executeQuery(statement);
4003 fileName = rs.getString(
"name");
4005 }
catch (SQLException ex) {
4006 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
4024 DerivedFile.DerivedMethod getDerivedMethod(
long id)
throws TskCoreException {
4025 CaseDbConnection connection = connections.getConnection();
4026 DerivedFile.DerivedMethod method = null;
4028 ResultSet rs1 = null;
4029 ResultSet rs2 = null;
4031 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_DERIVED_FILE);
4032 statement.clearParameters();
4033 statement.setLong(1,
id);
4034 rs1 = connection.executeQuery(statement);
4036 int method_id = rs1.getInt(
"derived_id");
4037 String rederive = rs1.getString(
"rederive");
4038 method =
new DerivedFile.DerivedMethod(method_id, rederive);
4039 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_DERIVATION_METHOD);
4040 statement.clearParameters();
4041 statement.setInt(1, method_id);
4042 rs2 = connection.executeQuery(statement);
4044 method.setToolName(rs2.getString(
"tool_name"));
4045 method.setToolVersion(rs2.getString(
"tool_version"));
4046 method.setOther(rs2.getString(
"other"));
4049 }
catch (SQLException e) {
4050 logger.log(Level.SEVERE,
"Error getting derived method for file: " +
id, e);
4052 closeResultSet(rs2);
4053 closeResultSet(rs1);
4071 CaseDbConnection connection = connections.getConnection();
4073 ResultSet rs = null;
4075 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_BY_ID);
4076 statement.clearParameters();
4077 statement.setLong(1,
id);
4078 rs = connection.executeQuery(statement);
4079 List<AbstractFile> files = resultSetToAbstractFiles(rs, connection);
4080 if (files.size() > 0) {
4081 return files.get(0);
4085 }
catch (SQLException ex) {
4086 throw new TskCoreException(
"Error getting file by id, id = " +
id, ex);
4105 CaseDbConnection connection = connections.getConnection();
4107 ResultSet rs = null;
4109 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_BY_ARTIFACT_OBJ_ID);
4110 statement.clearParameters();
4111 statement.setLong(1,
id);
4112 rs = connection.executeQuery(statement);
4113 List<BlackboardArtifact> artifacts = resultSetToArtifacts(rs);
4114 if (artifacts.size() > 0) {
4115 return artifacts.get(0);
4119 }
catch (SQLException ex) {
4120 throw new TskCoreException(
"Error getting artifacts by artifact_obj_id, artifact_obj_id = " +
id, ex);
4139 CaseDbConnection connection = connections.getConnection();
4141 ResultSet rs = null;
4143 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_BY_ARTIFACT_ID);
4144 statement.clearParameters();
4145 statement.setLong(1,
id);
4146 rs = connection.executeQuery(statement);
4147 List<BlackboardArtifact> artifacts = resultSetToArtifacts(rs);
4148 if (artifacts.size() > 0) {
4149 return artifacts.get(0);
4153 }
catch (SQLException ex) {
4154 throw new TskCoreException(
"Error getting artifacts by artifact id, artifact id = " +
id, ex);
4174 private long getFileSystemId(
long fileId, CaseDbConnection connection) {
4176 ResultSet rs = null;
4179 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_SYSTEM_BY_OBJECT);
4180 statement.clearParameters();
4181 statement.setLong(1, fileId);
4182 rs = connection.executeQuery(statement);
4184 ret = rs.getLong(
"fs_obj_id");
4189 }
catch (SQLException e) {
4190 logger.log(Level.SEVERE,
"Error checking file system id of a file, id = " + fileId, e);
4210 String query = String.format(
"SELECT COUNT(*) AS count FROM tsk_files WHERE obj_id = %d AND data_source_obj_id = %d", fileId, dataSource.getId());
4211 CaseDbConnection connection = connections.getConnection();
4213 Statement statement = null;
4214 ResultSet resultSet = null;
4216 statement = connection.createStatement();
4217 resultSet = connection.executeQuery(statement, query);
4219 return (resultSet.getLong(
"count") > 0L);
4220 }
catch (SQLException ex) {
4221 throw new TskCoreException(String.format(
"Error executing query %s", query), ex);
4223 closeResultSet(resultSet);
4224 closeStatement(statement);
4241 public List<AbstractFile>
findFiles(
Content dataSource, String fileName)
throws TskCoreException {
4242 List<AbstractFile> files =
new ArrayList<AbstractFile>();
4243 CaseDbConnection connection = connections.getConnection();
4245 ResultSet resultSet = null;
4247 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_DATA_SOURCE_AND_NAME);
4248 statement.clearParameters();
4249 statement.setString(1, fileName.toLowerCase());
4250 statement.setLong(2, dataSource.getId());
4251 resultSet = connection.executeQuery(statement);
4252 files.addAll(resultSetToAbstractFiles(resultSet, connection));
4253 }
catch (SQLException e) {
4254 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles.exception.msg3.text"), e);
4256 closeResultSet(resultSet);
4276 public List<AbstractFile>
findFiles(
Content dataSource, String fileName, String dirName)
throws TskCoreException {
4277 List<AbstractFile> files =
new ArrayList<AbstractFile>();
4278 CaseDbConnection connection = connections.getConnection();
4280 ResultSet resultSet = null;
4282 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_DATA_SOURCE_AND_PARENT_PATH_AND_NAME);
4283 statement.clearParameters();
4284 statement.setString(1, fileName.toLowerCase());
4285 statement.setString(2,
"%" + dirName.toLowerCase() +
"%");
4286 statement.setLong(3, dataSource.getId());
4287 resultSet = connection.executeQuery(statement);
4288 files.addAll(resultSetToAbstractFiles(resultSet, connection));
4289 }
catch (SQLException e) {
4290 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles3.exception.msg3.text"), e);
4292 closeResultSet(resultSet);
4317 }
catch (TskCoreException ex) {
4320 }
catch (TskCoreException ex2) {
4321 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
4347 if (transaction == null) {
4348 throw new TskCoreException(
"Passed null CaseDbTransaction");
4352 ResultSet resultSet = null;
4355 CaseDbConnection connection = transaction.getConnection();
4356 String parentPath = getFileParentPath(parentId, connection);
4357 if (parentPath == null) {
4360 String parentName = getFileName(parentId, connection);
4361 if (parentName != null && !parentName.isEmpty()) {
4362 parentPath = parentPath + parentName +
"/";
4367 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
4368 statement.clearParameters();
4369 if (parentId != 0) {
4370 statement.setLong(1, parentId);
4372 statement.setNull(1, java.sql.Types.BIGINT);
4375 connection.executeUpdate(statement);
4376 resultSet = statement.getGeneratedKeys();
4378 long newObjId = resultSet.getLong(1);
4384 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
4385 statement.clearParameters();
4386 statement.setLong(1, newObjId);
4389 if (0 != parentId) {
4390 long parentFs = this.getFileSystemId(parentId, connection);
4391 if (parentFs != -1) {
4392 statement.setLong(2, parentFs);
4394 statement.setNull(2, java.sql.Types.BIGINT);
4397 statement.setNull(2, java.sql.Types.BIGINT);
4401 statement.setString(3, directoryName);
4405 statement.setShort(5, (
short) 1);
4409 statement.setShort(6, dirType.
getValue());
4411 statement.setShort(7, metaType.
getValue());
4415 statement.setShort(8, dirFlag.
getValue());
4418 statement.setShort(9, metaFlags);
4421 statement.setLong(10, 0);
4424 statement.setNull(11, java.sql.Types.BIGINT);
4425 statement.setNull(12, java.sql.Types.BIGINT);
4426 statement.setNull(13, java.sql.Types.BIGINT);
4427 statement.setNull(14, java.sql.Types.BIGINT);
4430 statement.setString(15, parentPath);
4433 long dataSourceObjectId;
4434 if (0 == parentId) {
4435 dataSourceObjectId = newObjId;
4437 dataSourceObjectId = getDataSourceObjectId(connection, parentId);
4439 statement.setLong(16, dataSourceObjectId);
4442 statement.setString(17, null);
4443 connection.executeUpdate(statement);
4445 return new VirtualDirectory(
this, newObjId, dataSourceObjectId, directoryName, dirType,
4448 }
catch (SQLException e) {
4449 throw new TskCoreException(
"Error creating virtual directory '" + directoryName +
"'", e);
4451 closeResultSet(resultSet);
4475 }
catch (TskCoreException ex) {
4478 }
catch (TskCoreException ex2) {
4479 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
4505 if (transaction == null) {
4506 throw new TskCoreException(
"Passed null CaseDbTransaction");
4510 ResultSet resultSet = null;
4513 CaseDbConnection connection = transaction.getConnection();
4514 String parentPath = getFileParentPath(parentId, connection);
4515 if (parentPath == null) {
4518 String parentName = getFileName(parentId, connection);
4519 if (parentName != null && !parentName.isEmpty()) {
4520 parentPath = parentPath + parentName +
"/";
4525 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
4526 statement.clearParameters();
4527 if (parentId != 0) {
4528 statement.setLong(1, parentId);
4530 statement.setNull(1, java.sql.Types.BIGINT);
4533 connection.executeUpdate(statement);
4534 resultSet = statement.getGeneratedKeys();
4536 long newObjId = resultSet.getLong(1);
4542 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
4543 statement.clearParameters();
4544 statement.setLong(1, newObjId);
4547 statement.setNull(2, java.sql.Types.BIGINT);
4550 statement.setString(3, directoryName);
4554 statement.setShort(5, (
short) 1);
4558 statement.setShort(6, dirType.
getValue());
4560 statement.setShort(7, metaType.
getValue());
4564 statement.setShort(8, dirFlag.
getValue());
4567 statement.setShort(9, metaFlags);
4570 statement.setLong(10, 0);
4573 statement.setNull(11, java.sql.Types.BIGINT);
4574 statement.setNull(12, java.sql.Types.BIGINT);
4575 statement.setNull(13, java.sql.Types.BIGINT);
4576 statement.setNull(14, java.sql.Types.BIGINT);
4579 statement.setString(15, parentPath);
4582 long dataSourceObjectId = getDataSourceObjectId(connection, parentId);
4583 statement.setLong(16, dataSourceObjectId);
4586 statement.setString(17, null);
4588 connection.executeUpdate(statement);
4590 return new LocalDirectory(
this, newObjId, dataSourceObjectId, directoryName, dirType,
4593 }
catch (SQLException e) {
4594 throw new TskCoreException(
"Error creating local directory '" + directoryName +
"'", e);
4596 closeResultSet(resultSet);
4622 Statement statement = null;
4623 ResultSet resultSet = null;
4628 CaseDbConnection connection = transaction.getConnection();
4629 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
4630 preparedStatement.clearParameters();
4631 preparedStatement.setNull(1, java.sql.Types.BIGINT);
4633 connection.executeUpdate(preparedStatement);
4634 resultSet = preparedStatement.getGeneratedKeys();
4636 long newObjId = resultSet.getLong(1);
4642 statement = connection.createStatement();
4643 statement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone) "
4644 +
"VALUES(" + newObjId +
", '" + deviceId +
"', '" + timeZone +
"');");
4653 preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
4654 preparedStatement.clearParameters();
4655 preparedStatement.setLong(1, newObjId);
4656 preparedStatement.setNull(2, java.sql.Types.BIGINT);
4657 preparedStatement.setString(3, rootDirectoryName);
4659 preparedStatement.setShort(5, (
short) 1);
4663 preparedStatement.setShort(7, metaType.
getValue());
4665 preparedStatement.setShort(8, dirFlag.
getValue());
4668 preparedStatement.setShort(9, metaFlags);
4669 preparedStatement.setLong(10, 0);
4670 preparedStatement.setNull(11, java.sql.Types.BIGINT);
4671 preparedStatement.setNull(12, java.sql.Types.BIGINT);
4672 preparedStatement.setNull(13, java.sql.Types.BIGINT);
4673 preparedStatement.setNull(14, java.sql.Types.BIGINT);
4674 String parentPath =
"/";
4675 preparedStatement.setString(15, parentPath);
4676 preparedStatement.setLong(16, newObjId);
4677 preparedStatement.setString(17, null);
4678 connection.executeUpdate(preparedStatement);
4680 return new LocalFilesDataSource(
this, newObjId, newObjId, deviceId, rootDirectoryName, dirType, metaType, dirFlag, metaFlags, timeZone, null,
FileKnown.
UNKNOWN, parentPath);
4682 }
catch (SQLException ex) {
4683 throw new TskCoreException(String.format(
"Error creating local files data source with device id %s and directory name %s", deviceId, rootDirectoryName), ex);
4685 closeResultSet(resultSet);
4686 closeStatement(statement);
4700 CaseDbConnection connection = connections.getConnection();
4703 ResultSet rs = null;
4705 s = connection.createStatement();
4706 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE"
4708 +
" AND obj_id = data_source_obj_id"
4709 +
" ORDER BY dir_type, LOWER(name)");
4710 List<VirtualDirectory> virtDirRootIds =
new ArrayList<VirtualDirectory>();
4712 virtDirRootIds.add(virtualDirectory(rs));
4714 return virtDirRootIds;
4715 }
catch (SQLException ex) {
4716 throw new TskCoreException(
"Error getting local files virtual folder id", ex);
4738 assert (null != fileRanges);
4739 if (null == fileRanges) {
4740 throw new TskCoreException(
"TskFileRange object is null");
4743 assert (null != parent);
4744 if (null == parent) {
4745 throw new TskCoreException(
"Conent is null");
4749 Statement statement = null;
4750 ResultSet resultSet = null;
4755 CaseDbConnection connection = transaction.getConnection();
4757 List<LayoutFile> fileRangeLayoutFiles =
new ArrayList<LayoutFile>();
4764 PreparedStatement prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
4765 prepStmt.clearParameters();
4766 prepStmt.setLong(1, parent.getId());
4768 connection.executeUpdate(prepStmt);
4769 resultSet = prepStmt.getGeneratedKeys();
4771 long fileRangeId = resultSet.getLong(1);
4772 long end_byte_in_parent = fileRange.getByteStart() + fileRange.getByteLen() - 1;
4781 prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
4782 prepStmt.clearParameters();
4783 prepStmt.setLong(1, fileRangeId);
4784 prepStmt.setNull(2, java.sql.Types.BIGINT);
4785 prepStmt.setString(3,
"Unalloc_" + parent.getId() +
"_" + fileRange.getByteStart() +
"_" + end_byte_in_parent);
4787 prepStmt.setNull(5, java.sql.Types.BIGINT);
4792 prepStmt.setLong(10, fileRange.getByteLen());
4793 prepStmt.setNull(11, java.sql.Types.BIGINT);
4794 prepStmt.setNull(12, java.sql.Types.BIGINT);
4795 prepStmt.setNull(13, java.sql.Types.BIGINT);
4796 prepStmt.setNull(14, java.sql.Types.BIGINT);
4797 prepStmt.setNull(15, java.sql.Types.VARCHAR);
4798 prepStmt.setLong(16, parent.getId());
4801 prepStmt.setString(17, null);
4802 connection.executeUpdate(prepStmt);
4809 prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LAYOUT_FILE);
4810 prepStmt.clearParameters();
4811 prepStmt.setLong(1, fileRangeId);
4812 prepStmt.setLong(2, fileRange.getByteStart());
4813 prepStmt.setLong(3, fileRange.getByteLen());
4814 prepStmt.setLong(4, fileRange.getSequence());
4815 connection.executeUpdate(prepStmt);
4820 fileRangeLayoutFiles.add(
new LayoutFile(
this,
4823 Long.toString(fileRange.getSequence()),
4829 fileRange.getByteLen(),
4832 parent.getUniquePath(),
4837 return fileRangeLayoutFiles;
4839 }
catch (SQLException ex) {
4840 if (null != transaction) {
4843 }
catch (TskCoreException ex2) {
4844 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
4847 throw new TskCoreException(
"Failed to add layout files to case database", ex);
4849 }
catch (TskCoreException ex) {
4850 if (null != transaction) {
4853 }
catch (TskCoreException ex2) {
4854 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
4860 closeResultSet(resultSet);
4861 closeStatement(statement);
4878 assert (null != carvingResult);
4879 if (null == carvingResult) {
4880 throw new TskCoreException(
"Carving is null");
4882 assert (null != carvingResult.getParent());
4883 if (null == carvingResult.getParent()) {
4884 throw new TskCoreException(
"Carving result has null parent");
4886 assert (null != carvingResult.getCarvedFiles());
4887 if (null == carvingResult.getCarvedFiles()) {
4888 throw new TskCoreException(
"Carving result has null carved files");
4891 Statement statement = null;
4892 ResultSet resultSet = null;
4894 long newCacheKey = 0;
4897 CaseDbConnection connection = transaction.getConnection();
4906 while (null != root) {
4921 if (null == carvedFilesDir) {
4922 List<Content> rootChildren;
4924 rootChildren = ((FileSystem) root).getRootDirectory().
getChildren();
4928 for (
Content child : rootChildren) {
4934 if (null == carvedFilesDir) {
4935 long parId = root.
getId();
4937 if (root instanceof FileSystem) {
4938 Content rootDir = ((FileSystem) root).getRootDirectory();
4939 parId = rootDir.
getId();
4943 newCacheKey = root.
getId();
4944 rootIdsToCarvedFileDirs.put(newCacheKey, carvedFilesDir);
4951 String parentPath = getFileParentPath(carvedFilesDir.
getId(), connection) + carvedFilesDir.
getName() +
"/";
4952 List<LayoutFile> carvedFiles =
new ArrayList<LayoutFile>();
4958 PreparedStatement prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
4959 prepStmt.clearParameters();
4960 prepStmt.setLong(1, carvedFilesDir.
getId());
4962 connection.executeUpdate(prepStmt);
4963 resultSet = prepStmt.getGeneratedKeys();
4965 long carvedFileId = resultSet.getLong(1);
4975 prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
4976 prepStmt.clearParameters();
4977 prepStmt.setLong(1, carvedFileId);
4979 prepStmt.setLong(2, root.
getId());
4981 prepStmt.setNull(2, java.sql.Types.BIGINT);
4983 prepStmt.setString(3, carvedFile.getName());
4985 prepStmt.setShort(5, (
short) 1);
4990 prepStmt.setLong(10, carvedFile.getSizeInBytes());
4991 prepStmt.setNull(11, java.sql.Types.BIGINT);
4992 prepStmt.setNull(12, java.sql.Types.BIGINT);
4993 prepStmt.setNull(13, java.sql.Types.BIGINT);
4994 prepStmt.setNull(14, java.sql.Types.BIGINT);
4995 prepStmt.setString(15, parentPath);
4996 prepStmt.setLong(16, carvedFilesDir.getDataSourceObjectId());
4998 prepStmt.setString(17, extractExtension(carvedFile.getName()));
4999 connection.executeUpdate(prepStmt);
5006 prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LAYOUT_FILE);
5007 for (
TskFileRange tskFileRange : carvedFile.getLayoutInParent()) {
5008 prepStmt.clearParameters();
5009 prepStmt.setLong(1, carvedFileId);
5010 prepStmt.setLong(2, tskFileRange.getByteStart());
5011 prepStmt.setLong(3, tskFileRange.getByteLen());
5012 prepStmt.setLong(4, tskFileRange.getSequence());
5013 connection.executeUpdate(prepStmt);
5021 carvedFilesDir.getDataSourceObjectId(),
5022 carvedFile.getName(),
5028 carvedFile.getSizeInBytes(),
5038 }
catch (SQLException ex) {
5039 if (null != transaction) {
5042 }
catch (TskCoreException ex2) {
5043 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
5045 if (0 != newCacheKey) {
5046 rootIdsToCarvedFileDirs.remove(newCacheKey);
5049 throw new TskCoreException(
"Failed to add carved files to case database", ex);
5051 }
catch (TskCoreException ex) {
5052 if (null != transaction) {
5055 }
catch (TskCoreException ex2) {
5056 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
5058 if (0 != newCacheKey) {
5059 rootIdsToCarvedFileDirs.remove(newCacheKey);
5065 closeResultSet(resultSet);
5066 closeStatement(statement);
5102 long size,
long ctime,
long crtime,
long atime,
long mtime,
5103 boolean isFile,
Content parentObj,
5104 String rederiveDetails, String toolName, String toolVersion,
5106 CaseDbConnection connection = connections.getConnection();
5108 ResultSet rs = null;
5110 connection.beginTransaction();
5112 final long parentId = parentObj.
getId();
5113 String parentPath =
"";
5117 parentPath = ((AbstractFile) parentObj).getParentPath() + parentObj.
getName() +
'/';
5122 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
5123 statement.clearParameters();
5124 statement.setLong(1, parentId);
5126 connection.executeUpdate(statement);
5127 rs = statement.getGeneratedKeys();
5129 long newObjId = rs.getLong(1);
5137 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
5138 statement.clearParameters();
5139 statement.setLong(1, newObjId);
5142 long fsObjId = this.getFileSystemId(parentId, connection);
5143 if (fsObjId != -1) {
5144 statement.setLong(2, fsObjId);
5146 statement.setNull(2, java.sql.Types.BIGINT);
5148 statement.setString(3, fileName);
5152 statement.setShort(5, (
short) 1);
5156 statement.setShort(6, dirType.
getValue());
5158 statement.setShort(7, metaType.
getValue());
5162 statement.setShort(8, dirFlag.
getValue());
5165 statement.setShort(9, metaFlags);
5168 statement.setLong(10, size);
5172 statement.setLong(11, ctime);
5173 statement.setLong(12, crtime);
5174 statement.setLong(13, atime);
5175 statement.setLong(14, mtime);
5178 statement.setString(15, parentPath);
5181 long dataSourceObjId = getDataSourceObjectId(connection, parentId);
5182 statement.setLong(16, dataSourceObjId);
5183 final String extension = extractExtension(fileName);
5185 statement.setString(17, extension);
5187 connection.executeUpdate(statement);
5190 addFilePath(connection, newObjId, localPath, encodingType);
5192 connection.commitTransaction();
5195 return new DerivedFile(
this, newObjId, dataSourceObjId, fileName, dirType, metaType, dirFlag, metaFlags,
5196 size, ctime, crtime, atime, mtime, null, null, parentPath, localPath, parentId, null, encodingType, extension);
5197 }
catch (SQLException ex) {
5198 connection.rollbackTransaction();
5199 throw new TskCoreException(
"Failed to add derived file to case database", ex);
5227 long size,
long ctime,
long crtime,
long atime,
long mtime,
5233 LocalFile created =
addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime, isFile, encodingType, parent, localTrans);
5236 }
catch (TskCoreException ex) {
5239 }
catch (TskCoreException ex2) {
5240 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
5273 long size,
long ctime,
long crtime,
long atime,
long mtime,
5277 CaseDbConnection connection = transaction.getConnection();
5279 Statement queryStatement = null;
5280 ResultSet resultSet = null;
5285 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
5286 statement.clearParameters();
5287 statement.setLong(1, parent.getId());
5289 connection.executeUpdate(statement);
5290 resultSet = statement.getGeneratedKeys();
5291 if (!resultSet.next()) {
5292 throw new TskCoreException(String.format(
"Failed to INSERT local file %s (%s) with parent id %d in tsk_objects table", fileName, localPath, parent.getId()));
5294 long objectId = resultSet.getLong(1);
5302 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
5303 statement.clearParameters();
5304 statement.setLong(1, objectId);
5305 statement.setNull(2, java.sql.Types.BIGINT);
5306 statement.setString(3, fileName);
5308 statement.setShort(5, (
short) 1);
5310 statement.setShort(6, dirType.
getValue());
5312 statement.setShort(7, metaType.
getValue());
5314 statement.setShort(8, dirFlag.
getValue());
5316 statement.setShort(9, metaFlags);
5317 statement.setLong(10, size);
5318 statement.setLong(11, ctime);
5319 statement.setLong(12, crtime);
5320 statement.setLong(13, atime);
5321 statement.setLong(14, mtime);
5322 String parentPath = parent.getParentPath() + parent.getName() +
"/";
5323 statement.setString(15, parentPath);
5324 long dataSourceObjId = getDataSourceObjectId(connection, parent.getId());
5325 statement.setLong(16, dataSourceObjId);
5326 final String extension = extractExtension(fileName);
5327 statement.setString(17, extension);
5329 connection.executeUpdate(statement);
5330 addFilePath(connection, objectId, localPath, encodingType);
5340 ctime, crtime, atime, mtime,
5342 parent.getId(), parentPath,
5345 encodingType, extension);
5347 }
catch (SQLException ex) {
5348 throw new TskCoreException(String.format(
"Failed to INSERT local file %s (%s) with parent id %d in tsk_files table", fileName, localPath, parent.getId()), ex);
5350 closeResultSet(resultSet);
5351 closeStatement(queryStatement);
5368 private long getDataSourceObjectId(CaseDbConnection connection,
long objectId)
throws TskCoreException {
5370 Statement statement = null;
5371 ResultSet resultSet = null;
5373 statement = connection.createStatement();
5374 long dataSourceObjId;
5375 long ancestorId = objectId;
5377 dataSourceObjId = ancestorId;
5378 String query = String.format(
"SELECT par_obj_id FROM tsk_objects WHERE obj_id = %s;", ancestorId);
5379 resultSet = statement.executeQuery(query);
5380 if (resultSet.next()) {
5381 ancestorId = resultSet.getLong(
"par_obj_id");
5383 throw new TskCoreException(String.format(
"tsk_objects table is corrupt, SQL query returned no result: %s", query));
5387 }
while (0 != ancestorId);
5388 return dataSourceObjId;
5389 }
catch (SQLException ex) {
5390 throw new TskCoreException(String.format(
"Error finding root data source for object (obj_id = %d)", objectId), ex);
5392 closeResultSet(resultSet);
5393 closeStatement(statement);
5409 private void addFilePath(CaseDbConnection connection,
long objId, String path, TskData.EncodingType type) throws SQLException {
5410 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LOCAL_PATH);
5411 statement.clearParameters();
5412 statement.setLong(1, objId);
5413 statement.setString(2, path);
5414 statement.setInt(3, type.getType());
5415 connection.executeUpdate(statement);
5434 return findFiles(dataSource, fileName, parentFile.getName());
5449 CaseDbConnection connection = connections.getConnection();
5452 ResultSet rs = null;
5454 s = connection.createStatement();
5455 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files WHERE " + sqlWhereClause);
5457 return rs.getLong(
"count");
5458 }
catch (SQLException e) {
5459 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.countFilesWhere().", e);
5486 CaseDbConnection connection = connections.getConnection();
5489 ResultSet rs = null;
5491 s = connection.createStatement();
5492 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE " + sqlWhereClause);
5493 return resultSetToAbstractFiles(rs, connection);
5494 }
catch (SQLException e) {
5495 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findAllFilesWhere(): " + sqlWhereClause, e);
5517 CaseDbConnection connection = connections.getConnection();
5520 ResultSet rs = null;
5522 s = connection.createStatement();
5523 rs = connection.executeQuery(s,
"SELECT obj_id FROM tsk_files WHERE " + sqlWhereClause);
5524 List<Long> ret =
new ArrayList<Long>();
5526 ret.add(rs.getLong(
"obj_id"));
5529 }
catch (SQLException e) {
5530 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findAllFileIdsWhere(): " + sqlWhereClause, e);
5550 public List<AbstractFile>
openFiles(
Content dataSource, String filePath)
throws TskCoreException {
5557 int lastSlash = path.lastIndexOf(
'/');
5560 if (lastSlash == path.length()) {
5561 path = path.substring(0, lastSlash - 1);
5562 lastSlash = path.lastIndexOf(
'/');
5565 String parentPath = path.substring(0, lastSlash);
5566 String fileName = path.substring(lastSlash);
5568 return findFiles(dataSource, fileName, parentPath);
5582 CaseDbConnection connection = connections.getConnection();
5585 ResultSet rs = null;
5587 s = connection.createStatement();
5588 rs = connection.executeQuery(s,
"SELECT * FROM tsk_file_layout WHERE obj_id = " +
id +
" ORDER BY sequence");
5589 List<TskFileRange> ranges =
new ArrayList<TskFileRange>();
5592 rs.getLong(
"byte_len"), rs.getLong(
"sequence"));
5596 }
catch (SQLException ex) {
5597 throw new TskCoreException(
"Error getting TskFileLayoutRanges by id, id = " +
id, ex);
5617 CaseDbConnection connection = connections.getConnection();
5619 Statement s1 = null;
5620 ResultSet rs1 = null;
5621 Statement s2 = null;
5622 ResultSet rs2 = null;
5624 s1 = connection.createStatement();
5625 rs1 = connection.executeQuery(s1,
"SELECT tsk_image_info.type, tsk_image_info.ssize, tsk_image_info.tzone, tsk_image_info.size, tsk_image_info.md5, tsk_image_info.display_name, data_source_info.device_id "
5626 +
"FROM tsk_image_info "
5627 +
"INNER JOIN data_source_info ON tsk_image_info.obj_id = data_source_info.obj_id "
5628 +
"WHERE tsk_image_info.obj_id = " +
id);
5630 s2 = connection.createStatement();
5631 rs2 = connection.executeQuery(s2,
"SELECT name FROM tsk_image_names WHERE tsk_image_names.obj_id = " +
id);
5632 List<String> imagePaths =
new ArrayList<String>();
5633 while (rs2.next()) {
5634 imagePaths.add(rs2.getString(
"name"));
5636 long type = rs1.getLong(
"type");
5637 long ssize = rs1.getLong(
"ssize");
5638 String tzone = rs1.getString(
"tzone");
5639 long size = rs1.getLong(
"size");
5640 String md5 = rs1.getString(
"md5");
5641 String name = rs1.getString(
"display_name");
5643 if (imagePaths.size() > 0) {
5644 String path = imagePaths.get(0);
5645 name = (
new java.io.File(path)).getName();
5650 String device_id = rs1.getString(
"device_id");
5652 return new Image(
this,
id, type, device_id, ssize, name,
5653 imagePaths.toArray(
new String[imagePaths.size()]), tzone, md5, size);
5655 throw new TskCoreException(
"No image found for id: " +
id);
5657 }
catch (SQLException ex) {
5658 throw new TskCoreException(
"Error getting Image by id, id = " +
id, ex);
5660 closeResultSet(rs2);
5662 closeResultSet(rs1);
5680 VolumeSystem getVolumeSystemById(
long id,
Image parent)
throws TskCoreException {
5681 CaseDbConnection connection = connections.getConnection();
5684 ResultSet rs = null;
5686 s = connection.createStatement();
5687 rs = connection.executeQuery(s,
"SELECT * FROM tsk_vs_info "
5688 +
"where obj_id = " +
id);
5690 long type = rs.getLong(
"vs_type");
5691 long imgOffset = rs.getLong(
"img_offset");
5692 long blockSize = rs.getLong(
"block_size");
5694 vs.setParent(parent);
5697 throw new TskCoreException(
"No volume system found for id:" +
id);
5699 }
catch (SQLException ex) {
5700 throw new TskCoreException(
"Error getting Volume System by ID.", ex);
5717 VolumeSystem getVolumeSystemById(
long id,
long parentId)
throws TskCoreException {
5718 VolumeSystem vs = getVolumeSystemById(
id, null);
5719 vs.setParentId(parentId);
5734 FileSystem getFileSystemById(
long id, Image parent)
throws TskCoreException {
5735 return getFileSystemByIdHelper(
id, parent);
5746 FileSystem getFileSystemById(
long id,
long parentId)
throws TskCoreException {
5748 FileSystem fs = getFileSystemById(
id, vol);
5749 fs.setParentId(parentId);
5764 FileSystem getFileSystemById(
long id, Volume parent)
throws TskCoreException {
5765 return getFileSystemByIdHelper(
id, parent);
5779 private FileSystem getFileSystemByIdHelper(
long id, Content parent)
throws TskCoreException {
5783 synchronized (fileSystemIdMap) {
5784 if (fileSystemIdMap.containsKey(
id)) {
5785 return fileSystemIdMap.get(
id);
5788 CaseDbConnection connection = connections.getConnection();
5791 ResultSet rs = null;
5793 s = connection.createStatement();
5794 rs = connection.executeQuery(s,
"SELECT * FROM tsk_fs_info "
5795 +
"where obj_id = " +
id);
5797 TskData.TSK_FS_TYPE_ENUM fsType = TskData.TSK_FS_TYPE_ENUM.valueOf(rs.getInt(
"fs_type"));
5798 FileSystem fs =
new FileSystem(
this, rs.getLong(
"obj_id"),
"", rs.getLong(
"img_offset"),
5799 fsType, rs.getLong(
"block_size"), rs.getLong(
"block_count"),
5800 rs.getLong(
"root_inum"), rs.getLong(
"first_inum"), rs.getLong(
"last_inum"));
5801 fs.setParent(parent);
5803 synchronized (fileSystemIdMap) {
5804 fileSystemIdMap.put(
id, fs);
5808 throw new TskCoreException(
"No file system found for id:" +
id);
5810 }
catch (SQLException ex) {
5811 throw new TskCoreException(
"Error getting File System by ID", ex);
5831 Volume getVolumeById(
long id, VolumeSystem parent)
throws TskCoreException {
5832 CaseDbConnection connection = connections.getConnection();
5835 ResultSet rs = null;
5837 s = connection.createStatement();
5838 rs = connection.executeQuery(s,
"SELECT * FROM tsk_vs_parts "
5839 +
"where obj_id = " +
id);
5850 description = rs.getString(
"desc");
5851 }
catch (Exception ex) {
5852 description = rs.getString(
"descr");
5854 Volume vol =
new Volume(
this, rs.getLong(
"obj_id"), rs.getLong(
"addr"),
5855 rs.getLong(
"start"), rs.getLong(
"length"), rs.getLong(
"flags"),
5857 vol.setParent(parent);
5860 throw new TskCoreException(
"No volume found for id:" +
id);
5862 }
catch (SQLException ex) {
5863 throw new TskCoreException(
"Error getting Volume by ID", ex);
5880 Volume getVolumeById(
long id,
long parentId)
throws TskCoreException {
5881 Volume vol = getVolumeById(
id, null);
5882 vol.setParentId(parentId);
5897 Directory getDirectoryById(
long id, FileSystem parentFs)
throws TskCoreException {
5898 CaseDbConnection connection = connections.getConnection();
5901 ResultSet rs = null;
5903 s = connection.createStatement();
5904 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files "
5905 +
"WHERE obj_id = " +
id);
5906 Directory temp = null;
5908 final short type = rs.getShort(
"type");
5909 if (type == TSK_DB_FILES_TYPE_ENUM.FS.getFileType()) {
5910 if (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
5911 || rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()) {
5912 temp = directory(rs, parentFs);
5914 }
else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()) {
5915 throw new TskCoreException(
"Expecting an FS-type directory, got virtual, id: " +
id);
5918 throw new TskCoreException(
"No Directory found for id:" +
id);
5921 }
catch (SQLException ex) {
5922 throw new TskCoreException(
"Error getting Directory by ID", ex);
5939 List<FileSystem> fileSystems =
new ArrayList<FileSystem>();
5940 CaseDbConnection connection;
5942 connection = connections.getConnection();
5943 }
catch (TskCoreException ex) {
5944 logger.log(Level.SEVERE,
"Error getting file systems for image " + image.
getId(), ex);
5949 ResultSet rs = null;
5951 s = connection.createStatement();
5954 List<FileSystem> allFileSystems =
new ArrayList<FileSystem>();
5956 rs = connection.executeQuery(s,
"SELECT * FROM tsk_fs_info");
5960 fsType, rs.getLong(
"block_size"), rs.getLong(
"block_count"),
5961 rs.getLong(
"root_inum"), rs.getLong(
"first_inum"), rs.getLong(
"last_inum"));
5963 allFileSystems.add(fs);
5965 }
catch (SQLException ex) {
5966 logger.log(Level.SEVERE,
"There was a problem while trying to obtain all file systems", ex);
5976 Long imageID = null;
5977 Long currentObjID = fs.getId();
5978 while (imageID == null) {
5980 rs = connection.executeQuery(s,
"SELECT * FROM tsk_objects WHERE tsk_objects.obj_id = " + currentObjID);
5982 currentObjID = rs.getLong(
"par_obj_id");
5984 imageID = rs.getLong(
"obj_id");
5986 }
catch (SQLException ex) {
5987 logger.log(Level.SEVERE,
"There was a problem while trying to obtain this image's file systems", ex);
5995 if (imageID == image.
getId()) {
5996 fileSystems.add(fs);
5999 }
catch (SQLException ex) {
6000 logger.log(Level.SEVERE,
"Error getting case database connection", ex);
6020 List<Content> getImageChildren(
Image img)
throws TskCoreException {
6021 Collection<ObjectInfo> childInfos = getChildrenInfo(img);
6022 List<Content> children =
new ArrayList<Content>();
6023 for (ObjectInfo info : childInfos) {
6024 if (null != info.type) {
6025 switch (info.type) {
6027 children.add(getVolumeSystemById(info.id, img));
6030 children.add(getFileSystemById(info.id, img));
6045 throw new TskCoreException(
"Image has child of invalid type: " + info.type);
6062 List<Long> getImageChildrenIds(Image img)
throws TskCoreException {
6063 Collection<ObjectInfo> childInfos = getChildrenInfo(img);
6064 List<Long> children =
new ArrayList<Long>();
6065 for (ObjectInfo info : childInfos) {
6066 if (info.type == ObjectType.VS
6067 || info.type == ObjectType.FS
6068 || info.type == ObjectType.ABSTRACTFILE
6069 || info.type == ObjectType.ARTIFACT) {
6070 children.add(info.id);
6072 throw new TskCoreException(
"Image has child of invalid type: " + info.type);
6088 List<Content> getVolumeSystemChildren(VolumeSystem vs)
throws TskCoreException {
6089 Collection<ObjectInfo> childInfos = getChildrenInfo(vs);
6090 List<Content> children =
new ArrayList<Content>();
6091 for (ObjectInfo info : childInfos) {
6092 if (null != info.type) {
6093 switch (info.type) {
6095 children.add(getVolumeById(info.id, vs));
6110 throw new TskCoreException(
"VolumeSystem has child of invalid type: " + info.type);
6127 List<Long> getVolumeSystemChildrenIds(VolumeSystem vs)
throws TskCoreException {
6128 Collection<ObjectInfo> childInfos = getChildrenInfo(vs);
6129 List<Long> children =
new ArrayList<Long>();
6130 for (ObjectInfo info : childInfos) {
6131 if (info.type == ObjectType.VOL || info.type == ObjectType.ABSTRACTFILE || info.type == ObjectType.ARTIFACT) {
6132 children.add(info.id);
6134 throw new TskCoreException(
"VolumeSystem has child of invalid type: " + info.type);
6150 List<Content> getVolumeChildren(Volume vol)
throws TskCoreException {
6151 Collection<ObjectInfo> childInfos = getChildrenInfo(vol);
6152 List<Content> children =
new ArrayList<Content>();
6153 for (ObjectInfo info : childInfos) {
6154 if (null != info.type) {
6155 switch (info.type) {
6157 children.add(getFileSystemById(info.id, vol));
6172 throw new TskCoreException(
"Volume has child of invalid type: " + info.type);
6189 List<Long> getVolumeChildrenIds(Volume vol)
throws TskCoreException {
6190 final Collection<ObjectInfo> childInfos = getChildrenInfo(vol);
6191 final List<Long> children =
new ArrayList<Long>();
6192 for (ObjectInfo info : childInfos) {
6193 if (info.type == ObjectType.FS || info.type == ObjectType.ABSTRACTFILE || info.type == ObjectType.ARTIFACT) {
6194 children.add(info.id);
6196 throw new TskCoreException(
"Volume has child of invalid type: " + info.type);
6215 public Image addImageInfo(
long deviceObjId, List<String> imageFilePaths, String timeZone)
throws TskCoreException {
6216 long imageId = this.caseHandle.addImageInfo(deviceObjId, imageFilePaths, timeZone);
6230 CaseDbConnection connection = connections.getConnection();
6232 Statement s1 = null;
6233 Statement s2 = null;
6234 ResultSet rs1 = null;
6235 ResultSet rs2 = null;
6237 s1 = connection.createStatement();
6238 rs1 = connection.executeQuery(s1,
"SELECT obj_id FROM tsk_image_info");
6239 s2 = connection.createStatement();
6240 Map<Long, List<String>> imgPaths =
new LinkedHashMap<Long, List<String>>();
6241 while (rs1.next()) {
6242 long obj_id = rs1.getLong(
"obj_id");
6243 rs2 = connection.executeQuery(s2,
"SELECT * FROM tsk_image_names WHERE obj_id = " + obj_id);
6244 List<String> paths =
new ArrayList<String>();
6245 while (rs2.next()) {
6246 paths.add(rs2.getString(
"name"));
6250 imgPaths.put(obj_id, paths);
6253 }
catch (SQLException ex) {
6254 throw new TskCoreException(
"Error getting image paths.", ex);
6256 closeResultSet(rs2);
6258 closeResultSet(rs1);
6275 private List<String> getImagePathsById(
long objectId)
throws TskCoreException {
6276 List<String> imagePaths =
new ArrayList<String>();
6277 CaseDbConnection connection = connections.getConnection();
6279 Statement statement = null;
6280 ResultSet resultSet = null;
6282 statement = connection.createStatement();
6283 resultSet = connection.executeQuery(statement,
"SELECT name FROM tsk_image_names WHERE tsk_image_names.obj_id = " + objectId);
6284 while (resultSet.next()) {
6285 imagePaths.add(resultSet.getString(
"name"));
6287 }
catch (SQLException ex) {
6288 throw new TskCoreException(String.format(
"Error getting image names with obj_id = %d", objectId), ex);
6290 closeResultSet(resultSet);
6291 closeStatement(statement);
6306 CaseDbConnection connection = connections.getConnection();
6309 ResultSet rs = null;
6311 s = connection.createStatement();
6312 rs = connection.executeQuery(s,
"SELECT obj_id FROM tsk_image_info");
6313 Collection<Long> imageIDs =
new ArrayList<Long>();
6315 imageIDs.add(rs.getLong(
"obj_id"));
6317 List<Image> images =
new ArrayList<Image>();
6318 for (
long id : imageIDs) {
6322 }
catch (SQLException ex) {
6323 throw new TskCoreException(
"Error retrieving images.", ex);
6342 public void setImagePaths(
long obj_id, List<String> paths)
throws TskCoreException {
6343 CaseDbConnection connection = connections.getConnection();
6345 Statement statement = null;
6347 connection.beginTransaction();
6348 statement = connection.createStatement();
6349 connection.executeUpdate(statement,
"DELETE FROM tsk_image_names WHERE obj_id = " + obj_id);
6350 for (
int i = 0; i < paths.size(); i++) {
6351 connection.executeUpdate(statement,
"INSERT INTO tsk_image_names VALUES (" + obj_id +
", '" + paths.get(i) +
"', " + i +
")");
6353 connection.commitTransaction();
6354 }
catch (SQLException ex) {
6355 connection.rollbackTransaction();
6356 throw new TskCoreException(
"Error updating image paths.", ex);
6358 closeStatement(statement);
6389 private List<AbstractFile> resultSetToAbstractFiles(ResultSet rs, CaseDbConnection connection)
throws SQLException {
6390 ArrayList<AbstractFile> results =
new ArrayList<AbstractFile>();
6393 final short type = rs.getShort(
"type");
6398 result = directory(rs, null);
6400 result = file(rs, null);
6402 results.add(result);
6403 }
else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
6404 || (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue())) {
6405 final VirtualDirectory virtDir = virtualDirectory(rs);
6406 results.add(virtDir);
6407 }
else if (type == TSK_DB_FILES_TYPE_ENUM.LOCAL_DIR.getFileType()) {
6408 final LocalDirectory localDir = localDirectory(rs);
6409 results.add(localDir);
6410 }
else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
6411 || type == TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
6412 || type == TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()) {
6413 TSK_DB_FILES_TYPE_ENUM atype = TSK_DB_FILES_TYPE_ENUM.valueOf(type);
6414 String parentPath = rs.getString(
"parent_path");
6415 if (parentPath == null) {
6418 LayoutFile lf =
new LayoutFile(
this,
6419 rs.getLong(
"obj_id"),
6420 rs.getLong(
"data_source_obj_id"),
6421 rs.getString(
"name"),
6423 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")), TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6424 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
6426 rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")), parentPath, rs.getString(
"mime_type"));
6428 }
else if (type == TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()) {
6429 final DerivedFile df;
6430 df = derivedFile(rs, connection, AbstractContent.UNKNOWN_ID);
6432 }
else if (type == TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()) {
6434 lf = localFile(rs, connection, AbstractContent.UNKNOWN_ID);
6436 }
else if (type == TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()) {
6437 final SlackFile sf = slackFile(rs, null);
6441 }
catch (SQLException e) {
6442 logger.log(Level.SEVERE,
"Error getting abstract files from result set", e);
6462 rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
6463 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
6464 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
6465 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6466 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6467 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
6468 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
6469 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
6470 (short) rs.getInt(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
6471 rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")),
6472 rs.getString(
"parent_path"), rs.getString(
"mime_type"), rs.getString(
"extension"));
6473 f.setFileSystem(fs);
6488 Directory directory(ResultSet rs, FileSystem fs)
throws SQLException {
6489 Directory dir =
new Directory(
this, rs.getLong(
"obj_id"), rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
6490 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
6491 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
6492 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6493 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6494 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
6495 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
6496 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
6497 rs.getShort(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
6498 rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")),
6499 rs.getString(
"parent_path"));
6500 dir.setFileSystem(fs);
6513 VirtualDirectory virtualDirectory(ResultSet rs)
throws SQLException {
6514 String parentPath = rs.getString(
"parent_path");
6515 if (parentPath == null) {
6518 final VirtualDirectory vd =
new VirtualDirectory(
this, rs.getLong(
"obj_id"),
6519 rs.getLong(
"data_source_obj_id"), rs.getString(
"name"),
6520 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6521 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6522 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
6523 rs.getShort(
"meta_flags"), rs.getString(
"md5"),
6524 FileKnown.valueOf(rs.getByte(
"known")), parentPath);
6537 LocalDirectory localDirectory(ResultSet rs)
throws SQLException {
6538 String parentPath = rs.getString(
"parent_path");
6539 if (parentPath == null) {
6542 final LocalDirectory ld =
new LocalDirectory(
this, rs.getLong(
"obj_id"),
6543 rs.getLong(
"data_source_obj_id"), rs.getString(
"name"),
6544 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6545 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6546 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
6547 rs.getShort(
"meta_flags"), rs.getString(
"md5"),
6548 FileKnown.valueOf(rs.getByte(
"known")), parentPath);
6565 private DerivedFile derivedFile(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
6566 boolean hasLocalPath = rs.getBoolean(
"has_path");
6567 long objId = rs.getLong(
"obj_id");
6568 String localPath = null;
6569 TskData.EncodingType encodingType = TskData.EncodingType.NONE;
6571 ResultSet rsFilePath = null;
6574 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_LOCAL_PATH_AND_ENCODING_FOR_FILE);
6575 statement.clearParameters();
6576 statement.setLong(1, objId);
6577 rsFilePath = connection.executeQuery(statement);
6578 if (rsFilePath.next()) {
6579 localPath = rsFilePath.getString(
"path");
6580 encodingType = TskData.EncodingType.valueOf(rsFilePath.getInt(
"encoding_type"));
6582 }
catch (SQLException ex) {
6583 logger.log(Level.SEVERE,
"Error getting encoding type for file " + objId, ex);
6585 closeResultSet(rsFilePath);
6589 String parentPath = rs.getString(
"parent_path");
6590 if (parentPath == null) {
6593 final DerivedFile df =
new DerivedFile(
this, objId, rs.getLong(
"data_source_obj_id"),
6594 rs.getString(
"name"),
6595 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6596 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6597 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
6599 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
6600 rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")),
6601 parentPath, localPath, parentId, rs.getString(
"mime_type"),
6602 encodingType, rs.getString(
"extension"));
6619 private LocalFile localFile(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
6620 long objId = rs.getLong(
"obj_id");
6621 String localPath = null;
6622 TskData.EncodingType encodingType = TskData.EncodingType.NONE;
6623 if (rs.getBoolean(
"has_path")) {
6624 ResultSet rsFilePath = null;
6627 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_LOCAL_PATH_AND_ENCODING_FOR_FILE);
6628 statement.clearParameters();
6629 statement.setLong(1, objId);
6630 rsFilePath = connection.executeQuery(statement);
6631 if (rsFilePath.next()) {
6632 localPath = rsFilePath.getString(
"path");
6633 encodingType = TskData.EncodingType.valueOf(rsFilePath.getInt(
"encoding_type"));
6635 }
catch (SQLException ex) {
6636 logger.log(Level.SEVERE,
"Error getting encoding type for file " + objId, ex);
6638 closeResultSet(rsFilePath);
6642 String parentPath = rs.getString(
"parent_path");
6643 if (null == parentPath) {
6646 LocalFile file =
new LocalFile(
this, objId, rs.getString(
"name"),
6647 TSK_DB_FILES_TYPE_ENUM.valueOf(rs.getShort(
"type")),
6648 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6649 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6650 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
6652 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
6653 rs.getString(
"mime_type"), rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")),
6654 parentId, parentPath, rs.getLong(
"data_source_obj_id"),
6655 localPath, encodingType, rs.getString(
"extension"));
6672 rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
6673 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
6674 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
6675 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6676 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6677 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
6678 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
6679 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
6680 (short) rs.getInt(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
6681 rs.getString(
"md5"), FileKnown.valueOf(rs.getByte(
"known")),
6682 rs.getString(
"parent_path"), rs.getString(
"mime_type"), rs.getString(
"extension"));
6683 f.setFileSystem(fs);
6698 List<Content> fileChildren(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
6699 List<Content> children =
new ArrayList<Content>();
6702 TskData.TSK_DB_FILES_TYPE_ENUM type = TskData.TSK_DB_FILES_TYPE_ENUM.valueOf(rs.getShort(
"type"));
6707 if (rs.getShort(
"meta_type") != TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()) {
6709 if (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()) {
6710 result = directory(rs, null);
6712 result = file(rs, null);
6714 children.add(result);
6716 VirtualDirectory virtDir = virtualDirectory(rs);
6717 children.add(virtDir);
6721 VirtualDirectory virtDir = virtualDirectory(rs);
6722 children.add(virtDir);
6725 LocalDirectory localDir = localDirectory(rs);
6726 children.add(localDir);
6728 case UNALLOC_BLOCKS:
6731 String parentPath = rs.getString(
"parent_path");
6732 if (parentPath == null) {
6735 final LayoutFile lf =
new LayoutFile(
this, rs.getLong(
"obj_id"),
6736 rs.getLong(
"data_source_obj_id"), rs.getString(
"name"), type,
6737 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
6738 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
6739 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
6740 rs.getLong(
"size"), rs.getString(
"md5"),
6741 FileKnown.valueOf(rs.getByte(
"known")), parentPath, rs.getString(
"mime_type"));
6746 final DerivedFile df = derivedFile(rs, connection, parentId);
6750 final LocalFile lf = localFile(rs, connection, parentId);
6755 final SlackFile sf = slackFile(rs, null);
6780 private List<BlackboardArtifact> resultSetToArtifacts(ResultSet rs)
throws SQLException {
6781 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<BlackboardArtifact>();
6784 artifacts.add(
new BlackboardArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"), rs.getLong(
"artifact_obj_id"), rs.getLong(
"data_source_obj_id"),
6785 rs.getInt(
"artifact_type_id"), BlackboardArtifact.ARTIFACT_TYPE.fromID(rs.getInt(
"artifact_type_id")).getLabel(), BlackboardArtifact.ARTIFACT_TYPE.fromID(rs.getInt(
"artifact_type_id")).getDisplayName(),
6786 BlackboardArtifact.ReviewStatus.withID(rs.getInt(
"review_status_id"))));
6788 }
catch (SQLException e) {
6789 logger.log(Level.SEVERE,
"Error getting artifacts from result set", e);
6852 CaseDbConnection getConnection() throws TskCoreException {
6853 return connections.getConnection();
6872 connections.close();
6873 }
catch (TskCoreException ex) {
6874 logger.log(Level.SEVERE,
"Error closing database connection pool.", ex);
6877 fileSystemIdMap.clear();
6880 if (this.caseHandle != null) {
6881 this.caseHandle.free();
6882 this.caseHandle = null;
6884 }
catch (TskCoreException ex) {
6885 logger.log(Level.SEVERE,
"Error freeing case handle.", ex);
6904 long id = file.getId();
6905 FileKnown currentKnown = file.getKnown();
6906 if (currentKnown.compareTo(fileKnown) > 0) {
6909 CaseDbConnection connection = connections.getConnection();
6911 Statement statement = null;
6913 statement = connection.createStatement();
6914 connection.executeUpdate(statement,
"UPDATE tsk_files "
6915 +
"SET known='" + fileKnown.getFileKnownValue() +
"' "
6916 +
"WHERE obj_id=" + id);
6917 file.setKnown(fileKnown);
6918 }
catch (SQLException ex) {
6919 throw new TskCoreException(
"Error setting Known status.", ex);
6921 closeStatement(statement);
6938 CaseDbConnection connection = connections.getConnection();
6939 Statement statement = null;
6940 ResultSet rs = null;
6943 statement = connection.createStatement();
6944 connection.executeUpdate(statement, String.format(
"UPDATE tsk_files SET mime_type = '%s' WHERE obj_id = %d", mimeType, file.getId()));
6945 file.setMIMEType(mimeType);
6946 }
catch (SQLException ex) {
6947 throw new TskCoreException(String.format(
"Error setting MIME type for file (obj_id = %s)", file.getId()), ex);
6950 closeStatement(statement);
6965 void setMd5Hash(
AbstractFile file, String md5Hash)
throws TskCoreException {
6966 if (md5Hash == null) {
6969 long id = file.getId();
6970 CaseDbConnection connection = connections.getConnection();
6973 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.UPDATE_FILE_MD5);
6974 statement.clearParameters();
6975 statement.setString(1, md5Hash.toLowerCase());
6976 statement.setLong(2,
id);
6977 connection.executeUpdate(statement);
6978 file.setMd5Hash(md5Hash.toLowerCase());
6979 }
catch (SQLException ex) {
6980 throw new TskCoreException(
"Error setting MD5 hash", ex);
6998 if (newStatus == null) {
7001 CaseDbConnection connection = connections.getConnection();
7003 Statement statement = null;
7005 statement = connection.createStatement();
7006 connection.executeUpdate(statement,
"UPDATE blackboard_artifacts "
7007 +
" SET review_status_id=" + newStatus.getID()
7008 +
" WHERE blackboard_artifacts.artifact_id = " + artifact.
getArtifactID());
7009 }
catch (SQLException ex) {
7010 throw new TskCoreException(
"Error setting review status", ex);
7012 closeStatement(statement);
7029 CaseDbConnection connection = connections.getConnection();
7032 ResultSet rs = null;
7034 s = connection.createStatement();
7035 Short contentShort = contentType.getValue();
7036 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files WHERE meta_type = '" + contentShort.toString() +
"'");
7039 count = rs.getInt(
"count");
7042 }
catch (SQLException ex) {
7043 throw new TskCoreException(
"Error getting number of objects.", ex);
7061 String escapedText = null;
7063 escapedText = text.replaceAll(
"'",
"''");
7076 if (md5Hash == null) {
7079 CaseDbConnection connection;
7081 connection = connections.getConnection();
7082 }
catch (TskCoreException ex) {
7083 logger.log(Level.SEVERE,
"Error finding files by md5 hash " + md5Hash, ex);
7088 ResultSet rs = null;
7090 s = connection.createStatement();
7091 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE "
7092 +
" md5 = '" + md5Hash.toLowerCase() +
"' "
7094 return resultSetToAbstractFiles(rs, connection);
7095 }
catch (SQLException ex) {
7096 logger.log(Level.WARNING,
"Error querying database.", ex);
7113 CaseDbConnection connection;
7115 connection = connections.getConnection();
7116 }
catch (TskCoreException ex) {
7117 logger.log(Level.SEVERE,
"Error checking md5 hashing status", ex);
7120 boolean allFilesAreHashed =
false;
7123 ResultSet rs = null;
7125 s = connection.createStatement();
7126 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files "
7128 +
"AND md5 IS NULL "
7129 +
"AND size > '0'");
7130 if (rs.next() && rs.getInt(
"count") == 0) {
7131 allFilesAreHashed =
true;
7133 }
catch (SQLException ex) {
7134 logger.log(Level.WARNING,
"Failed to query whether all files have MD5 hashes", ex);
7141 return allFilesAreHashed;
7150 CaseDbConnection connection;
7152 connection = connections.getConnection();
7153 }
catch (TskCoreException ex) {
7154 logger.log(Level.SEVERE,
"Error getting database connection for hashed files count", ex);
7160 ResultSet rs = null;
7162 s = connection.createStatement();
7163 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files "
7164 +
"WHERE md5 IS NOT NULL "
7165 +
"AND size > '0'");
7167 count = rs.getInt(
"count");
7169 }
catch (SQLException ex) {
7170 logger.log(Level.WARNING,
"Failed to query for all the files.", ex);
7190 CaseDbConnection connection = connections.getConnection();
7192 ResultSet resultSet = null;
7195 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_TAG_NAMES);
7196 resultSet = connection.executeQuery(statement);
7197 ArrayList<TagName> tagNames =
new ArrayList<TagName>();
7198 while (resultSet.next()) {
7199 tagNames.add(
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7204 }
catch (SQLException ex) {
7205 throw new TskCoreException(
"Error selecting rows from tag_names table", ex);
7207 closeResultSet(resultSet);
7224 CaseDbConnection connection = connections.getConnection();
7226 ResultSet resultSet = null;
7229 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_TAG_NAMES_IN_USE);
7230 resultSet = connection.executeQuery(statement);
7231 ArrayList<TagName> tagNames =
new ArrayList<TagName>();
7232 while (resultSet.next()) {
7233 tagNames.add(
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7238 }
catch (SQLException ex) {
7239 throw new TskCoreException(
"Error selecting rows from tag_names table", ex);
7241 closeResultSet(resultSet);
7280 CaseDbConnection connection = connections.getConnection();
7282 ResultSet resultSet = null;
7284 PreparedStatement statement;
7287 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OR_UPDATE_TAG_NAME_POSTGRES, Statement.RETURN_GENERATED_KEYS);
7288 statement.clearParameters();
7289 statement.setString(5, description);
7290 statement.setString(6, color.getName());
7291 statement.setByte(7, knownStatus.getFileKnownValue());
7298 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OR_UPDATE_TAG_NAME_SQLITE, Statement.RETURN_GENERATED_KEYS);
7299 statement.clearParameters();
7301 statement.setString(1, displayName);
7302 statement.setString(2, description);
7303 statement.setString(3, color.getName());
7304 statement.setByte(4, knownStatus.getFileKnownValue());
7305 connection.executeUpdate(statement);
7306 resultSet = statement.getGeneratedKeys();
7308 return new TagName(resultSet.getLong(1),
7309 displayName, description, color, knownStatus);
7310 }
catch (SQLException ex) {
7311 throw new TskCoreException(
"Error adding row for " + displayName +
" tag name to tag_names table", ex);
7313 closeResultSet(resultSet);
7333 CaseDbConnection connection = connections.getConnection();
7335 ResultSet resultSet = null;
7338 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_CONTENT_TAG, Statement.RETURN_GENERATED_KEYS);
7339 statement.clearParameters();
7340 statement.setLong(1, content.getId());
7341 statement.setLong(2, tagName.getId());
7342 statement.setString(3, comment);
7343 statement.setLong(4, beginByteOffset);
7344 statement.setLong(5, endByteOffset);
7345 connection.executeUpdate(statement);
7346 resultSet = statement.getGeneratedKeys();
7349 content, tagName, comment, beginByteOffset, endByteOffset);
7350 }
catch (SQLException ex) {
7351 throw new TskCoreException(
"Error adding row to content_tags table (obj_id = " + content.getId() +
", tag_name_id = " + tagName.getId() +
")", ex);
7353 closeResultSet(resultSet);
7365 CaseDbConnection connection = connections.getConnection();
7369 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.DELETE_CONTENT_TAG);
7370 statement.clearParameters();
7371 statement.setLong(1, tag.getId());
7372 connection.executeUpdate(statement);
7373 }
catch (SQLException ex) {
7374 throw new TskCoreException(
"Error deleting row from content_tags table (id = " + tag.getId() +
")", ex);
7390 CaseDbConnection connection = connections.getConnection();
7392 ResultSet resultSet = null;
7395 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_CONTENT_TAGS);
7396 resultSet = connection.executeQuery(statement);
7397 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
7398 while (resultSet.next()) {
7399 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7403 tags.add(
new ContentTag(resultSet.getLong(
"tag_id"), content, tagName, resultSet.getString(
"comment"),
7404 resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset")));
7407 }
catch (SQLException ex) {
7408 throw new TskCoreException(
"Error selecting rows from content_tags table", ex);
7410 closeResultSet(resultSet);
7427 if (tagName.getId() ==
Tag.ID_NOT_SET) {
7428 throw new TskCoreException(
"TagName object is invalid, id not set");
7430 CaseDbConnection connection = connections.getConnection();
7432 ResultSet resultSet = null;
7435 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_CONTENT_TAGS_BY_TAG_NAME);
7436 statement.clearParameters();
7437 statement.setLong(1, tagName.getId());
7438 resultSet = connection.executeQuery(statement);
7439 if (resultSet.next()) {
7440 return resultSet.getLong(
"count");
7442 throw new TskCoreException(
"Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")");
7444 }
catch (SQLException ex) {
7445 throw new TskCoreException(
"Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")", ex);
7447 closeResultSet(resultSet);
7465 CaseDbConnection connection = connections.getConnection();
7467 ResultSet resultSet = null;
7471 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_CONTENT_TAG_BY_ID);
7472 statement.clearParameters();
7473 statement.setLong(1, contentTagID);
7474 resultSet = connection.executeQuery(statement);
7476 while (resultSet.next()) {
7477 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7481 resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"));
7485 }
catch (SQLException ex) {
7486 throw new TskCoreException(
"Error getting content tag with id = " + contentTagID, ex);
7488 closeResultSet(resultSet);
7507 if (tagName.getId() ==
Tag.ID_NOT_SET) {
7508 throw new TskCoreException(
"TagName object is invalid, id not set");
7510 CaseDbConnection connection = connections.getConnection();
7512 ResultSet resultSet = null;
7515 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_CONTENT_TAGS_BY_TAG_NAME);
7516 statement.clearParameters();
7517 statement.setLong(1, tagName.getId());
7518 resultSet = connection.executeQuery(statement);
7519 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
7520 while (resultSet.next()) {
7522 tagName, resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"));
7527 }
catch (SQLException ex) {
7528 throw new TskCoreException(
"Error getting content_tags rows (tag_name_id = " + tagName.getId() +
")", ex);
7530 closeResultSet(resultSet);
7548 CaseDbConnection connection = connections.getConnection();
7550 ResultSet resultSet = null;
7553 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_CONTENT_TAGS_BY_CONTENT);
7554 statement.clearParameters();
7555 statement.setLong(1, content.getId());
7556 resultSet = connection.executeQuery(statement);
7557 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
7558 while (resultSet.next()) {
7559 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7563 resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"));
7567 }
catch (SQLException ex) {
7568 throw new TskCoreException(
"Error getting content tags data for content (obj_id = " + content.getId() +
")", ex);
7570 closeResultSet(resultSet);
7590 CaseDbConnection connection = connections.getConnection();
7592 ResultSet resultSet = null;
7595 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_ARTIFACT_TAG, Statement.RETURN_GENERATED_KEYS);
7596 statement.clearParameters();
7597 statement.setLong(1, artifact.getArtifactID());
7598 statement.setLong(2, tagName.getId());
7599 statement.setString(3, comment);
7600 connection.executeUpdate(statement);
7601 resultSet = statement.getGeneratedKeys();
7604 artifact,
getContentById(artifact.getObjectID()), tagName, comment);
7605 }
catch (SQLException ex) {
7606 throw new TskCoreException(
"Error adding row to blackboard_artifact_tags table (obj_id = " + artifact.getArtifactID() +
", tag_name_id = " + tagName.getId() +
")", ex);
7608 closeResultSet(resultSet);
7620 CaseDbConnection connection = connections.getConnection();
7624 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.DELETE_ARTIFACT_TAG);
7625 statement.clearParameters();
7626 statement.setLong(1, tag.getId());
7627 connection.executeUpdate(statement);
7628 }
catch (SQLException ex) {
7629 throw new TskCoreException(
"Error deleting row from blackboard_artifact_tags table (id = " + tag.getId() +
")", ex);
7646 CaseDbConnection connection = connections.getConnection();
7648 ResultSet resultSet = null;
7651 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_TAGS);
7652 resultSet = connection.executeQuery(statement);
7653 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<BlackboardArtifactTag>();
7654 while (resultSet.next()) {
7655 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7661 artifact, content, tagName, resultSet.getString(
"comment"));
7665 }
catch (SQLException ex) {
7666 throw new TskCoreException(
"Error selecting rows from blackboard_artifact_tags table", ex);
7668 closeResultSet(resultSet);
7685 if (tagName.getId() ==
Tag.ID_NOT_SET) {
7686 throw new TskCoreException(
"TagName object is invalid, id not set");
7688 CaseDbConnection connection = connections.getConnection();
7690 ResultSet resultSet = null;
7693 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_BY_TAG_NAME);
7694 statement.clearParameters();
7695 statement.setLong(1, tagName.getId());
7696 resultSet = connection.executeQuery(statement);
7697 if (resultSet.next()) {
7698 return resultSet.getLong(
"count");
7700 throw new TskCoreException(
"Error getting blackboard_artifact_tags row count for tag name (tag_name_id = " + tagName.getId() +
")");
7702 }
catch (SQLException ex) {
7703 throw new TskCoreException(
"Error getting blackboard artifact_content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")", ex);
7705 closeResultSet(resultSet);
7723 if (tagName.getId() ==
Tag.ID_NOT_SET) {
7724 throw new TskCoreException(
"TagName object is invalid, id not set");
7726 CaseDbConnection connection = connections.getConnection();
7728 ResultSet resultSet = null;
7731 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_TAGS_BY_TAG_NAME);
7732 statement.clearParameters();
7733 statement.setLong(1, tagName.getId());
7734 resultSet = connection.executeQuery(statement);
7735 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<BlackboardArtifactTag>();
7736 while (resultSet.next()) {
7740 artifact, content, tagName, resultSet.getString(
"comment"));
7744 }
catch (SQLException ex) {
7745 throw new TskCoreException(
"Error getting blackboard artifact tags data (tag_name_id = " + tagName.getId() +
")", ex);
7747 closeResultSet(resultSet);
7766 CaseDbConnection connection = connections.getConnection();
7768 ResultSet resultSet = null;
7772 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_TAG_BY_ID);
7773 statement.clearParameters();
7774 statement.setLong(1, artifactTagID);
7775 resultSet = connection.executeQuery(statement);
7777 while (resultSet.next()) {
7778 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7784 artifact, content, tagName, resultSet.getString(
"comment"));
7788 }
catch (SQLException ex) {
7789 throw new TskCoreException(
"Error getting blackboard artifact tag with id = " + artifactTagID, ex);
7791 closeResultSet(resultSet);
7811 CaseDbConnection connection = connections.getConnection();
7813 ResultSet resultSet = null;
7816 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_TAGS_BY_ARTIFACT);
7817 statement.clearParameters();
7818 statement.setLong(1, artifact.getArtifactID());
7819 resultSet = connection.executeQuery(statement);
7820 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<BlackboardArtifactTag>();
7821 while (resultSet.next()) {
7822 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
7827 artifact, content, tagName, resultSet.getString(
"comment"));
7831 }
catch (SQLException ex) {
7832 throw new TskCoreException(
"Error getting blackboard artifact tags data (artifact_id = " + artifact.getArtifactID() +
")", ex);
7834 closeResultSet(resultSet);
7849 CaseDbConnection connection = connections.getConnection();
7853 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.UPDATE_IMAGE_PATH);
7854 statement.clearParameters();
7855 statement.setString(1, newPath);
7856 statement.setLong(2, objectId);
7857 connection.executeUpdate(statement);
7858 }
catch (SQLException ex) {
7859 throw new TskCoreException(
"Error updating image path in database for object " + objectId, ex);
7879 public Report addReport(String localPath, String sourceModuleName, String reportName)
throws TskCoreException {
7882 String relativePath =
"";
7892 String localPathLower = localPath.toLowerCase();
7893 int length =
new File(casePathLower).toURI().relativize(
new File(localPathLower).toURI()).getPath().length();
7894 relativePath =
new File(localPath.substring(localPathLower.length() - length)).getPath();
7895 }
catch (IllegalArgumentException ex) {
7896 String errorMessage = String.format(
"Local path %s not in the database directory or one of its subdirectories", localPath);
7897 throw new TskCoreException(errorMessage, ex);
7901 long createTime = 0;
7903 java.io.File tempFile =
new java.io.File(localPath);
7905 createTime = tempFile.lastModified() / 1000;
7906 }
catch (Exception ex) {
7907 throw new TskCoreException(
"Could not get create time for report at " + localPath, ex);
7911 CaseDbConnection connection = connections.getConnection();
7913 ResultSet resultSet = null;
7916 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_REPORT, Statement.RETURN_GENERATED_KEYS);
7917 statement.clearParameters();
7918 statement.setString(1, relativePath);
7919 statement.setLong(2, createTime);
7920 statement.setString(3, sourceModuleName);
7921 statement.setString(4, reportName);
7922 connection.executeUpdate(statement);
7923 resultSet = statement.getGeneratedKeys();
7925 return new Report(resultSet.getLong(1),
7926 localPath, createTime, sourceModuleName, reportName);
7927 }
catch (SQLException ex) {
7928 throw new TskCoreException(
"Error adding report " + localPath +
" to reports table", ex);
7930 closeResultSet(resultSet);
7945 CaseDbConnection connection = connections.getConnection();
7947 ResultSet resultSet = null;
7950 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_REPORTS);
7951 resultSet = connection.executeQuery(statement);
7952 ArrayList<Report> reports =
new ArrayList<Report>();
7953 while (resultSet.next()) {
7954 reports.add(
new Report(resultSet.getLong(
"report_id"),
7955 Paths.get(
getDbDirPath(), resultSet.getString(
"path")).normalize().toString(),
7956 resultSet.getLong(
"crtime"),
7957 resultSet.getString(
"src_module_name"),
7958 resultSet.getString(
"report_name")));
7961 }
catch (SQLException ex) {
7962 throw new TskCoreException(
"Error querying reports table", ex);
7964 closeResultSet(resultSet);
7978 CaseDbConnection connection = connections.getConnection();
7982 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.DELETE_REPORT);
7983 statement.setLong(1, report.getId());
7984 connection.executeUpdate(statement);
7985 }
catch (SQLException ex) {
7986 throw new TskCoreException(
"Error querying reports table", ex);
7992 static void closeResultSet(ResultSet resultSet) {
7993 if (resultSet != null) {
7996 }
catch (SQLException ex) {
7997 logger.log(Level.SEVERE,
"Error closing ResultSet", ex);
8002 static void closeStatement(Statement statement) {
8003 if (statement != null) {
8006 }
catch (SQLException ex) {
8007 logger.log(Level.SEVERE,
"Error closing Statement", ex);
8021 void setIngestJobEndDateTime(
long ingestJobId,
long endDateTime)
throws TskCoreException {
8022 CaseDbConnection connection = connections.getConnection();
8025 Statement statement = connection.createStatement();
8026 statement.executeUpdate(
"UPDATE ingest_jobs SET end_date_time=" + endDateTime +
" WHERE ingest_job_id=" + ingestJobId +
";");
8027 }
catch (SQLException ex) {
8028 throw new TskCoreException(
"Error updating the end date (ingest_job_id = " + ingestJobId +
".", ex);
8035 void setIngestJobStatus(
long ingestJobId, IngestJobStatusType status)
throws TskCoreException {
8036 CaseDbConnection connection = connections.getConnection();
8039 Statement statement = connection.createStatement();
8040 statement.executeUpdate(
"UPDATE ingest_jobs SET status_id=" + status.ordinal() +
" WHERE ingest_job_id=" + ingestJobId +
";");
8041 }
catch (SQLException ex) {
8042 throw new TskCoreException(
"Error ingest job status (ingest_job_id = " + ingestJobId +
".", ex);
8066 CaseDbConnection connection = connections.getConnection();
8068 ResultSet resultSet = null;
8069 Statement statement;
8071 connection.beginTransaction();
8072 statement = connection.createStatement();
8073 PreparedStatement insertStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_INGEST_JOB, Statement.RETURN_GENERATED_KEYS);
8074 insertStatement.setLong(1, dataSource.getId());
8075 insertStatement.setString(2, hostName);
8076 insertStatement.setLong(3, jobStart.getTime());
8077 insertStatement.setLong(4, jobEnd.getTime());
8078 insertStatement.setInt(5, status.ordinal());
8079 insertStatement.setString(6, settingsDir);
8080 connection.executeUpdate(insertStatement);
8081 resultSet = insertStatement.getGeneratedKeys();
8083 long id = resultSet.getLong(1);
8084 for (
int i = 0; i < ingestModules.size(); i++) {
8086 statement.executeUpdate(
"INSERT INTO ingest_job_modules (ingest_job_id, ingest_module_id, pipeline_position) "
8091 connection.commitTransaction();
8092 return new IngestJobInfo(
id, dataSource.getId(), hostName, jobStart,
"", ingestModules,
this);
8093 }
catch (SQLException ex) {
8094 connection.rollbackTransaction();
8095 throw new TskCoreException(
"Error adding the ingest job.", ex);
8097 closeResultSet(resultSet);
8117 CaseDbConnection connection = connections.getConnection();
8118 ResultSet resultSet = null;
8119 Statement statement = null;
8120 String uniqueName = factoryClassName +
"-" + displayName +
"-" + type.toString() +
"-" + version;
8123 statement = connection.createStatement();
8124 resultSet = statement.executeQuery(
"SELECT * FROM ingest_modules WHERE unique_name = '" + uniqueName +
"'");
8125 if (!resultSet.next()) {
8128 PreparedStatement insertStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_INGEST_MODULE, Statement.RETURN_GENERATED_KEYS);
8129 insertStatement.setString(1, displayName);
8130 insertStatement.setString(2, uniqueName);
8131 insertStatement.setInt(3, type.ordinal());
8132 insertStatement.setString(4, version);
8133 connection.executeUpdate(insertStatement);
8134 resultSet = statement.getGeneratedKeys();
8136 long id = resultSet.getLong(1);
8141 return new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
8142 resultSet.getString(
"unique_name"),
IngestModuleType.
fromID(resultSet.getInt(
"type_id")), resultSet.getString(
"version"));
8144 }
catch (SQLException ex) {
8146 closeStatement(statement);
8147 statement = connection.createStatement();
8148 resultSet = statement.executeQuery(
"SELECT * FROM ingest_modules WHERE unique_name = '" + uniqueName +
"'");
8149 if (resultSet.next()) {
8150 return new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
8153 throw new TskCoreException(
"Couldn't add new module to database.", ex);
8155 }
catch (SQLException ex1) {
8156 throw new TskCoreException(
"Couldn't add new module to database.", ex1);
8159 closeResultSet(resultSet);
8160 closeStatement(statement);
8174 CaseDbConnection connection = connections.getConnection();
8175 ResultSet resultSet = null;
8176 Statement statement = null;
8177 List<IngestJobInfo> ingestJobs =
new ArrayList<IngestJobInfo>();
8180 statement = connection.createStatement();
8181 resultSet = statement.executeQuery(
"SELECT * FROM ingest_jobs");
8182 while (resultSet.next()) {
8183 ingestJobs.add(
new IngestJobInfo(resultSet.getInt(
"ingest_job_id"), resultSet.getLong(
"obj_id"),
8184 resultSet.getString(
"host_name"),
new Date(resultSet.getLong(
"start_date_time")),
8186 resultSet.getString(
"settings_dir"), this.getIngestModules(resultSet.getInt(
"ingest_job_id"), connection),
this));
8189 }
catch (SQLException ex) {
8190 throw new TskCoreException(
"Couldn't get the ingest jobs.", ex);
8192 closeResultSet(resultSet);
8193 closeStatement(statement);
8209 private List<IngestModuleInfo> getIngestModules(
int ingestJobId, CaseDbConnection connection)
throws SQLException {
8210 ResultSet resultSet = null;
8211 Statement statement = null;
8212 List<IngestModuleInfo> ingestModules =
new ArrayList<IngestModuleInfo>();
8215 statement = connection.createStatement();
8216 resultSet = statement.executeQuery(
"SELECT ingest_job_modules.ingest_module_id AS ingest_module_id, "
8217 +
"ingest_job_modules.pipeline_position AS pipeline_position, "
8218 +
"ingest_modules.display_name AS display_name, ingest_modules.unique_name AS unique_name, "
8219 +
"ingest_modules.type_id AS type_id, ingest_modules.version AS version "
8220 +
"FROM ingest_job_modules, ingest_modules "
8221 +
"WHERE ingest_job_modules.ingest_job_id = " + ingestJobId +
" "
8222 +
"AND ingest_modules.ingest_module_id = ingest_job_modules.ingest_module_id "
8223 +
"ORDER BY (ingest_job_modules.pipeline_position);");
8224 while (resultSet.next()) {
8225 ingestModules.add(
new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
8226 resultSet.getString(
"unique_name"),
IngestModuleType.
fromID(resultSet.getInt(
"type_id")), resultSet.getString(
"version")));
8228 return ingestModules;
8230 closeResultSet(resultSet);
8231 closeStatement(statement);
8239 static class ObjectInfo {
8242 private TskData.ObjectType type;
8244 ObjectInfo(
long id, ObjectType type) {
8253 TskData.ObjectType getType() {
8258 private interface DbCommand {
8260 void execute() throws SQLException;
8263 private enum PREPARED_STATEMENT {
8265 SELECT_ARTIFACTS_BY_TYPE(
"SELECT artifact_id, obj_id FROM blackboard_artifacts "
8266 +
"WHERE artifact_type_id = ?"),
8267 COUNT_ARTIFACTS_OF_TYPE(
"SELECT COUNT(*) AS count FROM blackboard_artifacts WHERE artifact_type_id = ? AND review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID()),
8268 COUNT_ARTIFACTS_FROM_SOURCE(
"SELECT COUNT(*) AS count FROM blackboard_artifacts WHERE obj_id = ? AND review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID()),
8269 COUNT_ARTIFACTS_BY_SOURCE_AND_TYPE(
"SELECT COUNT(*) AS count FROM blackboard_artifacts WHERE obj_id = ? AND artifact_type_id = ? AND review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID()),
8270 SELECT_FILES_BY_PARENT(
"SELECT tsk_files.* "
8271 +
"FROM tsk_objects INNER JOIN tsk_files "
8272 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
8273 +
"WHERE (tsk_objects.par_obj_id = ? ) "
8274 +
"ORDER BY tsk_files.meta_type DESC, LOWER(tsk_files.name)"),
8275 SELECT_FILES_BY_PARENT_AND_TYPE(
"SELECT tsk_files.* "
8276 +
"FROM tsk_objects INNER JOIN tsk_files "
8277 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
8278 +
"WHERE (tsk_objects.par_obj_id = ? AND tsk_files.type = ? ) "
8279 +
"ORDER BY tsk_files.dir_type, LOWER(tsk_files.name)"),
8280 SELECT_FILE_IDS_BY_PARENT(
"SELECT tsk_files.obj_id AS obj_id "
8281 +
"FROM tsk_objects INNER JOIN tsk_files "
8282 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
8283 +
"WHERE (tsk_objects.par_obj_id = ?)"),
8284 SELECT_FILE_IDS_BY_PARENT_AND_TYPE(
"SELECT tsk_files.obj_id AS obj_id "
8285 +
"FROM tsk_objects INNER JOIN tsk_files "
8286 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
8287 +
"WHERE (tsk_objects.par_obj_id = ? "
8288 +
"AND tsk_files.type = ? )"),
8289 SELECT_FILE_BY_ID(
"SELECT * FROM tsk_files WHERE obj_id = ? LIMIT 1"),
8290 SELECT_ARTIFACT_BY_ARTIFACT_OBJ_ID(
"SELECT * FROM blackboard_artifacts WHERE artifact_obj_id = ? LIMIT 1"),
8291 SELECT_ARTIFACT_BY_ARTIFACT_ID(
"SELECT * FROM blackboard_artifacts WHERE artifact_id = ? LIMIT 1"),
8292 INSERT_ARTIFACT(
"INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_obj_id, data_source_obj_id, artifact_type_id, review_status_id) "
8293 +
"VALUES (?, ?, ?, ?, ?," + BlackboardArtifact.ReviewStatus.UNDECIDED.getID() +
")"),
8294 POSTGRESQL_INSERT_ARTIFACT(
"INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_obj_id, data_source_obj_id, artifact_type_id, review_status_id) "
8295 +
"VALUES (DEFAULT, ?, ?, ?, ?," + BlackboardArtifact.ReviewStatus.UNDECIDED.getID() +
")"),
8296 INSERT_STRING_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_text) "
8297 +
"VALUES (?,?,?,?,?,?,?)"),
8298 INSERT_BYTE_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_byte) "
8299 +
"VALUES (?,?,?,?,?,?,?)"),
8300 INSERT_INT_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_int32) "
8301 +
"VALUES (?,?,?,?,?,?,?)"),
8302 INSERT_LONG_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_int64) "
8303 +
"VALUES (?,?,?,?,?,?,?)"),
8304 INSERT_DOUBLE_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_double) "
8305 +
"VALUES (?,?,?,?,?,?,?)"),
8306 SELECT_FILES_BY_DATA_SOURCE_AND_NAME(
"SELECT * FROM tsk_files WHERE LOWER(name) LIKE LOWER(?) AND LOWER(name) NOT LIKE LOWER('%journal%') AND data_source_obj_id = ?"),
8307 SELECT_FILES_BY_DATA_SOURCE_AND_PARENT_PATH_AND_NAME(
"SELECT * FROM tsk_files WHERE LOWER(name) LIKE LOWER(?) AND LOWER(name) NOT LIKE LOWER('%journal%') AND LOWER(parent_path) LIKE LOWER(?) AND data_source_obj_id = ?"),
8308 UPDATE_FILE_MD5(
"UPDATE tsk_files SET md5 = ? WHERE obj_id = ?"),
8309 SELECT_LOCAL_PATH_FOR_FILE(
"SELECT path FROM tsk_files_path WHERE obj_id = ?"),
8310 SELECT_ENCODING_FOR_FILE(
"SELECT encoding_type FROM tsk_files_path WHERE obj_id = ?"),
8311 SELECT_LOCAL_PATH_AND_ENCODING_FOR_FILE(
"SELECT path, encoding_type FROM tsk_files_path WHERE obj_id = ?"),
8312 SELECT_PATH_FOR_FILE(
"SELECT parent_path FROM tsk_files WHERE obj_id = ?"),
8313 SELECT_FILE_NAME(
"SELECT name FROM tsk_files WHERE obj_id = ?"),
8314 SELECT_DERIVED_FILE(
"SELECT derived_id, rederive FROM tsk_files_derived WHERE obj_id = ?"),
8315 SELECT_FILE_DERIVATION_METHOD(
"SELECT tool_name, tool_version, other FROM tsk_files_derived_method WHERE derived_id = ?"),
8316 SELECT_MAX_OBJECT_ID(
"SELECT MAX(obj_id) AS max_obj_id FROM tsk_objects"),
8317 INSERT_OBJECT(
"INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)"),
8318 INSERT_FILE(
"INSERT INTO tsk_files (obj_id, fs_obj_id, name, type, has_path, dir_type, meta_type, dir_flags, meta_flags, size, ctime, crtime, atime, mtime, parent_path, data_source_obj_id,extension) "
8319 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)"),
8320 INSERT_LAYOUT_FILE(
"INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) "
8321 +
"VALUES (?, ?, ?, ?)"),
8322 INSERT_LOCAL_PATH(
"INSERT INTO tsk_files_path (obj_id, path, encoding_type) VALUES (?, ?, ?)"),
8323 COUNT_CHILD_OBJECTS_BY_PARENT(
"SELECT COUNT(obj_id) AS count FROM tsk_objects WHERE par_obj_id = ?"),
8324 SELECT_FILE_SYSTEM_BY_OBJECT(
"SELECT fs_obj_id from tsk_files WHERE obj_id=?"),
8325 SELECT_TAG_NAMES(
"SELECT * FROM tag_names"),
8326 SELECT_TAG_NAMES_IN_USE(
"SELECT * FROM tag_names "
8327 +
"WHERE tag_name_id IN "
8328 +
"(SELECT tag_name_id from content_tags UNION SELECT tag_name_id FROM blackboard_artifact_tags)"),
8329 INSERT_TAG_NAME(
"INSERT INTO tag_names (display_name, description, color, knownStatus) VALUES (?, ?, ?, ?)"),
8330 INSERT_CONTENT_TAG(
"INSERT INTO content_tags (obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset) VALUES (?, ?, ?, ?, ?)"),
8331 DELETE_CONTENT_TAG(
"DELETE FROM content_tags WHERE tag_id = ?"),
8332 COUNT_CONTENT_TAGS_BY_TAG_NAME(
"SELECT COUNT(*) AS count FROM content_tags WHERE tag_name_id = ?"),
8333 SELECT_CONTENT_TAGS(
"SELECT * FROM content_tags INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id"),
8334 SELECT_CONTENT_TAGS_BY_TAG_NAME(
"SELECT * FROM content_tags WHERE tag_name_id = ?"),
8335 SELECT_CONTENT_TAG_BY_ID(
"SELECT * FROM content_tags INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id WHERE tag_id = ?"),
8336 SELECT_CONTENT_TAGS_BY_CONTENT(
"SELECT * FROM content_tags INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id WHERE content_tags.obj_id = ?"),
8337 INSERT_ARTIFACT_TAG(
"INSERT INTO blackboard_artifact_tags (artifact_id, tag_name_id, comment) VALUES (?, ?, ?)"),
8338 DELETE_ARTIFACT_TAG(
"DELETE FROM blackboard_artifact_tags WHERE tag_id = ?"),
8339 SELECT_ARTIFACT_TAGS(
"SELECT * FROM blackboard_artifact_tags INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id"),
8340 COUNT_ARTIFACTS_BY_TAG_NAME(
"SELECT COUNT(*) AS count FROM blackboard_artifact_tags WHERE tag_name_id = ?"),
8341 SELECT_ARTIFACT_TAGS_BY_TAG_NAME(
"SELECT * FROM blackboard_artifact_tags WHERE tag_name_id = ?"),
8342 SELECT_ARTIFACT_TAG_BY_ID(
"SELECT * FROM blackboard_artifact_tags INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id WHERE blackboard_artifact_tags.tag_id = ?"),
8343 SELECT_ARTIFACT_TAGS_BY_ARTIFACT(
"SELECT * FROM blackboard_artifact_tags INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id WHERE blackboard_artifact_tags.artifact_id = ?"),
8344 SELECT_REPORTS(
"SELECT * FROM reports"),
8345 INSERT_REPORT(
"INSERT INTO reports (path, crtime, src_module_name, report_name) VALUES (?, ?, ?, ?)"),
8346 DELETE_REPORT(
"DELETE FROM reports WHERE reports.report_id = ?"),
8347 INSERT_INGEST_JOB(
"INSERT INTO ingest_jobs (obj_id, host_name, start_date_time, end_date_time, status_id, settings_dir) VALUES (?, ?, ?, ?, ?, ?)"),
8348 INSERT_INGEST_MODULE(
"INSERT INTO ingest_modules (display_name, unique_name, type_id, version) VALUES(?, ?, ?, ?)"),
8349 SELECT_ATTR_BY_VALUE_BYTE(
"SELECT source FROM blackboard_attributes WHERE artifact_id = ? AND attribute_type_id = ? AND value_type = 4 AND value_byte = ?"),
8350 UPDATE_ATTR_BY_VALUE_BYTE(
"UPDATE blackboard_attributes SET source = ? WHERE artifact_id = ? AND attribute_type_id = ? AND value_type = 4 AND value_byte = ?"),
8351 UPDATE_IMAGE_PATH(
"UPDATE tsk_image_names SET name = ? WHERE obj_id = ?"),
8352 SELECT_ARTIFACT_OBJECTIDS_BY_PARENT(
"SELECT blackboard_artifacts.artifact_obj_id AS artifact_obj_id "
8353 +
"FROM tsk_objects INNER JOIN blackboard_artifacts "
8354 +
"ON tsk_objects.obj_id=blackboard_artifacts.obj_id "
8355 +
"WHERE (tsk_objects.par_obj_id = ?)"),
8356 INSERT_OR_UPDATE_TAG_NAME_POSTGRES(
"INSERT INTO tag_names (display_name, description, color, knownStatus) VALUES (?, ?, ?, ?) ON CONFLICT (display_name) DO UPDATE SET description = ?, color = ?, knownStatus = ?"),
8357 INSERT_OR_UPDATE_TAG_NAME_SQLITE(
"WITH new (display_name, description, color, knownStatus) "
8358 +
"AS ( VALUES(?, ?, ?, ?)) INSERT OR REPLACE INTO tag_names "
8359 +
"(tag_name_id, display_name, description, color, knownStatus) "
8360 +
"SELECT old.tag_name_id, new.display_name, new.description, new.color, new.knownStatus "
8361 +
"FROM new LEFT JOIN tag_names AS old ON new.display_name = old.display_name");
8362 private final String sql;
8364 private PREPARED_STATEMENT(String sql) {
8378 abstract private class ConnectionPool {
8380 private PooledDataSource pooledDataSource;
8382 public ConnectionPool() {
8383 pooledDataSource = null;
8386 CaseDbConnection getConnection() throws TskCoreException {
8387 if (pooledDataSource == null) {
8388 throw new TskCoreException(
"Error getting case database connection - case is closed");
8391 return getPooledConnection();
8392 }
catch (SQLException exp) {
8393 throw new TskCoreException(exp.getMessage());
8397 void close() throws TskCoreException {
8398 if (pooledDataSource != null) {
8400 pooledDataSource.close();
8401 }
catch (SQLException exp) {
8402 throw new TskCoreException(exp.getMessage());
8404 pooledDataSource = null;
8409 abstract CaseDbConnection getPooledConnection() throws SQLException;
8411 public PooledDataSource getPooledDataSource() {
8412 return pooledDataSource;
8415 public void setPooledDataSource(PooledDataSource pooledDataSource) {
8416 this.pooledDataSource = pooledDataSource;
8424 private final class SQLiteConnections
extends ConnectionPool {
8426 private final Map<String, String> configurationOverrides =
new HashMap<String, String>();
8428 SQLiteConnections(String dbPath)
throws SQLException {
8429 configurationOverrides.put(
"acquireIncrement",
"2");
8430 configurationOverrides.put(
"initialPoolSize",
"5");
8431 configurationOverrides.put(
"maxPoolSize",
"20");
8432 configurationOverrides.put(
"minPoolSize",
"5");
8433 configurationOverrides.put(
"maxStatements",
"100");
8434 configurationOverrides.put(
"maxStatementsPerConnection",
"20");
8436 SQLiteConfig config =
new SQLiteConfig();
8437 config.setSynchronous(SQLiteConfig.SynchronousMode.OFF);
8438 config.setReadUncommited(
true);
8439 config.enforceForeignKeys(
true);
8440 SQLiteDataSource unpooled =
new SQLiteDataSource(config);
8441 unpooled.setUrl(
"jdbc:sqlite:" + dbPath);
8442 setPooledDataSource((PooledDataSource) DataSources.pooledDataSource(unpooled, configurationOverrides));
8446 public CaseDbConnection getPooledConnection() throws SQLException {
8447 return new SQLiteConnection(getPooledDataSource().getConnection());
8455 private final class PostgreSQLConnections
extends ConnectionPool {
8457 PostgreSQLConnections(String host,
int port, String dbName, String userName, String password)
throws PropertyVetoException, UnsupportedEncodingException {
8458 ComboPooledDataSource comboPooledDataSource =
new ComboPooledDataSource();
8459 comboPooledDataSource.setDriverClass(
"org.postgresql.Driver");
8460 comboPooledDataSource.setJdbcUrl(
"jdbc:postgresql://" + host +
":" + port +
"/"
8461 + URLEncoder.encode(dbName, StandardCharsets.UTF_8.toString()));
8462 comboPooledDataSource.setUser(userName);
8463 comboPooledDataSource.setPassword(password);
8464 comboPooledDataSource.setAcquireIncrement(2);
8465 comboPooledDataSource.setInitialPoolSize(5);
8466 comboPooledDataSource.setMaxPoolSize(20);
8467 comboPooledDataSource.setMinPoolSize(5);
8468 comboPooledDataSource.setMaxStatements(100);
8469 comboPooledDataSource.setMaxStatementsPerConnection(20);
8470 setPooledDataSource(comboPooledDataSource);
8474 public CaseDbConnection getPooledConnection() throws SQLException {
8475 return new PostgreSQLConnection(getPooledDataSource().getConnection());
8482 abstract class CaseDbConnection {
8484 static final int SLEEP_LENGTH_IN_MILLISECONDS = 5000;
8486 private class CreateStatement
implements DbCommand {
8488 private final Connection connection;
8489 private Statement statement = null;
8491 CreateStatement(Connection connection) {
8492 this.connection = connection;
8495 Statement getStatement() {
8500 public void execute() throws SQLException {
8501 statement = connection.createStatement();
8505 private class SetAutoCommit
implements DbCommand {
8507 private final Connection connection;
8508 private final boolean mode;
8510 SetAutoCommit(Connection connection,
boolean mode) {
8511 this.connection = connection;
8516 public void execute() throws SQLException {
8517 connection.setAutoCommit(mode);
8521 private class Commit
implements DbCommand {
8523 private final Connection connection;
8525 Commit(Connection connection) {
8526 this.connection = connection;
8530 public void execute() throws SQLException {
8531 connection.commit();
8535 private class ExecuteQuery
implements DbCommand {
8537 private final Statement statement;
8538 private final String query;
8539 private ResultSet resultSet;
8541 ExecuteQuery(Statement statement, String query) {
8542 this.statement = statement;
8546 ResultSet getResultSet() {
8551 public void execute() throws SQLException {
8552 resultSet = statement.executeQuery(query);
8556 private class ExecutePreparedStatementQuery
implements DbCommand {
8558 private final PreparedStatement preparedStatement;
8559 private ResultSet resultSet;
8561 ExecutePreparedStatementQuery(PreparedStatement preparedStatement) {
8562 this.preparedStatement = preparedStatement;
8565 ResultSet getResultSet() {
8570 public void execute() throws SQLException {
8571 resultSet = preparedStatement.executeQuery();
8575 private class ExecutePreparedStatementUpdate
implements DbCommand {
8577 private final PreparedStatement preparedStatement;
8579 ExecutePreparedStatementUpdate(PreparedStatement preparedStatement) {
8580 this.preparedStatement = preparedStatement;
8584 public void execute() throws SQLException {
8585 preparedStatement.executeUpdate();
8589 private class ExecuteStatementUpdate
implements DbCommand {
8591 private final Statement statement;
8592 private final String updateCommand;
8594 ExecuteStatementUpdate(Statement statement, String updateCommand) {
8595 this.statement = statement;
8596 this.updateCommand = updateCommand;
8600 public void execute() throws SQLException {
8601 statement.executeUpdate(updateCommand);
8605 private class ExecuteStatementUpdateGenerateKeys
implements DbCommand {
8607 private final Statement statement;
8608 private final int generateKeys;
8609 private final String updateCommand;
8611 ExecuteStatementUpdateGenerateKeys(Statement statement, String updateCommand,
int generateKeys) {
8612 this.statement = statement;
8613 this.generateKeys = generateKeys;
8614 this.updateCommand = updateCommand;
8618 public void execute() throws SQLException {
8619 statement.executeUpdate(updateCommand, generateKeys);
8623 private class PrepareStatement
implements DbCommand {
8625 private final Connection connection;
8626 private final String input;
8627 private PreparedStatement preparedStatement = null;
8629 PrepareStatement(Connection connection, String input) {
8630 this.connection = connection;
8634 PreparedStatement getPreparedStatement() {
8635 return preparedStatement;
8639 public void execute() throws SQLException {
8640 preparedStatement = connection.prepareStatement(input);
8644 private class PrepareStatementGenerateKeys
implements DbCommand {
8646 private final Connection connection;
8647 private final String input;
8648 private final int generateKeys;
8649 private PreparedStatement preparedStatement = null;
8651 PrepareStatementGenerateKeys(Connection connection, String input,
int generateKeysInput) {
8652 this.connection = connection;
8654 this.generateKeys = generateKeysInput;
8657 PreparedStatement getPreparedStatement() {
8658 return preparedStatement;
8662 public void execute() throws SQLException {
8663 preparedStatement = connection.prepareStatement(input, generateKeys);
8667 abstract void executeCommand(DbCommand command)
throws SQLException;
8669 private final Connection connection;
8670 private final Map<PREPARED_STATEMENT, PreparedStatement> preparedStatements;
8672 CaseDbConnection(Connection connection) {
8673 this.connection = connection;
8674 preparedStatements =
new EnumMap<PREPARED_STATEMENT, PreparedStatement>(PREPARED_STATEMENT.class);
8678 return this.connection != null;
8681 PreparedStatement getPreparedStatement(PREPARED_STATEMENT statementKey)
throws SQLException {
8682 return getPreparedStatement(statementKey, Statement.NO_GENERATED_KEYS);
8685 PreparedStatement getPreparedStatement(PREPARED_STATEMENT statementKey,
int generateKeys)
throws SQLException {
8687 PreparedStatement statement;
8688 if (this.preparedStatements.containsKey(statementKey)) {
8689 statement = this.preparedStatements.get(statementKey);
8691 statement = prepareStatement(statementKey.getSQL(), generateKeys);
8692 this.preparedStatements.put(statementKey, statement);
8697 PreparedStatement prepareStatement(String sqlStatement,
int generateKeys)
throws SQLException {
8698 PrepareStatement prepareStatement =
new PrepareStatement(this.getConnection(), sqlStatement);
8699 executeCommand(prepareStatement);
8700 return prepareStatement.getPreparedStatement();
8703 Statement createStatement() throws SQLException {
8704 CreateStatement createStatement =
new CreateStatement(this.connection);
8705 executeCommand(createStatement);
8706 return createStatement.getStatement();
8710 SetAutoCommit setAutoCommit =
new SetAutoCommit(connection,
false);
8711 executeCommand(setAutoCommit);
8714 void commitTransaction() throws SQLException {
8715 Commit commit =
new Commit(connection);
8716 executeCommand(commit);
8718 SetAutoCommit setAutoCommit =
new SetAutoCommit(connection,
true);
8719 executeCommand(setAutoCommit);
8727 void rollbackTransaction() {
8729 connection.rollback();
8730 }
catch (SQLException e) {
8731 logger.log(Level.SEVERE,
"Error rolling back transaction", e);
8734 connection.setAutoCommit(
true);
8735 }
catch (SQLException e) {
8736 logger.log(Level.SEVERE,
"Error restoring auto-commit", e);
8747 void rollbackTransactionWithThrow() throws SQLException {
8749 connection.rollback();
8751 connection.setAutoCommit(
true);
8755 ResultSet
executeQuery(Statement statement, String query)
throws SQLException {
8756 ExecuteQuery queryCommand =
new ExecuteQuery(statement, query);
8757 executeCommand(queryCommand);
8758 return queryCommand.getResultSet();
8770 ResultSet
executeQuery(PreparedStatement statement)
throws SQLException {
8771 ExecutePreparedStatementQuery executePreparedStatementQuery =
new ExecutePreparedStatementQuery(statement);
8772 executeCommand(executePreparedStatementQuery);
8773 return executePreparedStatementQuery.getResultSet();
8776 void executeUpdate(Statement statement, String update)
throws SQLException {
8777 executeUpdate(statement, update, Statement.NO_GENERATED_KEYS);
8780 void executeUpdate(Statement statement, String update,
int generateKeys)
throws SQLException {
8781 ExecuteStatementUpdate executeStatementUpdate =
new ExecuteStatementUpdate(statement, update);
8782 executeCommand(executeStatementUpdate);
8785 void executeUpdate(PreparedStatement statement)
throws SQLException {
8786 ExecutePreparedStatementUpdate executePreparedStatementUpdate =
new ExecutePreparedStatementUpdate(statement);
8787 executeCommand(executePreparedStatementUpdate);
8796 }
catch (SQLException ex) {
8797 logger.log(Level.SEVERE,
"Unable to close connection to case database", ex);
8801 Connection getConnection() {
8802 return this.connection;
8809 private final class SQLiteConnection
extends CaseDbConnection {
8811 private static final int DATABASE_LOCKED_ERROR = 0;
8812 private static final int SQLITE_BUSY_ERROR = 5;
8814 SQLiteConnection(Connection conn) {
8819 void executeCommand(DbCommand command)
throws SQLException {
8824 }
catch (SQLException ex) {
8825 if (ex.getErrorCode() == SQLITE_BUSY_ERROR || ex.getErrorCode() == DATABASE_LOCKED_ERROR) {
8830 Thread.sleep(SLEEP_LENGTH_IN_MILLISECONDS);
8831 }
catch (InterruptedException exp) {
8832 Logger.getLogger(SleuthkitCase.class.getName()).log(Level.WARNING,
"Unexpectedly unable to wait for database.", exp);
8845 private final class PostgreSQLConnection
extends CaseDbConnection {
8847 private final String COMMUNICATION_ERROR = PSQLState.COMMUNICATION_ERROR.getState();
8848 private final String SYSTEM_ERROR = PSQLState.SYSTEM_ERROR.getState();
8849 private final String UNKNOWN_STATE = PSQLState.UNKNOWN_STATE.getState();
8850 private static final int MAX_RETRIES = 3;
8852 PostgreSQLConnection(Connection conn) {
8857 void executeUpdate(Statement statement, String update,
int generateKeys)
throws SQLException {
8858 CaseDbConnection.ExecuteStatementUpdateGenerateKeys executeStatementUpdateGenerateKeys =
new CaseDbConnection.ExecuteStatementUpdateGenerateKeys(statement, update, generateKeys);
8859 executeCommand(executeStatementUpdateGenerateKeys);
8863 PreparedStatement prepareStatement(String sqlStatement,
int generateKeys)
throws SQLException {
8864 CaseDbConnection.PrepareStatementGenerateKeys prepareStatementGenerateKeys =
new CaseDbConnection.PrepareStatementGenerateKeys(this.getConnection(), sqlStatement, generateKeys);
8865 executeCommand(prepareStatementGenerateKeys);
8866 return prepareStatementGenerateKeys.getPreparedStatement();
8870 void executeCommand(DbCommand command)
throws SQLException {
8871 for (
int retries = 0; retries < MAX_RETRIES; retries++) {
8875 }
catch (SQLException ex) {
8876 String sqlState = ((PSQLException) ex).getSQLState();
8877 if (sqlState.equals(COMMUNICATION_ERROR) || sqlState.equals(SYSTEM_ERROR) || sqlState.equals(UNKNOWN_STATE)) {
8879 Thread.sleep(SLEEP_LENGTH_IN_MILLISECONDS);
8880 }
catch (InterruptedException exp) {
8881 Logger.getLogger(SleuthkitCase.class.getName()).log(Level.WARNING,
"Unexpectedly unable to wait for database.", exp);
8901 private final CaseDbConnection connection;
8903 private CaseDbTransaction(CaseDbConnection connection)
throws TskCoreException {
8904 this.connection = connection;
8906 this.connection.beginTransaction();
8907 }
catch (SQLException ex) {
8908 throw new TskCoreException(
"Failed to create transaction on case database", ex);
8919 private CaseDbConnection getConnection() {
8920 return this.connection;
8929 public void commit() throws TskCoreException {
8931 this.connection.commitTransaction();
8932 }
catch (SQLException ex) {
8933 throw new TskCoreException(
"Failed to commit transaction on case database", ex);
8947 this.connection.rollbackTransactionWithThrow();
8948 }
catch (SQLException ex) {
8949 throw new TskCoreException(
"Case database transaction rollback failed", ex);
8960 this.connection.close();
8975 private ResultSet resultSet;
8976 private CaseDbConnection connection;
8978 private CaseDbQuery(String query)
throws TskCoreException {
8982 private CaseDbQuery(String query,
boolean allowWriteQuery)
throws TskCoreException {
8983 if (!allowWriteQuery) {
8984 if (!query.regionMatches(
true, 0,
"SELECT", 0,
"SELECT".length())) {
8985 throw new TskCoreException(
"Unsupported query: Only SELECT queries are supported.");
8989 connection = connections.getConnection();
8990 }
catch (TskCoreException ex) {
8991 throw new TskCoreException(
"Error getting connection for query: ", ex);
8996 resultSet = connection.executeQuery(connection.createStatement(), query);
8997 }
catch (SQLException ex) {
8999 throw new TskCoreException(
"Error executing query: ", ex);
9013 public void close() throws TskCoreException {
9015 if (resultSet != null) {
9016 final Statement statement = resultSet.getStatement();
9017 if (statement != null) {
9023 }
catch (SQLException ex) {
9024 throw new TskCoreException(
"Error closing query: ", ex);
9040 sleuthkitCaseErrorObservers.add(observer);
9052 int i = sleuthkitCaseErrorObservers.indexOf(observer);
9054 sleuthkitCaseErrorObservers.remove(i);
9068 for (
ErrorObserver observer : sleuthkitCaseErrorObservers) {
9069 if (observer != null) {
9071 observer.receiveError(context, errorMessage);
9072 }
catch (Exception ex) {
9073 logger.log(Level.SEVERE,
"Observer client unable to receive message: {0}, {1}",
new Object[]{context, errorMessage, ex});
9105 private final String contextString;
9107 private Context(String context) {
9108 this.contextString = context;
9112 return contextString;
9116 void receiveError(String context, String errorMessage);
9133 long getDataSourceObjectId(
long objectId) {
9135 CaseDbConnection connection = connections.getConnection();
9137 return getDataSourceObjectId(connection, objectId);
9141 }
catch (TskCoreException ex) {
9142 logger.log(Level.SEVERE,
"Error getting data source object id for a file", ex);
9158 CaseDbConnection connection = connections.getConnection();
9160 ResultSet rs = null;
9163 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_MAX_OBJECT_ID);
9164 rs = connection.executeQuery(statement);
9167 id = rs.getLong(
"max_obj_id");
9170 }
catch (SQLException e) {
9171 throw new TskCoreException(
"Error getting last object id", e);
9193 public List<FsContent>
findFilesWhere(String sqlWhereClause)
throws TskCoreException {
9194 CaseDbConnection connection = connections.getConnection();
9197 ResultSet rs = null;
9199 s = connection.createStatement();
9200 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE " + sqlWhereClause);
9201 List<FsContent> results =
new ArrayList<FsContent>();
9202 List<AbstractFile> temp = resultSetToAbstractFiles(rs, connection);
9210 }
catch (SQLException e) {
9211 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findFilesWhere().", e);
9233 CaseDbConnection connection = connections.getConnection();
9236 ResultSet rs = null;
9238 s = connection.createStatement();
9239 rs = connection.executeQuery(s,
"SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = '" + artifactTypeName +
"'");
9242 typeId = rs.getInt(
"artifact_type_id");
9245 }
catch (SQLException ex) {
9246 throw new TskCoreException(
"Error getting artifact type id", ex);
9283 public int addArtifactType(String artifactTypeName, String displayName)
throws TskCoreException {
9286 }
catch (TskDataException ex) {
9287 throw new TskCoreException(
"Failed to add artifact type.", ex);
9305 public int addAttrType(String attrTypeString, String displayName)
throws TskCoreException {
9308 }
catch (TskDataException ex) {
9309 throw new TskCoreException(
"Couldn't add new attribute type");
9325 CaseDbConnection connection = connections.getConnection();
9328 ResultSet rs = null;
9330 s = connection.createStatement();
9331 rs = connection.executeQuery(s,
"SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = '" + attrTypeName +
"'");
9334 typeId = rs.getInt(
"attribute_type_id");
9337 }
catch (SQLException ex) {
9338 throw new TskCoreException(
"Error getting attribute type id", ex);
9361 CaseDbConnection connection = connections.getConnection();
9364 ResultSet rs = null;
9366 s = connection.createStatement();
9367 rs = connection.executeQuery(s,
"SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " + attrTypeID);
9369 return rs.getString(
"type_name");
9371 throw new TskCoreException(
"No type with that id");
9373 }
catch (SQLException ex) {
9374 throw new TskCoreException(
"Error getting or creating a attribute type name", ex);
9397 CaseDbConnection connection = connections.getConnection();
9400 ResultSet rs = null;
9402 s = connection.createStatement();
9403 rs = connection.executeQuery(s,
"SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " + attrTypeID);
9405 return rs.getString(
"display_name");
9407 throw new TskCoreException(
"No type with that id");
9409 }
catch (SQLException ex) {
9410 throw new TskCoreException(
"Error getting or creating a attribute type name", ex);
9449 public ResultSet
runQuery(String query)
throws SQLException {
9450 CaseDbConnection connection;
9452 connection = connections.getConnection();
9453 }
catch (TskCoreException ex) {
9454 throw new SQLException(
"Error getting connection for ad hoc query", ex);
9458 return connection.executeQuery(connection.createStatement(), query);
9478 final Statement statement = resultSet.getStatement();
9480 if (statement != null) {
9502 public LayoutFile addCarvedFile(String carvedFileName,
long carvedFileSize,
long containerId, List<TskFileRange> data)
throws TskCoreException {
9505 files.add(carvedFile);
9509 || parent instanceof
Volume
9510 || parent instanceof
Image) {
9513 throw new TskCoreException(String.format(
"Parent (id =%d) is not an file system, volume or image", containerId));
9532 public List<LayoutFile>
addCarvedFiles(List<CarvedFileContainer> filesToAdd)
throws TskCoreException {
9536 carvedFiles.add(carvedFile);
9541 || parent instanceof
Volume
9542 || parent instanceof
Image) {
9545 throw new TskCoreException(String.format(
"Parent (id =%d) is not an file system, volume or image", parent.
getId()));
9581 long size,
long ctime,
long crtime,
long atime,
long mtime,
9583 String rederiveDetails, String toolName, String toolVersion, String otherDetails)
throws TskCoreException {
9584 return addDerivedFile(fileName, localPath, size, ctime, crtime, atime, mtime,
9585 isFile, parentFile, rederiveDetails, toolName, toolVersion,
9615 long size,
long ctime,
long crtime,
long atime,
long mtime,
9618 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime, isFile,
9643 long size,
long ctime,
long crtime,
long atime,
long mtime,
9646 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime,
9668 return this.caseHandle.initAddImageProcess(timezone, addUnallocSpace, noFatFsOrphans,
"");
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, long value)
final IngestJobInfo addIngestJob(Content dataSource, String hostName, List< IngestModuleInfo > ingestModules, Date jobStart, Date jobEnd, IngestJobStatusType status, String settingsDir)
static ARTIFACT_TYPE fromID(int id)
FS
File that can be found in file system tree.
static FileKnown valueOf(byte known)
BlackboardArtifact getArtifactByArtifactId(long id)
AddImageProcess makeAddImageProcess(String timezone, boolean addUnallocSpace, boolean noFatFsOrphans)
BlackboardArtifact getArtifactById(long id)
List< Report > getAllReports()
ArrayList< BlackboardAttribute > getBlackboardAttributes(final BlackboardArtifact artifact)
long getBlackboardArtifactsCount(long objId)
int getArtifactTypeID(String artifactTypeName)
long getBlackboardArtifactTagsCountByTagName(TagName tagName)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(ARTIFACT_TYPE artifactType)
LocalDirectory addLocalDirectory(long parentId, String directoryName, CaseDbTransaction transaction)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(String artifactTypeName)
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, int value)
void addBlackboardAttributes(Collection< BlackboardAttribute > attributes, int artifactTypeId)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(int artifactTypeID, long obj_id)
DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parentFile, String rederiveDetails, String toolName, String toolVersion, String otherDetails)
CaseDbTransaction beginTransaction()
synchronized CommunicationsManager getCommunicationsManager()
boolean isCompatible(CaseDbSchemaVersionNumber dbSchemaVersion)
List< Content > getChildren()
LocalFile addLocalFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parent)
ALLOC
Metadata structure is currently in an allocated state.
int countFilesMd5Hashed()
static TSK_FS_TYPE_ENUM valueOf(int fsTypeValue)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(int artifactTypeID)
void addErrorObserver(ErrorObserver observer)
TSK_FS_META_TYPE_DIR
Directory file NON-NLS.
List< AbstractFile > findFiles(Content dataSource, String fileName, AbstractFile parentFile)
synchronized void close()
TagName addOrUpdateTagName(String displayName, String description, TagName.HTML_COLOR color, TskData.FileKnown knownStatus)
void setFileMIMEType(AbstractFile file, String mimeType)
UNALLOC
Metadata structure is currently in an unallocated state.
void addBlackboardAttribute(BlackboardAttribute attr, int artifactTypeId)
LocalFile addLocalFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parent, CaseDbTransaction transaction)
final List< LayoutFile > addLayoutFiles(Content parent, List< TskFileRange > fileRanges)
int addArtifactType(String artifactTypeName, String displayName)
List< DataSource > getDataSources()
BlackboardArtifactTag getBlackboardArtifactTagByID(long artifactTagID)
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, double value)
TSK_FS_META_TYPE_VIRT_DIR
"Virtual Directory" created by TSK for Orphan Files NON-NLS
List< AbstractFile > openFiles(Content dataSource, String filePath)
List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)
final IngestModuleInfo addIngestModule(String displayName, String factoryClassName, IngestModuleType type, String version)
long getBlackboardArtifactsCount(String artifactTypeName, long obj_id)
Content getContentById(long id)
VersionNumber getDBSchemaVersion()
static IngestJobStatusType fromID(int typeId)
List< TagName > getTagNamesInUse()
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, byte value)
static final String NAME_CARVED
static SleuthkitCase openCase(String databaseName, CaseDbConnectionInfo info, String caseDir)
static IngestModuleType fromID(int typeId)
List< ContentTag > getAllContentTags()
List< VirtualDirectory > getVirtualDirectoryRoots()
ArrayList< BlackboardArtifact.ARTIFACT_TYPE > getBlackboardArtifactTypes()
ContentTag getContentTagByID(long contentTagID)
LOCAL
Local file that was added (not from a disk image)
Map< Long, List< String > > getImagePaths()
List< Long > findAllFileIdsWhere(String sqlWhereClause)
BlackboardArtifact getBlackboardArtifact(long artifactID)
List< BlackboardArtifact.Type > getArtifactTypesInUse()
BlackboardAttribute.Type addArtifactAttributeType(String attrTypeString, TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName)
AbstractFile getAbstractFileById(long id)
CARVED
Set of blocks for a file found from carving. Could be on top of a TSK_DB_FILES_TYPE_UNALLOC_BLOCKS ra...
BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment)
long countFilesWhere(String sqlWhereClause)
long getBlackboardArtifactsCount(ARTIFACT_TYPE artifactType, long obj_id)
boolean isFileFromSource(Content dataSource, long fileId)
ArrayList< BlackboardArtifact > getMatchingArtifacts(String whereClause)
VirtualDirectory addVirtualDirectory(long parentId, String directoryName, CaseDbTransaction transaction)
ArrayList< BlackboardArtifact.ARTIFACT_TYPE > getBlackboardArtifactTypesInUse()
void deleteReport(Report report)
List< Image > getImages()
int getAttrTypeID(String attrTypeName)
Image getImageById(long id)
List< Content > getChildren()
USED
Metadata structure has been allocated at least once.
LOCAL_DIR
Local directory that was added (not from a disk image)
final List< LayoutFile > addCarvedFiles(CarvingResult carvingResult)
void releaseSingleUserCaseReadLock()
void closeRunQuery(ResultSet resultSet)
DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, Content parentObj, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)
int addAttrType(String attrTypeString, String displayName)
void deleteBlackboardArtifactTag(BlackboardArtifactTag tag)
List< ContentTag > getContentTagsByTagName(TagName tagName)
BlackboardArtifact newBlackboardArtifact(int artifactTypeID, long obj_id)
static String escapeSingleQuotes(String text)
String getAttrTypeDisplayName(int attrTypeID)
List< BlackboardArtifact > getBlackboardArtifacts(ARTIFACT_TYPE artifactType, BlackboardAttribute.ATTRIBUTE_TYPE attrType, String value)
List< AbstractFile > findFiles(Content dataSource, String fileName)
List< TagName > getAllTagNames()
BlackboardAttribute.Type getAttributeType(String attrTypeName)
Image addImageInfo(long deviceObjId, List< String > imageFilePaths, String timeZone)
static HTML_COLOR getColorByName(String colorName)
void acquireSingleUserCaseWriteLock()
List< AbstractFile > findFilesByMd5(String md5Hash)
BlackboardArtifact.Type getArtifactType(String artTypeName)
BlackboardArtifact newBlackboardArtifact(ARTIFACT_TYPE artifactType, long obj_id)
void releaseSingleUserCaseWriteLock()
DERIVED
File derived from a parent file (i.e. from ZIP)
List< LayoutFile > addCarvedFiles(List< CarvedFileContainer > filesToAdd)
List< BlackboardArtifactTag > getBlackboardArtifactTagsByTagName(TagName tagName)
static TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE fromType(long typeId)
static SleuthkitCase newCase(String caseName, CaseDbConnectionInfo info, String caseDirPath)
Report addReport(String localPath, String sourceModuleName, String reportName)
void releaseExclusiveLock()
List< BlackboardArtifactTag > getAllBlackboardArtifactTags()
ArrayList< BlackboardArtifact > getBlackboardArtifacts(String artifactTypeName, long obj_id)
void removeErrorObserver(ErrorObserver observer)
String getContextString()
List< Content > getRootObjects()
void acquireExclusiveLock()
boolean allFilesMd5Hashed()
String getAttrTypeString(int attrTypeID)
int getBlackboardAttributeTypesCount()
List< AbstractFile > findFiles(Content dataSource, String fileName, String dirName)
LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize, long containerId, List< TskFileRange > data)
ArrayList< BlackboardAttribute.ATTRIBUTE_TYPE > getBlackboardAttributeTypes()
UNALLOC_BLOCKS
Set of blocks not allocated by file system. Parent should be image, volume, or file system...
LocalFile addLocalFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, TskData.EncodingType encodingType, AbstractFile parent)
ArrayList< BlackboardAttribute > getMatchingAttributes(String whereClause)
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, String value)
long getBlackboardArtifactsTypeCount(int artifactTypeID)
void deleteContentTag(ContentTag tag)
static ObjectType valueOf(short objectType)
long getContentTagsCountByTagName(TagName tagName)
void updateImagePath(String newPath, long objectId)
UNKNOWN
File marked as unknown by hash db.
List< AbstractFile > findAllFilesWhere(String sqlWhereClause)
boolean setKnown(AbstractFile file, FileKnown fileKnown)
static void tryConnect(CaseDbConnectionInfo info)
static SleuthkitCase openCase(String dbPath)
CaseDbQuery executeInsertOrUpdate(String query)
static String createNonUniquePath(String uniquePath)
long getBlackboardArtifactsCount(int artifactTypeID, long obj_id)
void submitError(String context, String errorMessage)
final List< IngestJobInfo > getIngestJobs()
ALLOC
Name is in an allocated state.
VIRTUAL_DIR
Virtual directory (not on fs) with no meta-data entry that can be used to group files of types other ...
static SleuthkitCase newCase(String dbPath)
String getBackupDatabasePath()
void acquireSingleUserCaseReadLock()
VirtualDirectory addVirtualDirectory(long parentId, String directoryName)
List< ContentTag > getContentTagsByContent(Content content)
ArrayList< BlackboardArtifact > getBlackboardArtifacts(ARTIFACT_TYPE artifactType, long obj_id)
int countFsContentType(TskData.TSK_FS_META_TYPE_ENUM contentType)
TagName addTagName(String displayName, String description, TagName.HTML_COLOR color)
ABSTRACTFILE
File - see tsk_files for more details.
ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset)
DataSource getDataSource(long objectId)
List< BlackboardArtifact > getBlackboardArtifacts(BlackboardAttribute.ATTRIBUTE_TYPE attrType, String subString, boolean startsWith)
TSK_FS_META_TYPE_REG
Regular file NON-NLS.
Iterable< BlackboardArtifact.Type > getArtifactTypes()
List< BlackboardAttribute.Type > getAttributeTypes()
LocalFilesDataSource addLocalFilesDataSource(String deviceId, String rootDirectoryName, String timeZone, CaseDbTransaction transaction)
AddImageProcess makeAddImageProcess(String timeZone, boolean addUnallocSpace, boolean noFatFsOrphans, String imageCopyPath)
List< FsContent > findFilesWhere(String sqlWhereClause)
static ReviewStatus withID(int id)
void copyCaseDB(String newDBPath)
ResultSet runQuery(String query)
List< TskFileRange > getFileRanges(long id)
BlackboardArtifact.Type addBlackboardArtifactType(String artifactTypeName, String displayName)
LocalFile addLocalFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, TskData.EncodingType encodingType, AbstractFile parent, CaseDbTransaction transaction)
CaseDbQuery executeQuery(String query)
void setReviewStatus(BlackboardArtifact artifact, BlackboardArtifact.ReviewStatus newStatus)
void setImagePaths(long obj_id, List< String > paths)
IMG
Disk Image - see tsk_image_info for more details.
UNALLOC
Name is in an unallocated state.
Collection< FileSystem > getFileSystems(Image image)
LocalDirectory addLocalDirectory(long parentId, String directoryName)