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 int sectorSize;
47 private final String timeZone;
48 private final ImageWriterSettings imageWriterSettings;
49 private final boolean ignoreFatOrphanFiles;
50 private final DataSourceProcessorProgressMonitor progressMonitor;
51 private final DataSourceProcessorCallback callback;
52 private boolean criticalErrorOccurred;
65 private final Object tskAddImageProcessLock;
67 @GuardedBy(
"tskAddImageProcessLock")
68 private
boolean tskAddImageProcessStopped;
69 private SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess;
92 AddImageTask(String deviceId, String imagePath,
int sectorSize, String timeZone,
boolean ignoreFatOrphanFiles, ImageWriterSettings imageWriterSettings,
93 DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
94 this.deviceId = deviceId;
95 this.imagePath = imagePath;
96 this.sectorSize = sectorSize;
97 this.timeZone = timeZone;
98 this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
99 this.imageWriterSettings = imageWriterSettings;
100 this.callback = callback;
101 this.progressMonitor = progressMonitor;
102 tskAddImageProcessLock =
new Object();
112 currentCase = Case.getCurrentCaseThrows();
113 }
catch (NoCurrentCaseException ex) {
114 logger.log(Level.SEVERE,
"Exception while getting open case.", ex);
117 progressMonitor.setIndeterminate(
true);
118 progressMonitor.setProgress(0);
119 String imageWriterPath =
"";
120 if (imageWriterSettings != null) {
121 imageWriterPath = imageWriterSettings.getPath();
123 List<String> errorMessages =
new ArrayList<>();
124 List<Content> newDataSources =
new ArrayList<>();
126 currentCase.getSleuthkitCase().acquireSingleUserCaseWriteLock();
127 synchronized (tskAddImageProcessLock) {
128 if (!tskAddImageProcessStopped) {
129 tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(timeZone,
true,
130 ignoreFatOrphanFiles, imageWriterPath);
135 Thread progressUpdateThread =
new Thread(
new ProgressUpdater(progressMonitor, tskAddImageProcess));
136 progressUpdateThread.start();
137 runAddImageProcess(errorMessages);
138 progressUpdateThread.interrupt();
139 commitOrRevertAddImageProcess(currentCase, errorMessages, newDataSources);
140 progressMonitor.setProgress(100);
142 currentCase.getSleuthkitCase().releaseSingleUserCaseWriteLock();
143 DataSourceProcessorCallback.DataSourceProcessorResult result;
144 if (criticalErrorOccurred) {
145 result = DataSourceProcessorResult.CRITICAL_ERRORS;
146 }
else if (!errorMessages.isEmpty()) {
147 result = DataSourceProcessorResult.NONCRITICAL_ERRORS;
149 result = DataSourceProcessorResult.NO_ERRORS;
151 callback.done(result, errorMessages, newDataSources);
158 public void cancelTask() {
159 synchronized (tskAddImageProcessLock) {
160 tskAddImageProcessStopped =
true;
161 if (null != tskAddImageProcess) {
171 tskAddImageProcess.stop();
173 }
catch (TskCoreException ex) {
174 logger.log(Level.SEVERE, String.format(
"Error cancelling adding image %s to the case database", imagePath), ex);
186 private void runAddImageProcess(List<String> errorMessages) {
188 tskAddImageProcess.run(deviceId,
new String[]{imagePath}, sectorSize);
189 }
catch (TskCoreException ex) {
190 logger.log(Level.SEVERE, String.format(
"Critical error occurred adding image %s", imagePath), ex);
191 criticalErrorOccurred =
true;
192 errorMessages.add(ex.getMessage());
193 }
catch (TskDataException ex) {
194 logger.log(Level.WARNING, String.format(
"Non-critical error occurred adding image %s", imagePath), ex);
195 errorMessages.add(ex.getMessage());
213 private void commitOrRevertAddImageProcess(Case currentCase, List<String> errorMessages, List<Content> newDataSources) {
214 synchronized (tskAddImageProcessLock) {
215 if (tskAddImageProcessStopped || criticalErrorOccurred) {
217 tskAddImageProcess.revert();
218 }
catch (TskCoreException ex) {
219 logger.log(Level.SEVERE, String.format(
"Error reverting adding image %s to the case database", imagePath), ex);
220 errorMessages.add(ex.getMessage());
221 criticalErrorOccurred =
true;
225 long imageId = tskAddImageProcess.commit();
227 Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
228 String verificationError = newImage.verifyImageSize();
229 if (!verificationError.isEmpty()) {
230 errorMessages.add(verificationError);
232 if (imageWriterSettings != null) {
233 ImageWriterService.createImageWriter(imageId, imageWriterSettings);
235 newDataSources.add(newImage);
237 String errorMessage = String.format(
"Error commiting adding image %s to the case database, no object id returned", imagePath);
238 logger.log(Level.SEVERE, errorMessage);
239 errorMessages.add(errorMessage);
240 criticalErrorOccurred =
true;
242 }
catch (TskCoreException ex) {
243 logger.log(Level.SEVERE, String.format(
"Error committing adding image %s to the case database", imagePath), ex);
244 errorMessages.add(ex.getMessage());
245 criticalErrorOccurred =
true;
279 while (!Thread.currentThread().isInterrupted()) {
281 if (currDir != null) {
282 if (!currDir.isEmpty()) {
284 NbBundle.getMessage(
this.getClass(),
"AddImageTask.run.progress.adding",
299 }
catch (InterruptedException expected) {
void setProgressText(String text)
final SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess
final DataSourceProcessorProgressMonitor progressMonitor