19 package org.sleuthkit.autopsy.logicalimager.dsp;
21 import java.nio.file.Paths;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.logging.Level;
25 import org.openide.util.NbBundle.Messages;
48 "AddMultipleImageTask.fsTypeUnknownErr=Cannot determine file system type"
50 class AddMultipleImageTask implements Runnable {
52 private static final Logger LOGGER = Logger.getLogger(AddMultipleImageTask.class.getName());
53 public static final String TSK_FS_TYPE_UNKNOWN_ERR_MSG = Bundle.AddMultipleImageTask_fsTypeUnknownErr();
54 private final String deviceId;
55 private final List<String> imageFilePaths;
56 private final String timeZone;
57 private final DataSourceProcessorProgressMonitor progressMonitor;
58 private final DataSourceProcessorCallback callback;
59 private final Case currentCase;
60 private boolean criticalErrorOccurred;
61 private volatile boolean cancelled;
82 "# {0} - file",
"AddMultipleImageTask.addingFileAsLogicalFile=Adding: {0} as logical file",
83 "# {0} - deviceId",
"# {1} - exceptionMessage",
84 "AddMultipleImageTask.errorAddingImgWithoutFileSystem=Error adding images without file systems for device %s: %s",
86 AddMultipleImageTask(String deviceId, List<String> imageFilePaths, String timeZone,
87 DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
throws NoCurrentCaseException {
88 this.deviceId = deviceId;
89 this.imageFilePaths = imageFilePaths;
90 this.timeZone = timeZone;
91 this.callback = callback;
92 this.progressMonitor = progressMonitor;
93 currentCase = Case.getCurrentCaseThrows();
101 List<Content> newDataSources =
new ArrayList<>();
102 List<String> localFileDataSourcePaths =
new ArrayList<>();
103 List<String> errorMessages =
new ArrayList<>();
104 currentCase.getSleuthkitCase().acquireSingleUserCaseWriteLock();
106 progressMonitor.setIndeterminate(
true);
107 for (String imageFilePath : imageFilePaths) {
109 addImageToCase(imageFilePath, newDataSources, localFileDataSourcePaths, errorMessages);
113 currentCase.getSleuthkitCase().releaseSingleUserCaseWriteLock();
121 if (!cancelled && !localFileDataSourcePaths.isEmpty()) {
122 FileManager fileManager = currentCase.getServices().getFileManager();
123 FileManager.FileAddProgressUpdater progressUpdater = (
final AbstractFile newFile) -> {
124 progressMonitor.setProgressText(Bundle.AddMultipleImageTask_addingFileAsLogicalFile(Paths.get(newFile.getParentPath(), newFile.getName())));
127 LocalFilesDataSource localFilesDataSource = fileManager.addLocalFilesDataSource(deviceId,
"", timeZone, localFileDataSourcePaths, progressUpdater);
128 newDataSources.add(localFilesDataSource);
129 }
catch (TskCoreException | TskDataException ex) {
130 errorMessages.add(Bundle.AddMultipleImageTask_errorAddingImgWithoutFileSystem(deviceId, ex.getLocalizedMessage()));
131 criticalErrorOccurred =
true;
139 progressMonitor.setProgress(0);
140 progressMonitor.setProgress(100);
145 DataSourceProcessorResult result;
146 if (criticalErrorOccurred) {
147 result = DataSourceProcessorResult.CRITICAL_ERRORS;
148 }
else if (!errorMessages.isEmpty()) {
149 result = DataSourceProcessorResult.NONCRITICAL_ERRORS;
151 result = DataSourceProcessorResult.NO_ERRORS;
153 callback.done(result, errorMessages, newDataSources);
154 criticalErrorOccurred =
false;
162 LOGGER.log(Level.WARNING,
"AddMultipleImageTask cancelled, processing may be incomplete");
184 "# {0} - imageFilePath",
"AddMultipleImageTask.adding=Adding: {0}",
185 "# {0} - imageFilePath",
"# {1} - deviceId",
"# {2} - exceptionMessage",
"AddMultipleImageTask.criticalErrorAdding=Critical error adding {0} for device {1}: {2}",
186 "# {0} - imageFilePath",
"# {1} - deviceId",
"# {2} - exceptionMessage",
"AddMultipleImageTask.criticalErrorReverting=Critical error reverting add image process for {0} for device {1}: {2}",
187 "# {0} - imageFilePath",
"# {1} - deviceId",
"# {2} - exceptionMessage",
"AddMultipleImageTask.nonCriticalErrorAdding=Non-critical error adding {0} for device {1}: {2}",
189 private void addImageToCase(String imageFilePath, List<Content> newDataSources, List<String> localFileDataSourcePaths, List<String> errorMessages) {
193 progressMonitor.setProgressText(Bundle.AddMultipleImageTask_adding(imageFilePath));
194 SleuthkitCase caseDatabase = currentCase.getSleuthkitCase();
195 SleuthkitJNI.CaseDbHandle.AddImageProcess addImageProcess = caseDatabase.makeAddImageProcess(timeZone,
false,
false,
"");
197 addImageProcess.run(deviceId,
new String[]{imageFilePath});
198 }
catch (TskCoreException ex) {
199 if (ex.getMessage().contains(TSK_FS_TYPE_UNKNOWN_ERR_MSG)) {
206 localFileDataSourcePaths.add(imageFilePath);
208 errorMessages.add(Bundle.AddMultipleImageTask_criticalErrorAdding(imageFilePath, deviceId, ex.getLocalizedMessage()));
209 criticalErrorOccurred =
true;
215 addImageProcess.revert();
216 }
catch (TskCoreException e) {
217 errorMessages.add(Bundle.AddMultipleImageTask_criticalErrorReverting(imageFilePath, deviceId, e.getLocalizedMessage()));
218 criticalErrorOccurred =
true;
221 }
catch (TskDataException ex) {
222 errorMessages.add(Bundle.AddMultipleImageTask_nonCriticalErrorAdding(imageFilePath, deviceId, ex.getLocalizedMessage()));
231 long imageId = addImageProcess.commit();
232 Image dataSource = caseDatabase.getImageById(imageId);
233 newDataSources.add(dataSource);
239 String verificationError = dataSource.verifyImageSize();
240 if (!verificationError.isEmpty()) {
241 errorMessages.add(Bundle.AddMultipleImageTask_nonCriticalErrorAdding(imageFilePath, deviceId, verificationError));
243 }
catch (TskCoreException ex) {
249 errorMessages.add(Bundle.AddMultipleImageTask_criticalErrorAdding(imageFilePath, deviceId, ex.getLocalizedMessage()));
250 criticalErrorOccurred =
true;