Sleuth Kit Java Bindings (JNI)  4.10.1
Java bindings for using The Sleuth Kit
AbstractFile.java
Go to the documentation of this file.
1 /*
2  * SleuthKit Java Bindings
3  *
4  * Copyright 2011-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.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.RandomAccessFile;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26 import java.text.MessageFormat;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.ResourceBundle;
30 import java.util.Set;
31 import java.util.SortedSet;
32 import java.util.TimeZone;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
40 
45 public abstract class AbstractFile extends AbstractContent {
46 
48  protected final TSK_FS_NAME_TYPE_ENUM dirType;
50  protected final TSK_FS_NAME_FLAG_ENUM dirFlag;
51  protected final Set<TSK_FS_META_FLAG_ENUM> metaFlags;
52  protected long size;
53  protected final long metaAddr, ctime, crtime, atime, mtime;
54  protected final int metaSeq;
55  protected final int uid, gid;
56  protected final int attrId;
58  protected final Set<TskData.TSK_FS_META_MODE_ENUM> modes;
59  //local file support
60  private boolean localPathSet = false;
61  private String localPath;
62  private String localAbsPath;
63  private volatile RandomAccessFile localFileHandle;
64  private volatile java.io.File localFile;
65  private TskData.EncodingType encodingType;
66  //range support
67  private List<TskFileRange> ranges;
68  /*
69  * path of parent directory
70  */
71  protected final String parentPath;
76  private boolean knownStateDirty = false;
77  /*
78  * md5 hash
79  */
80  protected String md5Hash;
81  private boolean md5HashDirty = false;
82  /*
83  * SHA-256 hash
84  */
85  protected String sha256Hash;
86  private boolean sha256HashDirty = false;
87  private String mimeType;
88  private boolean mimeTypeDirty = false;
89  private static final Logger LOGGER = Logger.getLogger(AbstractFile.class.getName());
90  private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("org.sleuthkit.datamodel.Bundle");
91  private long dataSourceObjectId;
92  private final String extension;
93 
132  long objId,
133  long dataSourceObjectId,
135  String name,
137  long metaAddr, int metaSeq,
139  TSK_FS_NAME_FLAG_ENUM dirFlag, short metaFlags,
140  long size,
141  long ctime, long crtime, long atime, long mtime,
142  short modes,
143  int uid, int gid,
144  String md5Hash, String sha256Hash, FileKnown knownState,
145  String parentPath,
146  String mimeType,
147  String extension) {
148  super(db, objId, name);
149  this.dataSourceObjectId = dataSourceObjectId;
150  this.attrType = attrType;
151  this.attrId = attrId;
152  this.fileType = fileType;
153  this.metaAddr = metaAddr;
154  this.metaSeq = metaSeq;
155  this.dirType = dirType;
156  this.metaType = metaType;
157  this.dirFlag = dirFlag;
158  this.metaFlags = TSK_FS_META_FLAG_ENUM.valuesOf(metaFlags);
159  this.size = size;
160  this.ctime = ctime;
161  this.crtime = crtime;
162  this.atime = atime;
163  this.mtime = mtime;
164  this.uid = uid;
165  this.gid = gid;
166  this.modes = TskData.TSK_FS_META_MODE_ENUM.valuesOf(modes);
167 
168  this.md5Hash = md5Hash;
169  this.sha256Hash = sha256Hash;
170  if (knownState == null) {
171  this.knownState = FileKnown.UNKNOWN;
172  } else {
173  this.knownState = knownState;
174  }
175  this.parentPath = parentPath;
176  this.mimeType = mimeType;
177  this.extension = extension == null ? "" : extension;
178  this.encodingType = TskData.EncodingType.NONE;
179  }
180 
187  return fileType;
188  }
189 
196  return attrType;
197  }
198 
204  public int getAttributeId() {
205  return attrId;
206  }
207 
213  public long getCtime() {
214  return ctime;
215  }
216 
222  public String getCtimeAsDate() {
223  return epochToTime(ctime);
224  }
225 
231  public long getCrtime() {
232  return crtime;
233  }
234 
240  public String getCrtimeAsDate() {
241  return epochToTime(crtime);
242  }
243 
249  public long getAtime() {
250  return atime;
251  }
252 
258  public String getAtimeAsDate() {
259  return epochToTime(atime);
260  }
261 
267  public long getMtime() {
268  return mtime;
269  }
270 
276  public String getMtimeAsDate() {
277  return epochToTime(mtime);
278  }
279 
285  public int getUid() {
286  return uid;
287  }
288 
294  public int getGid() {
295  return gid;
296  }
297 
303  public long getMetaAddr() {
304  return metaAddr;
305  }
306 
313  public long getMetaSeq() {
314  return metaSeq;
315  }
316 
322  public String getModesAsString() {
324  String result = "";
325 
326  short isuid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISUID.getMode();
327  short isgid = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISGID.getMode();
328  short isvtx = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_ISVTX.getMode();
329 
330  short irusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRUSR.getMode();
331  short iwusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWUSR.getMode();
332  short ixusr = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXUSR.getMode();
333 
334  short irgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IRGRP.getMode();
335  short iwgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWGRP.getMode();
336  short ixgrp = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXGRP.getMode();
337 
338  short iroth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IROTH.getMode();
339  short iwoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IWOTH.getMode();
340  short ixoth = TskData.TSK_FS_META_MODE_ENUM.TSK_FS_META_MODE_IXOTH.getMode();
341 
342  // first character = the Meta Type
343  result += metaType.toString();
344 
345  // second and third characters = user permissions
346  if ((mode & irusr) == irusr) {
347  result += "r"; //NON-NLS
348  } else {
349  result += "-"; //NON-NLS
350  }
351  if ((mode & iwusr) == iwusr) {
352  result += "w"; //NON-NLS
353  } else {
354  result += "-"; //NON-NLS
355  }
356 
357  // fourth character = set uid
358  if ((mode & isuid) == isuid) {
359  if ((mode & ixusr) == ixusr) {
360  result += "s"; //NON-NLS
361  } else {
362  result += "S"; //NON-NLS
363  }
364  } else {
365  if ((mode & ixusr) == ixusr) {
366  result += "x"; //NON-NLS
367  } else {
368  result += "-"; //NON-NLS
369  }
370  }
371 
372  // fifth and sixth characters = group permissions
373  if ((mode & irgrp) == irgrp) {
374  result += "r"; //NON-NLS
375  } else {
376  result += "-"; //NON-NLS
377  }
378  if ((mode & iwgrp) == iwgrp) {
379  result += "w"; //NON-NLS
380  } else {
381  result += "-"; //NON-NLS
382  }
383 
384  // seventh character = set gid
385  if ((mode & isgid) == isgid) {
386  if ((mode & ixgrp) == ixgrp) {
387  result += "s"; //NON-NLS
388  } else {
389  result += "S"; //NON-NLS
390  }
391  } else {
392  if ((mode & ixgrp) == ixgrp) {
393  result += "x"; //NON-NLS
394  } else {
395  result += "-"; //NON-NLS
396  }
397  }
398 
399  // eighth and ninth character = other permissions
400  if ((mode & iroth) == iroth) {
401  result += "r"; //NON-NLS
402  } else {
403  result += "-"; //NON-NLS
404  }
405  if ((mode & iwoth) == iwoth) {
406  result += "w"; //NON-NLS
407  } else {
408  result += "-"; //NON-NLS
409  }
410 
411  // tenth character = sticky bit
412  if ((mode & isvtx) == isvtx) {
413  if ((mode & ixoth) == ixoth) {
414  result += "t"; //NON-NLS
415  } else {
416  result += "T"; //NON-NLS
417  }
418  } else {
419  if ((mode & ixoth) == ixoth) {
420  result += "x"; //NON-NLS
421  } else {
422  result += "-"; //NON-NLS
423  }
424  }
425 
426  // check the result
427  if (result.length() != 10) {
428  // throw error here
429  result = "ERROR"; //NON-NLS
430  }
431  return result;
432  }
433 
439  public String getMIMEType() {
440  return mimeType;
441  }
442 
451  public void setMIMEType(String mimeType) {
452  this.mimeType = mimeType;
453  this.mimeTypeDirty = true;
454  }
455 
456  public boolean isModeSet(TskData.TSK_FS_META_MODE_ENUM mode) {
457  return modes.contains(mode);
458  }
459 
468  public void setMd5Hash(String md5Hash) {
469  this.md5Hash = md5Hash;
470  this.md5HashDirty = true;
471  }
472 
478  public String getMd5Hash() {
479  return this.md5Hash;
480  }
481 
490  public void setSha256Hash(String sha256Hash) {
491  this.sha256Hash = sha256Hash;
492  this.sha256HashDirty = true;
493  }
494 
500  public String getSha256Hash() {
501  return this.sha256Hash;
502  }
503 
515  // don't allow them to downgrade the known state
516  if (this.knownState.compareTo(knownState) > 0) {
517  // ideally we'd return some kind of error, but
518  // the API doesn't allow it
519  return;
520  }
521  this.knownState = knownState;
522  this.knownStateDirty = true;
523  }
524 
532  return knownState;
533  }
534 
542  public String getNameExtension() {
543  return extension;
544  }
545 
551  @Override
552  public long getSize() {
553  return size;
554  }
555 
561  public String getParentPath() {
562  return parentPath;
563  }
564 
576  @Override
578  return getSleuthkitCase().getContentById(this.dataSourceObjectId);
579  }
580 
586  public long getDataSourceObjectId() {
587  return dataSourceObjectId;
588  }
589 
600  public List<TskFileRange> getRanges() throws TskCoreException {
601  if (ranges == null) {
602  ranges = getSleuthkitCase().getFileRanges(this.getId());
603  }
604  return ranges;
605  }
606 
620  public long convertToImgOffset(long fileOffset) throws TskCoreException {
621  long imgOffset = -1;
622  for (TskFileRange byteRange : getRanges()) {
623 
624  // if fileOffset is within the current byteRange, calculate the image
625  // offset and break
626  long rangeLength = byteRange.getByteLen();
627  if (fileOffset < rangeLength) {
628  imgOffset = byteRange.getByteStart() + fileOffset;
629  break;
630  }
631 
632  // otherwise, decrement fileOffset by the length of the current
633  // byte range and continue
634  fileOffset -= rangeLength;
635  }
636  return imgOffset;
637  }
638 
653  public List<TskFileRange> convertToImgRanges(long fileOffset, long length) throws TskCoreException {
654  if (fileOffset < 0 || length < 0) {
655  throw new TskCoreException("fileOffset and length must be non-negative");
656  }
657 
658  List<TskFileRange> thisRanges = getRanges();
659  List<TskFileRange> toRet = new ArrayList<>();
660 
661  long requestedEnd = fileOffset + length;
662 
663  // the number of bytes counted from the beginning of this file
664  long bytesCounted = 0;
665 
666  for (int curRangeIdx = 0; curRangeIdx < thisRanges.size(); curRangeIdx++) {
667  // if we exceeded length of requested, then we are done
668  if (bytesCounted >= requestedEnd) {
669  break;
670  }
671 
672  TskFileRange curRange = thisRanges.get(curRangeIdx);
673  long curRangeLen = curRange.getByteLen();
674  // the bytes counted when we reach the end of this range
675  long curRangeEnd = bytesCounted + curRangeLen;
676 
677  // if fileOffset is less than current range's end and we have not
678  // gone past the end we requested, then grab at least part of this
679  // range.
680  if (fileOffset < curRangeEnd) {
681  // offset into range to be returned to user (0 if fileOffset <= bytesCounted)
682  long rangeOffset = Math.max(0, fileOffset - bytesCounted);
683 
684  // calculate the new TskFileRange start by adding on the offset into the current range
685  long newRangeStart = curRange.getByteStart() + rangeOffset;
686 
687  // how much this current range exceeds the length requested (or 0 if within the length requested)
688  long rangeOvershoot = Math.max(0, curRangeEnd - requestedEnd);
689 
690  long newRangeLen = curRangeLen - rangeOffset - rangeOvershoot;
691  toRet.add(new TskFileRange(newRangeStart, newRangeLen, toRet.size()));
692  }
693 
694  bytesCounted = curRangeEnd;
695  }
696 
697  return toRet;
698  }
699 
706  public boolean isVirtual() {
708  || dirType.equals(TskData.TSK_FS_NAME_TYPE_ENUM.VIRT)
710  }
711 
719  public boolean isFile() {
720  return metaType.equals(TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG)
721  || (metaType.equals(TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_UNDEF)
722  && dirType.equals(TSK_FS_NAME_TYPE_ENUM.REG));
723 
724  }
725 
732  public boolean isDir() {
733  return (metaType.equals(TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR)
735  }
736 
742  public abstract boolean isRoot();
743 
752  public static String createNonUniquePath(String uniquePath) {
753 
754  // split the path into parts
755  String[] pathSegments = uniquePath.split("/");
756 
757  // see if uniquePath had an image and/or volume name
758  int index = 0;
759  if (pathSegments[0].startsWith("img_")) { //NON-NLS
760  ++index;
761  }
762  if (pathSegments[1].startsWith("vol_")) { //NON-NLS
763  ++index;
764  }
765 
766  // Assemble the non-unique path (skipping over the image and volume
767  // name, if they exist).
768  StringBuilder strbuf = new StringBuilder();
769  for (; index < pathSegments.length; ++index) {
770  if (!pathSegments[index].isEmpty()) {
771  strbuf.append("/").append(pathSegments[index]);
772  }
773  }
774 
775  return strbuf.toString();
776  }
777 
784  public List<AbstractFile> listFiles() throws TskCoreException {
785  // first, get all children
786  List<Content> children = getChildren();
787 
788  // only keep those that are of type AbstractFile
789  List<AbstractFile> files = new ArrayList<AbstractFile>();
790  for (Content child : children) {
791  if (child instanceof AbstractFile) {
792  AbstractFile afChild = (AbstractFile) child;
793  files.add(afChild);
794  }
795  }
796  return files;
797  }
798 
805  return metaType;
806  }
807 
808  public String getMetaTypeAsString() {
809  return metaType.toString();
810  }
811 
818  return dirType;
819  }
820 
821  public String getDirTypeAsString() {
822  return dirType.toString();
823  }
824 
831  return dirFlag == flag;
832  }
833 
838  public String getDirFlagAsString() {
839  return dirFlag.toString();
840  }
841 
845  public String getMetaFlagsAsString() {
846  String str = "";
847  if (metaFlags.contains(TSK_FS_META_FLAG_ENUM.ALLOC)) {
848  str = TSK_FS_META_FLAG_ENUM.ALLOC.toString();
849  } else if (metaFlags.contains(TSK_FS_META_FLAG_ENUM.UNALLOC)) {
850  str = TSK_FS_META_FLAG_ENUM.UNALLOC.toString();
851  }
852  return str;
853  }
854 
860  public boolean isMetaFlagSet(TSK_FS_META_FLAG_ENUM metaFlag) {
861  return metaFlags.contains(metaFlag);
862  }
863 
864  @Override
865  public final int read(byte[] buf, long offset, long len) throws TskCoreException {
866  //template method
867  //if localPath is set, use local, otherwise, use readCustom() supplied by derived class
868  if (localPathSet) {
869  return readLocal(buf, offset, len);
870  } else {
871  return readInt(buf, offset, len);
872  }
873 
874  }
875 
887  protected int readInt(byte[] buf, long offset, long len) throws TskCoreException {
888  return 0;
889  }
890 
902  protected final int readLocal(byte[] buf, long offset, long len) throws TskCoreException {
903  if (!localPathSet) {
904  throw new TskCoreException(
905  BUNDLE.getString("AbstractFile.readLocal.exception.msg1.text"));
906  }
907 
908  if (isDir()) {
909  return 0;
910  }
911 
912  // If the file is empty, just return that zero bytes were read.
913  if (getSize() == 0) {
914  return 0;
915  }
916 
917  loadLocalFile();
918  if (!localFile.exists()) {
919  throw new TskCoreException(
920  MessageFormat.format(BUNDLE.getString("AbstractFile.readLocal.exception.msg2.text"), localAbsPath));
921  }
922  if (!localFile.canRead()) {
923  throw new TskCoreException(
924  MessageFormat.format(BUNDLE.getString("AbstractFile.readLocal.exception.msg3.text"), localAbsPath));
925  }
926 
927  int bytesRead = 0;
928 
929  if (localFileHandle == null) {
930  synchronized (this) {
931  if (localFileHandle == null) {
932  try {
933  localFileHandle = new RandomAccessFile(localFile, "r");
934  } catch (FileNotFoundException ex) {
935  final String msg = MessageFormat.format(BUNDLE.getString(
936  "AbstractFile.readLocal.exception.msg4.text"),
937  localAbsPath);
938  LOGGER.log(Level.SEVERE, msg, ex);
939  //file could have been deleted or moved
940  throw new TskCoreException(msg, ex);
941  }
942  }
943  }
944  }
945 
946  try {
947  if (!encodingType.equals(TskData.EncodingType.NONE)) {
948  // The file is encoded, so we need to alter the offset to read (since there's
949  // a header on the encoded file) and then decode each byte
950  long encodedOffset = offset + EncodedFileUtil.getHeaderLength();
951 
952  //move to the user request offset in the stream
953  long curOffset = localFileHandle.getFilePointer();
954  if (curOffset != encodedOffset) {
955  localFileHandle.seek(encodedOffset);
956  }
957  bytesRead = localFileHandle.read(buf, 0, (int) len);
958  for (int i = 0; i < bytesRead; i++) {
959  buf[i] = EncodedFileUtil.decodeByte(buf[i], encodingType);
960  }
961  return bytesRead;
962  } else {
963  //move to the user request offset in the stream
964  long curOffset = localFileHandle.getFilePointer();
965  if (curOffset != offset) {
966  localFileHandle.seek(offset);
967  }
968  //note, we are always writing at 0 offset of user buffer
969  return localFileHandle.read(buf, 0, (int) len);
970  }
971  } catch (IOException ex) {
972  final String msg = MessageFormat.format(BUNDLE.getString("AbstractFile.readLocal.exception.msg5.text"), localAbsPath);
973  LOGGER.log(Level.SEVERE, msg, ex);
974  //local file could have been deleted / moved
975  throw new TskCoreException(msg, ex);
976  }
977  }
978 
986  void setLocalFilePath(String localPath) {
987 
988  if (localPath == null || localPath.equals("")) {
989  this.localPath = "";
990  localAbsPath = null;
991  localPathSet = false;
992  } else {
993  // It should always be the case that absolute paths start with slashes or a windows drive letter
994  // and relative paths do not, but some older versions of modules created derived file paths
995  // starting with slashes. So we first check if this file is a DerivedFile before looking at the path.
996  this.localPath = localPath;
997  if (this instanceof DerivedFile) {
998  // DerivedFiles always have relative paths
999  this.localAbsPath = getSleuthkitCase().getDbDirPath() + java.io.File.separator + localPath;
1000  } else {
1001  // If a path starts with a slash or with a Windows drive letter, then it is
1002  // absolute. Otherwise it is relative.
1003  if (localPath.startsWith("/") || localPath.startsWith("\\")
1004  || localPath.matches("[A-Za-z]:[/\\\\].*")) {
1005  this.localAbsPath = localPath;
1006  } else {
1007  this.localAbsPath = getSleuthkitCase().getDbDirPath() + java.io.File.separator + localPath;
1008  }
1009  }
1010  this.localPathSet = true;
1011  }
1012  }
1013 
1019  public String getLocalPath() {
1020  return localPath;
1021  }
1022 
1028  public String getLocalAbsPath() {
1029  return localAbsPath;
1030  }
1031 
1037  final void setEncodingType(TskData.EncodingType encodingType) {
1038  this.encodingType = encodingType;
1039  }
1040 
1047  public boolean exists() {
1048  if (!localPathSet) {
1049  return true;
1050  } else {
1051  try {
1052  loadLocalFile();
1053  return localFile.exists();
1054  } catch (TskCoreException ex) {
1055  LOGGER.log(Level.SEVERE, ex.getMessage());
1056  return false;
1057  }
1058  }
1059  }
1060 
1068  public boolean canRead() {
1069  if (!localPathSet) {
1070  return true;
1071  } else {
1072  try {
1073  loadLocalFile();
1074  return localFile.canRead();
1075  } catch (TskCoreException ex) {
1076  LOGGER.log(Level.SEVERE, ex.getMessage());
1077  return false;
1078  }
1079  }
1080  }
1081 
1088  private void loadLocalFile() throws TskCoreException {
1089  if (!localPathSet) {
1090  throw new TskCoreException(
1091  BUNDLE.getString("AbstractFile.readLocal.exception.msg1.text"));
1092  }
1093 
1094  // already been set
1095  if (localFile != null) {
1096  return;
1097  }
1098 
1099  synchronized (this) {
1100  if (localFile == null) {
1101  localFile = new java.io.File(localAbsPath);
1102  }
1103  }
1104  }
1105 
1106  @Override
1107  public void close() {
1108 
1109  //close local file handle if set
1110  if (localFileHandle != null) {
1111  synchronized (this) {
1112  if (localFileHandle != null) {
1113  try {
1114  localFileHandle.close();
1115  } catch (IOException ex) {
1116  LOGGER.log(Level.SEVERE, "Could not close file handle for file: " + getParentPath() + getName(), ex); //NON-NLS
1117  }
1118  localFileHandle = null;
1119  }
1120  }
1121  }
1122 
1123  }
1124 
1125  @Override
1126  protected void finalize() throws Throwable {
1127  try {
1128  close();
1129  } finally {
1130  super.finalize();
1131  }
1132  }
1133 
1134  @Override
1135  public String toString(boolean preserveState) {
1136  return super.toString(preserveState) + "AbstractFile [\t" //NON-NLS
1137  + "\t" + "fileType " + fileType //NON-NLS
1138  + "\tctime " + ctime //NON-NLS
1139  + "\tcrtime " + crtime //NON-NLS
1140  + "\t" + "mtime " + mtime + "\t" + "atime " + atime //NON-NLS
1141  + "\t" + "attrId " + attrId //NON-NLS
1142  + "\t" + "attrType " + attrType //NON-NLS
1143  + "\t" + "dirFlag " + dirFlag + "\t" + "dirType " + dirType //NON-NLS
1144  + "\t" + "uid " + uid //NON-NLS
1145  + "\t" + "gid " + gid //NON-NLS
1146  + "\t" + "metaAddr " + metaAddr + "\t" + "metaSeq " + metaSeq + "\t" + "metaFlags " + metaFlags //NON-NLS
1147  + "\t" + "metaType " + metaType + "\t" + "modes " + modes //NON-NLS
1148  + "\t" + "parentPath " + parentPath + "\t" + "size " + size //NON-NLS
1149  + "\t" + "knownState " + knownState + "\t" + "md5Hash " + md5Hash + "\t" + "sha256Hash " + sha256Hash //NON-NLS
1150  + "\t" + "localPathSet " + localPathSet + "\t" + "localPath " + localPath //NON-NLS
1151  + "\t" + "localAbsPath " + localAbsPath + "\t" + "localFile " + localFile //NON-NLS
1152  + "]\t";
1153  }
1154 
1158  public enum MimeMatchEnum {
1159 
1162  FALSE
1163  }
1164 
1173  public MimeMatchEnum isMimeType(SortedSet<String> mimeTypes) {
1174  if (this.mimeType == null) {
1175  return MimeMatchEnum.UNDEFINED;
1176  }
1177  if (mimeTypes.contains(this.mimeType)) {
1178  return MimeMatchEnum.TRUE;
1179  }
1180  return MimeMatchEnum.FALSE;
1181  }
1182 
1190  public void save() throws TskCoreException {
1191 
1192  // No fields have been updated
1193  if (!(md5HashDirty || sha256HashDirty || mimeTypeDirty || knownStateDirty)) {
1194  return;
1195  }
1196 
1197  String queryStr = "";
1198  if (mimeTypeDirty) {
1199  queryStr = "mime_type = '" + this.getMIMEType() + "'";
1200  }
1201  if (md5HashDirty) {
1202  if (!queryStr.isEmpty()) {
1203  queryStr += ", ";
1204  }
1205  queryStr += "md5 = '" + this.getMd5Hash() + "'";
1206  }
1207  if (sha256HashDirty) {
1208  if (!queryStr.isEmpty()) {
1209  queryStr += ", ";
1210  }
1211  queryStr += "sha256 = '" + this.getSha256Hash() + "'";
1212  }
1213  if (knownStateDirty) {
1214  if (!queryStr.isEmpty()) {
1215  queryStr += ", ";
1216  }
1217  queryStr += "known = '" + this.getKnown().getFileKnownValue() + "'";
1218  }
1219 
1220  queryStr = "UPDATE tsk_files SET " + queryStr + " WHERE obj_id = " + this.getId();
1221 
1223  try (SleuthkitCase.CaseDbConnection connection = getSleuthkitCase().getConnection();
1224  Statement statement = connection.createStatement();) {
1225 
1226  connection.executeUpdate(statement, queryStr);
1227  md5HashDirty = false;
1228  sha256HashDirty = false;
1229  mimeTypeDirty = false;
1230  knownStateDirty = false;
1231  } catch (SQLException ex) {
1232  throw new TskCoreException(String.format("Error saving properties for file (obj_id = %s)", this.getId()), ex);
1233  } finally {
1235  }
1236  }
1237 
1238  @Override
1239  public BlackboardArtifact newArtifact(int artifactTypeID) throws TskCoreException {
1240  // don't let them make more than 1 GEN_INFO
1241  if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
1242  return getGenInfoArtifact(true);
1243  }
1244  return getSleuthkitCase().newBlackboardArtifact(artifactTypeID, getId(), dataSourceObjectId);
1245  }
1246 
1278  @Deprecated
1279  @SuppressWarnings("deprecation")
1280  protected AbstractFile(SleuthkitCase db, long objId, TskData.TSK_FS_ATTR_TYPE_ENUM attrType, short attrId,
1281  String name, TskData.TSK_DB_FILES_TYPE_ENUM fileType, long metaAddr, int metaSeq,
1282  TSK_FS_NAME_TYPE_ENUM dirType, TSK_FS_META_TYPE_ENUM metaType, TSK_FS_NAME_FLAG_ENUM dirFlag, short metaFlags,
1283  long size, long ctime, long crtime, long atime, long mtime, short modes, int uid, int gid, String md5Hash, FileKnown knownState,
1284  String parentPath) {
1285  this(db, objId, db.getDataSourceObjectId(objId), attrType, (int) attrId, name, fileType, metaAddr, metaSeq, dirType, metaType, dirFlag, metaFlags, size, ctime, crtime, atime, mtime, modes, uid, gid, md5Hash, null, knownState, parentPath, null, null);
1286  }
1287 
1324  @Deprecated
1325  @SuppressWarnings("deprecation")
1326  AbstractFile(SleuthkitCase db, long objId, long dataSourceObjectId, TskData.TSK_FS_ATTR_TYPE_ENUM attrType, short attrId,
1327  String name, TskData.TSK_DB_FILES_TYPE_ENUM fileType, long metaAddr, int metaSeq, TSK_FS_NAME_TYPE_ENUM dirType, TSK_FS_META_TYPE_ENUM metaType,
1328  TSK_FS_NAME_FLAG_ENUM dirFlag, short metaFlags, long size, long ctime, long crtime, long atime, long mtime, short modes,
1329  int uid, int gid, String md5Hash, FileKnown knownState, String parentPath, String mimeType) {
1330  this(db, objId, dataSourceObjectId, attrType, (int) attrId, name, fileType, metaAddr, metaSeq, dirType, metaType, dirFlag, metaFlags, size, ctime, crtime, atime, mtime, modes, uid, gid, md5Hash, null, knownState, parentPath, null, null);
1331  }
1332 
1341  @Deprecated
1342  @SuppressWarnings("deprecation")
1343  public short getAttrId() {
1344  /*
1345  * NOTE: previously attrId used to be stored in AbstractFile as (signed)
1346  * short even though it is stored as uint16 in TSK. In extremely rare
1347  * occurrences attrId can be larger than what a signed short can hold
1348  * (2^15). Changes were made to AbstractFile to store attrId as integer.
1349  * Therefore this method has been deprecated. For backwards
1350  * compatibility, attribute ids that are larger than 32K are converted
1351  * to a negative number.
1352  */
1353  return (short) attrId; // casting to signed short converts values over 32K to negative values
1354  }
1355 
1367  @Deprecated
1368  protected void setLocalPath(String localPath, boolean isAbsolute) {
1369  setLocalFilePath(localPath);
1370  }
1371 
1372  /*
1373  * -------------------------------------------------------------------------
1374  * Util methods to convert / map the data
1375  * -------------------------------------------------------------------------
1376  */
1386  @Deprecated
1387  public static String epochToTime(long epoch) {
1388  return TimeUtilities.epochToTime(epoch);
1389  }
1390 
1402  @Deprecated
1403  public static String epochToTime(long epoch, TimeZone tzone) {
1404  return TimeUtilities.epochToTime(epoch, tzone);
1405  }
1406 
1414  @Deprecated
1415  public static long timeToEpoch(String time) {
1416  return TimeUtilities.timeToEpoch(time);
1417  }
1418 }
VIRT
Special (TSK added "Virtual" files) NON-NLS.
Definition: TskData.java:50
boolean isModeSet(TskData.TSK_FS_META_MODE_ENUM mode)
final TSK_FS_NAME_TYPE_ENUM dirType
static long timeToEpoch(String time)
static String epochToTime(long epoch)
static String epochToTime(long epoch)
static Set< TSK_FS_META_FLAG_ENUM > valuesOf(short metaFlags)
Definition: TskData.java:247
final int readLocal(byte[] buf, long offset, long len)
boolean isDirNameFlagSet(TSK_FS_NAME_FLAG_ENUM flag)
ALLOC
Metadata structure is currently in an allocated state.
Definition: TskData.java:206
final TSK_FS_NAME_FLAG_ENUM dirFlag
void setSha256Hash(String sha256Hash)
final TskData.TSK_DB_FILES_TYPE_ENUM fileType
UNALLOC
Metadata structure is currently in an unallocated state.
Definition: TskData.java:207
TskData.TSK_DB_FILES_TYPE_ENUM getType()
final TskData.TSK_FS_ATTR_TYPE_ENUM attrType
TSK_FS_META_TYPE_VIRT_DIR
"Virtual Directory" created by TSK for Orphan Files NON-NLS
Definition: TskData.java:114
long convertToImgOffset(long fileOffset)
TSK_FS_NAME_TYPE_ENUM getDirType()
BlackboardArtifact newArtifact(int artifactTypeID)
MimeMatchEnum isMimeType(SortedSet< String > mimeTypes)
final Set< TSK_FS_META_FLAG_ENUM > metaFlags
String toString(boolean preserveState)
void setKnown(TskData.FileKnown knownState)
FALSE
file has a defined mime type and it is one of the given ones
final Set< TskData.TSK_FS_META_MODE_ENUM > modes
BlackboardArtifact newBlackboardArtifact(int artifactTypeID, long obj_id)
TSK_FS_META_TYPE_VIRT
"Virtual File" created by TSK for file system areas NON-NLS
Definition: TskData.java:113
TSK_FS_META_TYPE_ENUM getMetaType()
boolean isMetaFlagSet(TSK_FS_META_FLAG_ENUM metaFlag)
TRUE
file does not have a defined mime time in blackboard
static short toInt(Set< TSK_FS_META_MODE_ENUM > modes)
Definition: TskData.java:422
static String epochToTime(long epoch, TimeZone tzone)
static long timeToEpoch(String time)
int readInt(byte[] buf, long offset, long len)
UNKNOWN
File marked as unknown by hash db.
Definition: TskData.java:782
static Set< TSK_FS_META_MODE_ENUM > valuesOf(short modes)
Definition: TskData.java:403
List< TskFileRange > convertToImgRanges(long fileOffset, long length)
void setLocalPath(String localPath, boolean isAbsolute)
static String createNonUniquePath(String uniquePath)
VIRTUAL_DIR
Virtual directory (not on fs) with no meta-data entry that can be used to group files of types other ...
Definition: TskData.java:682
final int read(byte[] buf, long offset, long len)
final TSK_FS_META_TYPE_ENUM metaType
List< TskFileRange > getFileRanges(long id)
TskData.TSK_FS_ATTR_TYPE_ENUM getAttrType()

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.