Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.casemodule;
20
21import java.io.File;
22import java.nio.file.Paths;
23import java.util.Calendar;
24import java.util.List;
25import java.util.logging.Level;
26import javax.swing.JFileChooser;
27import javax.swing.JPanel;
28import org.openide.util.NbBundle;
29import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
30import org.sleuthkit.autopsy.coreutils.LocalDisk;
31import org.sleuthkit.autopsy.coreutils.Logger;
32import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
33import org.sleuthkit.autopsy.coreutils.PlatformUtil;
34import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
35import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
36import org.sleuthkit.autopsy.imagewriter.ImageWriterSettings;
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
54final 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-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.