diff --git a/bindings/java/jni/auto_db_java.cpp b/bindings/java/jni/auto_db_java.cpp index c3833d86c776830b5bf30142a7f58fafc116b655..969d87ba117d3a9b4959ad27feb27c116d42b62f 100644 --- a/bindings/java/jni/auto_db_java.cpp +++ b/bindings/java/jni/auto_db_java.cpp @@ -115,11 +115,6 @@ TskAutoDbJava::initializeJni(JNIEnv * jniEnv, jobject jobj) { return TSK_ERR; } - m_getParentIdMethodID = m_jniEnv->GetMethodID(m_callbackClass, "findParentObjId", "(JJLjava/lang/String;Ljava/lang/String;)J"); - if (m_getParentIdMethodID == NULL) { - return TSK_ERR; - } - m_addUnallocParentMethodID = m_jniEnv->GetMethodID(m_callbackClass, "addUnallocFsBlockFilesParent", "(JLjava/lang/String;)J"); if (m_addUnallocParentMethodID == NULL) { return TSK_ERR; @@ -464,56 +459,10 @@ void extractExtension(char *name, char *extension) { } } -/** -* Store info about a directory in a complex map structure as a cache for the -* files who are a child of this directory and want to know its object id. -* -* @param fsObjId fs id of this directory -* @param fs_file File for the directory to store -* @param path Full path (parent and this file) of the directory -* @param objId object id of the directory -*/ -void TskAutoDbJava::storeObjId(const int64_t& fsObjId, const TSK_FS_FILE* fs_file, const char* path, const int64_t& objId) -{ - // skip the . and .. entries - if ((fs_file->name) && (fs_file->name->name) && (TSK_FS_ISDOT(fs_file->name->name))) - { - return; - } - - uint32_t seq; - uint32_t path_hash = hash((const unsigned char *)path); - - /* NTFS uses sequence, otherwise we hash the path. We do this to map to the - * correct parent folder if there are two from the root dir that eventually point to - * the same folder (one deleted and one allocated) or two hard links. */ - if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) { - /* Use the sequence stored in meta (which could be one larger than the name value - * if the directory is deleted. We do this because the par_seq gets added to the - * name structure when it is added to the directory based on teh value stored in - * meta. */ - seq = fs_file->meta->seq; - } - else { - seq = path_hash; - } - - map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > >& fsMap = m_parentDirIdCache[fsObjId]; - if (fsMap.count(fs_file->name->meta_addr) == 0) { - fsMap[fs_file->name->meta_addr][seq][path_hash] = objId; - } - else { - map<uint32_t, map<uint32_t, int64_t> >& fileMap = fsMap[fs_file->name->meta_addr]; - if (fileMap.count(seq) == 0) { - fileMap[seq][path_hash] = objId; - } - } -} - - /** * Adds a file and its associated slack file to database. -* Does not learn object ID for new files. +* Does not learn object ID for new files, and files may +* not be added to the database immediately. * * @param fs_file * @param fs_attr @@ -878,161 +827,6 @@ TskAutoDbJava::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t& objI return TSK_OK; } -/** -* Return a hash of the passed in string. We use this -* for full paths. -* From: http://www.cse.yorku.ca/~oz/hash.html -*/ -uint32_t -TskAutoDbJava::hash(const unsigned char* str) -{ - uint32_t hash = 5381; - int c; - - while ((c = *str++)) { - // skip slashes -> normalizes leading/ending/double slashes - if (c == '/') - continue; - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - } - - return hash; -} - -/* -* Utility method to break up path into parent folder and folder/file name. -* @param path Path of folder that we want to analyze -* @param ret_parent_path pointer to parent path (begins and ends with '/') -* @param ret_name pointer to final folder/file name -* @returns 0 on success, 1 on error -*/ -bool -TskAutoDbJava::getParentPathAndName(const char *path, const char **ret_parent_path, const char **ret_name) { - // Need to break up 'path' in to the parent folder to match in 'parent_path' and the folder - // name to match with the 'name' column in tsk_files table - - // reset all arrays - parent_name[0] = '\0'; - parent_path[0] = '\0'; - - size_t path_len = strlen(path); - if (path_len >= MAX_PATH_LENGTH_JAVA_DB_LOOKUP) { - tsk_error_reset(); - tsk_error_set_errno(TSK_ERR_AUTO_DB); - tsk_error_set_errstr("TskDb::getParentPathAndName: Path is too long. Length = %zd, Max length = %d", path_len, MAX_PATH_LENGTH_JAVA_DB_LOOKUP); - // assign return values to pointers - *ret_parent_path = ""; - *ret_name = ""; - return 1; - } - - // check if empty path or just "/" were passed in - if (path_len == 0 || (strcmp(path, "/") == 0)) { - *ret_name = ""; - *ret_parent_path = "/"; - return 0; - } - - - // step 1, copy everything into parent_path and clean it up - // add leading slash if its not in input. - if (path[0] != '/') { - sprintf(parent_path, "%s", "/"); - } - - strncat(parent_path, path, MAX_PATH_LENGTH_JAVA_DB_LOOKUP); - - // remove trailing slash - if (parent_path[strlen(parent_path) - 1] == '/') { - parent_path[strlen(parent_path) - 1] = '\0'; - } - - // replace all non-UTF8 characters - tsk_cleanupUTF8(parent_path, '^'); - - // Step 2, move the final folder/file to parent_file - - // Find the last '/' - char *chptr = strrchr(parent_path, '/'); - if (chptr) { - // character found in the string - size_t position = chptr - parent_path; - - sprintf(parent_name, "%s", chptr + 1); // copy everything after slash into parent_name - *ret_name = parent_name; - - parent_path[position + 1] = '\0'; // add terminating null after last "/" - *ret_parent_path = parent_path; - } - else { - // "/" character not found. the entire path is parent file name. parent path is "/" - *ret_name = parent_path; - *ret_parent_path = "/"; - } - return 0; -} - -/** -* Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL -* @param fs_file file to find parent obj id for -* @param parentPath Path of parent folder that we want to match -* @param fsObjId fs id of this file -* @returns parent obj id ( > 0), -1 on error -*/ -int64_t -TskAutoDbJava::findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, const int64_t& fsObjId) -{ - uint32_t seq; - uint32_t path_hash = hash((const unsigned char *)parentPath); - - /* NTFS uses sequence, otherwise we hash the path. We do this to map to the - * correct parent folder if there are two from the root dir that eventually point to - * the same folder (one deleted and one allocated) or two hard links. */ - if (TSK_FS_TYPE_ISNTFS(fs_file->fs_info->ftype)) - { - seq = fs_file->name->par_seq; - } - else - { - seq = path_hash; - } - - //get from cache by parent meta addr, if available - map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > >& fsMap = m_parentDirIdCache[fsObjId]; - if (fsMap.count(fs_file->name->par_addr) > 0) - { - map<uint32_t, map<uint32_t, int64_t> >& fileMap = fsMap[fs_file->name->par_addr]; - if (fileMap.count(seq) > 0) { - map<uint32_t, int64_t>& pathMap = fileMap[seq]; - if (pathMap.count(path_hash) > 0) { - return pathMap[path_hash]; - } - } - } - - // Need to break up 'path' in to the parent folder to match in 'parent_path' and the folder - // name to match with the 'name' column in tsk_files table - const char *parent_name = ""; - const char *parent_path = ""; - if (getParentPathAndName(parentPath, &parent_path, &parent_name)) { - return -1; - } - - jstring jpath = m_jniEnv->NewStringUTF(parent_path); - jstring jname = m_jniEnv->NewStringUTF(parent_name); - - // Look up in the database - jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_getParentIdMethodID, - fs_file->name->par_addr, fsObjId, jpath, jname); - int64_t objId = (int64_t)objIdj; - - if (objId < 0) { - return -1; - } - - return objId; -} - /** * Adds a new volume that will hold the unallocated blocks for the pool. * diff --git a/bindings/java/jni/auto_db_java.h b/bindings/java/jni/auto_db_java.h index 9ff046ce11a5611761f525413faee10812f21ff5..e6c5e68dd7217d784695749cf53c24df090db75d 100644 --- a/bindings/java/jni/auto_db_java.h +++ b/bindings/java/jni/auto_db_java.h @@ -143,16 +143,6 @@ class TskAutoDbJava :public TskAuto { std::map<int64_t, int64_t> m_poolOffsetToParentId; std::map<int64_t, int64_t> m_poolOffsetToVsId; - // Used to look up object IDs for files - #define MAX_PATH_LENGTH_JAVA_DB_LOOKUP 2048 - char parent_name[MAX_PATH_LENGTH_JAVA_DB_LOOKUP]; - char parent_path[MAX_PATH_LENGTH_JAVA_DB_LOOKUP + 2]; // +2 is for leading slash and trailing slash - map<int64_t, map<TSK_INUM_T, map<uint32_t, map<uint32_t, int64_t> > > > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to a map, which maps a sequence ID to a map, which maps a hash of a path to its object ID in the database - int64_t findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, const int64_t& fsObjId); - bool getParentPathAndName(const char *path, const char **ret_parent_path, const char **ret_name); - void storeObjId(const int64_t& fsObjId, const TSK_FS_FILE* fs_file, const char* path, const int64_t& objId); - uint32_t hash(const unsigned char* str); - // JNI data JNIEnv * m_jniEnv = NULL; jclass m_callbackClass = NULL; @@ -164,7 +154,6 @@ class TskAutoDbJava :public TskAuto { jmethodID m_addPoolMethodID = NULL; jmethodID m_addFileSystemMethodID = NULL; jmethodID m_addFileMethodID = NULL; - jmethodID m_getParentIdMethodID = NULL; jmethodID m_addUnallocParentMethodID = NULL; jmethodID m_addLayoutFileMethodID = NULL; jmethodID m_addLayoutFileRangeMethodID = NULL; diff --git a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java index 09285a40502f6b9f1c9042a0c675245159ede3f6..4f2e97246b222d0ad80f7406b7d36cd5e9a9264a 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java +++ b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java @@ -359,8 +359,7 @@ private long addBatchedFilesToDb() { } else { // The parent wasn't found in the cache so do a database query java.io.File parentAsFile = new java.io.File(parentPath); - computedParentObjId = findParentObjId(fileInfo.parMetaAddr, fileInfo.fsObjId, parentAsFile.getPath(), parentAsFile.getName()); - // TODO - error checking. findParentObjId might throw exception if not needed from native code TODO + computedParentObjId = caseDb.findParentObjIdJNI(fileInfo.parMetaAddr, fileInfo.fsObjId, parentAsFile.getPath(), parentAsFile.getName(), trans); } } @@ -509,28 +508,6 @@ private long addBatchedLayoutRangesToDb() { } } - /** - * Look up the parent of a file based on metadata address and name/path. - * Intended to be called from the native code during the add image process. - * // TODO is this still needed from native code????? - * // TODO note that transaction should be open - * - * @param metaAddr - * @param fsObjId - * @param path - * @param name - * - * @return The object ID of the parent or -1 if not found - */ - long findParentObjId(long metaAddr, long fsObjId, String path, String name) { - try { - return caseDb.findParentObjIdJNI(metaAddr, fsObjId, path, name, trans); - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error looking up parent with meta addr: " + metaAddr + " and name " + name, ex); - return -1; - } - } - /** * Add a virtual directory to hold unallocated file system blocks. * Intended to be called from the native code during the add image process. @@ -547,9 +524,9 @@ long addUnallocFsBlockFilesParent(long fsObjId, String name) { return -1; } beginTransaction(); - long objId = caseDb.addVirtualDirectoryJNI(fsIdToRootDir.get(fsObjId), name, trans); + VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans); commitTransaction(); - return objId; + return dir.getId(); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex); revertTransaction(); diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index bd102bf42a5a61accdeeddf4d2efb054352778c5..e835158cba185e1d6dcc1984b37edd0a84bd86b9 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -11106,10 +11106,10 @@ long findParentObjIdJNI(long metaAddr, long fsObjId, String path, String name, C if (resultSet.next()) { return resultSet.getLong("obj_id"); } else { - throw new TskCoreException(String.format("Error looking up parent meta addr %d", metaAddr)); + throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name)); } } catch (SQLException ex) { - throw new TskCoreException(String.format("Error looking up parent meta addr %d", metaAddr), ex); + throw new TskCoreException(String.format("Error looking up parent - meta addr: %d, path: %s, name: %s", metaAddr, path, name), ex); } finally { closeResultSet(resultSet); } @@ -11317,121 +11317,6 @@ void addLayoutFileRangeJNI(long objId, long byteStart, long byteLen, releaseSingleUserCaseWriteLock(); } } - - /** - * Adds a virtual directory to the database and returns a VirtualDirectory - * object representing it. - * For use with the JNI callbacks associated with the add image process. - * - * @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 The object ID of the new virtual directory - * - * @throws TskCoreException - */ - long addVirtualDirectoryJNI(long parentId, String directoryName, CaseDbTransaction transaction) throws TskCoreException { - 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 newObjId; - } 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 1ecd0cf20dd1c70f6d714824e76f037b51e571fa..4fe44e69095ea9e9a78621ed570f2a5b3417896d 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -531,11 +531,7 @@ public void run(String deviceId, String[] imageFilePaths, int sectorSize) throws } } if (imageHandle != 0) { - long startTime = System.currentTimeMillis(); runAddImgNat(tskAutoDbPointer, deviceId, imageHandle, timeZone, imageWriterPath); - long endTime = System.currentTimeMillis(); - long elapsed = endTime - startTime; - System.out.println("\n### runAddImgNat time: " + elapsed + " ms\n"); } } finally { releaseTSKReadLock();