Sleuth Kit Java Bindings (JNI)  4.9.0
Java bindings for using The Sleuth Kit
SleuthkitJNI.java
Go to the documentation of this file.
1 /*
2  * Sleuth Kit Data Model
3  *
4  * Copyright 2011-2018 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.BufferedReader;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.text.DateFormat;
25 import java.text.SimpleDateFormat;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.GregorianCalendar;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.TimeZone;
35 import java.util.UUID;
36 import java.util.concurrent.locks.ReadWriteLock;
37 import java.util.concurrent.locks.ReentrantReadWriteLock;
38 import org.apache.commons.lang3.StringUtils;
41 
50 public class SleuthkitJNI {
51 
58  private static final ReadWriteLock tskLock = new ReentrantReadWriteLock();
59 
60  /*
61  * Loads the SleuthKit libraries.
62  */
63  static {
65  }
66 
71  private SleuthkitJNI() {
72  }
73 
77  private static class CaseHandles {
78  /*
79  * A SleuthKit image handle cache implemented as a mappng of
80  * concatenated image file paths to image handles.
81  */
82  private final Map<String, Long> imageHandleCache = new HashMap<>();
83 
84  /*
85  * A SleuthKit file system handles cache implemented as a mapping of
86  * image handles to image offset and file system handle pairs.
87  */
88  private final Map<Long, Map<Long, Long>> fsHandleCache = new HashMap<>();
89 
90  /*
91  * The collection of open file handles. We will only allow requests
92  * through to the C code if the file handle exists in this collection.
93  */
94  private final Set<Long> fileHandleCache = new HashSet<>();
95 
96  private final Map<Long, List<Long>> fileSystemToFileHandles = new HashMap<>();
97 
98  private final Map<Long, Map<Long, Long>> poolHandleCache = new HashMap<>();
99 
100  // The poolImgCache is only used to close the images later.
101  private final List<Long> poolImgCache = new ArrayList<>();
102 
103  /*
104  * Currently, our APFS code is not thread-safe and it is the only code
105  * that uses pools. To prevent crashes, we make any reads to a file system
106  * contained in a pool single-threaded. This cache keeps track of which
107  * open file system handles are contained in a pool so we can set the locks
108  * appropriately.
109  */
110  private final List<Long> poolFsList = new ArrayList<>();
111 
112  private CaseHandles() {
113  // Nothing to do here
114  }
115  }
116 
123  private static class HandleCache {
124 
125  /*
126  * A monitor used to guard access to cached Sleuthkit JNI handles.
127  */
128  private static final Object cacheLock = new Object();
129 
130  private static final Map<String, CaseHandles> caseHandlesCache = new HashMap<>();
131 
132  private static final String INVALID_FILE_HANDLE = "Invalid file handle."; //NON-NLS
133 
134  /*
135  * Currently, our APFS code is not thread-safe and it is the only code
136  * that uses pools. To prevent crashes, we make any reads to a file system
137  * contained in a pool single-threaded. This cache keeps track of which
138  * open file handles are contained in a pool so we can set the locks
139  * appropriately.
140  *
141  * Access to this list should be guarded by cacheLock.
142  */
143  private static final List<Long> poolFileHandles = new ArrayList<>();
144 
150  private static void createCaseHandleCache(String caseIdentifier) {
151  caseHandlesCache.put(caseIdentifier, new CaseHandles());
152  }
153 
162  private static String getDefaultCaseIdentifier() throws TskCoreException {
163  synchronized (cacheLock) {
164  if (caseHandlesCache.keySet().size() > 1) {
165  throw new TskCoreException("Can not get default case identifier with multiple open cases");
166  } else if (caseHandlesCache.keySet().isEmpty()) {
167  throw new TskCoreException("Can not get default case identifier with no open case");
168  }
169 
170  return (caseHandlesCache.keySet().iterator().next());
171  }
172  }
173 
181  private static CaseHandles getCaseHandles(String caseIdentifier) {
182  synchronized (cacheLock) {
183  return caseHandlesCache.get(caseIdentifier);
184  }
185  }
186 
192  private static void removeCaseHandlesCache(String caseIdentifier) {
193  synchronized (cacheLock) {
194  if (caseHandlesCache.containsKey(caseIdentifier)) {
195  caseHandlesCache.get(caseIdentifier).fsHandleCache.clear();
196  caseHandlesCache.get(caseIdentifier).imageHandleCache.clear();
197  caseHandlesCache.get(caseIdentifier).fileHandleCache.clear();
198  caseHandlesCache.get(caseIdentifier).fileSystemToFileHandles.clear();
199  caseHandlesCache.get(caseIdentifier).poolHandleCache.clear();
200  caseHandlesCache.remove(caseIdentifier);
201  }
202  }
203  }
204 
212  private static boolean isImageInAnyCache(long imgHandle) {
213  synchronized (cacheLock) {
214  for (String caseIdentifier:caseHandlesCache.keySet()) {
215  if (caseHandlesCache.get(caseIdentifier).fsHandleCache.keySet().contains(imgHandle)) {
216  return true;
217  }
218  }
219  return false;
220  }
221  }
222 
230  private static void addFileHandle(String caseIdentifier, long fileHandle, long fsHandle) {
231  synchronized (cacheLock) {
232  // Add to collection of open file handles.
233  getCaseHandles(caseIdentifier).fileHandleCache.add(fileHandle);
234 
235  // Add to map of file system to file handles.
236  if (getCaseHandles(caseIdentifier).fileSystemToFileHandles.containsKey(fsHandle)) {
237  getCaseHandles(caseIdentifier).fileSystemToFileHandles.get(fsHandle).add(fileHandle);
238  } else {
239  getCaseHandles(caseIdentifier).fileSystemToFileHandles.put(fsHandle, new ArrayList<Long>(Arrays.asList(fileHandle)));
240  }
241  }
242  }
243 
250  private static void removeFileHandle(long fileHandle, SleuthkitCase skCase) {
251  synchronized (cacheLock) {
252  // Remove from collection of open file handles.
253  if (skCase != null) {
254  try {
255  getCaseHandles(skCase.getUniqueCaseIdentifier()).fileHandleCache.remove(fileHandle);
256  } catch (TskCoreException ex) {
257  // This exception will only occur if a file handle is closed as the case is being closed.
258  // The file will be closed by the case closing code.
259  }
260  } else {
261  // If we don't know what case the handle is from, delete the first one we find
262  for (String caseIdentifier:caseHandlesCache.keySet()) {
263  if (caseHandlesCache.get(caseIdentifier).fileHandleCache.contains(fileHandle)) {
264  caseHandlesCache.get(caseIdentifier).fileHandleCache.remove(fileHandle);
265  return;
266  }
267  }
268  }
269  }
270  }
271 
279  private static boolean isValidFileHandle(long fileHandle) {
280  synchronized (cacheLock) {
281  for (String caseIdentifier:caseHandlesCache.keySet()) {
282  if (caseHandlesCache.get(caseIdentifier).fileHandleCache.contains(fileHandle)) {
283  return true;
284  }
285  }
286  return false;
287  }
288  }
289 
290  private static void closeHandlesAndClearCache(String caseIdentifier) throws TskCoreException {
291  synchronized (cacheLock) {
292  /*
293  * Close any cached file system handles.
294  */
295  for (Map<Long, Long> imageToFsMap : getCaseHandles(caseIdentifier).fsHandleCache.values()) {
296  for (Long fsHandle : imageToFsMap.values()) {
297  // First close all open file handles for the file system.
298  if (getCaseHandles(caseIdentifier).fileSystemToFileHandles.containsKey(fsHandle)) {
299  for (Long fileHandle : getCaseHandles(caseIdentifier).fileSystemToFileHandles.get(fsHandle)) {
300  // Update the cache of file handles contained in pools
301  if (poolFileHandles.contains(fileHandle)) {
302  poolFileHandles.remove(fileHandle);
303  }
304  closeFile(fileHandle);
305  }
306  }
307  // Then close the file system handle.
308  closeFsNat(fsHandle);
309  }
310  }
311 
312  /*
313  * Clear out the list of pool file systems.
314  */
315  getCaseHandles(caseIdentifier).poolFsList.clear();
316 
317  /*
318  * Close any cached pools
319  */
320  for (Long imgHandle : getCaseHandles(caseIdentifier).poolHandleCache.keySet()) {
321  for (Long poolHandle : getCaseHandles(caseIdentifier).poolHandleCache.get(imgHandle).values()) {
322  closePoolNat(poolHandle);
323  }
324  }
325 
326  /*
327  * Close any open pool images
328  */
329  for (Long imageHandle : getCaseHandles(caseIdentifier).poolImgCache) {
330  closeImgNat(imageHandle);
331  }
332 
333  /*
334  * Close any cached image handles.
335  */
336  for (Long imageHandle : getCaseHandles(caseIdentifier).imageHandleCache.values()) {
337  closeImgNat(imageHandle);
338  }
339 
340  removeCaseHandlesCache(caseIdentifier);
341  }
342 
343  }
344  }
345 
350  public static class CaseDbHandle {
351 
352  /*
353  * A unique indentifier for a case
354  */
355  private final String caseDbIdentifier;
356 
363  private CaseDbHandle(String databaseName) {
364  this.caseDbIdentifier = "SingleUser:" + databaseName; // NON-NLS
365  HandleCache.createCaseHandleCache(caseDbIdentifier);
366  }
367 
375  private CaseDbHandle(String databaseName, CaseDbConnectionInfo info) {
376  this.caseDbIdentifier = "MultiUser:" + info.getHost() + ":" + databaseName;
377  HandleCache.createCaseHandleCache(caseDbIdentifier);
378  }
379 
385  String getCaseDbIdentifier() {
386  return caseDbIdentifier;
387  }
388 
395  void free() throws TskCoreException {
396  tskLock.writeLock().lock();
397  try {
398  HandleCache.closeHandlesAndClearCache(caseDbIdentifier);
399  //SleuthkitJNI.closeCaseDbNat(caseDbIdentifier);
400  } finally {
401  tskLock.writeLock().unlock();
402  }
403  }
404 
428  long addImageInfo(long deviceObjId, List<String> imageFilePaths, String timeZone, SleuthkitCase skCase) throws TskCoreException {
429  JniDbHelper dbHelper = new JniDbHelper(skCase, new DefaultAddDataSourceCallbacks());
430  try {
431  long tskAutoDbPointer = initializeAddImgNat(dbHelper, timezoneLongToShort(timeZone), false, false, false);
432  runOpenAndAddImgNat(tskAutoDbPointer, UUID.randomUUID().toString(), imageFilePaths.toArray(new String[0]), imageFilePaths.size(), timeZone);
433  long id = finishAddImgNat(tskAutoDbPointer);
434  dbHelper.finish();
435  skCase.addDataSourceToHasChildrenMap();
436  return id;
437  } catch (TskDataException ex) {
438  throw new TskCoreException("Error adding image to case database", ex);
439  }
440  }
441 
458  AddImageProcess initAddImageProcess(String timeZone, boolean addUnallocSpace, boolean skipFatFsOrphans, String imageCopyPath, SleuthkitCase skCase) {
459  return new AddImageProcess(timeZone, addUnallocSpace, skipFatFsOrphans, imageCopyPath, skCase);
460  }
461 
466  public class AddImageProcess {
467 
468  private final String timeZone;
469  private final boolean addUnallocSpace;
470  private final boolean skipFatFsOrphans;
471  private final String imageWriterPath;
472  private volatile long tskAutoDbPointer;
473  private long imageId = 0;
474  private boolean isCanceled;
475  private final SleuthkitCase skCase;
476  private JniDbHelper dbHelper;
477 
491  private AddImageProcess(String timeZone, boolean addUnallocSpace, boolean skipFatFsOrphans, String imageWriterPath, SleuthkitCase skCase) {
492  this.timeZone = timeZone;
493  this.addUnallocSpace = addUnallocSpace;
494  this.skipFatFsOrphans = skipFatFsOrphans;
495  this.imageWriterPath = imageWriterPath;
496  tskAutoDbPointer = 0;
497  this.isCanceled = false;
498  this.skCase = skCase;
499 
500  }
501 
518  public void run(String deviceId, String[] imageFilePaths, int sectorSize) throws TskCoreException, TskDataException {
519  Image img = addImageToDatabase(skCase, imageFilePaths, sectorSize, "", "", "", "", deviceId);
520  run(deviceId, img, sectorSize, new DefaultAddDataSourceCallbacks());
521  }
522 
540  public void run(String deviceId, Image image, int sectorSize,
541  AddDataSourceCallbacks addDataSourceCallbacks) throws TskCoreException, TskDataException {
542  dbHelper = new JniDbHelper(skCase, addDataSourceCallbacks);
543  getTSKReadLock();
544  try {
545  long imageHandle = 0;
546  synchronized (this) {
547  if (0 != tskAutoDbPointer) {
548  throw new TskCoreException("Add image process already started");
549  }
550  if (!isCanceled) { //with isCanceled being guarded by this it will have the same value everywhere in this synchronized block
551  imageHandle = image.getImageHandle();
552  tskAutoDbPointer = initAddImgNat(dbHelper, timezoneLongToShort(timeZone), addUnallocSpace, skipFatFsOrphans);
553  }
554  if (0 == tskAutoDbPointer) {
555  throw new TskCoreException("initAddImgNat returned a NULL TskAutoDb pointer");
556  }
557  }
558  if (imageHandle != 0) {
559  runAddImgNat(tskAutoDbPointer, deviceId, imageHandle, image.getId(), timeZone, imageWriterPath);
560  }
561  } finally {
562  finishAddImageProcess();
563  releaseTSKReadLock();
564  }
565  }
566 
576  public synchronized void stop() throws TskCoreException {
577  getTSKReadLock();
578  try {
579  isCanceled = true;
580  if (tskAutoDbPointer != 0) {
581  stopAddImgNat(tskAutoDbPointer);
582  }
583  } finally {
584  releaseTSKReadLock();
585  }
586  }
587 
598  private synchronized void finishAddImageProcess() throws TskCoreException {
599  if (tskAutoDbPointer == 0) {
600  return;
601  }
602 
603  // If the process wasn't cancelled, finish up processing the
604  // remaining files.
605  if (! this.isCanceled && dbHelper != null) {
606  dbHelper.finish();
607  }
608 
609  // Free the auto DB pointer and get the image ID
610  imageId = finishAddImgNat(tskAutoDbPointer);
611  tskAutoDbPointer = 0;
612 
613  skCase.addDataSourceToHasChildrenMap();
614  }
615 
624  @Deprecated
625  public synchronized void revert() throws TskCoreException {
626  // No-op
627  }
628 
640  @Deprecated
641  public synchronized long commit() throws TskCoreException {
642  return imageId;
643  }
644 
651  public synchronized String currentDirectory() {
652  return tskAutoDbPointer == 0 ? "" : getCurDirNat(tskAutoDbPointer); //NON-NLS
653  }
654 
670  @Deprecated
671  public void run(String[] imageFilePaths) throws TskCoreException, TskDataException {
672  run(null, imageFilePaths, 0);
673  }
674 
690  public void run(String deviceId, String[] imageFilePaths) throws TskCoreException, TskDataException {
691  run(deviceId, imageFilePaths, 0);
692  }
693  }
694 
695  }
696 
708  static CaseDbHandle newCaseDb(String path) throws TskCoreException {
709  return new CaseDbHandle(path);
710  }
711 
724  static CaseDbHandle newCaseDb(String databaseName, CaseDbConnectionInfo info) throws TskCoreException {
725  return new CaseDbHandle(databaseName, info);
726  }
727 
739  static CaseDbHandle openCaseDb(String path) throws TskCoreException {
740  return new CaseDbHandle(path);
741  }
742 
755  static CaseDbHandle openCaseDb(String databaseName, CaseDbConnectionInfo info) throws TskCoreException {
756  return new CaseDbHandle(databaseName, info);
757  }
758 
764  public static String getVersion() {
765  return getVersionNat();
766  }
767 
773  public static void startVerboseLogging(String logPath) {
774  startVerboseLoggingNat(logPath);
775  }
776 
788  public static long openImage(String[] imageFiles, SleuthkitCase skCase) throws TskCoreException {
789  if (skCase == null) {
790  throw new TskCoreException("SleuthkitCase can not be null");
791  }
792  return openImage(imageFiles, 0, true, skCase.getUniqueCaseIdentifier());
793  }
794 
808  public static long openImage(String[] imageFiles, int sSize, SleuthkitCase skCase) throws TskCoreException {
809  if (skCase == null) {
810  throw new TskCoreException("SleuthkitCase can not be null");
811  }
812  return openImage(imageFiles, sSize, true, skCase.getUniqueCaseIdentifier());
813  }
814 
832  private static long openImage(String[] imageFiles, int sSize, boolean useCache, String caseIdentifer) throws TskCoreException {
833  getTSKReadLock();
834  try {
835  long imageHandle;
836 
837  StringBuilder keyBuilder = new StringBuilder();
838  for (int i = 0; i < imageFiles.length; ++i) {
839  keyBuilder.append(imageFiles[i]);
840  }
841  final String imageKey = keyBuilder.toString();
842 
843  synchronized (HandleCache.cacheLock) {
844  String nonNullCaseIdentifer = caseIdentifer;
845  if (nonNullCaseIdentifer == null) {
846  nonNullCaseIdentifer = HandleCache.getDefaultCaseIdentifier();
847  }
848 
849  // If we're getting a fresh copy and an image with this path is already
850  // in the cache, move the existing cache reference so it won't be used by
851  // any subsequent calls to openImage but will still be valid if any objects
852  // have it cached. This happens in the case where the user adds the same data
853  // source twice (see JIRA-5868).
854  if (!useCache && HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.containsKey(imageKey)) {
855  long tempImageHandle = HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.get(imageKey);
856 
857  // Store the old image handle in a fake path. This way it will no longer be found but will
858  // still be valid and the image and its file systems will be closed with the case.
859  String newPath = "Image_" + UUID.randomUUID().toString();
860  HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.put(newPath, tempImageHandle);
861  HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.remove(imageKey);
862  }
863 
864  if (useCache && HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.containsKey(imageKey)) //get from cache
865  {
866  imageHandle = HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.get(imageKey);
867  } else {
868  //open new handle and cache it
869  imageHandle = openImgNat(imageFiles, imageFiles.length, sSize);
870  HandleCache.getCaseHandles(nonNullCaseIdentifer).fsHandleCache.put(imageHandle, new HashMap<>());
871  HandleCache.getCaseHandles(nonNullCaseIdentifer).imageHandleCache.put(imageKey, imageHandle);
872  }
873  }
874  return imageHandle;
875  } finally {
876  releaseTSKReadLock();
877  }
878  }
879 
891  private static void cacheImageHandle(SleuthkitCase skCase, List<String> imagePaths, long imageHandle) {
892 
893  // Construct the hash key from the image paths
894  StringBuilder keyBuilder = new StringBuilder();
895  for (int i = 0; i < imagePaths.size(); ++i) {
896  keyBuilder.append(imagePaths.get(i));
897  }
898  final String imageKey = keyBuilder.toString();
899 
900  // Get the case identifier
901  try {
902  String caseIdentifier = skCase.getUniqueCaseIdentifier();
903 
904  synchronized (HandleCache.cacheLock) {
905  HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.put(imageHandle, new HashMap<>());
906  HandleCache.getCaseHandles(caseIdentifier).imageHandleCache.put(imageKey, imageHandle);
907  }
908  } catch (TskCoreException ex) {
909  // getUniqueCaseIdentfier() will only fail if the case is closed
910  }
911  }
912 
929  public static Image addImageToDatabase(SleuthkitCase skCase, String[] imagePaths, int sectorSize,
930  String timeZone, String md5fromSettings, String sha1fromSettings, String sha256fromSettings, String deviceId) throws TskCoreException {
931 
932  // Open the image
933  long imageHandle = openImgNat(imagePaths, 1, sectorSize);
934 
935  // Get the fields stored in the native code
936  List<String> computedPaths = Arrays.asList(getPathsForImageNat(imageHandle));
937  long size = getSizeForImageNat(imageHandle);
938  long type = getTypeForImageNat(imageHandle);
939  long computedSectorSize = getSectorSizeForImageNat(imageHandle);
940  String md5 = md5fromSettings;
941  if (StringUtils.isEmpty(md5)) {
942  md5 = getMD5HashForImageNat(imageHandle);
943  }
944  String sha1 = sha1fromSettings;
945  if (StringUtils.isEmpty(sha1)) {
946  sha1 = getSha1HashForImageNat(imageHandle);
947  }
948  // Sleuthkit does not currently generate any SHA256 hashes. Set to empty
949  // string for consistency.
950  String sha256 = sha256fromSettings;
951  if (sha256 == null) {
952  sha256 = "";
953  }
954  String collectionDetails = getCollectionDetailsForImageNat(imageHandle);
955 
956  // Now save to database
957  CaseDbTransaction transaction = skCase.beginTransaction();
958  try {
959  Image img = skCase.addImage(TskData.TSK_IMG_TYPE_ENUM.valueOf(type), computedSectorSize,
960  size, null, computedPaths,
961  timeZone, md5, sha1, sha256,
962  deviceId, transaction);
963  if (!StringUtils.isEmpty(collectionDetails)) {
964  skCase.setAcquisitionDetails(img, collectionDetails);
965  }
966  transaction.commit();
967 
968  img.setImageHandle(imageHandle);
969  cacheImageHandle(skCase, computedPaths, imageHandle);
970  return img;
971  } catch (TskCoreException ex) {
972  transaction.rollback();
973  throw(ex);
974  }
975  }
976 
977 
978 
991  public static long openVs(long imgHandle, long vsOffset) throws TskCoreException {
992  getTSKReadLock();
993  try {
994  if(! imgHandleIsValid(imgHandle)) {
995  throw new TskCoreException("Image handle " + imgHandle + " is closed");
996  }
997  return openVsNat(imgHandle, vsOffset);
998  } finally {
999  releaseTSKReadLock();
1000  }
1001  }
1002 
1003  //get pointers
1015  public static long openVsPart(long vsHandle, long volId) throws TskCoreException {
1016  getTSKReadLock();
1017  try {
1018  //returned long is ptr to vs Handle object in tsk
1019  return openVolNat(vsHandle, volId);
1020  } finally {
1021  releaseTSKReadLock();
1022  }
1023  }
1024 
1036  static long openPool(long imgHandle, long offset, SleuthkitCase skCase) throws TskCoreException {
1037  getTSKReadLock();
1038  try {
1039  if(! imgHandleIsValid(imgHandle)) {
1040  throw new TskCoreException("Image handle " + imgHandle + " is closed");
1041  }
1042 
1043  synchronized (HandleCache.cacheLock) {
1044  String caseIdentifier;
1045  if (skCase == null) {
1046  caseIdentifier = HandleCache.getDefaultCaseIdentifier();
1047  } else {
1048  caseIdentifier = skCase.getUniqueCaseIdentifier();
1049  }
1050 
1051  // If a pool handle cache for this image does not exist, make one
1052  if (! HandleCache.getCaseHandles(caseIdentifier).poolHandleCache.containsKey(imgHandle)) {
1053  HandleCache.getCaseHandles(caseIdentifier).poolHandleCache.put(imgHandle, new HashMap<>());
1054  }
1055 
1056  // Get the pool handle cache for this image
1057  Map<Long, Long> poolCacheForImage = HandleCache.getCaseHandles(caseIdentifier).poolHandleCache.get(imgHandle);
1058 
1059  if (poolCacheForImage.containsKey(offset)) {
1060  return poolCacheForImage.get(offset);
1061  } else {
1062  //returned long is ptr to pool Handle object in tsk
1063  long poolHandle = openPoolNat(imgHandle, offset);
1064  poolCacheForImage.put(offset, poolHandle);
1065  return poolHandle;
1066  }
1067  }
1068  } finally {
1069  releaseTSKReadLock();
1070  }
1071  }
1072 
1086  public static long openFs(long imgHandle, long fsOffset, SleuthkitCase skCase) throws TskCoreException {
1087  getTSKReadLock();
1088  try {
1089  long fsHandle;
1090  synchronized (HandleCache.cacheLock) {
1091  String caseIdentifier;
1092  if (skCase == null) {
1093  caseIdentifier = HandleCache.getDefaultCaseIdentifier();
1094  } else {
1095  caseIdentifier = skCase.getUniqueCaseIdentifier();
1096  }
1097  final Map<Long, Long> imgOffSetToFsHandle = HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.get(imgHandle);
1098  if (imgOffSetToFsHandle == null) {
1099  throw new TskCoreException("Missing image offset to file system handle cache for image handle " + imgHandle);
1100  }
1101  if (imgOffSetToFsHandle.containsKey(fsOffset)) {
1102  //return cached
1103  fsHandle = imgOffSetToFsHandle.get(fsOffset);
1104  } else {
1105  fsHandle = openFsNat(imgHandle, fsOffset);
1106  //cache it
1107  imgOffSetToFsHandle.put(fsOffset, fsHandle);
1108  }
1109  }
1110  return fsHandle;
1111  } finally {
1112  releaseTSKReadLock();
1113  }
1114  }
1115 
1132  static long openFsPool(long imgHandle, long fsOffset, long poolHandle, long poolBlock, SleuthkitCase skCase) throws TskCoreException {
1133  /*
1134  * Currently, our APFS code is not thread-safe and it is the only code
1135  * that uses pools. To prevent crashes, we make any reads to a file system
1136  * contained in a pool single-threaded.
1137  */
1138  getTSKWriteLock();
1139  try {
1140  long fsHandle;
1141  synchronized (HandleCache.cacheLock) {
1142  String caseIdentifier;
1143  if (skCase == null) {
1144  caseIdentifier = HandleCache.getDefaultCaseIdentifier();
1145  } else {
1146  caseIdentifier = skCase.getUniqueCaseIdentifier();
1147  }
1148  final Map<Long, Long> imgOffSetToFsHandle = HandleCache.getCaseHandles(caseIdentifier).fsHandleCache.get(imgHandle);
1149  if (imgOffSetToFsHandle == null) {
1150  throw new TskCoreException("Missing image offset to file system handle cache for image handle " + imgHandle);
1151  }
1152 
1153  if (imgOffSetToFsHandle.containsKey(poolBlock)) {
1154  //return cached
1155  fsHandle = imgOffSetToFsHandle.get(poolBlock);
1156  } else {
1157  long poolImgHandle = getImgInfoForPoolNat(poolHandle, poolBlock);
1158  HandleCache.getCaseHandles(caseIdentifier).poolImgCache.add(poolImgHandle);
1159  fsHandle = openFsNat(poolImgHandle, fsOffset);
1160  //cache it
1161  imgOffSetToFsHandle.put(poolBlock, fsHandle);
1162  HandleCache.getCaseHandles(caseIdentifier).poolFsList.add(fsHandle);
1163  }
1164  }
1165  return fsHandle;
1166  } finally {
1167  releaseTSKWriteLock();
1168  }
1169  }
1170 
1185  public static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM attrType, int attrId, SleuthkitCase skCase) throws TskCoreException {
1186  /*
1187  * NOTE: previously attrId used to be stored in AbstractFile as (signed)
1188  * short even though it is stored as uint16 in TSK. In extremely rare
1189  * occurrences attrId can be larger than what a signed short can hold
1190  * (2^15). Changes were made to AbstractFile to store attrId as integer.
1191  * However, a depricated method still exists in AbstractFile to get
1192  * attrId as short. In that method we convert attribute ids that are
1193  * larger than 32K to a negative number. Therefore if encountered, we
1194  * need to convert negative attribute id to uint16 which is what TSK is
1195  * using to store attribute id.
1196  */
1197  boolean withinPool = false;
1198  synchronized (HandleCache.cacheLock) {
1199  String caseIdentifier;
1200  if (skCase == null) {
1201  caseIdentifier = HandleCache.getDefaultCaseIdentifier();
1202  } else {
1203  caseIdentifier = skCase.getUniqueCaseIdentifier();
1204  }
1205  if (HandleCache.getCaseHandles(caseIdentifier).poolFsList.contains(fsHandle)) {
1206  withinPool = true;
1207  }
1208  }
1209 
1210  /*
1211  * The current APFS code is not thread-safe. To compensate, we make any
1212  * reads to the APFS pool single-threaded by obtaining a write
1213  * lock instead of a read lock.
1214  */
1215  if (withinPool) {
1216  getTSKWriteLock();
1217  } else {
1218  getTSKReadLock();
1219  }
1220  try {
1221  long fileHandle = openFileNat(fsHandle, fileId, attrType.getValue(), convertSignedToUnsigned(attrId));
1222  synchronized (HandleCache.cacheLock) {
1223  String caseIdentifier;
1224  if (skCase == null) {
1225  caseIdentifier = HandleCache.getDefaultCaseIdentifier();
1226  } else {
1227  caseIdentifier = skCase.getUniqueCaseIdentifier();
1228  }
1229  HandleCache.addFileHandle(caseIdentifier, fileHandle, fsHandle);
1230 
1231  // If this file is in a pool file system, record it so the locks
1232  // can be set appropriately when reading it.
1233  if (withinPool) {
1234  HandleCache.poolFileHandles.add(fileHandle);
1235  }
1236  }
1237  return fileHandle;
1238  } finally {
1239  if (withinPool) {
1240  releaseTSKWriteLock();
1241  } else {
1242  releaseTSKReadLock();
1243  }
1244  }
1245  }
1246 
1254  private static int convertSignedToUnsigned(int val) {
1255  if (val >= 0) {
1256  return val;
1257  }
1258 
1259  return val & 0xffff; // convert negative value to positive value
1260  }
1261 
1267  private static boolean imgHandleIsValid(long imgHandle) {
1268  synchronized(HandleCache.cacheLock) {
1269  return HandleCache.isImageInAnyCache(imgHandle);
1270  }
1271  }
1272 
1273  //do reads
1288  public static int readImg(long imgHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1289  getTSKReadLock();
1290  try {
1291  if(! imgHandleIsValid(imgHandle)) {
1292  throw new TskCoreException("Image handle " + imgHandle + " is closed");
1293  }
1294  //returned byte[] is the data buffer
1295  return readImgNat(imgHandle, readBuffer, offset, len);
1296  } finally {
1297  releaseTSKReadLock();
1298  }
1299  }
1300 
1315  public static int readVs(long vsHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1316  getTSKReadLock();
1317  try {
1318  return readVsNat(vsHandle, readBuffer, offset, len);
1319  } finally {
1320  releaseTSKReadLock();
1321  }
1322  }
1323 
1336  static int readPool(long poolHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1337  getTSKReadLock();
1338  try {
1339  return readPoolNat(poolHandle, readBuffer, offset, len);
1340  } finally {
1341  releaseTSKReadLock();
1342  }
1343  }
1344 
1359  public static int readVsPart(long volHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1360  getTSKReadLock();
1361  try {
1362  //returned byte[] is the data buffer
1363  return readVolNat(volHandle, readBuffer, offset, len);
1364  } finally {
1365  releaseTSKReadLock();
1366  }
1367  }
1368 
1383  public static int readFs(long fsHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1384  getTSKReadLock();
1385  try {
1386  //returned byte[] is the data buffer
1387  return readFsNat(fsHandle, readBuffer, offset, len);
1388  } finally {
1389  releaseTSKReadLock();
1390  }
1391  }
1392 
1397  private enum TSK_FS_FILE_READ_OFFSET_TYPE_ENUM {
1398  START_OF_FILE(0),
1399  START_OF_SLACK(1);
1400 
1401  private final int val;
1402 
1403  TSK_FS_FILE_READ_OFFSET_TYPE_ENUM(int val) {
1404  this.val = val;
1405  }
1406 
1407  int getValue() {
1408  return val;
1409  }
1410  }
1411 
1426  public static int readFile(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1427  boolean withinPool = false;
1428  synchronized (HandleCache.cacheLock) {
1429  if (HandleCache.poolFileHandles.contains(fileHandle)) {
1430  withinPool = true;
1431  }
1432  }
1433 
1434  /*
1435  * The current APFS code is not thread-safe. To compensate, we make any
1436  * reads to the APFS pool single-threaded by obtaining a write
1437  * lock instead of a read lock.
1438  */
1439  if (withinPool) {
1440  getTSKWriteLock();
1441  } else {
1442  getTSKReadLock();
1443  }
1444  try {
1445  if (!HandleCache.isValidFileHandle(fileHandle)) {
1446  throw new TskCoreException(HandleCache.INVALID_FILE_HANDLE);
1447  }
1448 
1449  return readFileNat(fileHandle, readBuffer, offset, TSK_FS_FILE_READ_OFFSET_TYPE_ENUM.START_OF_FILE.getValue(), len);
1450  } finally {
1451  if (withinPool) {
1452  releaseTSKWriteLock();
1453  } else {
1454  releaseTSKReadLock();
1455  }
1456  }
1457  }
1458 
1473  public static int readFileSlack(long fileHandle, byte[] readBuffer, long offset, long len) throws TskCoreException {
1474  getTSKReadLock();
1475  try {
1476  if (!HandleCache.isValidFileHandle(fileHandle)) {
1477  throw new TskCoreException(HandleCache.INVALID_FILE_HANDLE);
1478  }
1479 
1480  return readFileNat(fileHandle, readBuffer, offset, TSK_FS_FILE_READ_OFFSET_TYPE_ENUM.START_OF_SLACK.getValue(), len);
1481  } finally {
1482  releaseTSKReadLock();
1483  }
1484  }
1485 
1496  public static List<String> getFileMetaDataText(long fileHandle) throws TskCoreException {
1497  getTSKReadLock();
1498  try {
1499  if (!HandleCache.isValidFileHandle(fileHandle)) {
1500  throw new TskCoreException(HandleCache.INVALID_FILE_HANDLE);
1501  }
1502 
1503  try {
1504  java.io.File tmp = java.io.File.createTempFile("tsk", ".txt");
1505 
1506  saveFileMetaDataTextNat(fileHandle, tmp.getAbsolutePath());
1507 
1508  FileReader fr = new FileReader(tmp.getAbsolutePath());
1509  BufferedReader textReader = new BufferedReader(fr);
1510 
1511  List<String> lines = new ArrayList<String>();
1512  while (true) {
1513  String line = textReader.readLine();
1514  if (line == null) {
1515  break;
1516  }
1517  lines.add(line);
1518  }
1519  textReader.close();
1520  fr.close();
1521  tmp.delete();
1522  return lines;
1523  } catch (IOException ex) {
1524  throw new TskCoreException("Error reading istat output: " + ex.getLocalizedMessage());
1525  }
1526  } finally {
1527  releaseTSKReadLock();
1528  }
1529  }
1530 
1536  public static void closeFile(long fileHandle) {
1537  closeFile(fileHandle, null);
1538  }
1539 
1546  public static void closeFile(long fileHandle, SleuthkitCase skCase) {
1547  boolean withinPool = false;
1548  synchronized (HandleCache.cacheLock) {
1549  if (HandleCache.poolFileHandles.contains(fileHandle)) {
1550  withinPool = true;
1551  }
1552  }
1553 
1554  /*
1555  * The current APFS code is not thread-safe. To compensate, we make any
1556  * reads to the APFS pool single-threaded by obtaining a write
1557  * lock instead of a read lock.
1558  */
1559  if (withinPool) {
1560  getTSKWriteLock();
1561  } else {
1562  getTSKReadLock();
1563  }
1564  try {
1565  synchronized (HandleCache.cacheLock) {
1566  if (!HandleCache.isValidFileHandle(fileHandle)) {
1567  // File handle is not open so this is a no-op.
1568  return;
1569  }
1570  closeFileNat(fileHandle);
1571  HandleCache.removeFileHandle(fileHandle, skCase);
1572  if (HandleCache.poolFileHandles.contains(fileHandle)) {
1573  HandleCache.poolFileHandles.remove(fileHandle);
1574  }
1575  }
1576  } finally {
1577  if (withinPool) {
1578  releaseTSKWriteLock();
1579  } else {
1580  releaseTSKReadLock();
1581  }
1582  }
1583  }
1584 
1592  public static void createLookupIndexForHashDatabase(int dbHandle) throws TskCoreException {
1593  hashDbCreateIndexNat(dbHandle);
1594  }
1595 
1605  public static boolean hashDatabaseHasLookupIndex(int dbHandle) throws TskCoreException {
1606  return hashDbIndexExistsNat(dbHandle);
1607  }
1608 
1619  public static boolean hashDatabaseCanBeReindexed(int dbHandle) throws TskCoreException {
1620  return hashDbIsReindexableNat(dbHandle);
1621  }
1622 
1632  public static String getHashDatabasePath(int dbHandle) throws TskCoreException {
1633  return hashDbPathNat(dbHandle);
1634  }
1635 
1645  public static String getHashDatabaseIndexPath(int dbHandle) throws TskCoreException {
1646  return hashDbIndexPathNat(dbHandle);
1647  }
1648 
1655  public static int openHashDatabase(String path) throws TskCoreException {
1656  return hashDbOpenNat(path);
1657  }
1658 
1668  public static int createHashDatabase(String path) throws TskCoreException {
1669  return hashDbNewNat(path);
1670  }
1671 
1678  public static void closeAllHashDatabases() throws TskCoreException {
1679  hashDbCloseAll();
1680  }
1681 
1691  public static void closeHashDatabase(int dbHandle) throws TskCoreException {
1692  hashDbClose(dbHandle);
1693  }
1694 
1704  public static String getHashDatabaseDisplayName(int dbHandle) throws TskCoreException {
1705  return hashDbGetDisplayName(dbHandle);
1706  }
1707 
1718  public static boolean lookupInHashDatabase(String hash, int dbHandle) throws TskCoreException {
1719  return hashDbLookup(hash, dbHandle);
1720  }
1721 
1733  public static HashHitInfo lookupInHashDatabaseVerbose(String hash, int dbHandle) throws TskCoreException {
1734  return hashDbLookupVerbose(hash, dbHandle);
1735  }
1736 
1749  public static void addToHashDatabase(String filename, String md5, String sha1, String sha256, String comment, int dbHandle) throws TskCoreException {
1750  hashDbAddEntryNat(filename, md5, sha1, sha256, comment, dbHandle);
1751  }
1752 
1753  public static void addToHashDatabase(List<HashEntry> hashes, int dbHandle) throws TskCoreException {
1754  hashDbBeginTransactionNat(dbHandle);
1755  try {
1756  for (HashEntry entry : hashes) {
1757  hashDbAddEntryNat(entry.getFileName(), entry.getMd5Hash(), entry.getSha1Hash(), entry.getSha256Hash(), entry.getComment(), dbHandle);
1758  }
1759  hashDbCommitTransactionNat(dbHandle);
1760  } catch (TskCoreException ex) {
1761  try {
1762  hashDbRollbackTransactionNat(dbHandle);
1763  } catch (TskCoreException ex2) {
1764  ex2.initCause(ex);
1765  throw ex2;
1766  }
1767  throw ex;
1768  }
1769  }
1770 
1771  public static boolean isUpdateableHashDatabase(int dbHandle) throws TskCoreException {
1772  return hashDbIsUpdateableNat(dbHandle);
1773  }
1774 
1775  public static boolean hashDatabaseIsIndexOnly(int dbHandle) throws TskCoreException {
1776  return hashDbIsIdxOnlyNat(dbHandle);
1777  }
1778 
1788  private static String timezoneLongToShort(String timezoneLongForm) {
1789  if (timezoneLongForm == null || timezoneLongForm.isEmpty()) {
1790  return "";
1791  }
1792 
1793  String timezoneShortForm;
1794  TimeZone zone = TimeZone.getTimeZone(timezoneLongForm);
1795  int offset = zone.getRawOffset() / 1000;
1796  int hour = offset / 3600;
1797  int min = (offset % 3600) / 60;
1798  DateFormat dfm = new SimpleDateFormat("z");
1799  dfm.setTimeZone(zone);
1800  boolean hasDaylight = zone.useDaylightTime();
1801  String first = dfm.format(new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3); // make it only 3 letters code
1802  String second = dfm.format(new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3); // make it only 3 letters code
1803  int mid = hour * -1;
1804  timezoneShortForm = first + Integer.toString(mid);
1805  if (min != 0) {
1806  timezoneShortForm = timezoneShortForm + ":" + (min < 10 ? "0" : "") + Integer.toString(min);
1807  }
1808  if (hasDaylight) {
1809  timezoneShortForm += second;
1810  }
1811  return timezoneShortForm;
1812  }
1813 
1824  public static int finishImageWriter(long imgHandle) throws TskCoreException {
1825  getTSKReadLock();
1826  try {
1827  if(! imgHandleIsValid(imgHandle)) {
1828  throw new TskCoreException("Image handle " + imgHandle + " is closed");
1829  }
1830  return finishImageWriterNat(imgHandle);
1831  } finally {
1832  releaseTSKReadLock();
1833  }
1834  }
1835 
1843  public static int getFinishImageProgress(long imgHandle) {
1844  getTSKReadLock();
1845  try {
1846  if (imgHandleIsValid(imgHandle)) {
1847  return getFinishImageProgressNat(imgHandle);
1848  } else {
1849  return 0;
1850  }
1851  } finally {
1852  releaseTSKReadLock();
1853  }
1854  }
1855 
1861  public static void cancelFinishImage(long imgHandle) {
1862  getTSKReadLock();
1863  try {
1864  if (imgHandleIsValid(imgHandle)) {
1865  cancelFinishImageNat(imgHandle);
1866  }
1867  } finally {
1868  releaseTSKReadLock();
1869  }
1870  }
1871 
1883  public static long findDeviceSize(String devPath) throws TskCoreException {
1884  return findDeviceSizeNat(devPath);
1885  }
1886 
1887  public static boolean isImageSupported(String imagePath) {
1888  return isImageSupportedNat(imagePath);
1889  }
1890 
1904  static long getSleuthkitVersion() {
1905  return getSleuthkitVersionNat();
1906  }
1907 
1912  private static void getTSKReadLock() {
1913  tskLock.readLock().lock();
1914  }
1915 
1919  private static void releaseTSKReadLock() {
1920  tskLock.readLock().unlock();
1921  }
1922 
1930  private static void getTSKWriteLock() {
1931  tskLock.writeLock().lock();
1932  }
1933 
1937  private static void releaseTSKWriteLock() {
1938  tskLock.writeLock().unlock();
1939  }
1940 
1941  //free pointers
1948  @Deprecated
1949  public static void closeImg(long imgHandle) {
1950  //closeImgNat(imgHandle);
1951  }
1952 
1958  @Deprecated
1959  public static void closeVs(long vsHandle) {
1960  // closeVsNat(vsHandle); TODO JIRA-3829
1961  }
1962 
1969  @Deprecated
1970  public static void closeFs(long fsHandle) {
1971  //closeFsNat(fsHandle);
1972  }
1973 
1985  @Deprecated
1986  public static long openImage(String[] imageFiles) throws TskCoreException {
1987 
1988  return openImage(imageFiles, 0, true, null);
1989  }
1990 
2004  @Deprecated
2005  public static long openImage(String[] imageFiles, int sSize) throws TskCoreException {
2006  return openImage(imageFiles, sSize, true, null);
2007  }
2008 
2009 
2023  @Deprecated
2024  public static long openFs(long imgHandle, long fsOffset) throws TskCoreException {
2025  return openFs(imgHandle, fsOffset, null);
2026  }
2027 
2042  @Deprecated
2043  public static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM attrType, int attrId) throws TskCoreException {
2044  return openFile(fsHandle, fileId, attrType, attrId, null);
2045  }
2046 
2047 
2048  private static native String getVersionNat();
2049 
2050  private static native void startVerboseLoggingNat(String logPath);
2051 
2052  private static native int hashDbOpenNat(String hashDbPath) throws TskCoreException;
2053 
2054  private static native int hashDbNewNat(String hashDbPath) throws TskCoreException;
2055 
2056  private static native int hashDbBeginTransactionNat(int dbHandle) throws TskCoreException;
2057 
2058  private static native int hashDbCommitTransactionNat(int dbHandle) throws TskCoreException;
2059 
2060  private static native int hashDbRollbackTransactionNat(int dbHandle) throws TskCoreException;
2061 
2062  private static native int hashDbAddEntryNat(String filename, String hashMd5, String hashSha1, String hashSha256, String comment, int dbHandle) throws TskCoreException;
2063 
2064  private static native boolean hashDbIsUpdateableNat(int dbHandle);
2065 
2066  private static native boolean hashDbIsReindexableNat(int dbHandle);
2067 
2068  private static native String hashDbPathNat(int dbHandle);
2069 
2070  private static native String hashDbIndexPathNat(int dbHandle);
2071 
2072  private static native String hashDbGetDisplayName(int dbHandle) throws TskCoreException;
2073 
2074  private static native void hashDbCloseAll() throws TskCoreException;
2075 
2076  private static native void hashDbClose(int dbHandle) throws TskCoreException;
2077 
2078  private static native void hashDbCreateIndexNat(int dbHandle) throws TskCoreException;
2079 
2080  private static native boolean hashDbIndexExistsNat(int dbHandle) throws TskCoreException;
2081 
2082  private static native boolean hashDbIsIdxOnlyNat(int dbHandle) throws TskCoreException;
2083 
2084  private static native boolean hashDbLookup(String hash, int dbHandle) throws TskCoreException;
2085 
2086  private static native HashHitInfo hashDbLookupVerbose(String hash, int dbHandle) throws TskCoreException;
2087 
2088  private static native long initAddImgNat(JniDbHelper dbHelperObj, String timezone, boolean addUnallocSpace, boolean skipFatFsOrphans) throws TskCoreException;
2089 
2090  private static native long initializeAddImgNat(JniDbHelper dbHelperObj, String timezone, boolean addFileSystems, boolean addUnallocSpace, boolean skipFatFsOrphans) throws TskCoreException;
2091 
2092  private static native void runOpenAndAddImgNat(long process, String deviceId, String[] imgPath, int splits, String timezone) throws TskCoreException, TskDataException;
2093 
2094  private static native void runAddImgNat(long process, String deviceId, long a_img_info, long image_id, String timeZone, String imageWriterPath) throws TskCoreException, TskDataException;
2095 
2096  private static native void stopAddImgNat(long process) throws TskCoreException;
2097 
2098  private static native long finishAddImgNat(long process) throws TskCoreException;
2099 
2100  private static native long openImgNat(String[] imgPath, int splits, int sSize) throws TskCoreException;
2101 
2102  private static native long openVsNat(long imgHandle, long vsOffset) throws TskCoreException;
2103 
2104  private static native long openVolNat(long vsHandle, long volId) throws TskCoreException;
2105 
2106  private static native long openPoolNat(long imgHandle, long offset) throws TskCoreException;
2107 
2108  private static native long getImgInfoForPoolNat(long poolHandle, long poolOffset) throws TskCoreException;
2109 
2110  private static native long openFsNat(long imgHandle, long fsId) throws TskCoreException;
2111 
2112  private static native long openFileNat(long fsHandle, long fileId, int attrType, int attrId) throws TskCoreException;
2113 
2114  private static native int readImgNat(long imgHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
2115 
2116  private static native int readVsNat(long vsHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
2117 
2118  private static native int readPoolNat(long poolHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
2119 
2120  private static native int readVolNat(long volHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
2121 
2122  private static native int readFsNat(long fsHandle, byte[] readBuffer, long offset, long len) throws TskCoreException;
2123 
2124  private static native int readFileNat(long fileHandle, byte[] readBuffer, long offset, int offset_type, long len) throws TskCoreException;
2125 
2126  private static native int saveFileMetaDataTextNat(long fileHandle, String fileName) throws TskCoreException;
2127 
2128  private static native String[] getPathsForImageNat(long imgHandle);
2129 
2130  private static native long getSizeForImageNat(long imgHandle);
2131 
2132  private static native long getTypeForImageNat(long imgHandle);
2133 
2134  private static native long getSectorSizeForImageNat(long imgHandle);
2135 
2136  private static native String getMD5HashForImageNat(long imgHandle);
2137 
2138  private static native String getSha1HashForImageNat(long imgHandle);
2139 
2140  private static native String getCollectionDetailsForImageNat(long imgHandle);
2141 
2142  private static native void closeImgNat(long imgHandle);
2143 
2144  private static native void closePoolNat(long poolHandle);
2145 
2146  private static native void closeVsNat(long vsHandle);
2147 
2148  private static native void closeFsNat(long fsHandle);
2149 
2150  private static native void closeFileNat(long fileHandle);
2151 
2152  private static native long findDeviceSizeNat(String devicePath) throws TskCoreException;
2153 
2154  private static native String getCurDirNat(long process);
2155 
2156  private static native boolean isImageSupportedNat(String imagePath);
2157 
2158  private static native long getSleuthkitVersionNat();
2159 
2160  private static native int finishImageWriterNat(long a_img_info);
2161 
2162  private static native int getFinishImageProgressNat(long a_img_info);
2163 
2164  private static native void cancelFinishImageNat(long a_img_info);
2165 
2166 }
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
static String getHashDatabaseIndexPath(int dbHandle)
static int readVs(long vsHandle, byte[] readBuffer, long offset, long len)
static void createLookupIndexForHashDatabase(int dbHandle)
void run(String deviceId, Image image, int sectorSize, AddDataSourceCallbacks addDataSourceCallbacks)
static void addToHashDatabase(String filename, String md5, String sha1, String sha256, String comment, int dbHandle)
static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM attrType, int attrId, SleuthkitCase skCase)
static int createHashDatabase(String path)
static void closeFs(long fsHandle)
static void cancelFinishImage(long imgHandle)
static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM attrType, int attrId)
void run(String deviceId, String[] imageFilePaths)
static int readFile(long fileHandle, byte[] readBuffer, long offset, long len)
static int finishImageWriter(long imgHandle)
void setAcquisitionDetails(String details)
Definition: Image.java:526
static HashHitInfo lookupInHashDatabaseVerbose(String hash, int dbHandle)
static long openVs(long imgHandle, long vsOffset)
static long openImage(String[] imageFiles, SleuthkitCase skCase)
static boolean hashDatabaseIsIndexOnly(int dbHandle)
static boolean isImageSupported(String imagePath)
static int readVsPart(long volHandle, byte[] readBuffer, long offset, long len)
static void closeFile(long fileHandle, SleuthkitCase skCase)
static long openImage(String[] imageFiles, int sSize)
static void closeVs(long vsHandle)
static long openImage(String[] imageFiles)
static long openFs(long imgHandle, long fsOffset, SleuthkitCase skCase)
static long openImage(String[] imageFiles, int sSize, SleuthkitCase skCase)
void run(String deviceId, String[] imageFilePaths, int sectorSize)
Definition: HashEntry.java:25
static long findDeviceSize(String devPath)
static String getHashDatabaseDisplayName(int dbHandle)
static List< String > getFileMetaDataText(long fileHandle)
static void closeImg(long imgHandle)
static long openFs(long imgHandle, long fsOffset)
static int getFinishImageProgress(long imgHandle)
static int openHashDatabase(String path)
static void closeFile(long fileHandle)
static boolean lookupInHashDatabase(String hash, int dbHandle)
static TSK_IMG_TYPE_ENUM valueOf(long imgType)
Definition: TskData.java:540
static boolean hashDatabaseHasLookupIndex(int dbHandle)
static Image addImageToDatabase(SleuthkitCase skCase, String[] imagePaths, int sectorSize, String timeZone, String md5fromSettings, String sha1fromSettings, String sha256fromSettings, String deviceId)
static long openVsPart(long vsHandle, long volId)
static int readFileSlack(long fileHandle, byte[] readBuffer, long offset, long len)
static boolean isUpdateableHashDatabase(int dbHandle)
static void addToHashDatabase(List< HashEntry > hashes, int dbHandle)
static boolean hashDatabaseCanBeReindexed(int dbHandle)
static void startVerboseLogging(String logPath)
static int readFs(long fsHandle, byte[] readBuffer, long offset, long len)
static String getHashDatabasePath(int dbHandle)
static void closeHashDatabase(int dbHandle)

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.