19 package org.sleuthkit.autopsy.casemodule;
 
   22 import java.util.Calendar;
 
   23 import java.util.List;
 
   24 import javax.swing.JFileChooser;
 
   25 import javax.swing.JOptionPane;
 
   26 import javax.swing.JPanel;
 
   27 import javax.swing.JTextField;
 
   28 import javax.swing.event.DocumentEvent;
 
   29 import javax.swing.event.DocumentListener;
 
   30 import javax.swing.filechooser.FileFilter;
 
   31 import org.apache.commons.lang3.StringUtils;
 
   32 import org.openide.util.NbBundle;
 
   46 @SuppressWarnings(
"PMD.SingularField") 
 
   49     private static final long serialVersionUID = 1L;
 
   50     private static final String PROP_LASTIMAGE_PATH = 
"LBL_LastImage_PATH"; 
 
   51     private static final String[] SECTOR_SIZE_CHOICES = {
"Auto Detect", 
"512", 
"1024", 
"2048", 
"4096"};
 
   65     private ImageFilePanel(String context, List<FileFilter> fileChooserFilters) {
 
   66         this.contextName = context;
 
   73         for (String choice : SECTOR_SIZE_CHOICES) {
 
   74             sectorSizeComboBox.addItem(choice);
 
   76         sectorSizeComboBox.setSelectedIndex(0);
 
   78         errorLabel.setVisible(
false);
 
   79         this.fileChooserFilters = fileChooserFilters;
 
   88         for (String timeZone : timeZoneList) {
 
   89             timeZoneComboBox.addItem(timeZone);
 
  117         return pathTextField;
 
  121         return md5HashTextField;
 
  125         return sha1HashTextField;
 
  129         return sha256HashTextField;
 
  133         if(fileChooser == null) {
 
  135             fileChooser.setDragEnabled(
false);
 
  136             fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 
  137             fileChooser.setMultiSelectionEnabled(
false);
 
  138             fileChooserFilters.forEach(fileChooser::addChoosableFileFilter);
 
  139             if (fileChooserFilters.isEmpty() == 
false) {
 
  140                 fileChooser.setFileFilter(fileChooserFilters.get(0));
 
  155         pathLabel = 
new javax.swing.JLabel();
 
  156         browseButton = 
new javax.swing.JButton();
 
  157         pathTextField = 
new javax.swing.JTextField();
 
  158         timeZoneLabel = 
new javax.swing.JLabel();
 
  159         timeZoneComboBox = 
new javax.swing.JComboBox<>();
 
  160         noFatOrphansCheckbox = 
new javax.swing.JCheckBox();
 
  161         errorLabel = 
new javax.swing.JLabel();
 
  162         sectorSizeLabel = 
new javax.swing.JLabel();
 
  163         sectorSizeComboBox = 
new javax.swing.JComboBox<>();
 
  164         sha256HashLabel = 
new javax.swing.JLabel();
 
  165         sha256HashTextField = 
new javax.swing.JTextField();
 
  166         sha1HashTextField = 
new javax.swing.JTextField();
 
  167         md5HashTextField = 
new javax.swing.JTextField();
 
  168         sha1HashLabel = 
new javax.swing.JLabel();
 
  169         md5HashLabel = 
new javax.swing.JLabel();
 
  170         hashValuesLabel = 
new javax.swing.JLabel();
 
  171         hashValuesNoteLabel = 
new javax.swing.JLabel();
 
  173         setMinimumSize(
new java.awt.Dimension(0, 65));
 
  174         setPreferredSize(
new java.awt.Dimension(403, 65));
 
  176         org.openide.awt.Mnemonics.setLocalizedText(pathLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.pathLabel.text")); 
 
  178         org.openide.awt.Mnemonics.setLocalizedText(browseButton, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.browseButton.text")); 
 
  179         browseButton.addActionListener(
new java.awt.event.ActionListener() {
 
  180             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  181                 browseButtonActionPerformed(evt);
 
  185         pathTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.pathTextField.text")); 
 
  187         org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.timeZoneLabel.text")); 
 
  189         timeZoneComboBox.setMaximumRowCount(30);
 
  191         org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.noFatOrphansCheckbox.text")); 
 
  192         noFatOrphansCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.noFatOrphansCheckbox.toolTipText")); 
 
  194         errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
 
  195         org.openide.awt.Mnemonics.setLocalizedText(errorLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.errorLabel.text")); 
 
  197         org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.sectorSizeLabel.text")); 
 
  199         org.openide.awt.Mnemonics.setLocalizedText(sha256HashLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.sha256HashLabel.text")); 
 
  200         sha256HashLabel.setEnabled(
false);
 
  202         sha256HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.sha256HashTextField.text")); 
 
  203         sha256HashTextField.setEnabled(
false);
 
  205         sha1HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.sha1HashTextField.text")); 
 
  206         sha1HashTextField.setEnabled(
false);
 
  208         md5HashTextField.setText(
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.md5HashTextField.text")); 
 
  209         md5HashTextField.setEnabled(
false);
 
  211         org.openide.awt.Mnemonics.setLocalizedText(sha1HashLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.sha1HashLabel.text")); 
 
  212         sha1HashLabel.setEnabled(
false);
 
  214         org.openide.awt.Mnemonics.setLocalizedText(md5HashLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.md5HashLabel.text")); 
 
  215         md5HashLabel.setEnabled(
false);
 
  217         org.openide.awt.Mnemonics.setLocalizedText(hashValuesLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.hashValuesLabel.text")); 
 
  218         hashValuesLabel.setEnabled(
false);
 
  220         org.openide.awt.Mnemonics.setLocalizedText(hashValuesNoteLabel, 
org.openide.util.NbBundle.getMessage(
ImageFilePanel.class, 
"ImageFilePanel.hashValuesNoteLabel.text")); 
 
  221         hashValuesNoteLabel.setEnabled(
false);
 
  223         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  224         this.setLayout(layout);
 
  225         layout.setHorizontalGroup(
 
  226             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  227             .addGroup(layout.createSequentialGroup()
 
  228                 .addComponent(pathTextField)
 
  229                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  230                 .addComponent(browseButton)
 
  232             .addGroup(layout.createSequentialGroup()
 
  233                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  234                     .addComponent(pathLabel)
 
  235                     .addComponent(noFatOrphansCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  236                 .addGap(0, 368, Short.MAX_VALUE))
 
  237             .addGroup(layout.createSequentialGroup()
 
  238                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  239                     .addComponent(errorLabel)
 
  240                     .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, 
false)
 
  241                         .addGroup(layout.createSequentialGroup()
 
  242                             .addComponent(timeZoneLabel)
 
  243                             .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  244                             .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  245                         .addGroup(layout.createSequentialGroup()
 
  246                             .addComponent(sectorSizeLabel)
 
  247                             .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  248                             .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  249                         .addGroup(layout.createSequentialGroup()
 
  250                             .addComponent(md5HashLabel)
 
  251                             .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  252                             .addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  253                         .addGroup(layout.createSequentialGroup()
 
  254                             .addComponent(sha1HashLabel)
 
  255                             .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  256                             .addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  257                         .addGroup(layout.createSequentialGroup()
 
  258                             .addComponent(sha256HashLabel)
 
  259                             .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  260                             .addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE)))
 
  261                     .addComponent(hashValuesNoteLabel)
 
  262                     .addComponent(hashValuesLabel))
 
  263                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  265         layout.setVerticalGroup(
 
  266             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  267             .addGroup(layout.createSequentialGroup()
 
  268                 .addComponent(pathLabel)
 
  269                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  270                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  271                     .addComponent(browseButton)
 
  272                     .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  273                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  274                 .addComponent(noFatOrphansCheckbox)
 
  275                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  276                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  277                     .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  278                     .addComponent(timeZoneLabel))
 
  279                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  280                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  281                     .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  282                     .addComponent(sectorSizeLabel))
 
  284                 .addComponent(hashValuesLabel)
 
  285                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  286                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  287                     .addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  288                     .addComponent(md5HashLabel))
 
  289                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  290                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  291                     .addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  292                     .addComponent(sha1HashLabel))
 
  293                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 
  294                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  295                     .addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  296                     .addComponent(sha256HashLabel))
 
  298                 .addComponent(hashValuesNoteLabel)
 
  300                 .addComponent(errorLabel)
 
  301                 .addContainerGap(51, Short.MAX_VALUE))
 
  305     @NbBundle.Messages({
"ImageFilePanel.000.confirmationMessage=The selected file" 
  306         + 
" has extenson .001 but there is a .000 file in the sequence of raw images." 
  307         + 
"\nShould the .000 file be used as the start, instead of the selected .001 file?\n"})
 
  309         String oldText = getContentPaths();
 
  311         File currentDir = 
new File(oldText);
 
  312         JFileChooser chooser = getChooser();
 
  313         if (currentDir.exists()) {
 
  314             chooser.setCurrentDirectory(currentDir);
 
  317         if (chooser.showOpenDialog(
this) == JFileChooser.APPROVE_OPTION) {
 
  318             String path = chooser.getSelectedFile().getPath();
 
  319             if (path.endsWith(
".001")) {
 
  320                 String zeroX3_path = StringUtils.removeEnd(path, 
".001") + 
".000";
 
  321                 if (
new File(zeroX3_path).exists()) {
 
  322                     int showConfirmDialog = JOptionPane.showConfirmDialog(
this,
 
  323                             Bundle.ImageFilePanel_000_confirmationMessage(),
 
  324                             "Choose .001 file?", JOptionPane.YES_NO_OPTION);
 
  325                     if (showConfirmDialog == JOptionPane.YES_OPTION) {
 
  331             setContentPath(path);
 
  337             if (!oldText.equals(getContentPaths())) {
 
  338                 md5HashTextField.setText(null);
 
  339                 sha1HashTextField.setText(null);
 
  340                 sha256HashTextField.setText(null);
 
  373         hashValuesLabel.setEnabled(enabled);
 
  374         hashValuesNoteLabel.setEnabled(enabled);
 
  376         md5HashLabel.setEnabled(enabled);
 
  377         md5HashTextField.setEnabled(enabled);
 
  379         sha1HashLabel.setEnabled(enabled);
 
  380         sha1HashTextField.setEnabled(enabled);
 
  382         sha256HashLabel.setEnabled(enabled);
 
  383         sha256HashTextField.setEnabled(enabled);
 
  392         return pathTextField.getText();
 
  401         pathTextField.setText(s);
 
  410         int sectorSizeSelectionIndex = sectorSizeComboBox.getSelectedIndex();
 
  412         if (sectorSizeSelectionIndex == 0) {
 
  416         return Integer.valueOf((String) sectorSizeComboBox.getSelectedItem());
 
  420         String tz = timeZoneComboBox.getSelectedItem().toString();
 
  421         return tz.substring(tz.indexOf(
')') + 2).trim();
 
  425         return noFatOrphansCheckbox.isSelected();
 
  429         return this.md5HashTextField.getText();
 
  433         return this.sha1HashTextField.getText();
 
  437         return this.sha256HashTextField.getText();
 
  442         pathTextField.setText(null);
 
  443         this.md5HashTextField.setText(null);
 
  444         this.sha1HashTextField.setText(null);
 
  445         this.sha256HashTextField.setText(null);
 
  454         "ImageFilePanel.validatePanel.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
 
  455         "ImageFilePanel.validatePanel.invalidMD5=Invalid MD5 hash",
 
  456         "ImageFilePanel.validatePanel.invalidSHA1=Invalid SHA1 hash",
 
  457         "ImageFilePanel.validatePanel.invalidSHA256=Invalid SHA256 hash",})
 
  459         errorLabel.setVisible(
false);
 
  461         String path = getContentPaths();
 
  462         if (!isImagePathValid()) {
 
  466         if (!StringUtils.isBlank(getMd5()) && !HashUtility.isValidMd5Hash(getMd5())) {
 
  467             errorLabel.setVisible(
true);
 
  468             errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidMD5());
 
  472         if (!StringUtils.isBlank(getSha1()) && !HashUtility.isValidSha1Hash(getSha1())) {
 
  473             errorLabel.setVisible(
true);
 
  474             errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA1());
 
  478         if (!StringUtils.isBlank(getSha256()) && !HashUtility.isValidSha256Hash(getSha256())) {
 
  479             errorLabel.setVisible(
true);
 
  480             errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA256());
 
  485             errorLabel.setVisible(
true);
 
  486             errorLabel.setText(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
 
  493         String path = getContentPaths();
 
  503         String imagePathName = getContentPaths();
 
  504         if (null != imagePathName) {
 
  505             String imagePath = imagePathName.substring(0, imagePathName.lastIndexOf(File.separator) + 1);
 
  512         if (StringUtils.isNotBlank(lastImagePath)) {
 
  513             setContentPath(lastImagePath);
 
  538     @NbBundle.Messages({
"ImageFilePanel.moduleErr=Module Error",
 
  539         "ImageFilePanel.moduleErr.msg=A module caused an error listening to ImageFilePanel updates." 
  540         + 
" See log to determine which module. Some data could be incomplete.\n"})
 
  542         if (isImagePathValid() && !getContentPaths().toLowerCase().endsWith(
".e01")) {
 
  543             setHashValuesComponentsEnabled(
true);
 
  545             setHashValuesComponentsEnabled(
false);
 
  555         pathTextField.requestFocusInWindow();
 
static synchronized String getConfigSetting(String moduleName, String settingName)
 
final List< FileFilter > fileChooserFilters
 
static boolean isPhysicalDrive(String path)
 
javax.swing.JLabel hashValuesNoteLabel
 
boolean getNoFatOrphans()
 
JTextField getSha256TextField()
 
javax.swing.JLabel timeZoneLabel
 
static List< String > createTimeZoneList()
 
javax.swing.JLabel pathLabel
 
boolean isImagePathValid()
 
JTextField getSha1TextField()
 
javax.swing.JTextField sha256HashTextField
 
javax.swing.JComboBox< String > sectorSizeComboBox
 
static synchronized ImageFilePanel createInstance(String context, List< FileFilter > fileChooserFilters)
 
javax.swing.JLabel sha1HashLabel
 
javax.swing.JTextField sha1HashTextField
 
javax.swing.JLabel sha256HashLabel
 
static boolean isValidForCaseType(String path, Case.CaseType caseType)
 
JTextField getMd5TextFieldField()
 
void createTimeZoneList()
 
static String createTimeZoneString(TimeZone timeZone)
 
void setContentPath(String s)
 
void browseButtonActionPerformed(java.awt.event.ActionEvent evt)
 
javax.swing.JLabel sectorSizeLabel
 
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
 
javax.swing.JLabel hashValuesLabel
 
javax.swing.JTextField md5HashTextField
 
javax.swing.JLabel md5HashLabel
 
ImageFilePanel(String context, List< FileFilter > fileChooserFilters)
 
JFileChooser getChooser()
 
javax.swing.JComboBox< String > timeZoneComboBox
 
void changedUpdate(DocumentEvent e)
 
void setHashValuesComponentsEnabled(boolean enabled)
 
JTextField getPathTextField()
 
javax.swing.JButton browseButton
 
static boolean isPartition(String path)
 
javax.swing.JTextField pathTextField
 
static Case getCurrentCase()
 
javax.swing.JLabel errorLabel
 
javax.swing.JCheckBox noFatOrphansCheckbox
 
void removeUpdate(DocumentEvent e)
 
void insertUpdate(DocumentEvent e)
 
JFileChooser getChooser()