Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
LocalDiskPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2021 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.io.File;
22 import java.nio.file.Paths;
23 import java.util.Calendar;
24 import java.util.List;
25 import java.util.logging.Level;
26 import javax.swing.JFileChooser;
27 import javax.swing.JPanel;
28 import org.openide.util.NbBundle;
37 
42 @NbBundle.Messages({
43  "LocalDiskPanel.errorMessage.noOpenCaseTitle=No open case available",
44  "LocalDiskPanel.errorMessage.noOpenCaseBody=LocalDiskPanel listener couldn't get the open case.",
45  "LocalDiskPanel.imageWriterError.directoryNotExist=Error - directory does not exist",
46  "LocalDiskPanel.imageWriterError.emptyPath=Error - enter path for VHD",
47  "LocalDiskPanel.imageWriterError.isDirectory=Error - VHD path is a directory",
48  "LocalDiskPanel.imageWriterError.fileExists=Error - VHD path already exists",
49  "LocalDiskPanel.moduleErrorMessage.title=Module Error",
50  "LocalDiskPanel.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.",
51  "LocalDiskPanel.localDiskMessage.unspecified=Unspecified"
52 })
53 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
54 final class LocalDiskPanel extends JPanel {
55 
56  private static final Logger logger = Logger.getLogger(LocalDiskPanel.class.getName());
57  private static final String[] SECTOR_SIZE_CHOICES = {"Auto Detect", "512", "1024", "2048", "4096"};
58  private static LocalDiskPanel instance;
59  private static final long serialVersionUID = 1L;
60  private LocalDisk localDisk;
61  private boolean enableNext = false;
62  private JFileChooser fc;
63  private final JFileChooserFactory chooserHelper;
64 
68  LocalDiskPanel() {
69  initComponents();
70  customInit();
71  createTimeZoneList();
72  createSectorSizeList();
73  chooserHelper = new JFileChooserFactory();
74  }
75 
79  static synchronized LocalDiskPanel getDefault() {
80  if (instance == null) {
81  instance = new LocalDiskPanel();
82  }
83  return instance;
84  }
85 
86  @SuppressWarnings("unchecked")
87  private void customInit() {
88  imageWriterErrorLabel.setVisible(false);
89  imageWriterErrorLabel.setText("");
90  if (!PlatformUtil.isWindowsOS()) {
91  copyImageCheckbox.setSelected(false);
92  copyImageCheckbox.setEnabled(false);
93  }
94  pathTextField.setEnabled(copyImageCheckbox.isSelected());
95  browseButton.setEnabled(copyImageCheckbox.isSelected());
96  changeDatabasePathCheckbox.setEnabled(copyImageCheckbox.isSelected());
97  }
98 
104  @SuppressWarnings("unchecked")
105  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
106  private void initComponents() {
107 
108  timeZoneLabel = new javax.swing.JLabel();
109  timeZoneComboBox = new javax.swing.JComboBox<>();
110  noFatOrphansCheckbox = new javax.swing.JCheckBox();
111  descLabel = new javax.swing.JLabel();
112  copyImageCheckbox = new javax.swing.JCheckBox();
113  pathTextField = new javax.swing.JTextField();
114  browseButton = new javax.swing.JButton();
115  jLabel1 = new javax.swing.JLabel();
116  imageWriterErrorLabel = new javax.swing.JLabel();
117  changeDatabasePathCheckbox = new javax.swing.JCheckBox();
118  sectorSizeLabel = new javax.swing.JLabel();
119  sectorSizeComboBox = new javax.swing.JComboBox<>();
120  selectDiskButton = new javax.swing.JButton();
121  localDiskLabel = new javax.swing.JLabel();
122  localDiskNameTextField = new javax.swing.JTextField();
123 
124  setMinimumSize(new java.awt.Dimension(0, 420));
125  setPreferredSize(new java.awt.Dimension(485, 410));
126 
127  org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.timeZoneLabel.text")); // NOI18N
128 
129  timeZoneComboBox.setMaximumRowCount(30);
130 
131  org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.text")); // NOI18N
132  noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
133 
134  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.descLabel.text")); // NOI18N
135 
136  org.openide.awt.Mnemonics.setLocalizedText(copyImageCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.copyImageCheckbox.text")); // NOI18N
137  copyImageCheckbox.addActionListener(new java.awt.event.ActionListener() {
138  public void actionPerformed(java.awt.event.ActionEvent evt) {
139  copyImageCheckboxActionPerformed(evt);
140  }
141  });
142 
143  pathTextField.setText(org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.pathTextField.text")); // NOI18N
144  pathTextField.addKeyListener(new java.awt.event.KeyAdapter() {
145  public void keyReleased(java.awt.event.KeyEvent evt) {
146  pathTextFieldKeyReleased(evt);
147  }
148  });
149 
150  org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.browseButton.text")); // NOI18N
151  browseButton.addActionListener(new java.awt.event.ActionListener() {
152  public void actionPerformed(java.awt.event.ActionEvent evt) {
153  browseButtonActionPerformed(evt);
154  }
155  });
156 
157  org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.jLabel1.text")); // NOI18N
158 
159  imageWriterErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
160  org.openide.awt.Mnemonics.setLocalizedText(imageWriterErrorLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.imageWriterErrorLabel.text")); // NOI18N
161 
162  org.openide.awt.Mnemonics.setLocalizedText(changeDatabasePathCheckbox, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.changeDatabasePathCheckbox.text")); // NOI18N
163 
164  org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.sectorSizeLabel.text")); // NOI18N
165 
166  org.openide.awt.Mnemonics.setLocalizedText(selectDiskButton, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.selectDiskButton.text")); // NOI18N
167  selectDiskButton.addActionListener(new java.awt.event.ActionListener() {
168  public void actionPerformed(java.awt.event.ActionEvent evt) {
169  selectDiskButtonActionPerformed(evt);
170  }
171  });
172 
173  org.openide.awt.Mnemonics.setLocalizedText(localDiskLabel, org.openide.util.NbBundle.getMessage(LocalDiskPanel.class, "LocalDiskPanel.localDiskLabel.text")); // NOI18N
174 
175  localDiskNameTextField.setEditable(false);
176 
177  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
178  this.setLayout(layout);
179  layout.setHorizontalGroup(
180  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
181  .addGroup(layout.createSequentialGroup()
182  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
183  .addGroup(layout.createSequentialGroup()
184  .addComponent(localDiskLabel)
185  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
186  .addComponent(localDiskNameTextField)
187  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188  .addComponent(selectDiskButton))
189  .addGroup(layout.createSequentialGroup()
190  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
191  .addGroup(layout.createSequentialGroup()
192  .addComponent(timeZoneLabel)
193  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
194  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE))
195  .addComponent(noFatOrphansCheckbox)
196  .addComponent(copyImageCheckbox)
197  .addGroup(layout.createSequentialGroup()
198  .addGap(21, 21, 21)
199  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE)
200  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
201  .addComponent(browseButton))
202  .addGroup(layout.createSequentialGroup()
203  .addGap(2, 2, 2)
204  .addComponent(sectorSizeLabel)
205  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
206  .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
207  .addGroup(layout.createSequentialGroup()
208  .addGap(21, 21, 21)
209  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
210  .addComponent(descLabel)
211  .addComponent(changeDatabasePathCheckbox)
212  .addGroup(layout.createSequentialGroup()
213  .addGap(21, 21, 21)
214  .addComponent(jLabel1))
215  .addComponent(imageWriterErrorLabel))))
216  .addGap(0, 39, Short.MAX_VALUE)))
217  .addContainerGap())
218  );
219  layout.setVerticalGroup(
220  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
221  .addGroup(layout.createSequentialGroup()
222  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
223  .addComponent(localDiskLabel)
224  .addComponent(selectDiskButton)
225  .addComponent(localDiskNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
226  .addGap(18, 18, 18)
227  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
228  .addComponent(timeZoneLabel)
229  .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
230  .addGap(18, 18, 18)
231  .addComponent(noFatOrphansCheckbox)
232  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
233  .addComponent(descLabel)
234  .addGap(18, 18, 18)
235  .addComponent(copyImageCheckbox)
236  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
237  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
238  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
239  .addComponent(browseButton))
240  .addGap(13, 13, 13)
241  .addComponent(changeDatabasePathCheckbox)
242  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
243  .addComponent(jLabel1)
244  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
245  .addComponent(imageWriterErrorLabel)
246  .addGap(12, 12, 12)
247  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
248  .addComponent(sectorSizeLabel)
249  .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
250  .addContainerGap(127, Short.MAX_VALUE))
251  );
252  }// </editor-fold>//GEN-END:initComponents
253 
254  private void copyImageCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyImageCheckboxActionPerformed
255  pathTextField.setEnabled(copyImageCheckbox.isSelected());
256  browseButton.setEnabled(copyImageCheckbox.isSelected());
257  changeDatabasePathCheckbox.setEnabled(copyImageCheckbox.isSelected());
258  changeDatabasePathCheckbox.setSelected(copyImageCheckbox.isSelected());
259  fireUpdateEvent();
260  }//GEN-LAST:event_copyImageCheckboxActionPerformed
261 
262  private void pathTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_pathTextFieldKeyReleased
263  fireUpdateEvent();
264  }//GEN-LAST:event_pathTextFieldKeyReleased
265 
266  private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
267  fc = chooserHelper.getChooser();
268  String oldText = pathTextField.getText();
269  // set the current directory of the FileChooser if the ImagePath Field is valid
270  File currentFile = new File(oldText);
271  if ((currentFile.getParentFile() != null) && (currentFile.getParentFile().exists())) {
272  fc.setSelectedFile(currentFile);
273  }
274 
275  int retval = fc.showOpenDialog(this);
276  if (retval == JFileChooser.APPROVE_OPTION) {
277  String path = fc.getSelectedFile().getPath();
278  pathTextField.setText(path);
279  }
280  fireUpdateEvent();
281  }//GEN-LAST:event_browseButtonActionPerformed
282 
283  private void selectDiskButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDiskButtonActionPerformed
284  LocalDiskSelectionDialog selectionDialog = new LocalDiskSelectionDialog();
285  selectionDialog.display();
286  LocalDisk selectedLocalDisk = selectionDialog.getLocalDiskSelection();
287  if (selectedLocalDisk != null) {
288  localDisk = selectedLocalDisk;
289  localDiskNameTextField.setText(selectedLocalDisk.getName());
290 
291  enableNext = true;
292  try {
293  setPotentialImageWriterPath(localDisk);
294  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
295  } catch (NoCurrentCaseException ex) {
296  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
297  MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_errorMessage_noOpenCaseTitle(),
298  Bundle.LocalDiskPanel_errorMessage_noOpenCaseBody(),
299  MessageNotifyUtil.MessageType.ERROR);
300  } catch (Exception ex) {
301  logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", ex); //NON-NLS
302  MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_moduleErrorMessage_title(),
303  Bundle.LocalDiskPanel_moduleErrorMessage_body(),
304  MessageNotifyUtil.MessageType.ERROR);
305  }
306  }
307  }//GEN-LAST:event_selectDiskButtonActionPerformed
308 
309  // Variables declaration - do not modify//GEN-BEGIN:variables
310  private javax.swing.JButton browseButton;
311  private javax.swing.JCheckBox changeDatabasePathCheckbox;
312  private javax.swing.JCheckBox copyImageCheckbox;
313  private javax.swing.JLabel descLabel;
314  private javax.swing.JLabel imageWriterErrorLabel;
315  private javax.swing.JLabel jLabel1;
316  private javax.swing.JLabel localDiskLabel;
317  private javax.swing.JTextField localDiskNameTextField;
318  private javax.swing.JCheckBox noFatOrphansCheckbox;
319  private javax.swing.JTextField pathTextField;
320  private javax.swing.JComboBox<String> sectorSizeComboBox;
321  private javax.swing.JLabel sectorSizeLabel;
322  private javax.swing.JButton selectDiskButton;
323  private javax.swing.JComboBox<String> timeZoneComboBox;
324  private javax.swing.JLabel timeZoneLabel;
325  // End of variables declaration//GEN-END:variables
326 
327  private void fireUpdateEvent() {
328  try {
329  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
330  } catch (Exception e) {
331  logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS
332  MessageNotifyUtil.Notify.show(Bundle.LocalDiskPanel_moduleErrorMessage_title(),
333  Bundle.LocalDiskPanel_moduleErrorMessage_body(),
334  MessageNotifyUtil.MessageType.ERROR);
335  }
336  }
337 
341  void resetLocalDiskSelection() {
342  localDisk = null;
343  localDiskNameTextField.setText(Bundle.LocalDiskPanel_localDiskMessage_unspecified());
344  enableNext = false;
345  }
346 
352  String getContentPath() {
353  if (localDisk != null) {
354  return localDisk.getPath();
355  } else {
356  return "";
357  }
358  }
359 
365  int getSectorSize() {
366  int sectorSizeSelectionIndex = sectorSizeComboBox.getSelectedIndex();
367 
368  if (sectorSizeSelectionIndex == 0) {
369  return 0;
370  }
371 
372  return Integer.valueOf((String) sectorSizeComboBox.getSelectedItem());
373  }
374 
375  String getTimeZone() {
376  String tz = timeZoneComboBox.getSelectedItem().toString();
377  return tz.substring(tz.indexOf(")") + 2).trim();
378 
379  }
380 
381  boolean getNoFatOrphans() {
382  return noFatOrphansCheckbox.isSelected();
383  }
384 
385  private static String getDefaultImageWriterFolder() throws NoCurrentCaseException {
386  return Paths.get(Case.getCurrentCaseThrows().getModuleDirectory(), "Image Writer").toString();
387  }
388 
389  private void setPotentialImageWriterPath(LocalDisk disk) throws NoCurrentCaseException {
390 
391  File subDirectory = Paths.get(getDefaultImageWriterFolder()).toFile();
392  if (!subDirectory.exists()) {
393  subDirectory.mkdirs();
394  }
395 
396  String path = disk.getName();
397 
398  // Remove any character that isn't alphanumeric, a space, parent, or underscore.
399  // If the name ends up empty or starting with a space, prepend "localDisk"
400  path = path.replaceAll("[^0-9A-Za-z _()]", ""); // NON-NLS
401  if (path.isEmpty() || path.startsWith(" ")) {
402  path = "localDisk" + path;
403  }
404 
405  path += " " + System.currentTimeMillis();
406  path += ".vhd";
407  pathTextField.setText(Paths.get(getDefaultImageWriterFolder(), path).toString());
408  }
409 
410  private boolean imageWriterPathIsValid() {
411  if ((!copyImageCheckbox.isSelected()) || localDisk == null) {
412  imageWriterErrorLabel.setVisible(false);
413  imageWriterErrorLabel.setText("");
414  return true;
415  }
416 
417  if (pathTextField.getText().isEmpty()) {
418  imageWriterErrorLabel.setVisible(true);
419  imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_emptyPath());
420  return false;
421  }
422 
423  File f = new File(pathTextField.getText());
424  if (((f.getParentFile() != null) && (!f.getParentFile().exists()))
425  || (f.getParentFile() == null)) {
426  imageWriterErrorLabel.setVisible(true);
427  imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_directoryNotExist());
428  return false;
429  }
430  if (f.isDirectory()) {
431  imageWriterErrorLabel.setVisible(true);
432  imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_isDirectory());
433  return false;
434  }
435  if (f.exists()) {
436  imageWriterErrorLabel.setVisible(true);
437  imageWriterErrorLabel.setText(Bundle.LocalDiskPanel_imageWriterError_fileExists());
438  return false;
439  }
440  imageWriterErrorLabel.setVisible(false);
441  imageWriterErrorLabel.setText("");
442  return true;
443  }
444 
445  boolean getImageWriterEnabled() {
446  return copyImageCheckbox.isSelected();
447  }
448 
449  ImageWriterSettings getImageWriterSettings() {
450  return new ImageWriterSettings(pathTextField.getText(), changeDatabasePathCheckbox.isSelected());
451  }
452 
459  boolean validatePanel() {
460  if (!imageWriterPathIsValid()) {
461  return false;
462  }
463  return enableNext;
464  }
465 
470  public void createTimeZoneList() {
471  List<String> timeZoneList = TimeZoneUtils.createTimeZoneList();
472  for (String timeZone : timeZoneList) {
473  timeZoneComboBox.addItem(timeZone);
474  }
475 
476  // set the selected timezone
477  timeZoneComboBox.setSelectedItem(TimeZoneUtils.createTimeZoneString(Calendar.getInstance().getTimeZone()));
478  }
479 
484  private void createSectorSizeList() {
485  for (String choice : SECTOR_SIZE_CHOICES) {
486  sectorSizeComboBox.addItem(choice);
487  }
488  sectorSizeComboBox.setSelectedIndex(0);
489  }
490 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.