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

Copyright © 2012-2020 Basis Technology. Generated on: Tue Sep 22 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.