diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java index 745599c240e3ca8bb2f90e04bb7c04bdedabc597..608123381cc53ad04dbdb90911b3875b90f3178e 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java @@ -35,6 +35,8 @@ import java.util.UUID; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.sleuthkit.datamodel.TskData.TSK_FS_ATTR_TYPE_ENUM; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction; @@ -49,6 +51,8 @@ */ public class SleuthkitJNI { + private static final Logger logger = Logger.getLogger(SleuthkitJNI.class.getName()); + /** * Lock to protect against the TSK data structures being closed while * another thread is in the C++ code. Do not use this lock after obtaining @@ -177,10 +181,16 @@ private static String getDefaultCaseIdentifier() throws TskCoreException { * @param caseIdentifier Unique identifier for the case. * * @return the case handle cache + * + * @throws TskCoreException If there is no cache for this case. */ - private static CaseHandles getCaseHandles(String caseIdentifier) { + private static CaseHandles getCaseHandles(String caseIdentifier) throws TskCoreException { synchronized (cacheLock) { - return caseHandlesCache.get(caseIdentifier); + if (caseHandlesCache.containsKey(caseIdentifier)) { + return caseHandlesCache.get(caseIdentifier); + } + // If the CaseHandles object isn't in there, it should mean the case has been closed. + throw new TskCoreException("No entry for case " + caseIdentifier + " in cache. Case may have been closed"); } } @@ -228,16 +238,20 @@ private static boolean isImageInAnyCache(long imgHandle) { * @param fsHandle The file system handle in which the file lives. */ private static void addFileHandle(String caseIdentifier, long fileHandle, long fsHandle) { - synchronized (cacheLock) { - // Add to collection of open file handles. - getCaseHandles(caseIdentifier).fileHandleCache.add(fileHandle); - - // Add to map of file system to file handles. - if (getCaseHandles(caseIdentifier).fileSystemToFileHandles.containsKey(fsHandle)) { - getCaseHandles(caseIdentifier).fileSystemToFileHandles.get(fsHandle).add(fileHandle); - } else { - getCaseHandles(caseIdentifier).fileSystemToFileHandles.put(fsHandle, new ArrayList<Long>(Arrays.asList(fileHandle))); + try { + synchronized (cacheLock) { + // Add to collection of open file handles. + getCaseHandles(caseIdentifier).fileHandleCache.add(fileHandle); + + // Add to map of file system to file handles. + if (getCaseHandles(caseIdentifier).fileSystemToFileHandles.containsKey(fsHandle)) { + getCaseHandles(caseIdentifier).fileSystemToFileHandles.get(fsHandle).add(fileHandle); + } else { + getCaseHandles(caseIdentifier).fileSystemToFileHandles.put(fsHandle, new ArrayList<>(Arrays.asList(fileHandle))); + } } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error caching file handle for case {0}", caseIdentifier); } } @@ -251,7 +265,11 @@ private static void removeFileHandle(long fileHandle, SleuthkitCase skCase) { synchronized (cacheLock) { // Remove from collection of open file handles. if (skCase != null) { - getCaseHandles(skCase.getCaseHandleIdentifier()).fileHandleCache.remove(fileHandle); + try { + getCaseHandles(skCase.getCaseHandleIdentifier()).fileHandleCache.remove(fileHandle); + } catch (TskCoreException ex) { + // If the call to getCaseHandles() failed, we've already cleared the cache. + } } else { // If we don't know what case the handle is from, delete the first one we find for (String caseIdentifier:caseHandlesCache.keySet()) { @@ -882,8 +900,10 @@ private static long openImage(String[] imageFiles, int sSize, boolean useCache, * @param skCase The case the image belongs to. * @param imagePaths The complete list of paths for the image. * @param imageHandle The open image handle from TSK. + * + * @throws TskCoreException If the new image could not be added to the cache */ - private static void cacheImageHandle(SleuthkitCase skCase, List<String> imagePaths, long imageHandle) { + private static void cacheImageHandle(SleuthkitCase skCase, List<String> imagePaths, long imageHandle) throws TskCoreException { // Construct the hash key from the image paths StringBuilder keyBuilder = new StringBuilder();