Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.casemodule;
20
21import java.awt.Window;
22import java.util.ArrayList;
23import java.util.Collections;
24import java.util.Iterator;
25import java.util.List;
26import java.util.concurrent.CancellationException;
27import java.util.concurrent.ExecutionException;
28import java.util.logging.Level;
29import javax.swing.JDialog;
30import javax.swing.SwingWorker;
31import javax.swing.event.ListSelectionEvent;
32import javax.swing.event.ListSelectionListener;
33import javax.swing.event.TableModelListener;
34import javax.swing.table.TableModel;
35import org.openide.util.NbBundle;
36import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
37import org.sleuthkit.autopsy.coreutils.LocalDisk;
38import org.sleuthkit.autopsy.coreutils.Logger;
39import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
40import org.sleuthkit.autopsy.coreutils.PlatformUtil;
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
53final 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 org.openide.awt.Mnemonics.setLocalizedText(selectLocalDiskLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.selectLocalDiskLabel.text")); // NOI18N
115
116 errorLabel.setForeground(new java.awt.Color(255, 0, 0));
117 org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.errorLabel.text")); // NOI18N
118
119 localDiskTable.setModel(model);
120 localDiskTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
121 localDiskScrollPane.setViewportView(localDiskTable);
122
123 org.openide.awt.Mnemonics.setLocalizedText(refreshLocalDisksButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.refreshLocalDisksButton.text")); // NOI18N
124 refreshLocalDisksButton.addActionListener(new java.awt.event.ActionListener() {
125 public void actionPerformed(java.awt.event.ActionEvent evt) {
126 refreshLocalDisksButtonActionPerformed(evt);
127 }
128 });
129
130 org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.okButton.text")); // NOI18N
131 okButton.setEnabled(false);
132 okButton.addActionListener(new java.awt.event.ActionListener() {
133 public void actionPerformed(java.awt.event.ActionEvent evt) {
134 okButtonActionPerformed(evt);
135 }
136 });
137
138 org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(LocalDiskSelectionDialog.class, "LocalDiskSelectionDialog.cancelButton.text")); // NOI18N
139 cancelButton.addActionListener(new java.awt.event.ActionListener() {
140 public void actionPerformed(java.awt.event.ActionEvent evt) {
141 cancelButtonActionPerformed(evt);
142 }
143 });
144
145 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
146 getContentPane().setLayout(layout);
147 layout.setHorizontalGroup(
148 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
149 .addGroup(layout.createSequentialGroup()
150 .addContainerGap()
151 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
152 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
153 .addGroup(layout.createSequentialGroup()
154 .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
155 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
156 .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
157 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
158 .addComponent(refreshLocalDisksButton))
159 .addGroup(layout.createSequentialGroup()
160 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
161 .addComponent(selectLocalDiskLabel)
162 .addComponent(errorLabel))
163 .addGap(0, 0, Short.MAX_VALUE)))
164 .addContainerGap())
165 );
166 layout.setVerticalGroup(
167 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
168 .addGroup(layout.createSequentialGroup()
169 .addGap(6, 6, 6)
170 .addComponent(selectLocalDiskLabel)
171 .addGap(4, 4, 4)
172 .addComponent(localDiskScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
173 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
174 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
175 .addComponent(refreshLocalDisksButton)
176 .addComponent(okButton)
177 .addComponent(cancelButton))
178 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
179 .addComponent(errorLabel)
180 .addContainerGap(27, Short.MAX_VALUE))
181 );
182
183 pack();
184 }// </editor-fold>//GEN-END:initComponents
185
186 private void refreshLocalDisksButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshLocalDisksButtonActionPerformed
187 refreshTable();
188 }//GEN-LAST:event_refreshLocalDisksButtonActionPerformed
189
190 private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
191 dispose();
192 }//GEN-LAST:event_okButtonActionPerformed
193
194 private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
195 localDiskTable.clearSelection();
196 dispose();
197 }//GEN-LAST:event_cancelButtonActionPerformed
198
199 // Variables declaration - do not modify//GEN-BEGIN:variables
200 private javax.swing.JButton cancelButton;
201 private javax.swing.JLabel errorLabel;
202 private javax.swing.JScrollPane localDiskScrollPane;
203 private javax.swing.JTable localDiskTable;
204 private javax.swing.JButton okButton;
205 private javax.swing.JButton refreshLocalDisksButton;
206 private javax.swing.JLabel selectLocalDiskLabel;
207 // End of variables declaration//GEN-END:variables
208
212 private void fireUpdateEvent() {
213 try {
214 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
215 } catch (Exception e) {
216 logger.log(Level.SEVERE, "LocalDiskSelectionDialog listener threw exception", e); //NON-NLS
217 MessageNotifyUtil.Notify.show(Bundle.LocalDiskSelectionDialog_moduleErrorMessage_title(),
218 Bundle.LocalDiskSelectionDialog_moduleErrorMessage_body(),
219 MessageNotifyUtil.MessageType.ERROR);
220 }
221 }
222
228 String getContentPaths() {
229 LocalDisk selected = getLocalDiskSelection();
230 if (selected != null) {
231 return selected.getPath();
232 }
233 return "";
234 }
235
239 private void refreshTable() {
240 model.loadDisks();
241 localDiskTable.clearSelection();
242 }
243
249 LocalDisk getLocalDiskSelection() {
250 if (disks.size() > 0) {
251 int selectedRow = localDiskTable.getSelectedRow();
252 if (selectedRow >= 0 && selectedRow < disks.size()) {
253 return disks.get(selectedRow);
254 }
255 }
256 return null;
257 }
258
259 @NbBundle.Messages({
260 "LocalDiskSelectionDialog.tableMessage.loading=Loading local disks...",
261 "LocalDiskSelectionDialog.tableMessage.noDrives=No Accessible Drives",
262 })
266 private class LocalDiskModel implements TableModel {
267
268 private LocalDiskThread worker = null;
269 private boolean ready = false;
270 private volatile boolean loadingDisks = false;
271
272 private void loadDisks() {
273
274 // if there is a worker already building the lists, then cancel it first.
275 if (loadingDisks && worker != null) {
276 worker.cancel(false);
277 }
278
279 // Clear the lists
280 errorLabel.setText("");
281 localDiskTable.setEnabled(false);
282 ready = false;
283 loadingDisks = true;
284 worker = new LocalDiskThread();
285 worker.execute();
286 }
287
288 @Override
289 public int getRowCount() {
290 if (disks.isEmpty()) {
291 return 0;
292 }
293 return disks.size();
294 }
295
296 @Override
297 public int getColumnCount() {
298 return 2;
299
300 }
301
302 @NbBundle.Messages({
303 "LocalDiskSelectionDialog.columnName.diskName=Disk Name",
304 "LocalDiskSelectionDialog.columnName.diskSize=Disk Size"
305 })
306
307 @Override
308 public String getColumnName(int columnIndex) {
309 switch (columnIndex) {
310 case 0:
311 return Bundle.LocalDiskSelectionDialog_columnName_diskName();
312 case 1:
313 return Bundle.LocalDiskSelectionDialog_columnName_diskSize();
314 default:
315 return "Unnamed"; //NON-NLS
316 }
317 }
318
319 @Override
320 public Class<?> getColumnClass(int columnIndex) {
321 return String.class;
322 }
323
324 @Override
325 public boolean isCellEditable(int rowIndex, int columnIndex) {
326 return false;
327 }
328
329 @Override
330 public Object getValueAt(int rowIndex, int columnIndex) {
331 if (ready) {
332 if (disks.isEmpty()) {
333 return Bundle.LocalDiskSelectionDialog_tableMessage_noDrives();
334 }
335 switch (columnIndex) {
336 case 0:
337 return disks.get(rowIndex).getName();
338 case 1:
339 return disks.get(rowIndex).getReadableSize();
340 default:
341 return disks.get(rowIndex).getPath();
342 }
343 } else {
344 return Bundle.LocalDiskSelectionDialog_tableMessage_loading();
345 }
346 }
347
348 @Override
349 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
350 //setter does nothing they should not be able to modify table
351 }
352
353 @Override
354 public void addTableModelListener(TableModelListener l) {
355
356 }
357
358 @Override
359 public void removeTableModelListener(TableModelListener l) {
360
361 }
362
367 class LocalDiskThread extends SwingWorker<Object, Void> {
368
369 private final Logger logger = Logger.getLogger(LocalDiskThread.class.getName());
370 private List<LocalDisk> physicalDrives = new ArrayList<>();
371 private List<LocalDisk> partitions = new ArrayList<>();
372
373 @Override
374 protected Object doInBackground() throws Exception {
375 // Populate the lists
376 physicalDrives = new ArrayList<>();
377 partitions = new ArrayList<>();
378 physicalDrives = PlatformUtil.getPhysicalDrives();
379 partitions = PlatformUtil.getPartitions();
380 return null;
381 }
382
387 private void displayErrors() {
388 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
390 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
391 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_disksNotDetected());
392 } else {
393 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
394 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_drivesNotDetected());
395 }
396 errorLabel.setVisible(true);
397 localDiskTable.setEnabled(false);
398 } else if (physicalDrives.isEmpty()) {
399 errorLabel.setText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
400 errorLabel.setToolTipText(Bundle.LocalDiskSelectionDialog_errorMessage_someDisksNotDetected());
401 errorLabel.setVisible(true);
402 }
403 }
404
405 @Override
406 protected void done() {
407 try {
408 super.get(); //block and get all exceptions thrown while doInBackground()
409 } catch (CancellationException ex) {
410 logger.log(Level.INFO, "Loading local disks was canceled."); //NON-NLS
411 } catch (InterruptedException ex) {
412 logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS
413 } catch (ExecutionException ex) {
414 logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS
415 } finally {
416 if (!this.isCancelled()) {
417 displayErrors();
418 worker = null;
419 loadingDisks = false;
420 disks = new ArrayList<>();
421 disks.addAll(physicalDrives);
422 disks.addAll(partitions);
423 if (disks.size() > 0) {
424 localDiskTable.setEnabled(true);
425 localDiskTable.clearSelection();
426
427 // Remove the partition the application is running on.
428 String userConfigPath = PlatformUtil.getUserConfigDirectory();
429 for (Iterator<LocalDisk> iterator = disks.iterator(); iterator.hasNext();) {
430 LocalDisk disk = iterator.next();
431 String diskPath = disk.getPath();
432 if (diskPath.startsWith("\\\\.\\")) {
433 // Strip out UNC prefix to get the drive letter.
434 diskPath = diskPath.substring(4);
435 }
436 if (userConfigPath.startsWith(diskPath)) {
437 iterator.remove();
438 }
439 }
440
441 Collections.sort(disks, (LocalDisk disk1, LocalDisk disk2) -> disk1.getName().compareToIgnoreCase(disk2.getName()));
442 }
443 fireUpdateEvent();
444 ready = true;
445 }
446 }
447 localDiskTable.revalidate();
448 }
449 }
450 }
451}
synchronized static Logger getLogger(String name)
Definition Logger.java:124

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.