19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.Cursor;
22 import java.awt.Frame;
23 import java.beans.PropertyChangeListener;
24 import java.beans.PropertyChangeSupport;
25 import java.io.BufferedInputStream;
27 import java.io.FileInputStream;
28 import java.io.IOException;
29 import java.nio.file.InvalidPathException;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.text.DateFormat;
33 import java.text.SimpleDateFormat;
34 import java.util.Date;
35 import java.util.Collection;
36 import java.util.GregorianCalendar;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
42 import java.util.TimeZone;
43 import java.util.UUID;
44 import java.util.logging.Level;
45 import java.util.stream.Collectors;
46 import java.util.stream.Stream;
47 import javax.swing.JOptionPane;
48 import javax.swing.SwingUtilities;
49 import org.apache.commons.io.FileUtils;
50 import org.openide.util.NbBundle;
51 import org.openide.util.actions.CallableSystemAction;
52 import org.openide.windows.WindowManager;
84 import org.
sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
93 public class Case implements SleuthkitCase.ErrorObserver {
221 @NbBundle.Messages({
"Case_caseType_singleUser=Single-user case",
222 "Case_caseType_multiUser=Multi-user case"})
235 return (otherType == null) ?
false : caseType.equals(otherType);
239 if (typeName != null) {
241 if (typeName.equalsIgnoreCase(c.caseType)) {
255 if (fromString(caseType) == SINGLE_USER_CASE) {
256 return Bundle.Case_caseType_singleUser();
258 return Bundle.Case_caseType_multiUser();
267 private final XMLCaseManagement
xmlcm;
268 private final SleuthkitCase
db;
274 static final String CASE_EXTENSION =
"aut";
275 static final String CASE_DOT_EXTENSION =
"." + CASE_EXTENSION;
279 final static String MODULE_FOLDER =
"ModuleOutput";
291 private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db,
CaseType type) {
297 this.caseType = type;
310 if (currentCase != null) {
313 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"));
323 return currentCase != null;
337 if (oldCase != null) {
338 SwingUtilities.invokeLater(() -> {
339 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
356 if (newCase != null) {
357 currentCase = newCase;
364 currentCase.
tskErrorReporter =
new IntervalErrorReportData(currentCase, MIN_SECONDS_BETWEEN_ERROR_REPORTS,
365 NbBundle.getMessage(
Case.class,
"IntervalErrorReport.ErrorText"));
367 SwingUtilities.invokeLater(() -> {
368 RecentCases.getInstance().addRecentCase(currentCase.
name, currentCase.
configFilePath);
381 logger.log(Level.SEVERE,
"Failed to setup for collaboration", ex);
382 MessageNotifyUtil.
Notify.
error(NbBundle.getMessage(
Case.class,
"Case.CollaborationSetup.FailNotify.Title"), NbBundle.getMessage(
Case.class,
"Case.CollaborationSetup.FailNotify.ErrMsg"));
390 SwingUtilities.invokeLater(() -> {
391 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
402 if (null != tskErrorReporter) {
403 tskErrorReporter.addProblems(context, errorMessage);
407 AddImageProcess makeAddImageProcess(String timezone,
boolean processUnallocSpace,
boolean noFatOrphans) {
408 return this.db.makeAddImageProcess(timezone, processUnallocSpace, noFatOrphans);
454 logger.log(Level.INFO,
"Creating case with case directory {0}, caseName {1}",
new Object[]{caseDir, caseName});
459 if (
new File(caseDir).exists() ==
false) {
460 Case.createCaseDirectory(caseDir, caseType);
468 String santizedCaseName = sanitizeCaseName(caseName);
469 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
470 Date date =
new Date();
471 String indexName = santizedCaseName +
"_" + dateFormat.format(date);
472 String dbName = null;
474 dbName = caseDir + File.separator +
"autopsy.db";
485 String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION;
486 XMLCaseManagement xmlcm =
new XMLCaseManagement();
487 xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName);
493 SleuthkitCase db = null;
496 db = SleuthkitCase.newCase(dbName);
500 }
catch (TskCoreException ex) {
501 logger.log(Level.SEVERE, String.format(
"Error creating a case %s in %s ", caseName, caseDir), ex);
502 SwingUtilities.invokeLater(() -> {
503 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
511 logger.log(Level.SEVERE,
"Error accessing case database connection info", ex);
512 SwingUtilities.invokeLater(() -> {
513 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
518 Case newCase =
new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
550 static String sanitizeCaseName(String caseName) {
555 result = caseName.replaceAll(
"[^\\p{ASCII}]",
"_");
558 result = result.replaceAll(
"[\\p{Cntrl}]",
"_");
561 result = result.replaceAll(
"[ /?:'\"\\\\]",
"_");
564 result = result.toLowerCase();
567 if (result.length() > 0 && !(Character.isLetter(result.codePointAt(0))) && !(result.codePointAt(0) ==
'_')) {
568 result =
"_" + result;
573 result = result.substring(0, MAX_SANITIZED_NAME_LENGTH);
576 if (result.isEmpty()) {
596 logger.log(Level.INFO,
"Opening case with metadata file path {0}", caseMetadataFilePath);
601 if (!caseMetadataFilePath.endsWith(CASE_DOT_EXTENSION)) {
602 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.open.exception.checkFile.msg", CASE_DOT_EXTENSION));
621 String dbPath = Paths.get(caseDir,
"autopsy.db").toString();
622 db = SleuthkitCase.openCase(dbPath);
643 if (null != db.getBackupDatabasePath()) {
644 SwingUtilities.invokeLater(() -> {
645 JOptionPane.showMessageDialog(
646 WindowManager.getDefault().getMainWindow(),
647 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg", db.getBackupDatabasePath()),
648 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
649 JOptionPane.INFORMATION_MESSAGE);
658 Map<Long, String> imgPaths = getImagePaths(db);
659 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
660 long obj_id = entry.getKey();
661 String path = entry.getValue();
662 boolean fileExists = (
pathExists(path) || driveExists(path));
664 int ret = JOptionPane.showConfirmDialog(
665 WindowManager.getDefault().getMainWindow(),
666 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.msg",
getAppName(), path),
667 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.title"),
668 JOptionPane.YES_NO_OPTION);
669 if (ret == JOptionPane.YES_OPTION) {
670 MissingImageDialog.makeDialog(obj_id, db);
672 logger.log(Level.WARNING,
"Selected image files don't match old files!");
682 XMLCaseManagement xmlcm =
new XMLCaseManagement();
683 xmlcm.open(caseMetadataFilePath);
684 Case openedCase =
new Case(caseName, caseNumber, examiner, caseMetadataFilePath, xmlcm, db, caseType);
689 }
catch (TskCoreException ex) {
690 SwingUtilities.invokeLater(() -> {
691 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
701 static Map<Long, String> getImagePaths(SleuthkitCase db) {
702 Map<Long, String> imgPaths =
new HashMap<>();
704 Map<Long, List<String>> imgPathsList = db.getImagePaths();
705 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
706 if (entry.getValue().size() > 0) {
707 imgPaths.put(entry.getKey(), entry.getValue().get(0));
710 }
catch (TskException ex) {
711 logger.log(Level.WARNING,
"Error getting image paths", ex);
729 Image newDataSource = db.getImageById(imgId);
731 return newDataSource;
732 }
catch (Exception ex) {
733 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
748 void addLocalDataSource(Content newDataSource) {
864 }
catch (Exception e) {
865 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.closeCase.exception.msg"), e);
877 logger.log(Level.INFO,
"Deleting case.\ncaseDir: {0}", caseDir);
882 boolean result = deleteCaseDirectory(caseDir);
884 RecentCases.getInstance().removeRecentCase(this.name, this.configFilePath);
886 if (result ==
false) {
888 NbBundle.getMessage(
this.getClass(),
"Case.deleteCase.exception.msg", caseDir));
890 }
catch (Exception ex) {
891 logger.log(Level.SEVERE,
"Error deleting the current case dir: " + caseDir, ex);
892 throw new CaseActionException(
893 NbBundle.getMessage(
this.getClass(),
"Case.deleteCase.exception.msg2", caseDir), ex);
907 void updateCaseName(String oldCaseName, String oldPath, String newCaseName, String newPath)
throws CaseActionException {
909 xmlcm.setCaseName(newCaseName);
911 eventPublisher.
publish(
new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName));
912 SwingUtilities.invokeLater(() -> {
914 RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath);
916 }
catch (Exception e) {
917 Logger.getLogger(
Case.class.getName()).log(Level.WARNING,
"Error: problem updating case name.", e);
920 }
catch (Exception e) {
921 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.updateCaseName.exception.msg"), e);
933 void updateExaminer(String oldExaminer, String newExaminer)
throws CaseActionException {
935 xmlcm.setCaseExaminer(newExaminer);
936 examiner = newExaminer;
937 eventPublisher.
publish(
new AutopsyEvent(Events.EXAMINER.toString(), oldExaminer, newExaminer));
938 }
catch (Exception e) {
939 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.updateExaminer.exception.msg"), e);
951 void updateCaseNumber(String oldCaseNumber, String newCaseNumber)
throws CaseActionException {
953 xmlcm.setCaseNumber(newCaseNumber);
954 number = newCaseNumber;
955 eventPublisher.
publish(
new AutopsyEvent(Events.NUMBER.toString(), oldCaseNumber, newCaseNumber));
956 }
catch (Exception e) {
957 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.updateCaseNum.exception.msg"), e);
967 return currentCase != null;
976 configFilePath = givenPath;
984 String getConfigFilePath() {
1003 if ((appName == null) || appName.equals(
"")) {
1004 appName = WindowManager.getDefault().getMainWindow().getTitle();
1042 if (xmlcm == null) {
1045 return xmlcm.getCaseDirectory();
1137 if (!theDirectory.exists()) {
1138 theDirectory.mkdirs();
1140 return theDirectory.toString();
1155 thePath = Paths.get(MODULE_FOLDER);
1159 return thePath.toString();
1176 hostPath = Paths.get(caseDirectory);
1178 if (!hostPath.toFile().exists()) {
1179 hostPath.toFile().mkdirs();
1181 return hostPath.toString();
1208 return "ModuleOutput";
1222 return new PropertyChangeSupport(
Case.class);
1233 List<Content> list = db.getRootObjects();
1234 hasData = (list.size() > 0);
1244 if (xmlcm == null) {
1247 return xmlcm.getCreatedDate();
1257 if (xmlcm == null) {
1260 return xmlcm.getTextIndexName();
1270 Set<TimeZone> timezones =
new HashSet<>();
1273 final Content dataSource = c.getDataSource();
1274 if ((dataSource != null) && (dataSource instanceof Image)) {
1275 Image image = (Image) dataSource;
1276 timezones.add(TimeZone.getTimeZone(image.getTimeZone()));
1279 }
catch (TskCoreException ex) {
1280 logger.log(Level.INFO,
"Error getting time zones", ex);
1294 .map(Events::toString)
1295 .collect(Collectors.toSet()), listener);
1307 .map(Events::toString)
1308 .collect(Collectors.toSet()), listener);
1363 return new File(imgPath).isFile();
1368 private static final String
pdisk =
"\\\\.\\physicaldrive";
1369 private static final String
dev =
"/dev/";
1371 static boolean isPhysicalDrive(String path) {
1372 return path.toLowerCase().startsWith(pdisk)
1373 || path.toLowerCase().startsWith(dev);
1379 static boolean isPartition(String path) {
1380 return path.toLowerCase().startsWith(
"\\\\.\\")
1381 && path.toLowerCase().endsWith(
":");
1391 static boolean driveExists(String path) {
1393 BufferedInputStream br = null;
1395 File tmp =
new File(path);
1396 br =
new BufferedInputStream(
new FileInputStream(tmp));
1399 }
catch (Exception ex) {
1406 }
catch (IOException ex) {
1422 TimeZone zone = TimeZone.getTimeZone(timezoneID);
1423 int offset = zone.getRawOffset() / 1000;
1424 int hour = offset / 3600;
1425 int min = (offset % 3600) / 60;
1427 DateFormat dfm =
new SimpleDateFormat(
"z");
1428 dfm.setTimeZone(zone);
1429 boolean hasDaylight = zone.useDaylightTime();
1430 String first = dfm.format(
new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3);
1431 String second = dfm.format(
new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3);
1432 int mid = hour * -1;
1433 String result = first + Integer.toString(mid);
1435 result = result +
":" + Integer.toString(min);
1438 result = result + second;
1454 static void createCaseDirectory(String caseDir, String caseName)
throws CaseActionException {
1466 static void createCaseDirectory(String caseDir, CaseType caseType)
throws CaseActionException {
1468 File caseDirF =
new File(caseDir);
1469 if (caseDirF.exists()) {
1470 if (caseDirF.isFile()) {
1471 throw new CaseActionException(
1472 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existNotDir", caseDir));
1473 }
else if (!caseDirF.canRead() || !caseDirF.canWrite()) {
1474 throw new CaseActionException(
1475 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existCantRW", caseDir));
1480 boolean result = (caseDirF).mkdirs();
1481 if (result ==
false) {
1482 throw new CaseActionException(
1483 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreate", caseDir));
1487 String hostClause =
"";
1490 hostClause = File.separator + NetworkUtils.getLocalHostName();
1492 result = result && (
new File(caseDir + hostClause + File.separator + EXPORT_FOLDER)).mkdirs()
1493 && (
new File(caseDir + hostClause + File.separator + LOG_FOLDER)).mkdirs()
1494 && (
new File(caseDir + hostClause + File.separator + TEMP_FOLDER)).mkdirs()
1495 && (
new File(caseDir + hostClause + File.separator + CACHE_FOLDER)).mkdirs();
1497 if (result ==
false) {
1498 throw new CaseActionException(
1499 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", caseDir));
1502 final String modulesOutDir = caseDir + hostClause + File.separator + MODULE_FOLDER;
1503 result =
new File(modulesOutDir).mkdir();
1504 if (result ==
false) {
1505 throw new CaseActionException(
1506 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateModDir",
1510 final String reportsOutDir = caseDir + hostClause + File.separator +
REPORTS_FOLDER;
1511 result =
new File(reportsOutDir).mkdir();
1512 if (result ==
false) {
1513 throw new CaseActionException(
1514 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateReportsDir",
1518 }
catch (Exception e) {
1519 throw new CaseActionException(
1520 NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.gen", caseDir), e);
1531 static boolean deleteCaseDirectory(File casePath) {
1532 logger.log(Level.INFO,
"Deleting case directory: {0}", casePath.getAbsolutePath());
1533 return FileUtil.deleteDir(casePath);
1551 return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
1552 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
1553 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
1558 if (tempFolder.isDirectory()) {
1559 File[] files = tempFolder.listFiles();
1560 if (files.length > 0) {
1561 for (File file : files) {
1562 if (file.isDirectory()) {
1563 deleteCaseDirectory(file);
1579 File modulesOutputDirF =
new File(modulesOutputDir);
1580 if (!modulesOutputDirF.exists()) {
1581 logger.log(Level.INFO,
"Creating modules output dir for the case.");
1584 if (!modulesOutputDirF.mkdir()) {
1585 logger.log(Level.SEVERE,
"Error creating modules output dir for the case, dir: {0}", modulesOutputDir);
1587 }
catch (SecurityException e) {
1588 logger.log(Level.SEVERE,
"Error creating modules output dir for the case, dir: " + modulesOutputDir, e);
1595 logger.log(Level.INFO,
"Changing Case to: {0}", toChangeTo);
1596 if (toChangeTo != null) {
1606 CallableSystemAction.get(CasePropertiesAction.class).setEnabled(
true);
1607 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
true);
1611 SwingUtilities.invokeLater(() -> {
1616 SwingUtilities.invokeLater(() -> {
1623 SwingUtilities.invokeLater(() -> {
1627 SwingUtilities.invokeLater(() -> {
1628 Frame f = WindowManager.getDefault().getMainWindow();
1636 SwingUtilities.invokeLater(() -> {
1641 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
1643 CallableSystemAction.get(CasePropertiesAction.class).setEnabled(
false);
1644 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
1649 SwingUtilities.invokeLater(() -> {
1653 SwingUtilities.invokeLater(() -> {
1654 Frame f = WindowManager.getDefault().getMainWindow();
1671 if (!newCaseName.equals(
"")) {
1672 Frame f = WindowManager.getDefault().getMainWindow();
1687 public void addReport(String localPath, String srcModuleName, String reportName)
throws TskCoreException {
1688 String normalizedLocalPath;
1690 normalizedLocalPath = Paths.get(localPath).normalize().toString();
1691 }
catch (InvalidPathException ex) {
1692 String errorMsg =
"Invalid local path provided: " + localPath;
1693 throw new TskCoreException(errorMsg, ex);
1695 Report report = this.db.addReport(normalizedLocalPath, srcModuleName, reportName);
1700 return this.db.getAllReports();
1713 public void deleteReports(Collection<? extends Report> reports,
boolean deleteFromDisk)
throws TskCoreException {
1715 String pathToReportsFolder = Paths.get(this.db.getDbDirPath(),
"Reports").normalize().toString();
1716 for (Report report : reports) {
1719 this.db.deleteReport(report);
1721 if (deleteFromDisk) {
1723 String reportPath = report.getPath();
1724 while (!Paths.get(reportPath,
"..").normalize().toString().equals(pathToReportsFolder)) {
1725 reportPath = Paths.get(reportPath,
"..").normalize().toString();
1730 FileUtils.deleteDirectory(
new File(reportPath));
1731 }
catch (IOException | SecurityException ex) {
1732 logger.log(Level.WARNING, NbBundle.getMessage(
Case.class,
"Case.deleteReports.deleteFromDiskException.log.msg"), ex);
1733 JOptionPane.showMessageDialog(null, NbBundle.getMessage(
Case.class,
"Case.deleteReports.deleteFromDiskException.msg", report.getReportName(), reportPath));
1751 }
catch (TskCoreException ex) {
String getLogDirectoryPath()
boolean equalsName(String otherType)
static final AutopsyEventPublisher eventPublisher
List< Content > getDataSources()
String getModuleOutputDirectoryRelativePath()
void notifyContentTagDeleted(ContentTag deletedTag)
static CaseType fromString(String typeName)
static String convertTimeZone(String timezoneID)
void publishLocally(AutopsyEvent event)
void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag)
Image addImage(String imgPath, long imgId, String timeZone)
static final String propStartup
static synchronized IngestManager getInstance()
String getTempDirectory()
void cancelAllIngestJobs()
static boolean existsCurrentCase()
Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db, CaseType type)
static final Logger logger
void publish(AutopsyEvent event)
String getLocalizedDisplayName()
ADDING_DATA_SOURCE_FAILED
static final String EXPORT_FOLDER
String getCaseDirectory()
static void openCoreWindows()
void addSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
synchronized static void setLogDirectory(String directoryPath)
static final String CACHE_FOLDER
static String getAutopsyVersion()
String getReportDirectory()
static boolean getIsMultiUserModeEnabled()
void setConfigFilePath(String givenPath)
void addReport(String localPath, String srcModuleName, String reportName)
static CaseDbConnectionInfo getDatabaseConnectionInfo()
String getModulesOutputDirAbsPath()
static void changeCase(Case newCase)
void deleteReports(Collection<?extends Report > reports, boolean deleteFromDisk)
volatile IntervalErrorReportData tskErrorReporter
List< Report > getAllReports()
static boolean isValidName(String caseName)
CollaborationMonitor collaborationMonitor
static void closeCoreWindows()
static String getModulesOutputDirRelPath()
Set< TimeZone > getTimeZone()
static void updateMainWindowTitle(String newCaseName)
static void invokeStartupDialog()
void openRemoteEventChannel(String channelName)
static boolean coreComponentsAreActive()
static void removeEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
SleuthkitCase getSleuthkitCase()
static void checkSubFolders(Case openedCase)
void closeRemoteEventChannel()
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
static PropertyChangeSupport getPropertyChangeSupport()
String getCacheDirectory()
void removeSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
String getModuleDirectory()
String getDirectory(String input)
static void removeEventSubscriber(String eventName, PropertyChangeListener subscriber)
static synchronized void removePropertyChangeListener(PropertyChangeListener listener)
static final int MAX_SANITIZED_NAME_LENGTH
static boolean pathExists(String imgPath)
BLACKBOARD_ARTIFACT_TAG_ADDED
static void open(String caseMetadataFilePath)
static final int MIN_SECONDS_BETWEEN_ERROR_REPORTS
final XMLCaseManagement xmlcm
String getOutputDirectory()
static void error(String title, String message)
static synchronized void addPropertyChangeListener(PropertyChangeListener listener)
static void create(String caseDir, String caseName, String caseNumber, String examiner)
static final String autopsyVer
static final String EVENT_CHANNEL_NAME
void notifyFailedAddingDataSource(UUID dataSourceId)
static Case getCurrentCase()
static String getLocalHostName()
synchronized static Logger getLogger(String name)
void notifyDataSourceAdded(Content newDataSource, UUID dataSourceId)
static final String LOG_FOLDER
void receiveError(String context, String errorMessage)
static String getAppName()
static String getVersion()
String getExportDirectory()
static void clearTempFolder()
static void addEventSubscriber(String eventName, PropertyChangeListener subscriber)
void notifyContentTagAdded(ContentTag newTag)
static StartupWindowProvider getInstance()
String getHostDirectory()
static void create(String caseDir, String caseName, String caseNumber, String examiner, CaseType caseType)
void notifyAddingDataSource(UUID dataSourceId)
static final String pdisk
static boolean isCaseOpen()
String getTextIndexName()
static final String REPORTS_FOLDER
static final String TEMP_FOLDER
BLACKBOARD_ARTIFACT_TAG_DELETED
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
static void doCaseChange(Case toChangeTo)