diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp index 35e18a139731694850f96c94e31baa90dbfd8dd2..7b1d4d4cb69c1cc2d0fbecc1d3a7767e36515f80 100644 --- a/bindings/java/jni/dataModel_SleuthkitJNI.cpp +++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp @@ -1604,6 +1604,48 @@ Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat(JNIEnv * env, } +/** + * Runs istat on a given file and saves the output to a temp file. + * + * @returns -1 on error (and throws exception) + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat + (JNIEnv *env, jclass obj, jlong a_file_handle, jstring a_tmp_path) +{ + const TSK_JNI_FILEHANDLE *file_handle = castFsFile(env, a_file_handle); + if (file_handle == 0) { + //exception already set + return -1; + } + + // check the pointers + if (file_handle->fs_file == NULL || file_handle->fs_file->fs_info == NULL || file_handle->fs_file->meta == NULL) { + setThrowTskCoreError(env, "NULL pointers for istat file."); + return -1; + } + TSK_FS_INFO *fs_info = file_handle->fs_file->fs_info; + + // open a file to write the details to + jboolean isCopy; + char *str8 = (char *) env->GetStringUTFChars(a_tmp_path, &isCopy); + FILE *hFile = fopen(str8, "w"); + if (hFile == NULL) { + env->ReleaseStringUTFChars(a_tmp_path, str8); + setThrowTskCoreError(env, "Couldn't open istat temp file for writing."); + return -1; + } + env->ReleaseStringUTFChars(a_tmp_path, str8); + + if (fs_info->istat(fs_info, hFile, file_handle->fs_file->meta->addr, 0, 0) != 0) { + fclose(hFile); + setThrowTskCoreError(env); + return -1; + } + + fclose(hFile); + return 0; +} + /* * Close the given image * @param env pointer to java environment this was called from diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.h b/bindings/java/jni/dataModel_SleuthkitJNI.h index 03c3ad83187c2fa344793da19da644a4646a9ece..3daa672b8c11c4e0e66c670e30ac067ad51dccff 100644 --- a/bindings/java/jni/dataModel_SleuthkitJNI.h +++ b/bindings/java/jni/dataModel_SleuthkitJNI.h @@ -1,3 +1,4 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_sleuthkit_datamodel_SleuthkitJNI */ @@ -61,84 +62,80 @@ JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbOpenNat * Method: hashDbNewNat * Signature: (Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat(JNIEnv * env, - jclass obj, jstring pathJ); - -JNIEXPORT jint JNICALL -Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat( - JNIEnv *env, jclass obj, jint dbHandle); +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbNewNat + (JNIEnv *, jclass, jstring); -JNIEXPORT jint JNICALL -Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat( - JNIEnv *env, jclass obj, jint dbHandle); +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbBeginTransactionNat + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbBeginTransactionNat + (JNIEnv *, jclass, jint); -JNIEXPORT jint JNICALL -Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat( - JNIEnv *env, jclass obj, jint dbHandle); +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbCommitTransactionNat + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCommitTransactionNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbAddRecordNat - * Signature: + * Method: hashDbRollbackTransactionNat + * Signature: (I)I */ -JNIEXPORT jint JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat(JNIEnv * env, - jclass obj, jstring filenameJ, jstring hashMd5J, jstring hashSha1J, jstring hashSha256J, - jstring commentJ, jint dbHandle); +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbRollbackTransactionNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbIsUpdateableNat - * Signature: + * Method: hashDbAddEntryNat + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I */ -JNIEXPORT jboolean JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat(JNIEnv * env, - jclass obj, jint dbHandle); +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbAddEntryNat + (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbIsIdxOnlyNat - * Signature: + * Method: hashDbIsUpdateableNat + * Signature: (I)Z */ -JNIEXPORT jboolean JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat(JNIEnv * env, - jclass obj, jint dbHandle); +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsUpdateableNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: hashDbIsReindexableNat - * Signature: + * Signature: (I)Z */ -JNIEXPORT jboolean JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat(JNIEnv * env, - jclass obj, jint dbHandle); +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsReindexableNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: hashDbPathNat - * Signature: + * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat(JNIEnv * env, - jclass obj, jint dbHandle); +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbPathNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: hashDbIndexPathNat - * Signature: + * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL - Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat(JNIEnv * env, - jclass obj, jint dbHandle); +JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexPathNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbGetName - * Signature: + * Method: hashDbGetDisplayName + * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbGetDisplayName - (JNIEnv *, jclass, jint dbHandle); + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI @@ -151,23 +148,47 @@ JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCloseAll /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: hashDbClose - * Signature: + * Signature: (I)V */ JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbClose - (JNIEnv *, jclass, jint dbHandle); + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbCreateIndexNat + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIndexExistsNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat + (JNIEnv *, jclass, jint); + +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: hashDbIsIdxOnlyNat + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIsIdxOnlyNat + (JNIEnv *, jclass, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: hashDbLookup - * Signature: (Ljava/lang/String;I)B + * Signature: (Ljava/lang/String;I)Z */ JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookup (JNIEnv *, jclass, jstring, jint); /* * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbLookup - * Signature: (Ljava/lang/String;I)Lorg/sleuthkit/datamodel/HashInfo + * Method: hashDbLookupVerbose + * Signature: (Ljava/lang/String;I)Lorg/sleuthkit/datamodel/HashHitInfo; */ JNIEXPORT jobject JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookupVerbose (JNIEnv *, jclass, jstring, jint); @@ -292,6 +313,14 @@ JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFsNat JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_readFileNat (JNIEnv *, jclass, jlong, jbyteArray, jlong, jlong); +/* + * Class: org_sleuthkit_datamodel_SleuthkitJNI + * Method: saveFileMetaDataTextNat + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDataTextNat + (JNIEnv *, jclass, jlong, jstring); + /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: closeImgNat @@ -324,22 +353,6 @@ JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFsNat JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_closeFileNat (JNIEnv *, jclass, jlong); -/* - * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbCreateIndexNat - * Signature: - */ -JNIEXPORT void JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbCreateIndexNat - (JNIEnv *, jclass, jint); - -/* - * Class: org_sleuthkit_datamodel_SleuthkitJNI - * Method: hashDbIndexExistsNat - * Signature: - */ -JNIEXPORT jboolean JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbIndexExistsNat - (JNIEnv *, jclass, jint); - /* * Class: org_sleuthkit_datamodel_SleuthkitJNI * Method: findDeviceSizeNat @@ -360,3 +373,25 @@ JNIEXPORT jstring JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_getCurDirNat } #endif #endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess */ + +#ifndef _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess +#define _Included_org_sleuthkit_datamodel_SleuthkitJNI_CaseDbHandle_AddImageProcess +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java index 4a987335a11ec5bea935611a15a663e80493882e..d8f7ac8e2108a541f93a004cb271d5d0496a5f70 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java +++ b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java @@ -18,10 +18,10 @@ */ package org.sleuthkit.datamodel; +import java.util.List; +import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.ResourceBundle; - import org.sleuthkit.datamodel.TskData.FileKnown; import org.sleuthkit.datamodel.TskData.TSK_FS_ATTR_TYPE_ENUM; import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM; @@ -45,6 +45,8 @@ public abstract class FsContent extends AbstractFile { ///read-write database tsk_files fields private final SleuthkitCase tskCase; + private List<String> metaDataText = null; + /** * parent file system */ @@ -124,6 +126,21 @@ public FileSystem getFileSystem() throws TskCoreException { } return parentFileSystem; } + + /** + * Open JNI file handle if it is not open already + * + * @throws TskCoreException + */ + private void loadFileHandle() throws TskCoreException { + if (fileHandle == 0) { + synchronized (this) { + if (fileHandle == 0) { + fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId); + } + } + } + } @Override @SuppressWarnings("deprecation") @@ -133,13 +150,7 @@ protected int readInt(byte[] buf, long offset, long len) throws TskCoreException //special case for 0-size file return 0; } - if (fileHandle == 0) { - synchronized (this) { - if (fileHandle == 0) { - fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId); - } - } - } + loadFileHandle(); return SleuthkitJNI.readFile(fileHandle, buf, offset, len); } catch (TskCoreException ex) { @@ -198,6 +209,24 @@ public synchronized String getUniquePath() throws TskCoreException { } return uniquePath; } + + /** + * Return a text-based description of the file's metadata. + * This is the same content as the TSK istat tool produces. + * Is different information for each type of file system. + * + * @return List of text, one string per line. + * @throws TskCoreException + */ + public List<String> getMetaDataText() throws TskCoreException { + if (metaDataText != null) { + return metaDataText; + } + + loadFileHandle(); + metaDataText = SleuthkitJNI.getFileMetaDataText(fileHandle); + return metaDataText; + } @Override public void close() { diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java index 91acb6e8c57afefb4f07a1d1c1cbdfb50de7cbea..30c95a212224c3947d7c64aec3b56e43de44cc95 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -18,11 +18,15 @@ */ package org.sleuthkit.datamodel; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.GregorianCalendar; -import java.util.List; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimeZone; import org.sleuthkit.datamodel.TskData.TSK_FS_ATTR_TYPE_ENUM; @@ -121,6 +125,8 @@ public class SleuthkitJNI { private static native int readFileNat(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException; + private static native int saveFileMetaDataTextNat(long fileHandle, String fileName) throws TskCoreException; + //close functions private static native void closeImgNat(long imgHandle); @@ -523,6 +529,39 @@ public static int readFs(long fsHandle, byte[] readBuffer, long offset, long len public static int readFile(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException { return readFileNat(fileHandle, readBuffer, offset, len); } + + + /** + * Get human readable (some what) details about a file. This is the same as the 'istat' TSK tool + * @param fileHandle pointer to file structure in the sleuthkit + * @return text + * @throws TskCoreException if errors occurred + */ + public static List<String> getFileMetaDataText(long fileHandle) throws TskCoreException { + try { + java.io.File tmp = java.io.File.createTempFile("tsk", ".txt"); + + saveFileMetaDataTextNat(fileHandle, tmp.getAbsolutePath()); + + FileReader fr = new FileReader(tmp.getAbsolutePath()); + BufferedReader textReader = new BufferedReader(fr); + + List<String> lines = new ArrayList<String>(); + while (true) { + String line = textReader.readLine(); + if (line == null) { + break; + } + lines.add(line); + } + + tmp.delete(); + return lines; + } catch (IOException ex) { + throw new TskCoreException("Error reading istat output: " + ex.getLocalizedMessage()); + } + } + //free pointers /**