Sleuth Kit Java Bindings (JNI)  4.10.1
Java bindings for using The Sleuth Kit
TskCaseDbBridge.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import java.sql.PreparedStatement;
22 import java.sql.SQLException;
23 import java.sql.Statement;
24 import org.apache.commons.lang3.StringUtils;
25 import java.util.List;
26 import java.util.Arrays;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.LinkedList;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.Queue;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
36 
46 class TskCaseDbBridge {
47 
48  private static final Logger logger = Logger.getLogger(TskCaseDbBridge.class.getName());
49 
50  private final SleuthkitCase caseDb;
51  private CaseDbTransaction trans = null;
52  private final AddDataSourceCallbacks addDataSourceCallbacks;
53 
54  private final Map<Long, Long> fsIdToRootDir = new HashMap<>();
55  private final Map<Long, TskData.TSK_FS_TYPE_ENUM> fsIdToFsType = new HashMap<>();
56  private final Map<ParentCacheKey, Long> parentDirCache = new HashMap<>();
57 
58  private static final long BATCH_FILE_THRESHOLD = 500;
59  private final Queue<FileInfo> batchedFiles = new LinkedList<>();
60  private final Queue<LayoutRangeInfo> batchedLayoutRanges = new LinkedList<>();
61  private final List<Long> layoutFileIds = new ArrayList<>();
62 
63  TskCaseDbBridge(SleuthkitCase caseDb, AddDataSourceCallbacks addDataSourceCallbacks) {
64  this.caseDb = caseDb;
65  this.addDataSourceCallbacks = addDataSourceCallbacks;
66  trans = null;
67  }
68 
74  private void beginTransaction() throws TskCoreException {
75  trans = caseDb.beginTransaction();
76  }
77 
83  private void commitTransaction() throws TskCoreException {
84  trans.commit();
85  trans = null;
86  }
87 
91  private void revertTransaction() {
92  try {
93  if (trans != null) {
94  trans.rollback();
95  trans = null;
96  }
97  } catch (TskCoreException ex) {
98  logger.log(Level.SEVERE, "Error rolling back transaction", ex);
99  }
100  }
101 
105  void finish() {
106  addBatchedFilesToDb();
107  addBatchedLayoutRangesToDb();
108  processLayoutFiles();
109  }
110 
129  long addImageInfo(int type, long ssize, String timezone,
130  long size, String md5, String sha1, String sha256, String deviceId,
131  String collectionDetails, String[] paths) {
132  try {
133  beginTransaction();
134  long objId = addImageToDb(TskData.TSK_IMG_TYPE_ENUM.valueOf(type), ssize, size,
135  timezone, md5, sha1, sha256, deviceId, collectionDetails, trans);
136  for (int i = 0;i < paths.length;i++) {
137  addImageNameToDb(objId, paths[i], i, trans);
138  }
139  commitTransaction();
140  return objId;
141  } catch (TskCoreException ex) {
142  logger.log(Level.SEVERE, "Error adding image to the database", ex);
143  revertTransaction();
144  return -1;
145  }
146  }
147 
154  void addAcquisitionDetails(long imgId, String details) {
155  try {
156  beginTransaction();
157  caseDb.setAcquisitionDetails(imgId, details, trans);
158  commitTransaction();
159  } catch (TskCoreException ex) {
160  logger.log(Level.SEVERE, "Error adding image details \"" + details + "\" to image with ID " + imgId, ex);
161  revertTransaction();
162  }
163  }
164 
176  long addVsInfo(long parentObjId, int vsType, long imgOffset, long blockSize) {
177  try {
178  beginTransaction();
179  VolumeSystem vs = caseDb.addVolumeSystem(parentObjId, TskData.TSK_VS_TYPE_ENUM.valueOf(vsType), imgOffset, blockSize, trans);
180  commitTransaction();
181  return vs.getId();
182  } catch (TskCoreException ex) {
183  logger.log(Level.SEVERE, "Error adding volume system to the database - parent obj ID: " + parentObjId
184  + ", image offset: " + imgOffset, ex);
185  revertTransaction();
186  return -1;
187  }
188  }
189 
203  long addVolume(long parentObjId, long addr, long start, long length, String desc,
204  long flags) {
205  try {
206  beginTransaction();
207  Volume vol = caseDb.addVolume(parentObjId, addr, start, length, desc, flags, trans);
208  commitTransaction();
209  return vol.getId();
210  } catch (TskCoreException ex) {
211  logger.log(Level.SEVERE, "Error adding volume to the database - parent object ID: " + parentObjId
212  + ", addr: " + addr, ex);
213  revertTransaction();
214  return -1;
215  }
216  }
217 
227  long addPool(long parentObjId, int poolType) {
228  try {
229  beginTransaction();
230  Pool pool = caseDb.addPool(parentObjId, TskData.TSK_POOL_TYPE_ENUM.valueOf(poolType), trans);
231  commitTransaction();
232  return pool.getId();
233  } catch (TskCoreException ex) {
234  logger.log(Level.SEVERE, "Error adding pool to the database - parent object ID: " + parentObjId, ex);
235  revertTransaction();
236  return -1;
237  }
238  }
239 
255  long addFileSystem(long parentObjId, long imgOffset, int fsType, long blockSize, long blockCount,
256  long rootInum, long firstInum, long lastInum) {
257  try {
258  beginTransaction();
259  FileSystem fs = caseDb.addFileSystem(parentObjId, imgOffset, TskData.TSK_FS_TYPE_ENUM.valueOf(fsType), blockSize, blockCount,
260  rootInum, firstInum, lastInum, null, trans);
261  commitTransaction();
262  fsIdToFsType.put(fs.getId(), TskData.TSK_FS_TYPE_ENUM.valueOf(fsType));
263  return fs.getId();
264  } catch (TskCoreException ex) {
265  logger.log(Level.SEVERE, "Error adding file system to the database - parent object ID: " + parentObjId
266  + ", offset: " + imgOffset, ex);
267  revertTransaction();
268  return -1;
269  }
270  }
271 
312  long addFile(long parentObjId,
313  long fsObjId, long dataSourceObjId,
314  int fsType,
315  int attrType, int attrId, String name,
316  long metaAddr, long metaSeq,
317  int dirType, int metaType, int dirFlags, int metaFlags,
318  long size,
319  long crtime, long ctime, long atime, long mtime,
320  int meta_mode, int gid, int uid,
321  String escaped_path, String extension,
322  long seq, long parMetaAddr, long parSeq) {
323 
324  // Add the new file to the list
325  batchedFiles.add(new FileInfo(parentObjId,
326  fsObjId, dataSourceObjId,
327  fsType,
328  attrType, attrId, name,
329  metaAddr, metaSeq,
330  dirType, metaType, dirFlags, metaFlags,
331  size,
332  crtime, ctime, atime, mtime,
333  meta_mode, gid, uid,
334  escaped_path, extension,
335  seq, parMetaAddr, parSeq));
336 
337  // Add the current files to the database if we've exceeded the threshold or if we
338  // have the root folder.
339  if ((fsObjId == parentObjId)
340  || (batchedFiles.size() > BATCH_FILE_THRESHOLD)) {
341  return addBatchedFilesToDb();
342  }
343  return 0;
344  }
345 
351  private long addBatchedFilesToDb() {
352  List<Long> newObjIds = new ArrayList<>();
353  try {
354  beginTransaction();
355  FileInfo fileInfo;
356  while ((fileInfo = batchedFiles.poll()) != null) {
357  long computedParentObjId = fileInfo.parentObjId;
358  try {
359  // If we weren't given the parent object ID, look it up
360  if (fileInfo.parentObjId == 0) {
361  computedParentObjId = getParentObjId(fileInfo);
362  }
363 
364  long objId = addFileToDb(computedParentObjId,
365  fileInfo.fsObjId, fileInfo.dataSourceObjId,
366  fileInfo.fsType,
367  fileInfo.attrType, fileInfo.attrId, fileInfo.name,
368  fileInfo.metaAddr, fileInfo.metaSeq,
369  fileInfo.dirType, fileInfo.metaType, fileInfo.dirFlags, fileInfo.metaFlags,
370  fileInfo.size,
371  fileInfo.crtime, fileInfo.ctime, fileInfo.atime, fileInfo.mtime,
372  fileInfo.meta_mode, fileInfo.gid, fileInfo.uid,
373  null, TskData.FileKnown.UNKNOWN,
374  fileInfo.escaped_path, fileInfo.extension,
375  false, trans);
376  if (fileInfo.fsObjId != fileInfo.parentObjId) {
377  // Add new file ID to the list to send to ingest unless it is the root folder
378  newObjIds.add(objId);
379  }
380 
381  // If we're adding the root directory for the file system, cache it
382  if (fileInfo.parentObjId == fileInfo.fsObjId) {
383  fsIdToRootDir.put(fileInfo.fsObjId, objId);
384  }
385 
386  // If the file is a directory, cache the object ID
387  if ((fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
388  || (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()))
389  && (fileInfo.name != null)
390  && ! fileInfo.name.equals(".")
391  && ! fileInfo.name.equals("..")) {
392  String dirName = fileInfo.escaped_path + fileInfo.name;
393  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.metaAddr, fileInfo.seq, dirName);
394  parentDirCache.put(key, objId);
395  }
396  } catch (TskCoreException ex) {
397  if (computedParentObjId > 0) {
398  // Most likely a database error occurred
399  logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
400  + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
401  } else {
402  // The parent lookup failed
403  logger.log(Level.SEVERE, "Error adding file to the database", ex);
404  }
405  }
406  }
407  commitTransaction();
408  try {
409  addDataSourceCallbacks.onFilesAdded(newObjIds);
410  } catch (Exception ex) {
411  // Exception firewall to prevent unexpected return to the native code
412  logger.log(Level.SEVERE, "Unexpected error from files added callback", ex);
413  }
414  } catch (TskCoreException ex) {
415  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
416  revertTransaction();
417  return -1;
418  }
419  return 0;
420  }
421 
431  private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
432  // Remove the final slash from the path unless we're in the root folder
433  String parentPath = fileInfo.escaped_path;
434  if(parentPath.endsWith("/") && ! parentPath.equals("/")) {
435  parentPath = parentPath.substring(0, parentPath.lastIndexOf('/'));
436  }
437 
438  // Look up the parent
439  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.parMetaAddr, fileInfo.parSeq, parentPath);
440  if (parentDirCache.containsKey(key)) {
441  return parentDirCache.get(key);
442  } else {
443  // There's no reason to do a database query since every folder added is being
444  // stored in the cache.
445  throw new TskCoreException("Could not find parent (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
446  + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
447  }
448  }
449 
463  long addLayoutFile(long parentObjId,
464  long fsObjId, long dataSourceObjId,
465  int fileType,
466  String name, long size) {
467  try {
468 
469  // The file system may be null for layout files
470  Long fsObjIdForDb = fsObjId;
471  if (fsObjId == 0) {
472  fsObjIdForDb = null;
473  }
474 
475  beginTransaction();
476  long objId = addFileToDb(parentObjId,
477  fsObjIdForDb, dataSourceObjId,
478  fileType,
479  null, null, name,
480  null, null,
481  TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue(),
482  TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(),
483  TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
484  TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue(),
485  size,
486  null, null, null, null,
487  null, null, null,
488  null, TskData.FileKnown.UNKNOWN,
489  null, null,
490  true, trans);
491  commitTransaction();
492 
493  // Store the layout file ID for later processing
494  layoutFileIds.add(objId);
495 
496  return objId;
497  } catch (TskCoreException ex) {
498  logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
499  + ", file system object ID: " + fsObjId + ", name: " + name, ex);
500  revertTransaction();
501  return -1;
502  }
503  }
504 
516  long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
517  batchedLayoutRanges.add(new LayoutRangeInfo(objId, byteStart, byteLen, seq));
518 
519  if (batchedLayoutRanges.size() > BATCH_FILE_THRESHOLD) {
520  return addBatchedLayoutRangesToDb();
521  }
522  return 0;
523  }
524 
530  private long addBatchedLayoutRangesToDb() {
531  try {
532  beginTransaction();
533  LayoutRangeInfo range;
534  while ((range = batchedLayoutRanges.poll()) != null) {
535  try {
536  addLayoutFileRangeToDb(range.objId, range.byteStart, range.byteLen, range.seq, trans);
537  } catch (TskCoreException ex) {
538  logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId
539  + ", byte start: " + range.byteStart + ", length: " + range.byteLen + ", seq: " + range.seq, ex);
540  }
541  }
542  commitTransaction();
543  return 0;
544  } catch (TskCoreException ex) {
545  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
546  revertTransaction();
547  return -1;
548  }
549  }
550 
556  void processLayoutFiles() {
557  addDataSourceCallbacks.onFilesAdded(layoutFileIds);
558  layoutFileIds.clear();
559  }
560 
570  long addUnallocFsBlockFilesParent(long fsObjId, String name) {
571  try {
572  if (! fsIdToRootDir.containsKey(fsObjId)) {
573  logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId);
574  return -1;
575  }
576  beginTransaction();
577  VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
578  commitTransaction();
579  addDataSourceCallbacks.onFilesAdded(Arrays.asList(dir.getId()));
580  return dir.getId();
581  } catch (TskCoreException ex) {
582  logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
583  revertTransaction();
584  return -1;
585  }
586  }
587 
591  private class ParentCacheKey {
592  long fsObjId;
593  long metaAddr;
594  long seqNum;
595  String path;
596 
606  ParentCacheKey(long fsObjId, long metaAddr, long seqNum, String path) {
607  this.fsObjId = fsObjId;
608  this.metaAddr = metaAddr;
609  if (fsIdToFsType.containsKey(fsObjId)
610  && (fsIdToFsType.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS)
611  || fsIdToFsType.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS_DETECT))) {
612  this.seqNum = seqNum;
613  } else {
614  this.seqNum = 0;
615  }
616  this.path = path;
617  }
618 
619  @Override
620  public boolean equals(Object obj) {
621  if (! (obj instanceof ParentCacheKey)) {
622  return false;
623  }
624 
625  ParentCacheKey otherKey = (ParentCacheKey) obj;
626  if (this.fsObjId != otherKey.fsObjId
627  || this.metaAddr != otherKey.metaAddr
628  || this.seqNum != otherKey.seqNum) {
629  return false;
630  }
631 
632  return StringUtils.equals(this.path, otherKey.path);
633  }
634 
635  @Override
636  public int hashCode() {
637  int hash = 3;
638  hash = 31 * hash + (int) (this.fsObjId ^ (this.fsObjId >>> 32));
639  hash = 31 * hash + (int) (this.metaAddr ^ (this.metaAddr >>> 32));
640  hash = 31 * hash + (int) (this.seqNum ^ (this.seqNum >>> 32));
641  hash = 31 * hash + Objects.hashCode(this.path);
642  return hash;
643  }
644  }
645 
650  private class LayoutRangeInfo {
651  long objId;
652  long byteStart;
653  long byteLen;
654  long seq;
655 
656  LayoutRangeInfo(long objId, long byteStart, long byteLen, long seq) {
657  this.objId = objId;
658  this.byteStart = byteStart;
659  this.byteLen = byteLen;
660  this.seq = seq;
661  }
662  }
663 
668  private class FileInfo {
669  long parentObjId;
670  long fsObjId;
671  long dataSourceObjId;
672  int fsType;
673  int attrType;
674  int attrId;
675  String name;
676  long metaAddr;
677  long metaSeq;
678  int dirType;
679  int metaType;
680  int dirFlags;
681  int metaFlags;
682  long size;
683  long crtime;
684  long ctime;
685  long atime;
686  long mtime;
687  int meta_mode;
688  int gid;
689  int uid;
690  String escaped_path;
691  String extension;
692  long seq;
693  long parMetaAddr;
694  long parSeq;
695 
696  FileInfo(long parentObjId,
697  long fsObjId, long dataSourceObjId,
698  int fsType,
699  int attrType, int attrId, String name,
700  long metaAddr, long metaSeq,
701  int dirType, int metaType, int dirFlags, int metaFlags,
702  long size,
703  long crtime, long ctime, long atime, long mtime,
704  int meta_mode, int gid, int uid,
705  String escaped_path, String extension,
706  long seq, long parMetaAddr, long parSeq) {
707 
708  this.parentObjId = parentObjId;
709  this.fsObjId = fsObjId;
710  this.dataSourceObjId = dataSourceObjId;
711  this.fsType = fsType;
712  this.attrType = attrType;
713  this.attrId = attrId;
714  this.name = name;
715  this.metaAddr = metaAddr;
716  this.metaSeq = metaSeq;
717  this.dirType = dirType;
718  this.metaType = metaType;
719  this.dirFlags = dirFlags;
720  this.metaFlags = metaFlags;
721  this.size = size;
722  this.crtime = crtime;
723  this.ctime = ctime;
724  this.atime = atime;
725  this.mtime = mtime;
726  this.meta_mode = meta_mode;
727  this.gid = gid;
728  this.uid = uid;
729  this.escaped_path = escaped_path;
730  this.extension = extension;
731  this.seq = seq;
732  this.parMetaAddr = parMetaAddr;
733  this.parSeq = parSeq;
734  }
735  }
736 
778  private long addFileToDb(long parentObjId,
779  Long fsObjId, long dataSourceObjId,
780  int fsType,
781  Integer attrType, Integer attrId, String name,
782  Long metaAddr, Long metaSeq,
783  int dirType, int metaType, int dirFlags, int metaFlags,
784  long size,
785  Long crtime, Long ctime, Long atime, Long mtime,
786  Integer meta_mode, Integer gid, Integer uid,
787  String md5, TskData.FileKnown known,
788  String escaped_path, String extension,
789  boolean hasLayout, CaseDbTransaction transaction) throws TskCoreException {
790 
791  try {
792  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
793 
794  // Insert a row for the local/logical file into the tsk_objects table.
795  // INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)
796  long objectId = caseDb.addObject(parentObjId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
797 
798  String fileInsert = "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, extension, has_layout)"
799  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
800  PreparedStatement preparedStatement = connection.getPreparedStatement(fileInsert, Statement.NO_GENERATED_KEYS);
801  preparedStatement.clearParameters();
802 
803  if (fsObjId != null) {
804  preparedStatement.setLong(1, fsObjId); // fs_obj_id
805  } else {
806  preparedStatement.setNull(1, java.sql.Types.BIGINT);
807  }
808  preparedStatement.setLong(2, objectId); // obj_id
809  preparedStatement.setLong(3, dataSourceObjId); // data_source_obj_id
810  preparedStatement.setShort(4, (short) fsType); // type
811  if (attrType != null) {
812  preparedStatement.setShort(5, attrType.shortValue()); // attr_type
813  } else {
814  preparedStatement.setNull(5, java.sql.Types.SMALLINT);
815  }
816  if (attrId != null) {
817  preparedStatement.setInt(6, attrId); // attr_id
818  } else {
819  preparedStatement.setNull(6, java.sql.Types.INTEGER);
820  }
821  preparedStatement.setString(7, name); // name
822  if (metaAddr != null) {
823  preparedStatement.setLong(8, metaAddr); // meta_addr
824  } else {
825  preparedStatement.setNull(8, java.sql.Types.BIGINT);
826  }
827  if (metaSeq != null) {
828  preparedStatement.setInt(9, metaSeq.intValue()); // meta_seq
829  } else {
830  preparedStatement.setNull(9, java.sql.Types.INTEGER);
831  }
832  preparedStatement.setShort(10, (short) dirType); // dir_type
833  preparedStatement.setShort(11, (short) metaType); // meta_type
834  preparedStatement.setShort(12, (short) dirFlags); // dir_flags
835  preparedStatement.setShort(13, (short) metaFlags); // meta_flags
836  preparedStatement.setLong(14, size < 0 ? 0 : size); // size
837  if (crtime != null) {
838  preparedStatement.setLong(15, crtime); // crtime
839  } else {
840  preparedStatement.setNull(15, java.sql.Types.BIGINT);
841  }
842  if (ctime != null) {
843  preparedStatement.setLong(16, ctime); // ctime
844  } else {
845  preparedStatement.setNull(16, java.sql.Types.BIGINT);
846  }
847  if (atime != null) {
848  preparedStatement.setLong(17, atime); // atime
849  } else {
850  preparedStatement.setNull(17, java.sql.Types.BIGINT);
851  }
852  if (mtime != null) {
853  preparedStatement.setLong(18, mtime); // mtime
854  } else {
855  preparedStatement.setNull(18, java.sql.Types.BIGINT);
856  }
857  if (meta_mode != null) {
858  preparedStatement.setLong(19, meta_mode); // mode
859  } else {
860  preparedStatement.setNull(19, java.sql.Types.BIGINT);
861  }
862  if (gid != null) {
863  preparedStatement.setLong(20, gid); // gid
864  } else {
865  preparedStatement.setNull(20, java.sql.Types.BIGINT);
866  }
867  if (uid != null) {
868  preparedStatement.setLong(21, uid); // uid
869  } else {
870  preparedStatement.setNull(21, java.sql.Types.BIGINT);
871  }
872  preparedStatement.setString(22, md5); // md5
873  preparedStatement.setInt(23, known.getFileKnownValue());// known
874  preparedStatement.setString(24, escaped_path); // parent_path
875  preparedStatement.setString(25, extension); // extension
876  if (hasLayout) {
877  preparedStatement.setInt(26, 1); // has_layout
878  } else {
879  preparedStatement.setNull(26, java.sql.Types.INTEGER);
880  }
881  connection.executeUpdate(preparedStatement);
882 
883  // If this is not a slack file create the timeline events
884  if (!hasLayout
885  && TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() != fsType
886  && (!name.equals(".")) && (!name.equals(".."))) {
887  TimelineManager timelineManager = caseDb.getTimelineManager();
888  DerivedFile derivedFile = new DerivedFile(caseDb, objectId, dataSourceObjId, name,
889  TskData.TSK_FS_NAME_TYPE_ENUM.valueOf((short) dirType),
890  TskData.TSK_FS_META_TYPE_ENUM.valueOf((short) metaType),
891  TskData.TSK_FS_NAME_FLAG_ENUM.valueOf(dirFlags),
892  (short) metaFlags,
893  size, ctime, crtime, atime, mtime, null, null, null, escaped_path, null, parentObjId, null, null, extension);
894 
895  timelineManager.addEventsForNewFileQuiet(derivedFile, connection);
896  }
897 
898  return objectId;
899  } catch (SQLException ex) {
900  throw new TskCoreException("Failed to add file system file", ex);
901  }
902  }
903 
922  private long addImageToDb(TskData.TSK_IMG_TYPE_ENUM type, long sectorSize, long size,
923  String timezone, String md5, String sha1, String sha256,
924  String deviceId, String collectionDetails,
925  CaseDbTransaction transaction) throws TskCoreException {
926  try {
927  // Insert a row for the Image into the tsk_objects table.
928  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
929  long newObjId = caseDb.addObject(0, TskData.ObjectType.IMG.getObjectType(), connection);
930 
931  // Add a row to tsk_image_info
932  // INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)
933  String imageInfoSql = "INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
934  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
935  PreparedStatement preparedStatement = connection.getPreparedStatement(imageInfoSql, Statement.NO_GENERATED_KEYS);
936  preparedStatement.clearParameters();
937  preparedStatement.setLong(1, newObjId);
938  preparedStatement.setShort(2, (short) type.getValue());
939  preparedStatement.setLong(3, sectorSize);
940  preparedStatement.setString(4, timezone);
941  //prevent negative size
942  long savedSize = size < 0 ? 0 : size;
943  preparedStatement.setLong(5, savedSize);
944  preparedStatement.setString(6, md5);
945  preparedStatement.setString(7, sha1);
946  preparedStatement.setString(8, sha256);
947  preparedStatement.setString(9, null);
948  connection.executeUpdate(preparedStatement);
949 
950  // Add a row to data_source_info
951  String dataSourceInfoSql = "INSERT INTO data_source_info (obj_id, device_id, time_zone, acquisition_details) VALUES (?, ?, ?, ?)"; // NON-NLS
952  preparedStatement = connection.getPreparedStatement(dataSourceInfoSql, Statement.NO_GENERATED_KEYS);
953  preparedStatement.clearParameters();
954  preparedStatement.setLong(1, newObjId);
955  preparedStatement.setString(2, deviceId);
956  preparedStatement.setString(3, timezone);
957  preparedStatement.setString(4, collectionDetails);
958  connection.executeUpdate(preparedStatement);
959 
960  return newObjId;
961  } catch (SQLException ex) {
962  throw new TskCoreException(String.format("Error adding image to database"), ex);
963  }
964  }
965 
976  private void addImageNameToDb(long objId, String name, long sequence,
977  CaseDbTransaction transaction) throws TskCoreException {
978  try {
979  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
980 
981  String imageNameSql = "INSERT INTO tsk_image_names (obj_id, name, sequence) VALUES (?, ?, ?)"; // NON-NLS
982  PreparedStatement preparedStatement = connection.getPreparedStatement(imageNameSql, Statement.NO_GENERATED_KEYS);
983  preparedStatement.clearParameters();
984  preparedStatement.setLong(1, objId);
985  preparedStatement.setString(2, name);
986  preparedStatement.setLong(3, sequence);
987  connection.executeUpdate(preparedStatement);
988  } catch (SQLException ex) {
989  throw new TskCoreException(String.format("Error adding image name %s to image with object ID %d", name, objId), ex);
990  }
991  }
992 
1004  void addLayoutFileRangeToDb(long objId, long byteStart, long byteLen,
1005  long seq, CaseDbTransaction transaction) throws TskCoreException {
1006  try {
1007  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1008 
1009  String insertRangeSql = "INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) " //NON-NLS
1010  + "VALUES (?, ?, ?, ?)";
1011  PreparedStatement preparedStatement = connection.getPreparedStatement(insertRangeSql, Statement.NO_GENERATED_KEYS);
1012  preparedStatement.clearParameters();
1013  preparedStatement.setLong(1, objId);
1014  preparedStatement.setLong(2, byteStart);
1015  preparedStatement.setLong(3, byteLen);
1016  preparedStatement.setLong(4, seq);
1017  connection.executeUpdate(preparedStatement);
1018  } catch (SQLException ex) {
1019  throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex);
1020  }
1021  }
1022 }

Copyright © 2011-2020 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.