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().acquireSingleUserCaseWriteLock();
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().releaseSingleUserCaseWriteLock();
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