Autopsy  4.10.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
LocalDiskSelectionDialog.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 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.awt.Window;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.concurrent.CancellationException;
27 import java.util.concurrent.ExecutionException;
28 import java.util.logging.Level;
29 import javax.swing.JDialog;
30 import javax.swing.SwingWorker;
31 import javax.swing.event.ListSelectionEvent;
32 import javax.swing.event.ListSelectionListener;
33 import javax.swing.event.TableModelListener;
34 import javax.swing.table.TableModel;
35 import org.openide.util.NbBundle;
41 
42 @NbBundle.Messages({
43  "LocalDiskSelectionDialog.moduleErrorMessage.title=Module Error",
44  "LocalDiskSelectionDialog.moduleErrorMessage.body=A module caused an error listening to LocalDiskPanel updates. See log to determine which module. Some data could be incomplete.",
45  "LocalDiskSelectionDialog.errorMessage.disksNotDetected=Disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\").",
46  "LocalDiskSelectionDialog.errorMessage.drivesNotDetected=Local drives were not detected. Auto-detection not supported on this OS or admin privileges required",
47  "LocalDiskSelectionDialog.errorMessage.someDisksNotDetected=Some disks were not detected. On some systems it requires admin privileges (or \"Run as administrator\")."
48 })
52 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
53 final class LocalDiskSelectionDialog extends JDialog {
54 
55  private static final Logger logger = Logger.getLogger(LocalDiskSelectionDialog.class.getName());
56  private static final long serialVersionUID = 1L;
57  private List<LocalDisk> disks;
58  private final LocalDiskModel model;
59 
63  LocalDiskSelectionDialog() {
64  super((Window) LocalDiskPanel.getDefault().getTopLevelAncestor(), ModalityType.MODELESS);
65 
66  this.model = new LocalDiskModel();
67  this.disks = new ArrayList<>();
68 
69  initComponents();
70  refreshTable();
71 
72  localDiskTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
73  @Override
74  public void valueChanged(ListSelectionEvent e) {
75  int selectedRow = localDiskTable.getSelectedRow();
76  okButton.setEnabled(selectedRow >= 0 && selectedRow < disks.size());
77  }
78  });
79  }
80 
84  void display() {
85  setModal(true);
86  setSize(getPreferredSize());
87  setLocationRelativeTo(this.getParent());
88  setAlwaysOnTop(false);
89  setVisible(true);
90  }
91 
97  @SuppressWarnings("unchecked")
98  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
99  private void initComponents() {
100 
101  selectLocalDiskLabel = new javax.swing.JLabel();
102  errorLabel = new javax.swing.JLabel();
103  localDiskScrollPane = new javax.swing.JScrollPane();
104  localDiskTable = new javax.swing.JTable();
105  refreshLocalDisksButton = new javax.swing.JButton();
106  okButton = new javax.swing.JButton();
107  cancelButton = new javax.swing.JButton();
108 
109  setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
110  setTitle(org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.title")); // NOI18N
111  setAlwaysOnTop(true);
112  setResizable(false);
113 
114  selectLocalDiskLabel.setFont(selectLocalDiskLabel.getFont().deriveFont(selectLocalDiskLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
115  org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.selectLocalDiskLabel.text")); // NOI18N
116 
117  errorLabel.setFont(errorLabel.getFont().deriveFont(errorLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
118  errorLabel.setForeground(new java.awt.Color(255, 0, 0));
119  org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.errorLabel.text")); // NOI18N
120 
121  localDiskTable.setModel(model);
122  localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
123  localDiskScrollPane.setViewportView(localDiskTable);
124 
125  org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.refreshLocalDisksButton.text")); // NOI18N
126  refreshLocalDisksButton.addActionListener(new java.awt.event.ActionListener() {
127  public void actionPerformed(java.awt.event.ActionEvent evt) {
128  refreshLocalDisksButtonActionPerformed(evt);
129  }
130  });
131 
132  org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.okButton.text")); // NOI18N
133  okButton.setEnabled(false);
134  okButton.addActionListener(new java.awt.event.ActionListener() {
135  public void actionPerformed(java.awt.event.ActionEvent evt) {
136  okButtonActionPerformed(evt);
137  }
138  });
139 
140  org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.cancelButton.text")); // NOI18N
141  cancelButton.addActionListener(new java.awt.event.ActionListener() {
142  public void actionPerformed(java.awt.event.ActionEvent evt) {
143  cancelButtonActionPerformed(evt);
144  }
145  });
146 
147  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
148  getContentPane().setLayout(layout);
149  layout.setHorizontalGroup(
150  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
151  .addGroup(layout.createSequentialGroup()
152  .addContainerGap()
153  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
154  .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
155  .addGroup(layout.createSequentialGroup()
156  .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
157  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
158  .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
159  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
160  .addComponent(refreshLocalDisksButton))
161  .addGroup(layout.createSequentialGroup()
162  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
163  .addComponent(selectLocalDiskLabel)
164  .addComponent(errorLabel))
165  .addGap(0, 0, Short.MAX_VALUE)))
166  .addContainerGap())
167  );
168  layout.setVerticalGroup(
169  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
170  .addGroup(layout.createSequentialGroup()
171  .addGap(6, 6, 6)
172  .addComponent(selectLocalDiskLabel)
173  .addGap(4, 4, 4)
174  .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
175  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
176  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
177  .addComponent(refreshLocalDisksButton)
178  .addComponent(okButton)
179  .addComponent(cancelButton))
180  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
181  .addComponent(errorLabel)
182  .addContainerGap(27, Short.MAX_VALUE))
183  );
184 
185  pack();
186  }// </editor-fold>//GEN-END:initComponents
187 
188  private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshLocalDisksButtonActionPerformed
189  refreshTable();
190  }//GEN-LAST:event_refreshLocalDisksButtonActionPerformed
191 
192  private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
193  dispose();
194  }//GEN-LAST:event_okButtonActionPerformed
195 
196  private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
197  localDiskTable.clearSelection();
198  dispose();
199  }//GEN-LAST:event_cancelButtonActionPerformed
200 
201  // Variables declaration - do not modify//GEN-BEGIN:variables
202  private javax.swing.JButton cancelButton;
203  private javax.swing.JLabel errorLabel;
204  private javax.swing.JScrollPane localDiskScrollPane;
205  private javax.swing.JTable localDiskTable;
206  private javax.swing.JButton okButton;
207  private javax.swing.JButton refreshLocalDisksButton;
208  private javax.swing.JLabel selectLocalDiskLabel;
209  // End of variables declaration//GEN-END:variables
210 
214  private void fireUpdateEvent() {
215  try {
216  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
217  } catch (Exception e) {
218  logger.log(Level.SEVERE, "LocalDiskSelectionDialog listener threw exception", e); //NON-NLS
219  MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
220  Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
221  MessageNotifyUtil.MessageType.ERROR);
222  }
223  }
224 
230  String getContentPaths() {
231  LocalDisk selected = getLocalDiskSelection();
232  if (selected != null) {
233  return selected.getPath();
234  }
235  return "";
236  }
237 
241  private void refreshTable() {
242  model.loadDisks();
243  localDiskTable.clearSelection();
244  }
245 
251  LocalDisk getLocalDiskSelection() {
252  if (disks.size() > 0) {
253  int selectedRow = localDiskTable.getSelectedRow();
254  if (selectedRow >= 0 && selectedRow < disks.size()) {
255  return disks.get(selectedRow);
256  }
257  }
258  return null;
259  }
260 
261  @NbBundle.Messages({
262  "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
263  "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
264  })
268  private class LocalDiskModel implements TableModel {
269 
270  private LocalDiskThread worker = null;
271  private boolean ready = false;
272  private volatile boolean loadingDisks = false;
273 
274  private void loadDisks() {
275 
276  // if there is a worker already building the lists, then cancel it first.
277  if (loadingDisks && worker != null) {
278  worker.cancel(false);
279  }
280 
281  // Clear the lists
282  errorLabel.setText("");
283  localDiskTable.setEnabled(false);
284  ready = false;
285  loadingDisks = true;
286  worker = new LocalDiskThread();
287  worker.execute();
288  }
289 
290  @Override
291  public int getRowCount() {
292  if (disks.isEmpty()) {
293  return 0;
294  }
295  return disks.size();
296  }
297 
298  @Override
299  public int getColumnCount() {
300  return 2;
301 
302  }
303 
304  @NbBundle.Messages({
305  "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
306  "LocalDiskSelectionDialog.columnName.diskSize=Disk Size"
307  })
308 
309  @Override
310  public String getColumnName(int columnIndex) {
311  switch (columnIndex) {
312  case 0:
313  return Bundle.LocalDiskSelectionDialog_columnName_diskName();
314  case 1:
315  return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
316  default:
317  return "Unnamed"; //NON-NLS
318  }
319  }
320 
321  @Override
322  public Class<?> getColumnClass(int columnIndex) {
323  return String.class;
324  }
325 
326  @Override
327  public boolean isCellEditable(int rowIndex, int columnIndex) {
328  return false;
329  }
330 
331  @Override
332  public Object getValueAt(int rowIndex, int columnIndex) {
333  if (ready) {
334  if (disks.isEmpty()) {
335  return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
336  }
337  switch (columnIndex) {
338  case 0:
339  return disks.get(rowIndex).getName();
340  case 1:
341  return disks.get(rowIndex).getReadableSize();
342  default:
343  return disks.get(rowIndex).getPath();
344  }
345  } else {
346  return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
347  }
348  }
349 
350  @Override
351  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
352  //setter does nothing they should not be able to modify table
353  }
354 
355  @Override
356  public void addTableModelListener(TableModelListener l) {
357 
358  }
359 
360  @Override
361  public void removeTableModelListener(TableModelListener l) {
362 
363  }
364 
369  class LocalDiskThread extends SwingWorker<Object, Void> {
370 
371  private final Logger logger = Logger.getLogger(LocalDiskThread.class.getName());
372  private List<LocalDisk> physicalDrives = new ArrayList<>();
373  private List<LocalDisk> partitions = new ArrayList<>();
374 
375  @Override
376  protected Object doInBackground() throws Exception {
377  // Populate the lists
378  physicalDrives = new ArrayList<>();
379  partitions = new ArrayList<>();
380  physicalDrives = PlatformUtil.getPhysicalDrives();
381  partitions = PlatformUtil.getPartitions();
382  return null;
383  }
384 
389  private void displayErrors() {
390  if (physicalDrives.isEmpty() && partitions.isEmpty()) {
391  if (PlatformUtil.isWindowsOS()) {
392  errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
393  errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
394  } else {
395  errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
396  errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
397  }
398  errorLabel.setVisible(true);
399  localDiskTable.setEnabled(false);
400  } else if (physicalDrives.isEmpty()) {
401  errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
402  errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
403  errorLabel.setVisible(true);
404  }
405  }
406 
407  @Override
408  protected void done() {
409  try {
410  super.get(); //block and get all exceptions thrown while doInBackground()
411  } catch (CancellationException ex) {
412  logger.log(Level.INFO, "Loading local disks was canceled."); //NON-NLS
413  } catch (InterruptedException ex) {
414  logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS
415  } catch (ExecutionException ex) {
416  logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS
417  } finally {
418  if (!this.isCancelled()) {
419  displayErrors();
420  worker = null;
421  loadingDisks = false;
422  disks = new ArrayList<>();
423  disks.addAll(physicalDrives);
424  disks.addAll(partitions);
425  if (disks.size() > 0) {
426  localDiskTable.setEnabled(true);
427  localDiskTable.clearSelection();
428 
429  // Remove the partition the application is running on.
430  String userConfigPath = PlatformUtil.getUserConfigDirectory();
431  for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
432  LocalDisk disk = iterator.next();
433  String diskPath = disk.getPath();
434  if (diskPath.startsWith("\\\\.\\")) {
435  // Strip out UNC prefix to get the drive letter.
436  diskPath = diskPath.substring(4);
437  }
438  if (userConfigPath.startsWith(diskPath)) {
439  iterator.remove();
440  }
441  }
442 
443  Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
444  }
445  fireUpdateEvent();
446  ready = true;
447  }
448  }
449  localDiskTable.revalidate();
450  }
451  }
452  }
453 }
static List< LocalDisk > getPhysicalDrives()
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.