1 /*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2011-2015 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 package org.sleuthkit.autopsy.casemodule;
20
21 import java.awt.Frame;
22 import java.beans.PropertyChangeListener;
23 import java.beans.PropertyChangeSupport;
24 import java.io.BufferedInputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.text.DateFormat;
29 import java.text.SimpleDateFormat;
30 import java.util.GregorianCalendar;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.TimeZone;
37 import java.util.logging.Level;
38 import javax.swing.JOptionPane;
39 import javax.swing.SwingUtilities;
40 import org.openide.util.Lookup;
41 import org.openide.util.NbBundle;
42 import org.openide.util.actions.CallableSystemAction;
43 import org.openide.util.actions.SystemAction;
44 import org.openide.windows.WindowManager;
54
60 @SuppressWarnings("deprecation") // TODO: Remove this when ErrorObserver is replaced.
62
63 private static final String autopsyVer =
Version.
getVersion();
// current version of autopsy. Change it when the version is changed
64 private static String appName = null;
65
70 public static final String propStartup =
"LBL_StartupDialog";
//NON-NLS
71 // pcs is initialized in CaseListener constructor
72 private static final PropertyChangeSupport pcs =
new PropertyChangeSupport(
Case.class);
73
79
87 // @@@ BC: I propose that this is no longer called for case open/close.
131
132 private String name;
136 private final XMLCaseManagement
xmlcm;
138 // Track the current case (only set with changeCase() method)
139 private static Case currentCase = null;
142 static final String CASE_EXTENSION = "aut"; //NON-NLS
143 static final String CASE_DOT_EXTENSION = "." + CASE_EXTENSION;
144
145 // we cache if the case has data in it yet since a few places ask for it and we dont' need to keep going to DB
146 private boolean hasData =
false;
147
151 private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm,
SleuthkitCase db) {
152 this.name = name;
153 this.number = number;
154 this.examiner = examiner;
155 this.configFilePath = configFilePath;
156 this.xmlcm = xmlcm;
157 this.db = db;
159 }
160
167 }
168
177 if (currentCase != null) {
178 return currentCase;
179 } else {
180 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"));
181 }
182 }
183
190 return currentCase != null;
191 }
192
201
202 // close the existing case
205 if (oldCase != null) {
206 doCaseChange(null); //closes windows, etc
207
208 try {
210 } catch (Exception e) {
211 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
213 NbBundle.getMessage(
Case.class,
214 "Case.changeCase.errListenToCaseUpdates.msg"),
216 }
217 doCaseNameChange("");
218
219 try {
221 } catch (Exception e) {
222 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
224 NbBundle.getMessage(
Case.class,
225 "Case.changeCase.errListenToCaseUpdates.msg"),
227 }
228 }
229
230 if (newCase != null) {
231 currentCase = newCase;
232
234
235 try {
237 } catch (Exception e) {
238 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
240 NbBundle.getMessage(
Case.class,
241 "Case.changeCase.errListenToCaseUpdates.msg"),
243 }
244 doCaseChange(currentCase);
245
246 try {
247 pcs.firePropertyChange(
Events.
NAME.toString(),
"", currentCase.
name);
248 } catch (Exception e) {
249 logger.log(Level.SEVERE, "Case threw exception", e); //NON-NLS
251 NbBundle.getMessage(
Case.class,
252 "Case.changeCase.errListenToCaseUpdates.msg"),
254 }
255 doCaseNameChange(currentCase.
name);
256
257 RecentCases.getInstance().addRecentCase(currentCase.
name, currentCase.
configFilePath);
// update the recent cases
258 } else {
260 }
261 }
262
263 AddImageProcess makeAddImageProcess(String timezone,
boolean processUnallocSpace,
boolean noFatOrphans) {
265 }
266
278 logger.log(Level.INFO, "Creating new case.\ncaseDir: {0}\ncaseName: {1}", new Object[]{caseDir, caseName}); //NON-NLS
279
280 // create case directory if it doesn't already exist.
281 if (new File(caseDir).exists() == false) {
282 Case.createCaseDirectory(caseDir);
283 }
284
285 String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION;
286
287 XMLCaseManagement xmlcm = new XMLCaseManagement();
288 xmlcm.create(caseDir, caseName, examiner, caseNumber); // create a new XML config file
289 xmlcm.writeFile();
290
291 String dbPath = caseDir + File.separator + "autopsy.db"; //NON-NLS
293 try {
296 logger.log(Level.SEVERE, "Error creating a case: " + caseName + " in dir " + caseDir, ex); //NON-NLS
298 NbBundle.getMessage(
Case.class,
"Case.create.exception.msg", caseName, caseDir), ex);
299 }
300
305 Case newCase =
new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
307
308 changeCase(newCase);
309 }
310
319 logger.log(Level.INFO, "Opening case.\nconfigFilePath: {0}", configFilePath); //NON-NLS
320
321 try {
322 XMLCaseManagement xmlcm = new XMLCaseManagement();
323
324 xmlcm.open(configFilePath); // open and load the config file to the document handler in the XML class
325 xmlcm.writeFile(); // write any changes to the config file
326
327 String caseName = xmlcm.getCaseName();
328 String caseNumber = xmlcm.getCaseNumber();
329 String examiner = xmlcm.getCaseExaminer();
330 // if the caseName is "", case / config file can't be opened
331 if (caseName.equals("")) {
333 }
334
335 String caseDir = xmlcm.getCaseDirectory();
336 String dbPath = caseDir + File.separator + "autopsy.db"; //NON-NLS
339 JOptionPane.showMessageDialog(null,
340 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg",
342 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
343 JOptionPane.INFORMATION_MESSAGE);
344 }
345
346 checkImagesExist(db);
347
352 Case openedCase =
new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
354
355 changeCase(openedCase);
356
357 } catch (Exception ex) {
358 logger.log(Level.SEVERE, "Error opening the case: ", ex); //NON-NLS
359 // close the previous case if there's any
360 CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class);
361 closeCase.actionPerformed(null);
362 if (!configFilePath.endsWith(CASE_DOT_EXTENSION)) {
364 NbBundle.getMessage(
Case.class,
"Case.open.exception.checkFile.msg", CASE_DOT_EXTENSION), ex);
365 } else {
366 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.open.exception.gen.msg") +
". " + ex.getMessage(), ex);
367 }
368 }
369 }
370
371 static Map<Long, String> getImagePaths(
SleuthkitCase db) {
//TODO: clean this up
372 Map<Long, String> imgPaths = new HashMap<>();
373 try {
375 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
376 if (entry.getValue().size() > 0) {
377 imgPaths.put(entry.getKey(), entry.getValue().get(0));
378 }
379 }
381 logger.log(Level.WARNING, "Error getting image paths", ex); //NON-NLS
382 }
383 return imgPaths;
384 }
385
390 Map<Long, String> imgPaths = getImagePaths(db);
391 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
392 long obj_id = entry.getKey();
393 String path = entry.getValue();
394 boolean fileExists = (pathExists(path)
395 || driveExists(path));
396 if (!fileExists) {
397 int ret = JOptionPane.showConfirmDialog(null,
398 NbBundle.getMessage(
Case.class,
399 "Case.checkImgExist.confDlg.doesntExist.msg",
400 appName, path),
401 NbBundle.getMessage(
Case.class,
402 "Case.checkImgExist.confDlg.doesntExist.title"),
403 JOptionPane.YES_NO_OPTION);
404 if (ret == JOptionPane.YES_OPTION) {
405
406 MissingImageDialog.makeDialog(obj_id, db);
407
408 } else {
409 logger.log(Level.WARNING, "Selected image files don't match old files!"); //NON-NLS
410 }
411
412 }
413 }
414 }
415
424 @Deprecated
426 logger.log(Level.INFO, "Adding image to Case. imgPath: {0} ID: {1} TimeZone: {2}", new Object[]{imgPath, imgId, timeZone}); //NON-NLS
427
428 try {
430
431 try {
432 pcs.firePropertyChange(
Events.
DATA_SOURCE_ADDED.toString(), null, newImage);
// the new value is the instance of the image
433 } catch (Exception e) {
434 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
436 NbBundle.getMessage(this.getClass(),
437 "Case.changeCase.errListenToCaseUpdates.msg"),
439 }
441 return newImage;
442 } catch (Exception ex) {
443 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
444 }
445 }
446
453 @Deprecated
454 void addLocalDataSource(
Content newDataSource) {
455
456 notifyNewDataSource(newDataSource);
457 }
458
465 void notifyNewDataSource(
Content newDataSource) {
466
467 try {
468 pcs.firePropertyChange(Events.DATA_SOURCE_ADDED.toString(), null, newDataSource);
469 } catch (Exception e) {
470 logger.log(Level.SEVERE, "Case threw exception", e); //NON-NLS
471 MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
472 NbBundle.getMessage(this.getClass(),
473 "Case.changeCase.errListenToCaseUpdates.msg"),
474 MessageNotifyUtil.MessageType.ERROR);
475 }
476 CoreComponentControl.openCoreWindows();
477 }
478
483 return services;
484 }
485
493 return this.db;
494 }
495
500 changeCase(null);
501
502 try {
504 this.xmlcm.close(); // close the xmlcm
506 } catch (Exception e) {
507 throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.closeCase.exception.msg"), e);
508 }
509 }
510
519 logger.log(Level.INFO, "Deleting case.\ncaseDir: {0}", caseDir); //NON-NLS
520
521 try {
522
523 xmlcm.close(); // close the xmlcm
524 boolean result = deleteCaseDirectory(caseDir); // delete the directory
525
526 RecentCases.getInstance().removeRecentCase(this.name, this.configFilePath); // remove it from the recent case
528 if (result == false) {
530 NbBundle.getMessage(this.getClass(), "Case.deleteCase.exception.msg", caseDir));
531 }
532 } catch (Exception ex) {
533 logger.log(Level.SEVERE, "Error deleting the current case dir: " + caseDir, ex); //NON-NLS
534 throw new CaseActionException(
535 NbBundle.getMessage(this.getClass(), "Case.deleteCase.exception.msg2", caseDir), ex);
536 }
537 }
538
547 void updateCaseName(String oldCaseName, String oldPath, String newCaseName, String newPath) throws CaseActionException {
548 try {
549 xmlcm.setCaseName(newCaseName); // set the case
550 name = newCaseName; // change the local value
551 RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case
552 try {
553 pcs.firePropertyChange(Events.NAME.toString(), oldCaseName, newCaseName);
554 } catch (Exception e) {
555 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
556 MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
557 NbBundle.getMessage(this.getClass(),
558 "Case.changeCase.errListenToCaseUpdates.msg"),
559 MessageNotifyUtil.MessageType.ERROR);
560 }
561 doCaseNameChange(newCaseName);
562
563 } catch (Exception e) {
564 throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseName.exception.msg"), e);
565 }
566 }
567
574 void updateExaminer(String oldExaminer, String newExaminer) throws CaseActionException {
575 try {
576 xmlcm.setCaseExaminer(newExaminer); // set the examiner
577 examiner = newExaminer;
578 try {
579 pcs.firePropertyChange(Events.EXAMINER.toString(), oldExaminer, newExaminer);
580 } catch (Exception e) {
581 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
582 MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
583 NbBundle.getMessage(this.getClass(),
584 "Case.changeCase.errListenToCaseUpdates.msg"),
585 MessageNotifyUtil.MessageType.ERROR);
586 }
587 } catch (Exception e) {
588 throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateExaminer.exception.msg"), e);
589 }
590 }
591
598 void updateCaseNumber(String oldCaseNumber, String newCaseNumber) throws CaseActionException {
599 try {
600 xmlcm.setCaseNumber(newCaseNumber); // set the case number
601 number = newCaseNumber;
602
603 try {
604 pcs.firePropertyChange(Events.NUMBER.toString(), oldCaseNumber, newCaseNumber);
605 } catch (Exception e) {
606 logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
607 MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
608 NbBundle.getMessage(this.getClass(),
609 "Case.changeCase.errListenToCaseUpdates.msg"),
610 MessageNotifyUtil.MessageType.ERROR);
611 }
612 } catch (Exception e) {
613 throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseNum.exception.msg"), e);
614 }
615 }
616
623 return currentCase != null;
624 }
625
632 configFilePath = givenPath;
633 }
634
640 String getConfigFilePath() {
641 return configFilePath;
642 }
643
650 return autopsyVer;
651 }
652
659 if ((appName == null) || appName.equals("")) {
660 appName = WindowManager.getDefault().getMainWindow().getTitle();
661 }
662 return appName;
663 }
664
671 return name;
672 }
673
680 return number;
681 }
682
689 return examiner;
690 }
691
698 if (xmlcm == null) {
699 return "";
700 } else {
701 return xmlcm.getCaseDirectory();
702 }
703 }
704
711 if (xmlcm == null) {
712 return "";
713 } else {
714 return xmlcm.getTempDir();
715 }
716 }
717
724 if (xmlcm == null) {
725 return "";
726 } else {
727 return xmlcm.getCacheDir();
728 }
729 }
730
737 if (xmlcm == null) {
738 return "";
739 } else {
740 return xmlcm.getExportDir();
741 }
742 }
743
750 if (xmlcm == null) {
751 return "";
752 } else {
753 return xmlcm.getLogDir();
754 }
755 }
756
763 if (xmlcm == null) {
764 return "";
765 } else {
766 return xmlcm.getCreatedDate();
767 }
768 }
769
777 return this.getCaseDirectory() + File.separator + getModulesOutputDirRelPath();
778 }
779
788 return "ModuleOutput"; //NON-NLS
789 }
790
797 return pcs;
798 }
799
808 hasData = (list.size() > 0);
809 return list;
810 }
811
818 Set<TimeZone> timezones = new HashSet<>();
819 try {
820 for (
Content c : getDataSources()) {
822 if ((dataSource != null) && (dataSource instanceof
Image)) {
823 Image image = (Image) dataSource;
824 timezones.add(TimeZone.getTimeZone(image.
getTimeZone()));
825 }
826 }
828 logger.log(Level.INFO, "Error getting time zones", ex); //NON-NLS
829 }
830 return timezones;
831 }
832
834 pcs.addPropertyChangeListener(listener);
835 }
836
838 pcs.removePropertyChangeListener(listener);
839 }
840
849 return new File(imgPath).isFile();
850 }
854 private static final String pdisk =
"\\\\.\\physicaldrive";
//NON-NLS
855 private static final String dev =
"/dev/";
//NON-NLS
856
857 static boolean isPhysicalDrive(String path) {
858 return path.toLowerCase().startsWith(pdisk)
859 || path.toLowerCase().startsWith(dev);
860 }
861
865 static boolean isPartition(String path) {
866 return path.toLowerCase().startsWith("\\\\.\\")
867 && path.toLowerCase().endsWith(":");
868 }
869
877 static boolean driveExists(String path) {
878 // Test the drive by reading the first byte and checking if it's -1
879 BufferedInputStream br = null;
880 try {
882 br = new BufferedInputStream(new FileInputStream(tmp));
883 int b = br.read();
884 return b != -1;
885 } catch (Exception ex) {
886 return false;
887 } finally {
888 try {
889 if (br != null) {
890 br.close();
891 }
892 } catch (IOException ex) {
893 }
894 }
895 }
896
907
908 TimeZone zone = TimeZone.getTimeZone(timezoneID);
909 int offset = zone.getRawOffset() / 1000;
910 int hour = offset / 3600;
911 int min = (offset % 3600) / 60;
912
913 DateFormat dfm = new SimpleDateFormat("z");
914 dfm.setTimeZone(zone);
915 boolean hasDaylight = zone.useDaylightTime();
916 String first = dfm.format(new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3); // make it only 3 letters code
917 String second = dfm.format(new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3); // make it only 3 letters code
918 int mid = hour * -1;
919 String result = first + Integer.toString(mid);
920 if (min != 0) {
921 result = result + ":" + Integer.toString(min);
922 }
923 if (hasDaylight) {
924 result = result + second;
925 }
926
927 return result;
928 }
929
930 /*
931 * The methods below are used to manage the case directories (creating,
932 * checking, deleting, etc)
933 */
943 static void createCaseDirectory(String caseDir, String caseName)
throws CaseActionException {
944 createCaseDirectory(caseDir);
945
946 }
947
955 static void createCaseDirectory(String caseDir) throws CaseActionException {
956
960 throw new CaseActionException(
961 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.existNotDir", caseDir));
962 }
else if (!caseDirF.
canRead() || !caseDirF.canWrite()) {
963 throw new CaseActionException(
964 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.existCantRW", caseDir));
965 }
966 }
967
968 try {
969 boolean result = (caseDirF).mkdirs(); // create root case Directory
970 if (result == false) {
971 throw new CaseActionException(
972 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreate", caseDir));
973 }
974
975 // create the folders inside the case directory
976 result = result && (
new File(caseDir +
File.separator + XMLCaseManagement.EXPORT_FOLDER_RELPATH)).mkdir()
977 && (
new File(caseDir +
File.separator + XMLCaseManagement.LOG_FOLDER_RELPATH)).mkdir()
978 && (
new File(caseDir +
File.separator + XMLCaseManagement.TEMP_FOLDER_RELPATH)).mkdir()
979 && (
new File(caseDir +
File.separator + XMLCaseManagement.CACHE_FOLDER_RELPATH)).mkdir();
980
981 if (result == false) {
982 throw new CaseActionException(
983 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreateCaseDir", caseDir));
984 }
985
986 final String modulesOutDir = caseDir +
File.separator + getModulesOutputDirRelPath();
987 result =
new File(modulesOutDir).mkdir();
988 if (result == false) {
989 throw new CaseActionException(
990 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.cantCreateModDir",
991 modulesOutDir));
992 }
993
994 } catch (Exception e) {
995 throw new CaseActionException(
996 NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.gen", caseDir), e);
997 }
998 }
999
1007 static boolean deleteCaseDirectory(
File casePath) {
1008 logger.log(Level.INFO, "Deleting case directory: {0}", casePath.getAbsolutePath()); //NON-NLS
1009 return FileUtil.deleteDir(casePath);
1010 }
1011
1017 }
1018
1024 SwingUtilities.invokeLater(new Runnable() {
1025 @Override
1026 public void run() {
1029 }
1030 });
1031 }
1032
1041 return !(caseName.contains("\\") || caseName.contains("/") || caseName.contains(":")
1042 || caseName.contains("*") || caseName.contains("?") || caseName.contains("\"")
1043 || caseName.contains("<") || caseName.contains(">") || caseName.contains("|"));
1044 }
1045
1048 if (tempFolder.isDirectory()) {
1049 File[] files = tempFolder.listFiles();
1050 if (files.length > 0) {
1051 for (File file : files) {
1052 if (file.isDirectory()) {
1053 deleteCaseDirectory(file);
1054 } else {
1055 file.delete();
1056 }
1057 }
1058 }
1059 }
1060 }
1061
1069 File modulesOutputDirF = new File(modulesOutputDir);
1070 if (!modulesOutputDirF.exists()) {
1071 logger.log(Level.INFO, "Creating modules output dir for the case."); //NON-NLS
1072
1073 try {
1074 if (!modulesOutputDirF.mkdir()) {
1075 logger.log(Level.SEVERE, "Error creating modules output dir for the case, dir: {0}", modulesOutputDir); //NON-NLS
1076 }
1077 } catch (SecurityException e) {
1078 logger.log(Level.SEVERE, "Error creating modules output dir for the case, dir: " + modulesOutputDir, e); //NON-NLS
1079 }
1080 }
1081 }
1082
1083 //case change helper
1085 logger.log(Level.INFO, "Changing Case to: {0}", toChangeTo); //NON-NLS
1086 if (toChangeTo != null) { // new case is open
1087
1088 // clear the temp folder when the case is created / opened
1090 checkSubFolders(toChangeTo);
1091
1092 // enable these menus
1094 CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
1095 CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
1096 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
1097
1099 // open all top components
1101 } else {
1102 // close all top components
1104 }
1105 } else { // case is closed
1106 // close all top components first
1108
1109 // disable these menus
1110 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
// Add Image menu
1111 CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
1112 CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
1113 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
1114
1115 //clear pending notifications
1117
1118 Frame f = WindowManager.getDefault().getMainWindow();
1119 f.setTitle(
Case.
getAppName());
// set the window name to just application name
1120
1121 //try to force gc to happen
1122 System.gc();
1123 System.gc();
1124 }
1125
1126 //log memory usage after case changed
1128
1129 }
1130
1131 //case name change helper
1133 // update case name
1134 if (!newCaseName.equals("")) {
1135 Frame f = WindowManager.getDefault().getMainWindow();
1136 f.setTitle(newCaseName +
" - " +
Case.
getAppName());
// set the window name to the new value
1137 }
1138 }
1139
1140 //delete image helper
1142 // no more image left in this case
1144 // close all top components
1146 }
1147 }
1148
1149 @Override
1152 }
1153
1166 Report report = this.db.
addReport(localPath, srcModuleName, reportName);
1167 try {
1169 } catch (Exception ex) {
1170 String errorMessage = String.format(
"A Case %s listener threw an exception",
Events.
REPORT_ADDED.toString());
//NON-NLS
1171 logger.log(Level.SEVERE, errorMessage, ex);
1172 }
1173 }
1174
1177 }
1178
1185 // false is also the initial value, so make the DB trip if it is still false
1186 if (!hasData) {
1187 try {
1188 hasData = (getDataSources().size() > 0);
1190 }
1191 }
1192 return hasData;
1193 }
1194 }
String getLogDirectoryPath()
List< Content > getDataSources()
List< Report > getAllReports()
static String convertTimeZone(String timezoneID)
static final PropertyChangeSupport pcs
AddImageProcess makeAddImageProcess(String timezone, boolean processUnallocSpace, boolean noFatFsOrphans)
Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db)
Image addImage(String imgPath, long imgId, String timeZone)
void addErrorObserver(ErrorObserver observer)
String getTempDirectory()
static void doCaseNameChange(String newCaseName)
static boolean existsCurrentCase()
static void open(String configFilePath)
String getCaseDirectory()
static void openCoreWindows()
static String getAutopsyVersion()
static void setLogDirectory(String directoryPath)
void setConfigFilePath(String givenPath)
void addReport(String localPath, String srcModuleName, String reportName)
Map< Long, List< String > > getImagePaths()
String getModulesOutputDirAbsPath()
static void changeCase(Case newCase)
List< Report > getAllReports()
static boolean isValidName(String caseName)
static void closeCoreWindows()
static String getModulesOutputDirRelPath()
Image getImageById(long id)
Set< TimeZone > getTimeZone()
static void invokeStartupDialog()
void actionPerformed(ActionEvent e)
SleuthkitCase getSleuthkitCase()
static void checkSubFolders(Case openedCase)
static PropertyChangeSupport getPropertyChangeSupport()
Report addReport(String localPath, String sourceModuleName, String reportName)
String getCacheDirectory()
static void checkImagesExist(SleuthkitCase db)
List< Content > getRootObjects()
static synchronized void removePropertyChangeListener(PropertyChangeListener listener)
static boolean pathExists(String imgPath)
final XMLCaseManagement xmlcm
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 Case getCurrentCase()
static void show(String title, String message, MessageType type, ActionListener actionListener)
static SleuthkitCase openCase(String dbPath)
static void runAddImageAction()
static SleuthkitCase newCase(String dbPath)
String getBackupDatabasePath()
void receiveError(String context, String errorMessage)
static String getAppName()
static String getVersion()
String getExportDirectory()
static void clearTempFolder()
static StartupWindowProvider getInstance()
static boolean isCaseOpen()
static Logger getLogger(String name)
static void doCaseChange(Case toChangeTo)