19package org.sleuthkit.autopsy.casemodule;
21import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils;
22import com.google.common.annotations.Beta;
23import com.google.common.eventbus.Subscribe;
24import com.google.common.util.concurrent.ThreadFactoryBuilder;
25import java.awt.Cursor;
26import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
28import java.awt.GraphicsEnvironment;
29import java.awt.event.ActionEvent;
30import java.awt.event.ActionListener;
31import java.beans.PropertyChangeListener;
32import java.beans.PropertyChangeSupport;
34import java.lang.reflect.InvocationTargetException;
35import java.nio.file.InvalidPathException;
36import java.nio.file.Path;
37import java.nio.file.Paths;
38import java.sql.Connection;
39import java.sql.DriverManager;
40import java.sql.ResultSet;
41import java.sql.SQLException;
42import java.sql.Statement;
43import java.text.SimpleDateFormat;
44import java.util.ArrayList;
45import java.util.Collection;
47import java.util.HashMap;
48import java.util.HashSet;
51import java.util.Optional;
53import java.util.TimeZone;
55import java.util.concurrent.CancellationException;
56import java.util.concurrent.ExecutionException;
57import java.util.concurrent.ExecutorService;
58import java.util.concurrent.Executors;
59import java.util.concurrent.Future;
60import java.util.concurrent.ThreadFactory;
61import java.util.concurrent.TimeUnit;
62import java.util.logging.Level;
63import java.util.stream.Collectors;
64import java.util.stream.Stream;
65import javax.annotation.concurrent.GuardedBy;
66import javax.annotation.concurrent.ThreadSafe;
67import javax.swing.JOptionPane;
68import javax.swing.SwingUtilities;
69import org.apache.commons.lang3.ArrayUtils;
70import org.apache.commons.lang3.StringUtils;
71import org.openide.util.Lookup;
72import org.openide.util.NbBundle;
73import org.openide.util.NbBundle.Messages;
74import org.openide.util.actions.CallableSystemAction;
75import org.openide.windows.WindowManager;
76import org.sleuthkit.autopsy.actions.OpenOutputFolderAction;
77import org.sleuthkit.autopsy.appservices.AutopsyService;
78import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
79import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
80import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryAction;
81import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
82import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
83import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
84import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent;
85import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent;
86import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
87import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
88import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
89import org.sleuthkit.autopsy.casemodule.events.DataSourceDeletedEvent;
90import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent;
91import org.sleuthkit.autopsy.casemodule.events.HostsAddedEvent;
92import org.sleuthkit.autopsy.casemodule.events.HostsAddedToPersonEvent;
93import org.sleuthkit.autopsy.casemodule.events.HostsUpdatedEvent;
94import org.sleuthkit.autopsy.casemodule.events.HostsDeletedEvent;
95import org.sleuthkit.autopsy.casemodule.events.HostsRemovedFromPersonEvent;
96import org.sleuthkit.autopsy.casemodule.events.OsAccountsAddedEvent;
97import org.sleuthkit.autopsy.casemodule.events.OsAccountsUpdatedEvent;
98import org.sleuthkit.autopsy.casemodule.events.OsAccountsDeletedEvent;
99import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent;
100import org.sleuthkit.autopsy.casemodule.events.PersonsAddedEvent;
101import org.sleuthkit.autopsy.casemodule.events.PersonsUpdatedEvent;
102import org.sleuthkit.autopsy.casemodule.events.PersonsDeletedEvent;
103import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
104import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesAddedEvent;
105import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesDeletedEvent;
106import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesUpdatedEvent;
107import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsAddedEvent;
108import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsDeletedEvent;
109import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData.CaseNodeDataException;
110import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils;
111import org.sleuthkit.autopsy.casemodule.services.Services;
112import org.sleuthkit.autopsy.commonpropertiessearch.CommonAttributeSearchAction;
113import org.sleuthkit.autopsy.communications.OpenCommVisualizationToolAction;
114import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
115import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
116import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
117import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
118import org.sleuthkit.autopsy.core.RuntimeProperties;
119import org.sleuthkit.autopsy.core.UserPreferences;
120import org.sleuthkit.autopsy.core.UserPreferencesException;
121import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
122import org.sleuthkit.autopsy.coreutils.DriveUtils;
123import org.sleuthkit.autopsy.coreutils.FileUtil;
124import org.sleuthkit.autopsy.coreutils.Logger;
125import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
126import org.sleuthkit.autopsy.coreutils.NetworkUtils;
127import org.sleuthkit.autopsy.coreutils.PlatformUtil;
128import org.sleuthkit.autopsy.coreutils.ThreadUtils;
129import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
130import org.sleuthkit.autopsy.coreutils.Version;
131import org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction;
132import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
133import org.sleuthkit.autopsy.events.AutopsyEvent;
134import org.sleuthkit.autopsy.events.AutopsyEventException;
135import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
136import org.sleuthkit.autopsy.discovery.ui.OpenDiscoveryAction;
137import org.sleuthkit.autopsy.ingest.IngestJob;
138import org.sleuthkit.autopsy.ingest.IngestManager;
139import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
140import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
141import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
142import org.sleuthkit.autopsy.progress.LoggingProgressIndicator;
143import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
144import org.sleuthkit.autopsy.progress.ProgressIndicator;
145import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
146import org.sleuthkit.autopsy.timeline.events.TimelineEventAddedEvent;
147import org.sleuthkit.datamodel.BlackboardArtifactTag;
148import org.sleuthkit.datamodel.CaseDbConnectionInfo;
149import org.sleuthkit.datamodel.ConcurrentDbAccessException;
150import org.sleuthkit.datamodel.Content;
151import org.sleuthkit.datamodel.ContentStreamProvider;
152import org.sleuthkit.datamodel.ContentTag;
153import org.sleuthkit.datamodel.DataSource;
154import org.sleuthkit.datamodel.FileSystem;
155import org.sleuthkit.datamodel.Image;
156import org.sleuthkit.datamodel.Report;
157import org.sleuthkit.datamodel.SleuthkitCase;
158import org.sleuthkit.datamodel.TimelineManager;
159import org.sleuthkit.datamodel.SleuthkitCaseAdminUtil;
160import org.sleuthkit.datamodel.TskCoreException;
161import org.sleuthkit.datamodel.TskDataException;
162import org.sleuthkit.datamodel.TskEvent;
163import org.sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
190 = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(
"case-open-file-systems-%d").build());
210 if (!GraphicsEnvironment.isHeadless()) {
211 WindowManager.getDefault().invokeWhenUIReady(() -> {
212 mainFrame = WindowManager.getDefault().getMainWindow();
237 if (
typeName.equalsIgnoreCase(c.toString())) {
261 "Case_caseType_singleUser=Single-user case",
262 "Case_caseType_multiUser=Multi-user case"
266 return Bundle.Case_caseType_singleUser();
268 return Bundle.Case_caseType_multiUser();
293 return (otherTypeName ==
null) ? false :
typeName.equals(otherTypeName);
548 }
catch (TskCoreException ex) {
549 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
592 }
catch (TskCoreException ex) {
593 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
676 .map(Events::toString)
677 .collect(Collectors.toSet()), listener);
688 .map(Events::toString)
689 .collect(Collectors.toSet()), listener);
712 eventTypes.forEach((
Events event) -> {
757 eventTypes.forEach((
Events event) -> {
771 return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
772 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
773 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
825 "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
826 "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path."
832 if (caseDir.isEmpty()) {
852 "# {0} - exception message",
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
853 "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case."
860 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
863 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
891 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"), ex);
915 if (openCase ==
null) {
931 "# {0} - exception message",
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
932 "Case.progressIndicatorTitle.closingCase=Closing Case"
942 logger.log(Level.INFO,
"Closing current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
944 logger.log(Level.INFO,
"Closed current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
987 "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source"
989 static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID)
throws CaseActionException {
1006 Case theCase =
new Case(caseMetadata);
1007 theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE,
false, dataSourceObjectID);
1028 "Case.progressIndicatorTitle.deletingCase=Deleting Case",
1029 "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
1030 "# {0} - case display name",
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled."
1045 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
1052 }
catch (InterruptedException ex) {
1062 progressIndicator.
finish();
1077 "Case.progressIndicatorTitle.creatingCase=Creating Case",
1078 "Case.progressIndicatorTitle.openingCase=Opening Case",
1079 "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window"
1095 logger.log(Level.INFO,
"Opening {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1096 String progressIndicatorTitle;
1099 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
1100 openCaseAction = newCurrentCase::create;
1102 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
1103 openCaseAction = newCurrentCase::open;
1107 logger.log(Level.INFO,
"Opened {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1134 String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]",
"_");
1139 uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]",
"_");
1144 uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]",
"_");
1149 uniqueCaseName = uniqueCaseName.toLowerCase();
1154 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
1155 Date date =
new Date();
1156 uniqueCaseName = uniqueCaseName +
"_" + dateFormat.format(date);
1158 return uniqueCaseName;
1175 File caseDir =
new File(caseDirPath);
1176 if (caseDir.exists()) {
1177 if (caseDir.isFile()) {
1178 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existNotDir", caseDirPath));
1179 }
else if (!caseDir.canRead() || !caseDir.canWrite()) {
1180 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existCantRW", caseDirPath));
1187 if (!caseDir.mkdirs()) {
1188 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreate", caseDirPath));
1196 String hostPathComponent =
"";
1201 Path exportDir = Paths.get(caseDirPath, hostPathComponent,
EXPORT_FOLDER);
1202 if (!exportDir.toFile().mkdirs()) {
1203 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
1206 Path logsDir = Paths.get(caseDirPath, hostPathComponent,
LOG_FOLDER);
1207 if (!logsDir.toFile().mkdirs()) {
1208 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
1211 Path cacheDir = Paths.get(caseDirPath, hostPathComponent,
CACHE_FOLDER);
1212 if (!cacheDir.toFile().mkdirs()) {
1213 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
1216 Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent,
MODULE_FOLDER);
1217 if (!moduleOutputDir.toFile().mkdirs()) {
1218 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
1221 Path reportsDir = Paths.get(caseDirPath, hostPathComponent,
REPORTS_FOLDER);
1222 if (!reportsDir.toFile().mkdirs()) {
1223 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
1234 static Map<Long, String> getImagePaths(SleuthkitCase db) {
1235 Map<Long, String> imgPaths =
new HashMap<>();
1237 Map<Long, List<String>> imgPathsList = db.getImagePaths();
1238 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
1239 if (entry.getValue().size() > 0) {
1240 imgPaths.put(entry.getKey(), entry.getValue().get(0));
1243 }
catch (TskCoreException ex) {
1244 logger.log(Level.SEVERE,
"Error getting image paths", ex);
1260 "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources"
1264 Path caseDirPath = Paths.get(caseDir);
1268 }
catch (InterruptedException ex) {
1271 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
1294 String backupDbPath =
caseDb.getBackupDatabasePath();
1295 if (
null != backupDbPath) {
1296 JOptionPane.showMessageDialog(
1298 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg", backupDbPath),
1299 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
1300 JOptionPane.INFORMATION_MESSAGE);
1307 Map<Long, String> imgPaths = getImagePaths(
caseDb);
1308 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
1309 long obj_id = entry.getKey();
1310 String path = entry.getValue();
1315 String hostName = StringUtils.defaultString(ds.getHost() ==
null ?
"" : ds.getHost().getName());
1320 SwingUtilities.invokeAndWait(
new Runnable() {
1323 int response = JOptionPane.showConfirmDialog(
1325 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.msg", hostName, path),
1326 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.title"),
1327 JOptionPane.YES_NO_OPTION);
1328 if (response == JOptionPane.YES_OPTION) {
1329 MissingImageDialog.makeDialog(obj_id,
caseDb);
1331 logger.log(Level.SEVERE,
"User proceeding with missing image files");
1337 }
catch (InterruptedException | InvocationTargetException | TskCoreException | TskDataException ex) {
1338 logger.log(Level.SEVERE,
"Failed to show missing image confirmation dialog", ex);
1349 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
1366 SwingUtilities.invokeLater(() -> {
1375 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1382 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1398 SwingUtilities.invokeLater(() -> {
1408 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
1411 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
1413 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
1486 return metadata.getCaseDisplayName();
1513 return metadata.getExaminerPhone();
1522 return metadata.getExaminerEmail();
1540 return metadata.getCaseDirectory();
1557 hostPath = Paths.get(caseDirectory);
1559 if (!hostPath.toFile().exists()) {
1560 hostPath.toFile().mkdirs();
1562 return hostPath.toString();
1569 return Paths.get(System.getProperty(
"java.io.tmpdir"),
APP_NAME,
getName());
1581 Path basePath =
null;
1586 basePath = (StringUtils.isBlank(customDirectory))
1608 File caseTempDir = basePath
1609 .resolve(caseRelPath)
1613 if (!caseTempDir.exists()) {
1614 caseTempDir.mkdirs();
1617 return caseTempDir.getAbsolutePath();
1690 return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
1692 return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
1706 return caseDb.getRootObjects();
1715 Set<TimeZone> timezones =
new HashSet<>();
1716 String query =
"SELECT time_zone FROM data_source_info";
1717 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
1718 ResultSet timeZoneSet = dbQuery.getResultSet();
1719 while (timeZoneSet.next()) {
1720 String timeZone = timeZoneSet.getString(
"time_zone");
1721 if (timeZone !=
null && !timeZone.isEmpty()) {
1722 timezones.add(TimeZone.getTimeZone(timeZone));
1725 }
catch (TskCoreException | SQLException ex) {
1726 logger.log(Level.SEVERE,
"Error getting data source time zones", ex);
1878 logger.log(Level.WARNING,
"Unable to send notifcation regarding comment change due to no current case being open", ex);
1928 public void addReport(String localPath, String srcModuleName, String reportName)
throws TskCoreException {
1929 addReport(localPath, srcModuleName, reportName,
null);
1946 public Report
addReport(String localPath, String srcModuleName, String reportName, Content parent)
throws TskCoreException {
1947 String normalizedLocalPath;
1949 if (localPath.toLowerCase().contains(
"http:")) {
1950 normalizedLocalPath = localPath;
1952 normalizedLocalPath = Paths.get(localPath).normalize().toString();
1954 }
catch (InvalidPathException ex) {
1955 String errorMsg =
"Invalid local path provided: " + localPath;
1956 throw new TskCoreException(errorMsg, ex);
1960 Report
report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
1974 return this.caseDb.getAllReports();
1985 public void deleteReports(Collection<? extends Report> reports)
throws TskCoreException {
1986 for (Report
report : reports) {
1987 this.caseDb.deleteReport(
report);
1992 }
catch (TskCoreException ex) {
1993 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
1996 for (Report
report : reports) {
2018 "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata"
2020 void updateCaseDetails(CaseDetails caseDetails)
throws CaseActionException {
2023 metadata.setCaseDetails(caseDetails);
2024 }
catch (CaseMetadataException ex) {
2025 throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
2031 CaseNodeData.writeCaseNodeData(nodeData);
2032 }
catch (CaseNodeDataException | InterruptedException ex) {
2033 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2036 if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
2039 if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
2046 if (RuntimeProperties.runningWithGUI()) {
2047 SwingUtilities.invokeLater(() -> {
2050 RecentCases.getInstance().updateRecentCase(oldCaseDetails.getCaseDisplayName(),
metadata.getFilePath().toString(), caseDetails.
getCaseDisplayName(),
metadata.getFilePath().toString());
2051 }
catch (Exception ex) {
2052 logger.log(Level.SEVERE,
"Error updating case name in UI", ex);
2114 "Case.progressIndicatorCancelButton.label=Cancel",
2115 "Case.progressMessage.preparing=Preparing...",
2116 "Case.progressMessage.cancelling=Cancelling...",
2117 "Case.exceptionMessage.cancelled=Cancelled.",
2118 "# {0} - exception message",
"Case.exceptionMessage.execExceptionWrapperMessage={0}"
2128 if (allowCancellation) {
2132 progressIndicatorTitle,
2133 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2134 Bundle.Case_progressIndicatorCancelButton_label(),
2135 cancelButtonListener);
2139 progressIndicatorTitle);
2144 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2156 caseAction.
execute(progressIndicator, additionalParams);
2160 if (
null == resourcesLock) {
2161 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
2163 caseAction.
execute(progressIndicator, additionalParams);
2171 if (
null != cancelButtonListener) {
2180 }
catch (InterruptedException discarded) {
2184 if (
null != cancelButtonListener) {
2187 future.cancel(
true);
2190 }
catch (CancellationException discarded) {
2196 }
catch (ExecutionException ex) {
2201 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
2203 progressIndicator.
finish();
2223 assert (additionalParams ==
null);
2253 }
catch (InterruptedException discarded) {
2255 close(progressIndicator);
2275 assert (additionalParams ==
null);
2306 }
catch (InterruptedException discarded) {
2308 close(progressIndicator);
2319 "Case_checkImagePaths_noPaths=The following images had no associated paths: {0}",
2320 "Case_checkImagePaths_exceptionOccurred=An exception occurred while checking if image paths are present"
2324 if (StringUtils.isNotBlank(
this.metadata.getContentProviderName())) {
2330 List<Image> noPathImages =
new ArrayList<>();
2331 List<Image> images = this.caseDb.getImages();
2332 for (Image img: images) {
2333 if (ArrayUtils.isEmpty(img.getPaths())) {
2334 noPathImages.add(img);
2338 if (!noPathImages.isEmpty()) {
2339 String imageListStr = noPathImages.stream().map(Image::getName).collect(Collectors.joining(
", "));
2342 }
catch (TskCoreException ex) {
2357 "# {0} - case",
"Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...",
2358 "# {0} - image",
"Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..."
2373 private static class BackgroundOpenFileSystemsTask
implements Runnable {
2391 caseName = (this.tskCase !=
null) ? this.tskCase.getDatabaseName() :
"";
2402 if (Thread.interrupted()) {
2403 throw new InterruptedException();
2415 return this.tskCase.getImages();
2416 }
catch (TskCoreException ex) {
2419 String.format(
"Could not obtain images while opening case: %s.",
caseName),
2435 private void openFileSystems(List<Image> images)
throws TskCoreException, InterruptedException {
2436 byte[] tempBuff =
new byte[512];
2438 for (Image image : images) {
2439 String imageStr = image.getName();
2443 Collection<FileSystem> fileSystems = this.tskCase.getImageFileSystems(image);
2445 for (FileSystem fileSystem : fileSystems) {
2446 fileSystem.read(tempBuff, 0, 512);
2458 if (images ==
null) {
2466 String.format(
"Skipping background load of file systems due to large number of images in case (%d)", images.size()));
2472 }
catch (InterruptedException ex) {
2475 String.format(
"Background operation opening all file systems in %s has been cancelled.",
caseName));
2476 }
catch (Exception ex) {
2478 logger.log(Level.WARNING,
"Error while opening file systems in background", ex);
2499 "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
2500 "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
2501 "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
2502 "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
2503 Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams)
throws CaseActionException {
2504 assert (additionalParams instanceof Long);
2505 open(progressIndicator,
null);
2507 progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
2508 Long dataSourceObjectID = (Long) additionalParams;
2510 DataSource dataSource = this.caseDb.getDataSource(dataSourceObjectID);
2511 if (dataSource ==
null) {
2512 throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
2514 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
2515 }
catch (TskDataException | TskCoreException ex) {
2516 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
2520 }
catch (KeywordSearchServiceException ex) {
2521 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
2523 eventPublisher.publish(
new DataSourceDeletedEvent(dataSourceObjectID));
2526 close(progressIndicator);
2541 public SleuthkitCase
createPortableCase(String caseName, File portableCaseFolder)
throws TskCoreException {
2543 if (portableCaseFolder.exists()) {
2544 throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() +
" already exists");
2546 if (!portableCaseFolder.mkdirs()) {
2547 throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
2557 throw new TskCoreException(
"Error creating case metadata", ex);
2561 SleuthkitCase portableSleuthkitCase;
2563 portableSleuthkitCase = SleuthkitCase.newCase(dbFilePath);
2565 return portableSleuthkitCase;
2578 if (Thread.currentThread().isInterrupted()) {
2594 "Case.progressMessage.creatingCaseDirectory=Creating case directory..."
2601 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2602 if (
new File(
metadata.getCaseDirectory()).exists() ==
false) {
2603 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2615 "Case.progressMessage.switchingLogDirectory=Switching log directory..."
2618 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
2634 "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
2635 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}."
2638 progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
2640 this.metadata.writeToFile();
2642 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
2658 "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
2659 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}."
2663 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
2667 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
2684 "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
2685 "# {0} - exception message",
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}."
2689 progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
2695 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2706 "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..."
2712 progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
2728 "Case.progressMessage.creatingCaseDatabase=Creating case database...",
2729 "# {0} - exception message",
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
2730 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
2731 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}."
2734 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
2753 }
catch (TskCoreException ex) {
2755 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
2757 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2759 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
2775 "Case.progressMessage.openingCaseDatabase=Opening case database...",
2776 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
2777 "# {0} - exception message",
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
2778 "Case.exceptionMessage.contentProviderCouldNotBeFound=Content provider was specified for the case but could not be loaded.",
2779 "# {0} - provider name, {1} - required version, {2} - installed version",
2780 "Case.versionMismatch.message=This case requires version {1} of the ''{0}'' plugin but version {2} is installed. Please upgrade the module to version {1} or a compatible version.",
2781 "Case.versionMismatch.title=Content Provider Version Mismatch",
2782 "Case.exceptionMessage.contentProviderVersionMismatch=The installed content provider plugin is not compatible with this case.",
2783 "# {0} - provider name",
"Case.contentProviderNotFound.message=This case requires a content provider plugin (''{0}'') that is not installed. Please install the appropriate plugin.",
2784 "Case.contentProviderNotFound.title=Content Provider Not Found",
2785 "# {0} - provider name",
"Case.contentProviderLoadFailed.message=The content provider plugin (''{0}'') is installed but could not be loaded. Check the module for errors.",
2786 "Case.contentProviderLoadFailed.title=Content Provider Load Failed",
2787 "Case.exceptionMessage.contentProviderLoadFailed=The content provider plugin is installed but failed to load.",
2788 "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User."
2791 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
2793 String databaseName =
metadata.getCaseDatabaseName();
2795 ContentStreamProvider contentProvider = ContentProviderUtils.getContentProvider(
metadata.getContentProviderName());
2796 if (StringUtils.isNotBlank(
metadata.getContentProviderName()) && contentProvider ==
null) {
2797 String createdName =
metadata.getContentProviderName().trim();
2798 Optional<AutopsyContentProvider> installedProvider = ContentProviderUtils.findInstalledProvider(createdName);
2799 if (installedProvider.isPresent()) {
2802 SwingUtilities.invokeAndWait(() -> JOptionPane.showMessageDialog(
2803 WindowManager.getDefault().getMainWindow(),
2804 Bundle.Case_contentProviderLoadFailed_message(createdName),
2805 Bundle.Case_contentProviderLoadFailed_title(),
2806 JOptionPane.ERROR_MESSAGE));
2807 }
catch (InterruptedException | InvocationTargetException ex) {
2808 logger.log(Level.WARNING,
"Error showing content provider load failed dialog", ex);
2815 SwingUtilities.invokeAndWait(() -> JOptionPane.showMessageDialog(
2816 WindowManager.getDefault().getMainWindow(),
2817 Bundle.Case_contentProviderNotFound_message(createdName),
2818 Bundle.Case_contentProviderNotFound_title(),
2819 JOptionPane.ERROR_MESSAGE));
2820 }
catch (InterruptedException | InvocationTargetException ex) {
2821 logger.log(Level.WARNING,
"Error showing content provider not found dialog", ex);
2824 throw new CaseActionException(Bundle.Case_exceptionMessage_contentProviderCouldNotBeFound());
2836 }
catch (TskUnsupportedSchemaVersionException ex) {
2837 throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
2839 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2840 }
catch (TskCoreException ex) {
2842 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);
2853 "# {0} - appplicationName",
2854 "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException=The case is open in {0}. Please close it before attempting to open it in Autopsy.",
2855 "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp=another application"
2858 ConcurrentDbAccessException concurrentEx =
null;
2859 Throwable curEx = ex;
2861 for (
int i = 0; i < 10; i++) {
2862 if (curEx ==
null) {
2864 }
else if (curEx instanceof ConcurrentDbAccessException foundEx) {
2865 concurrentEx = foundEx;
2868 curEx = curEx.getCause();
2872 if (concurrentEx !=
null) {
2873 throw new CaseActionException(Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException(
2874 StringUtils.defaultIfBlank(concurrentEx.getConflictingApplicationName(),
2875 Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp())
2890 "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
2892 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
2914 @NbBundle.Messages({
2915 "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
2916 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
2917 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
2918 "# {0} - service name",
"Case.servicesException.notificationTitle={0} Error"
2929 progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
2941 cancelButtonListener =
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
2944 Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
2945 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2946 Bundle.Case_progressIndicatorCancelButton_label(),
2947 cancelButtonListener);
2951 appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
2953 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
2954 threadNameSuffix = threadNameSuffix.toLowerCase();
2956 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
2957 Future<Void> future = executor.submit(() -> {
2958 service.openCaseResources(context);
2961 if (
null != cancelButtonListener) {
2973 }
catch (InterruptedException discarded) {
2978 future.cancel(
true);
2979 }
catch (CancellationException discarded) {
2986 Case.logger.log(Level.WARNING, String.format(
"Opening of case resources by %s for %s (%s) in %s cancelled", service.getServiceName(),
getDisplayName(),
getName(),
getCaseDirectory(), service.getServiceName()));
2987 }
catch (ExecutionException ex) {
2994 Case.logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(),
this.getDisplayName()), ex);
2996 SwingUtilities.invokeLater(() -> {
3008 appServiceProgressIndicator.
finish();
3026 "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
3027 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
3028 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}."
3032 progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
3038 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
3039 }
catch (CollaborationMonitor.CollaborationMonitorException ex) {
3040 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
3068 Bundle.Case_progressIndicatorTitle_closingCase());
3072 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3083 close(progressIndicator);
3090 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
3092 if (
null == resourcesLock) {
3093 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
3095 close(progressIndicator);
3109 }
catch (InterruptedException | CancellationException unused) {
3116 }
catch (ExecutionException ex) {
3117 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
3120 progressIndicator.
finish();
3130 "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
3131 "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
3132 "Case.progressMessage.closingCaseDatabase=Closing case database..."
3142 progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
3153 progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
3160 progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
3173 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
3182 "# {0} - serviceName",
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
3183 "# {0} - service name",
"# {1} - exception message",
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}"
3196 Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
3200 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3202 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
3203 threadNameSuffix = threadNameSuffix.toLowerCase();
3205 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
3206 Future<Void> future = executor.submit(() -> {
3207 service.closeCaseResources(context);
3212 }
catch (InterruptedException ex) {
3213 Case.logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
3214 }
catch (CancellationException ex) {
3215 Case.logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
3216 }
catch (ExecutionException ex) {
3217 Case.logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
3220 Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
3221 Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
3225 progressIndicator.
finish();
3236 "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
3237 "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case."
3240 String caseDir =
metadata.getCaseDirectory();
3250 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
3255 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
3257 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
3284 if (!subDirectory.exists()) {
3285 subDirectory.mkdirs();
3287 return subDirectory.toString();
3303 "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details."
3306 boolean errorsOccurred =
false;
3310 errorsOccurred =
true;
3311 logger.log(Level.WARNING, String.format(
"Failed to delete text index for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3317 errorsOccurred =
true;
3318 logger.log(Level.WARNING, String.format(
"Failed to delete case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3323 if (errorsOccurred) {
3348 "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
3349 "# {0} - exception message",
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
3350 "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
3351 "# {0} - exception message",
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
3352 "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
3353 "# {0} - exception message",
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
3354 "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
3355 "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..."
3358 progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
3363 logger.log(Level.SEVERE, String.format(
"Failed to connect to coordination service when attempting to delete %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3364 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
3368 boolean errorsOccurred =
false;
3370 if (dirLock ==
null) {
3371 logger.log(Level.INFO, String.format(
"Could not delete %s (%s) in %s because a case directory lock was held by another host",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()));
3375 progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
3379 logger.log(Level.SEVERE, String.format(
"Failed to get coordination service node data %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3380 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
3385 progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
3391 errorsOccurred =
true;
3392 logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3394 }
catch (InterruptedException ex) {
3395 logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3399 logger.log(Level.SEVERE, String.format(
"Error exclusively locking the case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3400 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
3403 if (!errorsOccurred) {
3404 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
3409 logger.log(Level.SEVERE, String.format(
"Error deleting the case directory lock node for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3410 errorsOccurred =
true;
3414 if (errorsOccurred) {
3445 boolean errorsOccurred =
false;
3452 errorsOccurred =
true;
3453 logger.log(Level.WARNING, String.format(
"Failed to delete the case database for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3455 errorsOccurred =
true;
3456 logger.log(Level.WARNING, String.format(
"Failed to delete the text index for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3458 errorsOccurred =
true;
3459 logger.log(Level.WARNING, String.format(
"Failed to delete the case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3461 return errorsOccurred;
3485 "Case.progressMessage.deletingCaseDatabase=Deleting case database..."
3489 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
3492 String url =
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres";
3493 Class.forName(
"org.postgresql.Driver");
3494 try (Connection connection = DriverManager.getConnection(url, info.getUserName(), info.getPassword()); Statement statement = connection.createStatement()) {
3495 String dbExistsQuery =
"SELECT 1 from pg_database WHERE datname = '" +
metadata.getCaseDatabaseName() +
"'";
3496 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
3497 if (queryResult.next()) {
3498 String deleteCommand =
"DROP DATABASE \"" +
metadata.getCaseDatabaseName() +
"\"";
3499 statement.execute(deleteCommand);
3540 "Case.progressMessage.deletingTextIndex=Deleting text index..."
3543 progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
3547 searchService.deleteTextIndex(
metadata);
3583 "Case.progressMessage.deletingCaseDirectory=Deleting case directory..."
3586 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
3600 "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..."
3604 progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
3605 SwingUtilities.invokeLater(() -> {
3606 RecentCases.getInstance().removeRecentCase(
metadata.getCaseDisplayName(),
metadata.getFilePath().toString());
3621 boolean isNodeNodeEx =
false;
3622 Throwable cause = ex.getCause();
3623 if (cause !=
null) {
3624 String causeMessage = cause.getMessage();
3627 return isNodeNodeEx;
3646 logger.log(Level.SEVERE, String.format(
"Error updating deleted item flag %s for %s (%s) in %s", flag.name(), caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory()), ex);
3680 String query =
"SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
3681 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
3682 ResultSet resultSet = dbQuery.getResultSet();
3683 if (resultSet.next()) {
3684 return resultSet.getLong(
"count") > 0;
3687 }
catch (SQLException ex) {
3688 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3689 throw new TskCoreException(
"Error accessing case databse", ex);
3704 String query =
"SELECT SUM(cnt) total FROM "
3705 +
"(SELECT COUNT(*) AS cnt FROM "
3706 +
"(SELECT * FROM tsk_objects LIMIT 1)t "
3708 +
"SELECT COUNT(*) AS cnt FROM "
3709 +
"(SELECT * FROM tsk_hosts LIMIT 1)r) s";
3710 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
3711 ResultSet resultSet = dbQuery.getResultSet();
3712 if (resultSet.next()) {
3713 return resultSet.getLong(
"total") > 0;
3717 }
catch (SQLException ex) {
3718 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3719 throw new TskCoreException(
"Error accessing case databse", ex);
3831 this.cancelRequested =
true;
4005 return new File(filePath).isFile();
4044 return "ModuleOutput";
4057 public static PropertyChangeSupport
4059 return new PropertyChangeSupport(
Case.class
4093 Image newDataSource =
caseDb.getImageById(imgId);
4095 return newDataSource;
4096 }
catch (TskCoreException ex) {
4097 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
4124 public void deleteReports(Collection<? extends Report> reports,
boolean deleteFromDisk)
throws TskCoreException {
void openFileSystems(List< Image > images)
final long MAX_IMAGE_THRESHOLD
final ProgressIndicator progressIndicator
List< Image > getImages()
final SleuthkitCase tskCase
void publishOsAccountInstancesAddedEvent(TskEvent.OsAcctInstancesAddedTskEvent event)
void publishHostsAddedEvent(TskEvent.HostsAddedTskEvent event)
void publicTagNamesDeleted(TskEvent.TagNamesDeletedTskEvent event)
void publishOsAccountsUpdatedEvent(TskEvent.OsAccountsUpdatedTskEvent event)
void publishHostsAddedToPersonEvent(TskEvent.HostsAddedToPersonTskEvent event)
void publishTimelineEventAddedEvent(TimelineManager.TimelineEventAddedEvent event)
void publishPersonsDeletedEvent(TskEvent.PersonsDeletedTskEvent event)
void publishOsAccountsAddedEvent(TskEvent.OsAccountsAddedTskEvent event)
void publishHostsDeletedEvent(TskEvent.HostsDeletedTskEvent event)
void publishPersonsUpdatedEvent(TskEvent.PersonsUpdatedTskEvent event)
void publishPersonsAddedEvent(TskEvent.PersonsAddedTskEvent event)
void publicTagSetsDeleted(TskEvent.TagSetsDeletedTskEvent event)
void publicTagSetsAdded(TskEvent.TagSetsAddedTskEvent event)
void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event)
void publicTagNamesAdded(TskEvent.TagNamesAddedTskEvent event)
void publicTagNamesUpdated(TskEvent.TagNamesUpdatedTskEvent event)
void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event)
void publishOsAccountDeletedEvent(TskEvent.OsAccountsDeletedTskEvent event)
Thread newThread(Runnable task)
TaskThreadFactory(String threadName)
String getCaseDisplayName()
static boolean pathExists(String filePath)
static void openAsCurrentCase(String caseMetadataFilePath)
static final String EVENT_CHANNEL_NAME
static String getAutopsyVersion()
void notifyContentTagAdded(ContentTag newTag, List< ContentTag > deletedTagList)
String getExaminerEmail()
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
String getOrCreateSubdirectory(String subDirectoryName)
static void closeCurrentCase()
static void deleteMultiUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyFailedAddingDataSource(UUID addingDataSourceEventId)
static final int CASE_RESOURCES_LOCK_TIMEOUT_HOURS
static String displayNameToUniqueName(String caseDisplayName)
Set< TimeZone > getTimeZones()
Case(CaseMetadata caseMetaData)
String getLogDirectoryPath()
void doOpenCaseAction(String progressIndicatorTitle, CaseAction< ProgressIndicator, Object, Void > caseAction, CaseLockType caseLockType, boolean allowCancellation, Object additionalParams)
static void deleteMultiUserCaseDirectory(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
Void open(ProgressIndicator progressIndicator, Object additionalParams)
void deleteReports(Collection<? extends Report > reports, boolean deleteFromDisk)
static final String MODULE_FOLDER
static volatile Case currentCase
volatile ExecutorService caseActionExecutor
static final String CASE_RESOURCES_THREAD_NAME
final CaseMetadata metadata
String getTextIndexName()
static void setDeletedItemFlag(CaseNodeData caseNodeData, CaseNodeData.DeletedFlags flag)
void openFileSystemsInBackground()
List< Content > getDataSources()
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
static void deleteMultiUserCaseTextIndex(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
Case(CaseType caseType, String caseDir, CaseDetails caseDetails)
static Future<?> backgroundOpenFileSystemsFuture
volatile boolean hasDataSource
static void updateGUIForCaseOpened(Case newCurrentCase)
static void deleteFromRecentCases(CaseMetadata metadata, ProgressIndicator progressIndicator)
static final String TEMP_FOLDER
SleuthkitCase createPortableCase(String caseName, File portableCaseFolder)
SleuthkitCase getSleuthkitCase()
void updateCaseNodeData(ProgressIndicator progressIndicator)
static final String EXPORT_FOLDER
static void addEventSubscriber(String eventName, PropertyChangeListener subscriber)
List< Report > getAllReports()
static final String SINGLE_USER_CASE_DB_NAME
static void invokeStartupDialog()
static void removeEventSubscriber(String eventName, PropertyChangeListener subscriber)
static void openAsCurrentCase(Case newCurrentCase, boolean isNewCase)
static void open(String caseMetadataFilePath)
void createCaseDatabase(ProgressIndicator progressIndicator)
void notifyContentTagDeleted(ContentTag deletedTag)
String getExaminerPhone()
String getModuleOutputDirectoryRelativePath()
static final String CACHE_FOLDER
static String getNameForTitle()
static String getAppName()
String getModulesOutputDirAbsPath()
static void removePropertyChangeListener(PropertyChangeListener listener)
void notifyDataSourceNameChanged(Content dataSource, String newName)
void notifyAddingDataSource(UUID eventId)
void createCaseNodeData(ProgressIndicator progressIndicator)
static boolean isValidName(String caseName)
static void updateGUIForCaseClosed()
static void checkForCancellation()
Report addReport(String localPath, String srcModuleName, String reportName, Content parent)
static final String NO_NODE_ERROR_MSG_FRAGMENT
static final Object caseActionSerializationLock
static Case getCurrentCaseThrows()
static final String REPORTS_FOLDER
CaseMetadata getMetadata()
static void deleteCurrentCase()
void createCaseDirectoryIfDoesNotExist(ProgressIndicator progressIndicator)
void addReport(String localPath, String srcModuleName, String reportName)
static String getModulesOutputDirRelPath()
static void createCaseDirectory(String caseDirPath, CaseType caseType)
static Case getCurrentCase()
final SleuthkitEventListener sleuthkitEventListener
static final Logger logger
static void removeEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
String getCaseDirectory()
void openCommunicationChannels(ProgressIndicator progressIndicator)
static final AutopsyEventPublisher eventPublisher
static final ExecutorService openFileSystemsExecutor
static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
static final String APP_NAME
static void addPropertyChangeListener(PropertyChangeListener listener)
static boolean existsCurrentCase()
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
Set< TimeZone > getTimeZone()
static String convertTimeZone(String timeZoneId)
static final String LOG_FOLDER
void close(ProgressIndicator progressIndicator)
void updateDataParameters()
String getCacheDirectory()
static void deleteTextIndex(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag, List< BlackboardArtifactTag > removedTagList)
static boolean isCaseOpen()
static final String CONFIG_FOLDER
String getConfigDirectory()
void notifyTagDefinitionChanged(String changedTagName)
static void deleteCase(CaseMetadata metadata)
static CoordinationService.Lock acquireCaseResourcesLock(String caseDir)
String getModuleDirectory()
static PropertyChangeSupport getPropertyChangeSupport()
static volatile Frame mainFrame
void deleteReports(Collection<? extends Report > reports)
void notifyCentralRepoCommentChanged(long contentId, String newComment)
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
static void deleteMultiUserCaseDatabase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
void notifyContentTagAdded(ContentTag newTag)
void openAppServiceCaseResources(ProgressIndicator progressIndicator, boolean isNewCase)
String getTempDirectory()
static final String CASE_ACTION_THREAD_NAME
String getExportDirectory()
static final int CASE_LOCK_TIMEOUT_MINS
void throwIfConcurrentDbAccessException(Exception ex)
boolean dbHasDataSource()
void closeAppServiceCaseResources()
void saveCaseMetadataToFile(ProgressIndicator progressIndicator)
void acquireCaseLock(CaseLockType lockType)
String getReportDirectory()
static void deleteSingleUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
static void createAsCurrentCase(CaseType caseType, String caseDir, CaseDetails caseDetails)
String getOutputDirectory()
static boolean isNoNodeException(CoordinationServiceException ex)
static boolean deleteMultiUserCase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
CollaborationMonitor collaborationMonitor
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
void switchLoggingToCaseLogsDirectory(ProgressIndicator progressIndicator)
void deleteTempfilesFromCaseDirectory(ProgressIndicator progressIndicator)
Image addImage(String imgPath, long imgId, String timeZone)
void notifyDataSourceAdded(Content dataSource, UUID addingDataSourceEventId)
Path getBaseSystemTempPath()
static void deleteCaseDirectory(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag)
void openCaseDataBase(ProgressIndicator progressIndicator)
void openCaseLevelServices(ProgressIndicator progressIndicator)
CoordinationService.Lock caseLock
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Void create(ProgressIndicator progressIndicator, Object additionalParams)
static StartupWindowProvider getInstance()
void setDeletedFlag(DeletedFlags flag)
void setLastAccessDate(Date lastAccessDate)
static CaseNodeData createCaseNodeData(final CaseMetadata metadata)
boolean isDeletedFlagSet(DeletedFlags flag)
static void writeCaseNodeData(CaseNodeData nodeData)
static CaseNodeData readCaseNodeData(String nodePath)
static String getCaseResourcesNodePath(Path caseDirectoryPath)
static String getCaseDirectoryNodePath(Path caseDirectoryPath)
KeywordSearchService getKeywordSearchService()
Lock tryGetExclusiveLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
Lock tryGetSharedLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
void deleteNode(CategoryNode category, String nodePath)
static synchronized CoordinationService getInstance()
static boolean runningWithGUI
static boolean getIsMultiUserModeEnabled()
static CaseDbConnectionInfo getDatabaseConnectionInfo()
static String getAppName()
static void openCoreWindows()
static void closeCoreWindows()
static boolean driveExists(String path)
static boolean deleteDir(File dirPath)
synchronized static Logger getLogger(String name)
synchronized static void setLogDirectory(String directoryPath)
static void error(String message)
static void error(String title, String message)
static String getLocalHostName()
static void shutDownTaskExecutor(ExecutorService executor)
static String convertToAlphaNumericFormat(String timeZoneId)
static String getVersion()
static synchronized DirectoryTreeTopComponent findInstance()
static boolean canAddDataSources()
static boolean canDeleteCurrentCase()
static synchronized IngestManager getInstance()
void cancelAllIngestJobs(IngestJob.CancellationReason reason)
static String getCustomTempDirectory()
static TempDirChoice getTempDirChoice()
static CaseType fromString(String typeName)
String getLocalizedDisplayName()
CaseType(String typeName)
boolean equalsName(String otherTypeName)
HOSTS_REMOVED_FROM_PERSON
ADDING_DATA_SOURCE_FAILED
BLACKBOARD_ARTIFACT_TAG_DELETED
BLACKBOARD_ARTIFACT_TAG_ADDED
R execute(T progressIndicator, V additionalParams)
void deleteDataSource(Long dataSourceId)
void start(String message, int totalWorkUnits)
void progress(String message)