From fb1138cc3b5d3762559a7d5aa9c0ddffb524de2a Mon Sep 17 00:00:00 2001
From: Karl Mortensen <kmortensen@basistech.com>
Date: Wed, 17 Feb 2016 10:29:21 -0500
Subject: [PATCH] Add data_source_obj_id column

---
 tools/autotools/tsk_comparedir.cpp |   3 +-
 tools/autotools/tsk_gettimes.cpp   |   8 +-
 tools/autotools/tsk_recover.cpp    |   4 +-
 tsk/auto/auto.cpp                  |   8 +-
 tsk/auto/auto_db.cpp               |  55 ++++-----
 tsk/auto/db_postgresql.cpp         | 177 +++++++----------------------
 tsk/auto/db_sqlite.cpp             |  64 +++++++----
 tsk/auto/tsk_auto.h                |  10 +-
 tsk/auto/tsk_case_db.h             |   8 +-
 tsk/auto/tsk_db.h                  |  12 +-
 tsk/auto/tsk_db_postgresql.h       |  19 ++--
 tsk/auto/tsk_db_sqlite.h           |  19 ++--
 12 files changed, 155 insertions(+), 232 deletions(-)

diff --git a/tools/autotools/tsk_comparedir.cpp b/tools/autotools/tsk_comparedir.cpp
index c1cf55040..9a0d9d483 100644
--- a/tools/autotools/tsk_comparedir.cpp
+++ b/tools/autotools/tsk_comparedir.cpp
@@ -408,7 +408,8 @@ main(int argc, char **argv1)
 
     tskCompareDir.setFileFilterFlags(TSK_FS_DIR_WALK_FLAG_ALLOC);
 
-    if (tskCompareDir.openImage(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) {
+	int64_t objId=0;
+    if (tskCompareDir.openImage(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize, objId)) {
         tsk_error_print(stderr);
         exit(1);
     }
diff --git a/tools/autotools/tsk_gettimes.cpp b/tools/autotools/tsk_gettimes.cpp
index 7458b3c3d..66b801ff3 100644
--- a/tools/autotools/tsk_gettimes.cpp
+++ b/tools/autotools/tsk_gettimes.cpp
@@ -214,10 +214,10 @@ main(int argc, char **argv1)
             "Missing image name\n");
         usage();
     }
-
-    TskGetTimes tskGetTimes(sec_skew, do_hash);
-    if (tskGetTimes.openImage(argc - OPTIND, &argv[OPTIND], imgtype,
-            ssize)) {
+	
+	TskGetTimes tskGetTimes(sec_skew, do_hash);
+	int64_t objId=0;
+    if (tskGetTimes.openImage(argc - OPTIND, &argv[OPTIND], imgtype, ssize, objId)) {
         tsk_error_print(stderr);
         exit(1);
     }
diff --git a/tools/autotools/tsk_recover.cpp b/tools/autotools/tsk_recover.cpp
index ac9acb1da..6723a1b21 100644
--- a/tools/autotools/tsk_recover.cpp
+++ b/tools/autotools/tsk_recover.cpp
@@ -489,8 +489,8 @@ main(int argc, char **argv1)
     TskRecover tskRecover(argv[argc-1]);
 
     tskRecover.setFileFilterFlags(walkflag);    
-    if (tskRecover.openImage(argc - OPTIND - 1, &argv[OPTIND], imgtype,
-            ssize)) {
+	int64_t objId=0;
+	if (tskRecover.openImage(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize, objId)) {
         tsk_error_print(stderr);
         exit(1);
     }
diff --git a/tsk/auto/auto.cpp b/tsk/auto/auto.cpp
index 40c2b6bbb..880c95ef1 100644
--- a/tsk/auto/auto.cpp
+++ b/tsk/auto/auto.cpp
@@ -69,11 +69,12 @@ bool TskAuto::isCurVsValid() const {
  * be equal to num_img and they must be in a sorted order)
  * @param a_imgType The disk image type (can be autodetection)
  * @param a_sSize Size of device sector in bytes (or 0 for default)
+ * @param dataSourceObjId The object ID for the data source
  * @returns 1 on error (messages were NOT registered), 0 on success
  */
 uint8_t
     TskAuto::openImage(int a_numImg, const TSK_TCHAR * const a_images[],
-    TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize)
+    TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize, int64_t & dataSourceObjId)
 {
     resetErrorList();
     if (m_img_info)
@@ -97,11 +98,12 @@ uint8_t
  * be equal to num_img and they must be in a sorted order)
  * @param a_imgType The disk image type (can be autodetection)
  * @param a_sSize Size of device sector in bytes (or 0 for default)
+ * @param dataSourceObjId The object ID for the data source
  * @returns 1 on error (messages were NOT registered), 0 on success
  */
 uint8_t
     TskAuto::openImageUtf8(int a_numImg, const char *const a_images[],
-    TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize)
+    TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize, int64_t & dataSourceObjId)
 {
     resetErrorList();
     if (m_img_info)
@@ -517,7 +519,7 @@ TSK_WALK_RET_ENUM
         // we have no way to register an error...
         return TSK_WALK_STOP;
     }
-    
+
     TSK_RETVAL_ENUM retval = tsk->processFile(a_fs_file, a_path);
     if ((retval == TSK_STOP) || (tsk->getStopProcessing()))
         return TSK_WALK_STOP;
diff --git a/tsk/auto/auto_db.cpp b/tsk/auto/auto_db.cpp
index f5b47a89d..1e1feb959 100644
--- a/tsk/auto/auto_db.cpp
+++ b/tsk/auto/auto_db.cpp
@@ -113,15 +113,16 @@ void TskAutoDb::setAddUnallocSpace(bool addUnallocSpace, int64_t chunkSize)
  * @param a_images Array of paths to the image parts
  * @param a_type Image type
  * @param a_ssize Size of device sector in bytes (or 0 for default)
+ * @param dataSourceObjId The object ID for the data source
  * @param a_deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID).
  * @return 0 for success, 1 for failure
  */
 uint8_t
     TskAutoDb::openImageUtf8(int a_num, const char *const a_images[],
-    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, const char* a_deviceId)
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, int64_t & dataSourceObjId, const char* a_deviceId)
 {
     uint8_t retval =
-        TskAuto::openImageUtf8(a_num, a_images, a_type, a_ssize);
+        TskAuto::openImageUtf8(a_num, a_images, a_type, a_ssize, dataSourceObjId);
     if (retval != 0) {
         return retval;
     }
@@ -129,6 +130,7 @@ uint8_t
     if (addImageDetails(a_deviceId, a_images, a_num)) {
         return 1;
     }
+	dataSourceObjId = m_curImgId;
     return 0;
 }
 
@@ -139,18 +141,19 @@ uint8_t
  * @param a_images Array of paths to the image parts
  * @param a_type Image type
  * @param a_ssize Size of device sector in bytes (or 0 for default)
+ * @param dataSourceObjId The object ID for the data source
  * @param a_deviceId An ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID).
  * @return 0 for success, 1 for failure
  */
 uint8_t
     TskAutoDb::openImage(int a_num, const TSK_TCHAR * const a_images[],
-    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, const char* a_deviceId)
+    TSK_IMG_TYPE_ENUM a_type, unsigned int a_ssize, int64_t & dataSourceObjId, const char* a_deviceId)
 {
 
 // make name of database
 #ifdef TSK_WIN32
 
-    uint8_t retval = TskAuto::openImage(a_num, a_images, a_type, a_ssize);
+    uint8_t retval = TskAuto::openImage(a_num, a_images, a_type, a_ssize, dataSourceObjId);
 
     if (retval != 0) {
         return retval;
@@ -197,10 +200,10 @@ uint8_t
         free(img_ptrs[i]);
     }
     free(img_ptrs);
-
+	dataSourceObjId = m_curImgId;
     return 0;
 #else
-    return openImageUtf8(a_num, a_images, a_type, a_ssize, a_deviceId);
+    return openImageUtf8(a_num, a_images, a_type, a_ssize, dataSourceObjId, a_deviceId);
 #endif
 }
 
@@ -218,7 +221,7 @@ TskAutoDb::addImageDetails(const char* deviceId, const char *const imgPaths[], i
    string md5 = "";
 #if HAVE_LIBEWF 
    if (m_img_info->itype == TSK_IMG_TYPE_EWF_EWF) {
-     // @@@ This shoudl really probably be inside of a tsk_img_ method
+     // @@@ This should really probably be inside of a tsk_img_ method
        IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *)m_img_info;
        if (ewf_info->md5hash_isset) {
            md5 = ewf_info->md5hash;
@@ -336,8 +339,7 @@ TSK_RETVAL_ENUM
     const unsigned char *const md5,
     const TSK_DB_FILES_KNOWN_ENUM known)
 {
-    if (m_db->addFsFile(fs_file, fs_attr, path, md5, known, m_curFsId,
-            m_curFileId)) {
+    if (m_db->addFsFile(fs_file, fs_attr, path, md5, known, m_curFsId, m_curFileId, m_curImgId)) {
         registerError();
         return TSK_ERR;
     }
@@ -439,8 +441,8 @@ uint8_t
     }
 
     m_imgTransactionOpen = true;
-
-    if (openImage(numImg, imagePaths, imgType, sSize, deviceId)) {
+	int64_t dataSourceObjId=-1;
+    if (openImage(numImg, imagePaths, imgType, sSize, dataSourceObjId, deviceId)) {
         tsk_error_set_errstr2("TskAutoDb::startAddImage");
         registerError();
         if (revertAddImage())
@@ -448,7 +450,7 @@ uint8_t
         return 1;
     }
     
-    return addFilesInImgToDb();
+	return addFilesInImgToDb();
 }
 
 
@@ -470,7 +472,8 @@ uint8_t
     TskAutoDb::startAddImage(int numImg, const char *const imagePaths[],
     TSK_IMG_TYPE_ENUM imgType, unsigned int sSize, const char* deviceId)
 {
-    if (tsk_verbose)
+	 int64_t dataSourceObjId=-1;
+    if (tsk_verbose) 
         tsk_fprintf(stderr, "TskAutoDb::startAddImage_utf8: Starting add image process\n");
    
 
@@ -499,7 +502,7 @@ uint8_t
 
     m_imgTransactionOpen = true;
 
-    if (openImageUtf8(numImg, imagePaths, imgType, sSize, deviceId)) {
+    if (openImageUtf8(numImg, imagePaths, imgType, sSize, dataSourceObjId, deviceId)) {
         tsk_error_set_errstr2("TskAutoDb::startAddImage");
         registerError();
         if (revertAddImage())
@@ -601,8 +604,8 @@ TskAutoDb::setTz(string tzone)
 TSK_RETVAL_ENUM
 TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path)
 {
-
-    // Check if the process has been canceled
+    
+	// Check if the process has been canceled
      if (m_stopped) {
         if (tsk_verbose)
             tsk_fprintf(stderr, "TskAutoDb::processFile: Stop request detected\n");
@@ -634,7 +637,7 @@ TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path)
 
     // insert a general row if we didn't add a specific attribute one
     if ((retval == TSK_OK) && (m_attributeAdded == false)) {
-        retval = insertFileData(fs_file, NULL, path, NULL, TSK_DB_FILES_KNOWN_UNKNOWN);
+		retval = insertFileData(fs_file, NULL, path, NULL, TSK_DB_FILES_KNOWN_UNKNOWN);
     }
     
     // reset the file id
@@ -652,7 +655,7 @@ TSK_RETVAL_ENUM
 TskAutoDb::processAttribute(TSK_FS_FILE * fs_file,
     const TSK_FS_ATTR * fs_attr, const char *path)
 {
-    // add the file metadata for the default attribute type
+	// add the file metadata for the default attribute type
     if (isDefaultType(fs_file, fs_attr)) {
 
         // calculate the MD5 hash if the attribute is a file
@@ -692,7 +695,7 @@ TskAutoDb::processAttribute(TSK_FS_FILE * fs_file,
             }
         }
 
-        if (insertFileData(fs_attr->fs_file, fs_attr, path, md5, file_known) == TSK_ERR) {
+		if (insertFileData(fs_attr->fs_file, fs_attr, path, md5, file_known) == TSK_ERR) {
             registerError();
             return TSK_OK;
         }
@@ -715,7 +718,7 @@ TskAutoDb::processAttribute(TSK_FS_FILE * fs_file,
 
                 // @@@ We probaly want to keep on going here
                 if (m_db->addFileLayoutRange(m_curFileId,
-                        run->addr * block_size, run->len * block_size, sequence++)) {
+					run->addr * block_size, run->len * block_size, sequence++)) {
                     registerError();
                     return TSK_OK;
                 }
@@ -819,12 +822,12 @@ TSK_WALK_RET_ENUM TskAutoDb::fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_block,
 		(unallocBlockWlkTrack->size < unallocBlockWlkTrack->chunkSize))) {
 		return TSK_WALK_CONT;
 	}
-
+	
 	// at this point we are either chunking and have reached the chunk limit
 	// or we're not chunking. Either way we now add what we've got to the DB
 	int64_t fileObjId = 0;
 	if (unallocBlockWlkTrack->tskAutoDb.m_db->addUnallocBlockFile(unallocBlockWlkTrack->tskAutoDb.m_curUnallocDirId, 
-		unallocBlockWlkTrack->fsObjId, unallocBlockWlkTrack->size, unallocBlockWlkTrack->ranges, fileObjId) == TSK_ERR) {
+		unallocBlockWlkTrack->fsObjId, unallocBlockWlkTrack->size, unallocBlockWlkTrack->ranges, fileObjId, ((TskAutoDb*)a_ptr)->m_curImgId) == TSK_ERR) {
             // @@@ Handle error -> Don't have access to registerError() though...
     }
 
@@ -857,7 +860,7 @@ TSK_RETVAL_ENUM TskAutoDb::addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo) {
     }
 
     //create a "fake" dir to hold the unalloc files for the fs
-    if (m_db->addUnallocFsBlockFilesParent(dbFsInfo.objId, m_curUnallocDirId) == TSK_ERR) {
+	if (m_db->addUnallocFsBlockFilesParent(dbFsInfo.objId, m_curUnallocDirId, m_curImgId) == TSK_ERR) {
         tsk_error_set_errstr2("addFsInfoUnalloc: error creating dir for unallocated space");
         registerError();
         return TSK_ERR;
@@ -892,7 +895,7 @@ TSK_RETVAL_ENUM TskAutoDb::addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo) {
 	unallocBlockWlkTrack.size += byteLen;
     int64_t fileObjId = 0;
 
-    if (m_db->addUnallocBlockFile(m_curUnallocDirId, dbFsInfo.objId, unallocBlockWlkTrack.size, unallocBlockWlkTrack.ranges, fileObjId) == TSK_ERR) {
+    if (m_db->addUnallocBlockFile(m_curUnallocDirId, dbFsInfo.objId, unallocBlockWlkTrack.size, unallocBlockWlkTrack.ranges, fileObjId, m_curImgId) == TSK_ERR) {
         registerError();
         tsk_fs_close(fsInfo);
         return TSK_ERR;
@@ -1059,7 +1062,7 @@ TSK_RETVAL_ENUM TskAutoDb::addUnallocVsSpaceToDb(size_t & numVsP) {
         TSK_DB_FILE_LAYOUT_RANGE tempRange(byteStart, byteLen, 0);
         ranges.push_back(tempRange);
         int64_t fileObjId = 0;
-        if (m_db->addUnallocBlockFile(vsPart.objId, 0, tempRange.byteLen, ranges, fileObjId) == TSK_ERR) {
+        if (m_db->addUnallocBlockFile(vsPart.objId, 0, tempRange.byteLen, ranges, fileObjId, m_curImgId) == TSK_ERR) {
             registerError();
             return TSK_ERR;
         }
@@ -1089,7 +1092,7 @@ TSK_RETVAL_ENUM TskAutoDb::addUnallocImageSpaceToDb() {
         vector<TSK_DB_FILE_LAYOUT_RANGE> ranges;
         ranges.push_back(tempRange);
         int64_t fileObjId = 0;
-        retImgFile = m_db->addUnallocBlockFile(m_curImgId, 0, imgSize, ranges, fileObjId);
+        retImgFile = m_db->addUnallocBlockFile(m_curImgId, 0, imgSize, ranges, fileObjId, m_curImgId);
     }
     return retImgFile;
 }
diff --git a/tsk/auto/db_postgresql.cpp b/tsk/auto/db_postgresql.cpp
index 39745ae74..21c80bad9 100755
--- a/tsk/auto/db_postgresql.cpp
+++ b/tsk/auto/db_postgresql.cpp
@@ -514,8 +514,8 @@ int TskDbPostgreSQL::initialize() {
         "Error creating tsk_fs_info table: %s\n")
         ||
         attempt_exec
-        ("CREATE TABLE tsk_files (obj_id BIGSERIAL PRIMARY KEY, fs_obj_id BIGINT, attr_type INTEGER, attr_id INTEGER, name TEXT NOT NULL, meta_addr BIGINT, meta_seq BIGINT, type INTEGER, has_layout INTEGER, has_path INTEGER, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size BIGINT, ctime BIGINT, crtime BIGINT, atime BIGINT, mtime BIGINT, mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, parent_path TEXT, mime_type TEXT, "
-        "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id));",
+        ("CREATE TABLE tsk_files (obj_id BIGSERIAL PRIMARY KEY, fs_obj_id BIGINT, data_source_obj_id BIGINT, attr_type INTEGER, attr_id INTEGER, name TEXT NOT NULL, meta_addr BIGINT, meta_seq BIGINT, type INTEGER, has_layout INTEGER, has_path INTEGER, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size BIGINT, ctime BIGINT, crtime BIGINT, atime BIGINT, mtime BIGINT, mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, parent_path TEXT, mime_type TEXT, "
+        "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id));",
         "Error creating tsk_files table: %s\n")
         ||
         attempt_exec("CREATE TABLE tsk_files_path (obj_id BIGSERIAL PRIMARY KEY, path TEXT NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id))",
@@ -821,12 +821,13 @@ int TskDbPostgreSQL::addFsInfo(const TSK_FS_INFO * fs_info, int64_t parObjId, in
 * @param known Status regarding if it was found in hash database or not
 * @param fsObjId File system object of its file system
 * @param objId ID that was assigned to it from the objects table
+* @param dataSourceObjId The object Id of the data source
 * @returns 1 on error and 0 on success
 */
 int TskDbPostgreSQL::addFsFile(TSK_FS_FILE * fs_file,
     const TSK_FS_ATTR * fs_attr, const char *path,
     const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known,
-    int64_t fsObjId, int64_t & objId)
+    int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId)
 {
     int64_t parObjId = 0;
 
@@ -849,16 +850,18 @@ int TskDbPostgreSQL::addFsFile(TSK_FS_FILE * fs_file,
         }    
     }
 
-    return addFile(fs_file, fs_attr, path, md5, known, fsObjId, parObjId, objId);
+    return addFile(fs_file, fs_attr, path, md5, known, fsObjId, parObjId, objId, dataSourceObjId);
 }
 
 /**
 * Add file data to the file table
 * @param md5 binary value of MD5 (i.e. 16 bytes) or NULL
+* @param dataSourceObjId The object Id of the data source
 * Return 0 on success, 1 on error.
 */
 int TskDbPostgreSQL::addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr, const char *path,
-    const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId, int64_t parObjId, int64_t & objId)
+    const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId, int64_t parObjId, int64_t & objId, 
+	int64_t dataSourceObjId)
 {
     time_t mtime = 0;
     time_t crtime = 0;
@@ -966,10 +969,11 @@ int TskDbPostgreSQL::addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
     }
 
     char zSQL[2048];
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) "
+    snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) "
         "VALUES ("
         "%" PRId64 ",%" PRId64 ","
-        "%d,"
+        "%" PRId64 ","
+		"%d,"
         "%d,%d,%s,"
         "%" PRIuINUM ",%d,"
         "%d,%d,%d,%d,"
@@ -977,7 +981,8 @@ int TskDbPostgreSQL::addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
         "%llu,%llu,%llu,%llu,"
         "%d,%d,%d,%s,%d,"
         "%s)",
-        fsObjId, objId,
+        fsObjId, objId, 
+		dataSourceObjId,
         TSK_DB_FILES_TYPE_FS,
         type, idx, name_sql,
         fs_file->name->meta_addr, fs_file->name->meta_seq, 
@@ -1242,9 +1247,10 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::getObjectInfo(int64_t objId, TSK_DB_OBJECT & ob
 * @param parentDirId (in) parent dir object id of the new directory: either another virtual directory or root fs directory
 * @param name name (int) of the new virtual directory
 * @param objId (out) object id of the created virtual directory object
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId, int64_t dataSourceObjId) {
     char zSQL[2048];
 
     if (addObject(TSK_DB_OBJECT_TYPE_FILE, parentDirId, objId))
@@ -1260,8 +1266,7 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int6
         PQfreemem(name_sql);
         return TSK_ERR;
     }
-
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (attr_type, attr_id, has_layout, fs_obj_id, obj_id, type, "
+	snprintf(zSQL, 2048, "INSERT INTO tsk_files (attr_type, attr_id, has_layout, fs_obj_id, obj_id, data_source_obj_id type, "
         "name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, "
         "crtime, ctime, atime, mtime, mode, gid, uid, known, parent_path) "
         "VALUES ("
@@ -1269,7 +1274,8 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int6
         "NULL,"
         "%lld,"
         "%lld,"
-        "%d,"
+        "%" PRId64 ","
+		"%d,"
         "%s,"
         "NULL,NULL,"
         "%d,%d,%d,%d,"
@@ -1277,6 +1283,7 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int6
         "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'/')",
         fsObjId,
         objId,
+		dataSourceObjId,
         TSK_DB_FILES_TYPE_VIRTUAL_DIR,
         name_sql,
         TSK_FS_NAME_TYPE_DIR, TSK_FS_META_TYPE_DIR,
@@ -1298,9 +1305,10 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addVirtualDir(const int64_t fsObjId, const int6
 * The dir has is associated with its root dir parent for the fs.
 * @param fsObjId (in) fs id to find root dir for and create $Unalloc dir for
 * @param objId (out) object id of the $Unalloc dir created
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId) {
 
     const char * const unallocDirName = "$Unalloc";
 
@@ -1310,7 +1318,7 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocFsBlockFilesParent(const int64_t fsOb
         return TSK_ERR;
     }
 
-    return addVirtualDir(fsObjId, rootDirObjInfo.objId, unallocDirName, objId);
+    return addVirtualDir(fsObjId, rootDirObjInfo.objId, unallocDirName, objId, dataSourceObjId);
 }
 
 //internal function object to check for range overlap
@@ -1353,10 +1361,11 @@ typedef struct _checkFileLayoutRangeOverlap{
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 /**
@@ -1367,10 +1376,11 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addUnallocBlockFile(const int64_t parentObjId,
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNUSED_BLOCKS, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbPostgreSQL::addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNUSED_BLOCKS, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 /**
@@ -1381,18 +1391,20 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addUnusedBlockFile(const int64_t parentObjId, c
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_CARVED, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbPostgreSQL::addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_CARVED, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 /**
 * Internal helper method to add unalloc, unused and carved files with layout ranges to db
 * Generates file_name and populates tsk_files, tsk_objects and tsk_file_layout tables
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbPostgreSQL::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
     const size_t numRanges = ranges.size();
 
     if (numRanges < 1) {
@@ -1444,7 +1456,7 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_
     fileNameSs << "_" << (ranges[numRanges-1].byteStart + ranges[numRanges-1].byteLen);
 
     //insert into tsk files and tsk objects
-    if (addLayoutFileInfo(parentObjId, fsObjId, dbFileType, fileNameSs.str().c_str(), size, objId) ) {
+    if (addLayoutFileInfo(parentObjId, fsObjId, dbFileType, fileNameSs.str().c_str(), size, objId, dataSourceObjId) ) {
         return TSK_ERR;
     }
 
@@ -1469,10 +1481,10 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_
 * @param fileName file name for the layout file
 * @param size Number of bytes in file
 * @param objId layout file Id (output)
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbPostgreSQL::addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName,
-    const uint64_t size, int64_t & objId)
+TSK_RETVAL_ENUM TskDbPostgreSQL::addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size, int64_t & objId, int64_t dataSourceObjId)
 {
     char zSQL[2048];
 
@@ -1500,10 +1512,10 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addLayoutFileInfo(const int64_t parObjId, const
         PQfreemem(name_sql);
         return TSK_ERR;
     }
-
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (has_layout, fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid) "
+    snprintf(zSQL, 2048, "INSERT INTO tsk_files (has_layout, fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid) "
         "VALUES ("
         "1, %s, %lld,"
+		"%" PRId64 ","
         "%d,"
         "NULL,NULL,%s,"
         "NULL,NULL,"
@@ -1511,7 +1523,8 @@ TSK_RETVAL_ENUM TskDbPostgreSQL::addLayoutFileInfo(const int64_t parObjId, const
         "%" PRIuOFF ","
         "NULL,NULL,NULL,NULL,NULL,NULL,NULL)",
         fsObjIdStrPtr, objId,
-        dbFileType,
+        dataSourceObjId,
+		dbFileType,
         name_sql,
         TSK_FS_NAME_TYPE_REG, TSK_FS_META_TYPE_REG,
         TSK_FS_NAME_FLAG_UNALLOC, TSK_FS_META_FLAG_UNALLOC, size);
@@ -1893,7 +1906,7 @@ bool TskDbPostgreSQL::inTransaction() {
 }
 
 
-/* ELTODO: These functions will be needed when functionality to get PostgreSQL quesries in binary format is added.
+/* ELTODO: These functions will be needed when functionality to get PostgreSQL queries in binary format is added.
 // PostgreSQL returns binary results in network byte order so then need to be converted to local byte order.
 int64_t ntoh64(int64_t *input)
 {
@@ -1928,114 +1941,6 @@ hton_any(T &input)
     return output;
 }*/
 
-// ELTODO: delete this test code
-/*
-void TskDbPostgreSQL::test()
-{
-    TSK_VS_INFO vsInfo;
-    vsInfo.tag = 20;
-    vsInfo.img_info = (TSK_IMG_INFO *)21;
-    vsInfo.block_size = 22;
-    vsInfo.vstype = TSK_VS_TYPE_BSD;        ///< Type of volume system / media management
-    vsInfo.offset = 23;     ///< Byte offset where VS starts in disk image
-    vsInfo.endian = TSK_BIG_ENDIAN; ///< Endian ordering of data
-    vsInfo.part_list = (TSK_VS_PART_INFO *)24;    ///< Linked list of partitions
-    vsInfo.part_count = 25;  ///< number of partitions 
-
-    int64_t objId;
-    const std::string timezone = "America/New York";
-    const std::string md5 = "";
-    int error = addImageInfo(1, 512, objId, timezone, 2097152, md5);
-
-    int max = (unsigned int)-1;
-    char largeNum[32] = "44294967296";
-    int64_t largeNumInt = atoll(largeNum);
-    __int64 largeNumInt2 = _atoi64(largeNum);
-    const std::string timezone2 = "That's America/New York";
-    const std::string md52 = "C:\\Temp";
-    error = addImageInfo(1, 512, objId, timezone2, 2097152, md52);
-
-
-    //    int64_t parObjId = 2;
-    int64_t parObjId = 444294967296;
-
-    error = addVsInfo(&vsInfo, parObjId, objId);
-    TSK_DB_VS_INFO vsInfoRes;
-    getVsInfo(1, vsInfoRes);
-
-    TSK_DB_OBJECT objectInfo;
-    TSK_RETVAL_ENUM ret = getObjectInfo(objId, objectInfo);
-
-    // insert files
-    addObject(TSK_DB_OBJECT_TYPE_VS, 2, objId);    
-    char zSQL[2048];
-    snprintf(zSQL, 2048, "INSERT INTO tsk_fs_info (obj_id, img_offset, fs_type, block_size, block_count, root_inum, first_inum, last_inum) VALUES (2,0,2,512,4096,2,2,65430)");
-    if (attempt_exec(zSQL, "TskDbPostgreSQL::INSERT INTO tsk_fs_info\n")) {
-        return;
-    }
-
-    //Ln 859: addObject() - parObjId=2, type=TSK_DB_OBJECT_TYPE_FILE. objId = 3;
-    addObject(TSK_DB_OBJECT_TYPE_VS, 2, objId);
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) VALUES (2,3,0,1,0,'',2,0,3,2,1,5,16384,0,0,0,0,0,0,0,NULL,0,'/')");
-    if (attempt_exec(zSQL, "TskDbPostgreSQL::INSERT INTO tsk_files\n")) {
-        return;
-    }
-
-    //Ln 859: addObject() - parObjId=3, type=TSK_DB_OBJECT_TYPE_FILE. objId = 4;
-    addObject(TSK_DB_OBJECT_TYPE_VS, 3, objId);
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) VALUES (2,4,0,1,0,'test.txt',4,0,5,1,1,1,6,1181684630,0,1181620800,1181684630,511,0,0,NULL,0,'/')");
-    if (attempt_exec(zSQL, "TskDbPostgreSQL::INSERT INTO tsk_files\n")) {
-        return;
-    }
-    //Ln 859: addObject() - parObjId=3, type=TSK_DB_OBJECT_TYPE_FILE. objId = 5;
-    addObject(TSK_DB_OBJECT_TYPE_VS, 3, objId);
-    snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) VALUES (2,5,0,1,0,'$MBR',65427,0,10,10,1,5,512,0,0,0,0,0,0,0,NULL,0,'/')");
-    if (attempt_exec(zSQL, "TskDbPostgreSQL::INSERT INTO tsk_files\n")) {
-        return;
-    }
-
-    for (int indx = 3; indx <=5; indx++) {
-        snprintf(zSQL, 1024, "SELECT fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path FROM tsk_files WHERE obj_id = %d", indx);
-        PGresult *res = PQexec(conn, zSQL);
-        if (PQresultStatus(res) != PGRES_TUPLES_OK) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_AUTO_DB);
-            char * str = PQerrorMessage(conn);
-            tsk_error_set_errstr("TskDbPostgreSQL::getVsInfo: Error selecting object by objid: %s (result code %d)\n", PQerrorMessage(conn));
-            PQclear(res);
-            continue;
-        }
-
-        int numResults = PQntuples(res);
-        int fs_obj_id = atoi(PQgetvalue(res, 0, 0));         
-        int obj_id = atoi(PQgetvalue(res, 0, 1)); 
-        int type  = atoi(PQgetvalue(res, 0, 2));      
-        int attr_type = atoi(PQgetvalue(res, 0, 3));  
-        int attr_id = atoi(PQgetvalue(res, 0, 4));  
-        char* name = PQgetvalue(res, 0, 5); 
-        int meta_addr = atoi(PQgetvalue(res, 0, 6)); 
-        int meta_seq = atoi(PQgetvalue(res, 0, 7)); 
-        int dir_type  = atoi(PQgetvalue(res, 0, 8)); 
-        int meta_type = atoi(PQgetvalue(res, 0, 9)); 
-        int dir_flags = atoi(PQgetvalue(res, 0, 10)); 
-        int meta_flags = atoi(PQgetvalue(res, 0, 11));
-        int size = atoi(PQgetvalue(res, 0, 12)); 
-        int crtime = atoi(PQgetvalue(res, 0, 13));
-        int ctime = atoi(PQgetvalue(res, 0, 14)); 
-        int atime = atoi(PQgetvalue(res, 0, 15));         
-        int mtime = atoi(PQgetvalue(res, 0, 16)); 
-        int mode = atoi(PQgetvalue(res, 0, 17)); 
-        int uid = atoi(PQgetvalue(res, 0, 18));      
-        int gid = atoi(PQgetvalue(res, 0, 19)); 
-        char* md5 = PQgetvalue(res, 0, 20); 
-        int known = atoi(PQgetvalue(res, 0, 21)); 
-        char* parent_path = PQgetvalue(res, 0, 22);
-
-        //cleanup
-        PQclear(res);    
-    }
-
-};*/
 
 
 #endif // TSK_WIN32
diff --git a/tsk/auto/db_sqlite.cpp b/tsk/auto/db_sqlite.cpp
index 63af0c673..b6062396a 100755
--- a/tsk/auto/db_sqlite.cpp
+++ b/tsk/auto/db_sqlite.cpp
@@ -273,8 +273,8 @@ int
         "Error creating data_source_info table: %s\n")
         ||
         attempt_exec
-        ("CREATE TABLE tsk_files (obj_id INTEGER PRIMARY KEY, fs_obj_id INTEGER, attr_type INTEGER, attr_id INTEGER, name TEXT NOT NULL, meta_addr INTEGER, meta_seq INTEGER, type INTEGER, has_layout INTEGER, has_path INTEGER, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size INTEGER, ctime INTEGER, crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, parent_path TEXT, mime_type TEXT, "
-         "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id));",
+        ("CREATE TABLE tsk_files (obj_id INTEGER PRIMARY KEY, fs_obj_id INTEGER, data_source_obj_id INTEGER, attr_type INTEGER, attr_id INTEGER, name TEXT NOT NULL, meta_addr INTEGER, meta_seq INTEGER, type INTEGER, has_layout INTEGER, has_path INTEGER, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size INTEGER, ctime INTEGER, crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, gid INTEGER, md5 TEXT, known INTEGER, parent_path TEXT, mime_type TEXT, "
+         "FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(fs_obj_id) REFERENCES tsk_fs_info(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id));",
         "Error creating tsk_files table: %s\n")
         ||
         attempt_exec
@@ -624,13 +624,14 @@ int
 * @param known Status regarding if it was found in hash database or not
 * @param fsObjId File system object of its file system
 * @param objId ID that was assigned to it from the objects table
+* @param dataSourceObjId The object ID for the data source
 * @returns 1 on error and 0 on success
 */
 int
     TskDbSqlite::addFsFile(TSK_FS_FILE * fs_file,
     const TSK_FS_ATTR * fs_attr, const char *path,
     const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known,
-    int64_t fsObjId, int64_t & objId)
+    int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId)
 {
     int64_t parObjId = 0;
 
@@ -653,7 +654,7 @@ int
         }    
     }
 
-    return addFile(fs_file, fs_attr, path, md5, known, fsObjId, parObjId, objId);
+    return addFile(fs_file, fs_attr, path, md5, known, fsObjId, parObjId, objId, dataSourceObjId);
 }
 
 
@@ -776,6 +777,7 @@ int64_t TskDbSqlite::findParObjId(const TSK_FS_FILE * fs_file, const char *path,
 /**
 * Add file data to the file table
 * @param md5 binary value of MD5 (i.e. 16 bytes) or NULL
+* @param dataSourceObjId The object ID for the data source
 * Return 0 on success, 1 on error.
 */
 int
@@ -783,7 +785,7 @@ int
     const TSK_FS_ATTR * fs_attr, const char *path,
     const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known,
     int64_t fsObjId, int64_t parObjId,
-    int64_t & objId)
+    int64_t & objId, int64_t dataSourceObjId)
 {
 
 
@@ -890,10 +892,11 @@ int
     }
 
     zSQL = sqlite3_mprintf(
-        "INSERT INTO tsk_files (fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) "
+        "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) "
         "VALUES ("
         "%" PRId64 ",%" PRId64 ","
-        "%d,"
+        "%" PRId64 "," 
+		"%d,"
         "%d,%d,'%q',"
         "%" PRIuINUM ",%d,"
         "%d,%d,%d,%d,"
@@ -902,6 +905,7 @@ int
         "%d,%d,%d,%Q,%d,"
         "'%q')",
         fsObjId, objId,
+		dataSourceObjId,
         TSK_DB_FILES_TYPE_FS,
         type, idx, name,
         fs_file->name->meta_addr, fs_file->name->meta_seq, 
@@ -1018,7 +1022,7 @@ int
 * @returns 1 on error
 */
 int TskDbSqlite::addFileLayoutRange(const TSK_DB_FILE_LAYOUT_RANGE & fileLayoutRange) {
-    return addFileLayoutRange(fileLayoutRange.fileObjId, fileLayoutRange.byteStart, fileLayoutRange.byteLen, fileLayoutRange.sequence);
+	return addFileLayoutRange(fileLayoutRange.fileObjId, fileLayoutRange.byteStart, fileLayoutRange.byteLen, fileLayoutRange.sequence);
 }
 
 
@@ -1031,11 +1035,12 @@ int TskDbSqlite::addFileLayoutRange(const TSK_DB_FILE_LAYOUT_RANGE & fileLayoutR
 * @param fileName file name for the layout file
 * @param size Number of bytes in file
 * @param objId layout file Id (output)
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
 TSK_RETVAL_ENUM
     TskDbSqlite::addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName,
-    const uint64_t size, int64_t & objId)
+    const uint64_t size, int64_t & objId, int64_t dataSourceObjId)
 {
     char *zSQL;
 
@@ -1050,10 +1055,11 @@ TSK_RETVAL_ENUM
         fsObjIdStrPtr = fsObjIdStr;
     }
 
-    zSQL = sqlite3_mprintf(
-        "INSERT INTO tsk_files (has_layout, fs_obj_id, obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid) "
+	zSQL = sqlite3_mprintf(
+		"INSERT INTO tsk_files (has_layout, fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid) "
         "VALUES ("
         "1, %Q, %lld,"
+		"%" PRId64 ","
         "%d,"
         "NULL,NULL,'%q',"
         "NULL,NULL,"
@@ -1061,6 +1067,7 @@ TSK_RETVAL_ENUM
         "%" PRIuOFF ","
         "NULL,NULL,NULL,NULL,NULL,NULL,NULL)",
         fsObjIdStrPtr, objId,
+		dataSourceObjId,
         dbFileType,
         fileName,
         TSK_FS_NAME_TYPE_REG, TSK_FS_META_TYPE_REG,
@@ -1123,10 +1130,11 @@ bool
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbSqlite::addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbSqlite::addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 /**
@@ -1137,10 +1145,11 @@ TSK_RETVAL_ENUM TskDbSqlite::addUnallocBlockFile(const int64_t parentObjId, cons
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbSqlite::addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNUSED_BLOCKS, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbSqlite::addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_UNUSED_BLOCKS, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 /**
@@ -1151,10 +1160,11 @@ TSK_RETVAL_ENUM TskDbSqlite::addUnusedBlockFile(const int64_t parentObjId, const
 * @param size Number of bytes in file
 * @param ranges vector containing one or more TSK_DB_FILE_LAYOUT_RANGE layout ranges (in)
 * @param objId object id of the file object created (output)
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_OK on success or TSK_ERR on error.
 */
-TSK_RETVAL_ENUM TskDbSqlite::addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
-    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_CARVED, parentObjId, fsObjId, size, ranges, objId);
+TSK_RETVAL_ENUM TskDbSqlite::addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
+    return addFileWithLayoutRange(TSK_DB_FILES_TYPE_CARVED, parentObjId, fsObjId, size, ranges, objId, dataSourceObjId);
 }
 
 //internal function object to check for range overlap
@@ -1196,16 +1206,16 @@ typedef struct _checkFileLayoutRangeOverlap{
 * @param parentDirId (in) parent dir object id of the new directory: either another virtual directory or root fs directory
 * @param name name (int) of the new virtual directory
 * @param objId (out) object id of the created virtual directory object
+* @param dataSourceObjId The object Id of the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbSqlite::addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbSqlite::addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId, int64_t dataSourceObjId) {
     char *zSQL;
 
     if (addObject(TSK_DB_OBJECT_TYPE_FILE, parentDirId, objId))
         return TSK_ERR;
-
-    zSQL = sqlite3_mprintf(
-        "INSERT INTO tsk_files (attr_type, attr_id, has_layout, fs_obj_id, obj_id, type, attr_type, "
+	zSQL = sqlite3_mprintf(
+        "INSERT INTO tsk_files (attr_type, attr_id, has_layout, fs_obj_id, obj_id, data_source_obj_id, type, attr_type, "
         "attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, "
         "crtime, ctime, atime, mtime, mode, gid, uid, known, parent_path) "
         "VALUES ("
@@ -1213,6 +1223,7 @@ TSK_RETVAL_ENUM TskDbSqlite::addVirtualDir(const int64_t fsObjId, const int64_t
         "NULL,"
         "%lld,"
         "%lld,"
+		"%" PRId64 ","
         "%d,"
         "NULL,NULL,'%q',"
         "NULL,NULL,"
@@ -1221,6 +1232,7 @@ TSK_RETVAL_ENUM TskDbSqlite::addVirtualDir(const int64_t fsObjId, const int64_t
         "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'/')",
         fsObjId,
         objId,
+		dataSourceObjId,
         TSK_DB_FILES_TYPE_VIRTUAL_DIR,
         name,
         TSK_FS_NAME_TYPE_DIR, TSK_FS_META_TYPE_DIR,
@@ -1240,9 +1252,10 @@ TSK_RETVAL_ENUM TskDbSqlite::addVirtualDir(const int64_t fsObjId, const int64_t
 * The dir has is associated with its root dir parent for the fs.
 * @param fsObjId (in) fs id to find root dir for and create $Unalloc dir for
 * @param objId (out) object id of the $Unalloc dir created
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbSqlite::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbSqlite::addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId) {
 
     const char * const unallocDirName = "$Unalloc";
 
@@ -1252,15 +1265,16 @@ TSK_RETVAL_ENUM TskDbSqlite::addUnallocFsBlockFilesParent(const int64_t fsObjId,
         return TSK_ERR;
     }
 
-    return addVirtualDir(fsObjId, rootDirObjInfo.objId, unallocDirName, objId);
+    return addVirtualDir(fsObjId, rootDirObjInfo.objId, unallocDirName, objId, dataSourceObjId);
 }
 
 /**
 * Internal helper method to add unalloc, unused and carved files with layout ranges to db
 * Generates file_name and populates tsk_files, tsk_objects and tsk_file_layout tables
+* @param dataSourceObjId The object ID for the data source
 * @returns TSK_ERR on error or TSK_OK on success
 */
-TSK_RETVAL_ENUM TskDbSqlite::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) {
+TSK_RETVAL_ENUM TskDbSqlite::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) {
     const size_t numRanges = ranges.size();
 
     if (numRanges < 1) {
@@ -1312,7 +1326,7 @@ TSK_RETVAL_ENUM TskDbSqlite::addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM
     fileNameSs << "_" << (ranges[numRanges-1].byteStart + ranges[numRanges-1].byteLen);
 
     //insert into tsk files and tsk objects
-    if (addLayoutFileInfo(parentObjId, fsObjId, dbFileType, fileNameSs.str().c_str(), size, objId) ) {
+    if (addLayoutFileInfo(parentObjId, fsObjId, dbFileType, fileNameSs.str().c_str(), size, objId, dataSourceObjId) ) {
         return TSK_ERR;
     }
 
diff --git a/tsk/auto/tsk_auto.h b/tsk/auto/tsk_auto.h
index 97b5412c5..69c6781c1 100644
--- a/tsk/auto/tsk_auto.h
+++ b/tsk/auto/tsk_auto.h
@@ -69,9 +69,9 @@ class TskAuto {
      virtual ~ TskAuto();
 
     virtual uint8_t openImage(int, const TSK_TCHAR * const images[],
-        TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, int64_t & dataSourceObjId);
     virtual uint8_t openImageUtf8(int, const char *const images[],
-        TSK_IMG_TYPE_ENUM, unsigned int a_ssize);
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, int64_t & dataSourceObjId);
     virtual uint8_t openImageHandle(TSK_IMG_INFO *);
     virtual void closeImage();
 
@@ -137,7 +137,7 @@ class TskAuto {
      * @returns STOP or OK. All error must have been registered. 
      */
     virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file,
-        const char *path) = 0;
+		const char *path) = 0;
 
     
     /**
@@ -229,8 +229,8 @@ class TskAuto {
     TSK_IMG_INFO * m_img_info;
     bool m_internalOpen;        ///< True if m_img_info was opened in TskAuto and false if passed in
     bool m_stopAllProcessing;   ///< True if no further processing should occur
-    
-    
+
+
     uint8_t isNtfsSystemFiles(TSK_FS_FILE * fs_file, const char *path);
     uint8_t isFATSystemFiles(TSK_FS_FILE * fs_file);
     uint8_t isDotDir(TSK_FS_FILE * fs_file);
diff --git a/tsk/auto/tsk_case_db.h b/tsk/auto/tsk_case_db.h
index 5dd76bdcf..8a7ae52fb 100644
--- a/tsk/auto/tsk_case_db.h
+++ b/tsk/auto/tsk_case_db.h
@@ -36,9 +36,9 @@ class TskAutoDb:public TskAuto {
     TskAutoDb(TskDb * a_db, TSK_HDB_INFO * a_NSRLDb, TSK_HDB_INFO * a_knownBadDb);
     virtual ~ TskAutoDb();
     virtual uint8_t openImage(int, const TSK_TCHAR * const images[],
-        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, const char* deviceId = NULL);
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, int64_t & dataSourceObjId, const char* deviceId = NULL);
     virtual uint8_t openImageUtf8(int, const char *const images[],
-        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, const char* deviceId = NULL);
+        TSK_IMG_TYPE_ENUM, unsigned int a_ssize, int64_t & dataSourceObjId, const char* deviceId = NULL);
     virtual void closeImage();
     virtual void setTz(string tzone);
 
@@ -46,7 +46,7 @@ class TskAutoDb:public TskAuto {
     virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
     virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
     virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file,
-        const char *path);
+		const char *path);
     virtual void createBlockMap(bool flag);
     const std::string getCurDir();
 	
@@ -154,7 +154,7 @@ class TskAutoDb:public TskAuto {
         const unsigned char *const md5,
         const TSK_DB_FILES_KNOWN_ENUM known);
     virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *,
-        const TSK_FS_ATTR * fs_attr, const char *path);
+		const TSK_FS_ATTR * fs_attr, const char *path);
     static TSK_WALK_RET_ENUM md5HashCallback(TSK_FS_FILE * file,
         TSK_OFF_T offset, TSK_DADDR_T addr, char *buf, size_t size,
         TSK_FS_BLOCK_FLAG_ENUM a_flags, void *ptr);
diff --git a/tsk/auto/tsk_db.h b/tsk/auto/tsk_db.h
index 698d131c0..95c9770e9 100755
--- a/tsk/auto/tsk_db.h
+++ b/tsk/auto/tsk_db.h
@@ -170,16 +170,16 @@ class TskDb {
     virtual int addFsFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
         const char *path, const unsigned char *const md5,
         const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId,
-        int64_t & objId) = 0;
+        int64_t & objId, int64_t dataSourceObjId) = 0;
 
-    virtual TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId) = 0;
-    virtual TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId) = 0;
+    virtual TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId, int64_t dataSourceObjId) = 0;
+    virtual TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId) = 0;
     virtual TSK_RETVAL_ENUM addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) = 0;
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) = 0;
     virtual TSK_RETVAL_ENUM addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) = 0;
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) = 0;
     virtual TSK_RETVAL_ENUM addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId) = 0;
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId) = 0;
     
     virtual int addFileLayoutRange(const TSK_DB_FILE_LAYOUT_RANGE & fileLayoutRange) = 0;
     virtual int addFileLayoutRange(int64_t a_fileObjId, uint64_t a_byteStart, uint64_t a_byteLen, int a_sequence) = 0;
diff --git a/tsk/auto/tsk_db_postgresql.h b/tsk/auto/tsk_db_postgresql.h
index e558b2478..025e1c18a 100755
--- a/tsk/auto/tsk_db_postgresql.h
+++ b/tsk/auto/tsk_db_postgresql.h
@@ -59,16 +59,16 @@ class TskDbPostgreSQL : public TskDb {
     int addFsFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
         const char *path, const unsigned char *const md5,
         const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId,
-        int64_t & objId);
+        int64_t & objId, int64_t dataSourceObjId);
 
-    TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId);
-    TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId);
+    TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId, int64_t dataSourceObjId);
+    TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     
     int addFileLayoutRange(const TSK_DB_FILE_LAYOUT_RANGE & fileLayoutRange);
     int addFileLayoutRange(int64_t a_fileObjId, uint64_t a_byteStart, uint64_t a_byteLen, int a_sequence);
@@ -118,7 +118,7 @@ class TskDbPostgreSQL : public TskDb {
 
     uint8_t addObject(TSK_DB_OBJECT_TYPE_ENUM type, int64_t parObjId, int64_t & objId);
     int addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr, const char *path, const unsigned char *const md5, 
-        const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId, int64_t parObjId, int64_t & objId);
+        const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId, int64_t parObjId, int64_t & objId, int64_t dataSourceObjId);
 
     void storeObjId(const int64_t & fsObjId, const TSK_FS_FILE *fs_file, const char *path, const int64_t & objId);
     int64_t findParObjId(const TSK_FS_FILE * fs_file, const char *path, const int64_t & fsObjId);
@@ -126,9 +126,8 @@ class TskDbPostgreSQL : public TskDb {
     map<int64_t, map<TSK_INUM_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 its object ID in the database
 
     TSK_RETVAL_ENUM addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId,
-        const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
-    TSK_RETVAL_ENUM addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size,
-        int64_t & objId);
+        const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
+    TSK_RETVAL_ENUM addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size, int64_t & objId, int64_t dataSourceObjId);
 
     // ELTODO: delete this:
     //void test();
diff --git a/tsk/auto/tsk_db_sqlite.h b/tsk/auto/tsk_db_sqlite.h
index d72ba898d..c370075f6 100755
--- a/tsk/auto/tsk_db_sqlite.h
+++ b/tsk/auto/tsk_db_sqlite.h
@@ -51,16 +51,16 @@ class TskDbSqlite : public TskDb {
     int addFsFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
         const char *path, const unsigned char *const md5,
         const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId,
-        int64_t & objId);
+        int64_t & objId, int64_t dataSourceObjId);
 
-    TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId);
-    TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId);
+    TSK_RETVAL_ENUM addVirtualDir(const int64_t fsObjId, const int64_t parentDirId, const char * const name, int64_t & objId, int64_t dataSourceObjId);
+    TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addUnallocBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addUnusedBlockFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addCarvedFile(const int64_t parentObjId, const int64_t fsObjId, const uint64_t size, 
-        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
+        vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
     
     int addFileLayoutRange(const TSK_DB_FILE_LAYOUT_RANGE & fileLayoutRange);
     int addFileLayoutRange(int64_t a_fileObjId, uint64_t a_byteStart, uint64_t a_byteLen, int a_sequence);
@@ -103,11 +103,10 @@ class TskDbSqlite : public TskDb {
     int addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr,
         const char *path, const unsigned char *const md5,
         const TSK_DB_FILES_KNOWN_ENUM known, int64_t fsObjId,
-        int64_t parObjId, int64_t & objId);
+        int64_t parObjId, int64_t & objId, int64_t dataSourceObjId);
     TSK_RETVAL_ENUM addFileWithLayoutRange(const TSK_DB_FILES_TYPE_ENUM dbFileType, const int64_t parentObjId, const int64_t fsObjId,
-        const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
-    TSK_RETVAL_ENUM addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size,
-        int64_t & objId);
+        const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId, int64_t dataSourceObjId);
+    TSK_RETVAL_ENUM addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size, int64_t & objId, int64_t dataSourceObjId);
     
     void storeObjId(const int64_t & fsObjId, const TSK_FS_FILE *fs_file, const char *path, const int64_t & objId);
     int64_t findParObjId(const TSK_FS_FILE * fs_file, const char *path, const int64_t & fsObjId);
-- 
GitLab