19 package org.sleuthkit.autopsy.casemodule;
 
   21 import java.util.ArrayList;
 
   22 import java.util.List;
 
   23 import java.util.logging.Level;
 
   24 import javax.annotation.concurrent.GuardedBy;
 
   25 import org.openide.util.NbBundle;
 
   41 class AddImageTask 
implements Runnable {
 
   43     private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
 
   44     private final String deviceId;
 
   45     private final String imagePath;
 
   46     private final String timeZone;
 
   47     private final ImageWriterSettings imageWriterSettings;
 
   48     private final boolean ignoreFatOrphanFiles;
 
   49     private final DataSourceProcessorProgressMonitor progressMonitor;
 
   50     private final DataSourceProcessorCallback callback;
 
   51     private boolean criticalErrorOccurred;
 
   64     private final Object tskAddImageProcessLock;
 
   66     @GuardedBy(
"tskAddImageProcessLock")
 
   67     private 
boolean tskAddImageProcessStopped;
 
   68     private SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess;
 
   90     AddImageTask(String deviceId, String imagePath, String timeZone, 
boolean ignoreFatOrphanFiles, ImageWriterSettings imageWriterSettings,
 
   91             DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
 
   92         this.deviceId = deviceId;
 
   93         this.imagePath = imagePath;
 
   94         this.timeZone = timeZone;
 
   95         this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
 
   96         this.imageWriterSettings = imageWriterSettings;
 
   97         this.callback = callback;
 
   98         this.progressMonitor = progressMonitor;
 
   99         tskAddImageProcessLock = 
new Object();
 
  107         progressMonitor.setIndeterminate(
true);
 
  108         progressMonitor.setProgress(0);
 
  109         Case currentCase = Case.getCurrentCase();
 
  110         String imageWriterPath = 
"";
 
  111         if (imageWriterSettings != null) {
 
  112             imageWriterPath = imageWriterSettings.getPath();
 
  114         List<String> errorMessages = 
new ArrayList<>();
 
  115         List<Content> newDataSources = 
new ArrayList<>();
 
  117             currentCase.getSleuthkitCase().acquireExclusiveLock();
 
  118             synchronized (tskAddImageProcessLock) {
 
  119                 if (!tskAddImageProcessStopped) {  
 
  120                     tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(timeZone, 
true,
 
  121                             ignoreFatOrphanFiles, imageWriterPath);
 
  126             Thread progressUpdateThread = 
new Thread(
new ProgressUpdater(progressMonitor, tskAddImageProcess));
 
  127             progressUpdateThread.start();
 
  128             runAddImageProcess(errorMessages);
 
  129             if (null != progressUpdateThread) {
 
  130                 progressUpdateThread.interrupt();
 
  132             commitOrRevertAddImageProcess(currentCase, errorMessages, newDataSources);
 
  133             progressMonitor.setProgress(100);
 
  135             currentCase.getSleuthkitCase().releaseExclusiveLock();
 
  136             DataSourceProcessorCallback.DataSourceProcessorResult result;
 
  137             if (criticalErrorOccurred) {
 
  138                 result = DataSourceProcessorResult.CRITICAL_ERRORS;
 
  139             } 
else if (!errorMessages.isEmpty()) {
 
  140                 result = DataSourceProcessorResult.NONCRITICAL_ERRORS;
 
  142                 result = DataSourceProcessorResult.NO_ERRORS;
 
  144             callback.done(result, errorMessages, newDataSources);
 
  151     public void cancelTask() {
 
  152         synchronized (tskAddImageProcessLock) {
 
  153             tskAddImageProcessStopped = 
true;
 
  154             if (null != tskAddImageProcess) {
 
  164                     tskAddImageProcess.stop();
 
  166                 } 
catch (TskCoreException ex) {
 
  167                     logger.log(Level.SEVERE, String.format(
"Error cancelling adding image %s to the case database", imagePath), ex); 
 
  179     private void runAddImageProcess(List<String> errorMessages) {
 
  181             tskAddImageProcess.run(deviceId, 
new String[]{imagePath});
 
  182         } 
catch (TskCoreException ex) {
 
  183             logger.log(Level.SEVERE, String.format(
"Critical error occurred adding image %s", imagePath), ex); 
 
  184             criticalErrorOccurred = 
true;
 
  185             errorMessages.add(ex.getMessage());
 
  186         } 
catch (TskDataException ex) {
 
  187             logger.log(Level.WARNING, String.format(
"Non-critical error occurred adding image %s", imagePath), ex); 
 
  188             errorMessages.add(ex.getMessage());
 
  206     private void commitOrRevertAddImageProcess(Case currentCase, List<String> errorMessages, List<Content> newDataSources) {
 
  207         synchronized (tskAddImageProcessLock) {
 
  208             if (tskAddImageProcessStopped || criticalErrorOccurred) {
 
  210                     tskAddImageProcess.revert();
 
  211                 } 
catch (TskCoreException ex) {
 
  212                     logger.log(Level.SEVERE, String.format(
"Error reverting adding image %s to the case database", imagePath), ex); 
 
  213                     errorMessages.add(ex.getMessage());
 
  214                     criticalErrorOccurred = 
true;
 
  218                     long imageId = tskAddImageProcess.commit();
 
  220                         Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
 
  221                         String verificationError = newImage.verifyImageSize();
 
  222                         if (!verificationError.isEmpty()) {
 
  223                             errorMessages.add(verificationError);
 
  225                         if (imageWriterSettings != null) {
 
  226                             ImageWriterService.createImageWriter(imageId, imageWriterSettings);
 
  228                         newDataSources.add(newImage);
 
  230                         String errorMessage = String.format(
"Error commiting adding image %s to the case database, no object id returned", imagePath); 
 
  231                         logger.log(Level.SEVERE, errorMessage);
 
  232                         errorMessages.add(errorMessage);
 
  233                         criticalErrorOccurred = 
true;
 
  235                 } 
catch (TskCoreException ex) {
 
  236                     logger.log(Level.SEVERE, String.format(
"Error committing adding image %s to the case database", imagePath), ex); 
 
  237                     errorMessages.add(ex.getMessage());
 
  238                     criticalErrorOccurred = 
true;
 
  272                 while (!Thread.currentThread().isInterrupted()) {
 
  274                     if (currDir != null) {
 
  275                         if (!currDir.isEmpty()) {
 
  277                                     NbBundle.getMessage(
this.getClass(), 
"AddImageTask.run.progress.adding",
 
  292             } 
catch (InterruptedException expected) {
 
void setProgressText(String text)
 
final SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess
 
final DataSourceProcessorProgressMonitor progressMonitor