diff --git a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java index b92d33debc572d378ac575621a7c302af202c7a1..524d2d99972cbcb57a54edf5eea0027702f1577e 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java +++ b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java @@ -392,7 +392,7 @@ long addUnallocFsBlockFilesParent(long fsObjId, String name) { logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId); return -1; } - VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans); + VirtualDirectory dir = caseDb.addVirtualDirectoryJNI(fsIdToRootDir.get(fsObjId), name, trans); return dir.getId(); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex); diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index c548f023b69b4fed510812b6eac77f352540ac64..af4eb9b739a4c62b2b114aedd3f31796ac2c8af2 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -11144,7 +11144,7 @@ long addFileJNI(long parentObjId, Statement queryStatement = null; try { - transaction.acquireSingleUserCaseWriteLock(); + acquireSingleUserCaseWriteLock(); CaseDbConnection connection = transaction.getConnection(); // Insert a row for the local/logical file into the tsk_objects table. @@ -11256,6 +11256,7 @@ long addFileJNI(long parentObjId, throw new TskCoreException("Failed to add file system file", ex); } finally { closeStatement(queryStatement); + releaseSingleUserCaseWriteLock(); } } @@ -11274,7 +11275,7 @@ long addFileJNI(long parentObjId, void addLayoutFileRangeJNI(long objId, long byteStart, long byteLen, long seq, CaseDbTransaction transaction) throws TskCoreException { try { - transaction.acquireSingleUserCaseWriteLock(); + acquireSingleUserCaseWriteLock(); CaseDbConnection connection = transaction.getConnection(); PreparedStatement prepStmt = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LAYOUT_FILE); @@ -11286,8 +11287,134 @@ void addLayoutFileRangeJNI(long objId, long byteStart, long byteLen, connection.executeUpdate(prepStmt); } catch (SQLException ex) { throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex); + } finally { + releaseSingleUserCaseWriteLock(); } } + + /** + * Adds a virtual directory to the database and returns a VirtualDirectory + * object representing it. + * + * Make sure the connection in transaction is used for all database + * interactions called by this method + * + * @param parentId the ID of the parent, or 0 if NULL + * @param directoryName the name of the virtual directory to create + * @param transaction the transaction in the scope of which the operation + * is to be performed, managed by the caller + * + * @return a VirtualDirectory object representing the one added to the + * database. + * + * @throws TskCoreException + */ + public VirtualDirectory addVirtualDirectoryJNI(long parentId, String directoryName, CaseDbTransaction transaction) throws TskCoreException { + if (transaction == null) { + throw new TskCoreException("Passed null CaseDbTransaction"); + } + + acquireSingleUserCaseWriteLock(); + ResultSet resultSet = null; + try { + // Get the parent path. + CaseDbConnection connection = transaction.getConnection(); + + String parentPath; + Content parent = this.getAbstractFileById(parentId, connection); + if (parent instanceof AbstractFile) { + if (isRootDirectory((AbstractFile) parent, transaction)) { + parentPath = "/"; + } else { + parentPath = ((AbstractFile) parent).getParentPath() + parent.getName() + "/"; //NON-NLS + } + } else { + // The parent was either null or not an abstract file + parentPath = "/"; + } + + // Insert a row for the virtual directory into the tsk_objects table. + long newObjId = addObject(parentId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection); + + // Insert a row for the virtual directory into the tsk_files table. + // 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, md5, known, mime_type, parent_path, data_source_obj_id,extension) + // VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?) + PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE); + statement.clearParameters(); + statement.setLong(1, newObjId); + + // If the parent is part of a file system, grab its file system ID + if (0 != parentId) { + long parentFs = this.getFileSystemId(parentId, connection); + if (parentFs != -1) { + statement.setLong(2, parentFs); + } else { + statement.setNull(2, java.sql.Types.BIGINT); + } + } else { + statement.setNull(2, java.sql.Types.BIGINT); + } + + // name + statement.setString(3, directoryName); + + //type + statement.setShort(4, TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()); + statement.setShort(5, (short) 1); + + //flags + final TSK_FS_NAME_TYPE_ENUM dirType = TSK_FS_NAME_TYPE_ENUM.DIR; + statement.setShort(6, dirType.getValue()); + final TSK_FS_META_TYPE_ENUM metaType = TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR; + statement.setShort(7, metaType.getValue()); + + //allocated + final TSK_FS_NAME_FLAG_ENUM dirFlag = TSK_FS_NAME_FLAG_ENUM.ALLOC; + statement.setShort(8, dirFlag.getValue()); + final short metaFlags = (short) (TSK_FS_META_FLAG_ENUM.ALLOC.getValue() + | TSK_FS_META_FLAG_ENUM.USED.getValue()); + statement.setShort(9, metaFlags); + + //size + statement.setLong(10, 0); + + // nulls for params 11-14 + statement.setNull(11, java.sql.Types.BIGINT); + statement.setNull(12, java.sql.Types.BIGINT); + statement.setNull(13, java.sql.Types.BIGINT); + statement.setNull(14, java.sql.Types.BIGINT); + + statement.setNull(15, java.sql.Types.VARCHAR); // MD5 + statement.setByte(16, FileKnown.UNKNOWN.getFileKnownValue()); // Known + statement.setNull(17, java.sql.Types.VARCHAR); // MIME type + + // parent path + statement.setString(18, parentPath); + + // data source object id (same as object id if this is a data source) + long dataSourceObjectId; + if (0 == parentId) { + dataSourceObjectId = newObjId; + } else { + dataSourceObjectId = getDataSourceObjectId(connection, parentId); + } + statement.setLong(19, dataSourceObjectId); + + //extension, since this is not really file we just set it to null + statement.setString(20, null); + connection.executeUpdate(statement); + + return new VirtualDirectory(this, newObjId, dataSourceObjectId, directoryName, dirType, + metaType, dirFlag, metaFlags, null, FileKnown.UNKNOWN, + parentPath); + } catch (SQLException e) { + throw new TskCoreException("Error creating virtual directory '" + directoryName + "'", e); + } finally { + closeResultSet(resultSet); + releaseSingleUserCaseWriteLock(); + } + } /** * Stores a pair of object ID and its type diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java index 496d6fb51fda54d4f9d7da0f1bbb16f7454974b2..6697a50ae0a44e570c086785a370ddf5f3e710e9 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -414,15 +414,18 @@ long addImageInfo(long deviceObjId, List<String> imageFilePaths, String timeZone JniDbHelper dbHelper = new JniDbHelper(skCase); try { dbHelper.beginTransaction(); + long startTime = System.currentTimeMillis(); long tskAutoDbPointer = initializeAddImgNat(caseDbPointer, dbHelper, timezoneLongToShort(timeZone), false, false, false); runOpenAndAddImgNat(tskAutoDbPointer, UUID.randomUUID().toString(), imageFilePaths.toArray(new String[0]), imageFilePaths.size(), timeZone); long id = finishAddImgNat(tskAutoDbPointer); + long endTime = System.currentTimeMillis(); + System.out.println("### addImage time: " + (endTime - startTime) + " ms"); skCase.addDataSourceToHasChildrenMap(); return id; } catch (TskDataException ex) { throw new TskCoreException("Error adding image to case database", ex); } finally { - dbHelper.commitTransaction(); + dbHelper.commitTransaction(); // TODO - is this right? } } @@ -507,7 +510,7 @@ public void run(String deviceId, String[] imageFilePaths, int sectorSize) throws getTSKReadLock(); try { long imageHandle = 0; - + long startTime = System.currentTimeMillis(); synchronized (this) { if (0 != tskAutoDbPointer) { throw new TskCoreException("Add image process already started"); @@ -524,6 +527,8 @@ public void run(String deviceId, String[] imageFilePaths, int sectorSize) throws if (imageHandle != 0) { runAddImgNat(tskAutoDbPointer, deviceId, imageHandle, timeZone, imageWriterPath); } + long endTime = System.currentTimeMillis(); + System.out.println("### addImage time: " + (endTime - startTime) + " ms"); } finally { releaseTSKReadLock(); }