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)