Autopsy  4.19.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
VolumeNode.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.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.EnumSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.logging.Level;
28 import javax.swing.Action;
29 import org.openide.nodes.Sheet;
30 import org.openide.util.NbBundle;
38 import org.sleuthkit.datamodel.Content;
39 import org.sleuthkit.datamodel.Pool;
40 import org.sleuthkit.datamodel.TskCoreException;
41 import org.sleuthkit.datamodel.VirtualDirectory;
42 import org.sleuthkit.datamodel.Volume;
44 import org.sleuthkit.datamodel.Tag;
45 
50 public class VolumeNode extends AbstractContentNode<Volume> {
51 
52  private static final Logger logger = Logger.getLogger(VolumeNode.class.getName());
54 
63  static String nameForVolume(Volume vol) {
64  return "vol" + Long.toString(vol.getAddr()); //NON-NLS
65  }
66 
71  public VolumeNode(Volume vol) {
72  super(vol);
73 
74  // set name, display name, and icon
75  String volName = nameForVolume(vol);
76  long end = vol.getStart() + (vol.getLength() - 1);
77  String tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")";
78 
79  // If this is a pool volume use a custom display name
80  try {
81  if (vol.getParent() != null
82  && vol.getParent().getParent() instanceof Pool) {
83  // Pool volumes are not contiguous so printing a range of blocks is inaccurate
84  tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + ")";
85  }
86  } catch (TskCoreException ex) {
87  logger.log(Level.WARNING, "Error looking up parent(s) of volume with obj ID = " + vol.getId(), ex);
88  }
89  this.setDisplayName(tempVolName);
90 
91  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png"); //NON-NLS
92  // Listen for ingest events so that we can detect new added files (e.g. carved)
94  // Listen for case events so that we can detect when case is closed
96  }
97 
98  private void removeListeners() {
101  }
102 
103  /*
104  * This property change listener refreshes the tree when a new file is
105  * carved out of the unallocated space of this volume.
106  */
107  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
108  String eventType = evt.getPropertyName();
109 
110  // See if the new file is a child of ours
111  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
112  if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
113  return;
114  }
115  ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
116  if ((moduleContentEvent.getSource() instanceof Content) == false) {
117  return;
118  }
119  Content newContent = (Content) moduleContentEvent.getSource();
120 
121  try {
122  Content parent = newContent.getParent();
123  if (parent != null) {
124  // Is this a new carved file?
125  if (parent.getName().equals(VirtualDirectory.NAME_CARVED)) {
126  // Is this new carved file for this data source?
127  if (newContent.getDataSource().getId() == getContent().getDataSource().getId()) {
128  // Find the volume (if any) associated with the new content and
129  // trigger a refresh if it matches the volume wrapped by this node.
130  while ((parent = parent.getParent()) != null) {
131  if (parent.getId() == getContent().getId()) {
133  break;
134  }
135  }
136  }
137  }
138  }
139  } catch (TskCoreException ex) {
140  // Do nothing.
141  } catch (NoSuchEventBusException ex) {
142  logger.log(Level.WARNING, eventType, ex);
143  }
144  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
145  if (evt.getNewValue() == null) {
146  // case was closed. Remove listeners so that we don't get called with a stale case handle
147  removeListeners();
148  }
149  }
150  };
151 
159  @Override
160  public Action[] getActions(boolean popup) {
161  List<Action> actionsList = new ArrayList<>();
162 
163  for (Action a : super.getActions(true)) {
164  actionsList.add(a);
165  }
166  actionsList.add(new FileSystemDetailsAction(content));
167  actionsList.add(new NewWindowViewAction(
168  NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this));
169  actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));
170 
171  return actionsList.toArray(new Action[actionsList.size()]);
172  }
173 
174  @Override
175  protected Sheet createSheet() {
176  Sheet sheet = super.createSheet();
177  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
178  if (sheetSet == null) {
179  sheetSet = Sheet.createPropertiesSet();
180  sheet.put(sheetSet);
181  }
182 
183  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.name"),
184  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.displayName"),
185  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.desc"),
186  this.getDisplayName()));
187  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.name"),
188  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.displayName"),
189  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.desc"),
190  content.getAddr()));
191  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.name"),
192  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.displayName"),
193  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.desc"),
194  content.getStart()));
195  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.name"),
196  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.displayName"),
197  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.desc"),
198  content.getLength()));
199  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.name"),
200  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.displayName"),
201  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.desc"),
202  content.getDescription()));
203  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.name"),
204  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.displayName"),
205  NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.desc"),
206  content.getFlagsAsString()));
207 
208  return sheet;
209  }
210 
211  @Override
212  public <T> T accept(ContentNodeVisitor<T> visitor) {
213  return visitor.visit(this);
214  }
215 
216  @Override
217  public boolean isLeafTypeNode() {
218  return false;
219  }
220 
221  @Override
222  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
223  return visitor.visit(this);
224  }
225 
226  @Override
227  public String getItemType() {
228  return DisplayableItemNode.FILE_PARENT_NODE_KEY;
229  }
230 
238  @Override
239  protected List<Tag> getAllTagsFromDatabase() {
240  return new ArrayList<>();
241  }
242 
243 }
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
Definition: VolumeNode.java:53
final PropertyChangeListener pcl
static void post(String nodeName, Object event)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:711
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:756

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