19 package org.sleuthkit.autopsy.recentactivity;
 
   21 import java.util.ArrayList;
 
   22 import java.util.Collection;
 
   23 import java.util.List;
 
   24 import java.util.logging.Level;
 
   25 import org.apache.commons.io.FilenameUtils;
 
   26 import org.openide.util.NbBundle.Messages;
 
   45 @Messages({
"DataSourceUsageAnalyzer.displayName=Data Source Usage Analyzer"})
 
   46 class DataSourceUsageAnalyzer extends Extract {
 
   48     private static final Logger logger = Logger.getLogger(DataSourceUsageAnalyzer.class.getName());
 
   50             | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue()
 
   51             | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_EXFAT.getValue();
 
   52     private static final long HUNDRED_GB = 100 * 1024 * 1024 * 1024l;
 
   54     private static final String ANDROID_MEDIACARD_ROOT_FILENAMES[]
 
   56             {
".android_secure", 
"android", 
"audio",
 
   57                 "photos", 
"dcim", 
"music", 
"pictures", 
"videos"}; 
 
   58     private Content dataSource;
 
   59     private final IngestJobContext context;
 
   61     DataSourceUsageAnalyzer(IngestJobContext context) {
 
   62         super(Bundle.DataSourceUsageAnalyzer_displayName(), context);
 
   63         this.context = context;
 
   68         "DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})",
 
   69         "Progress_Message_Analyze_Usage=Data Sources Usage Analysis",})
 
   71     void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
 
   72         this.dataSource = dataSource;
 
   74             progressBar.progress(Bundle.Progress_Message_Analyze_Usage());
 
   75             createDataSourceUsageArtifacts();
 
   76         } 
catch (TskCoreException ex) {
 
   77             logger.log(Level.WARNING, 
"Failed to check if datasource contained a volume with operating system specific files", ex);
 
   82     private void createDataSourceUsageArtifacts() throws TskCoreException {
 
   83         createOSInfoDataSourceUsageArtifacts();
 
   84         if (context.dataSourceIngestIsCancelled()) {
 
   87         createAndroidMediaCardArtifacts();
 
   88         if (context.dataSourceIngestIsCancelled()) {
 
   91         createDJIDroneDATArtitifacts();
 
  100     private void createOSInfoDataSourceUsageArtifacts() throws TskCoreException {
 
  101         boolean windowsOsDetected = 
false;
 
  102         List<BlackboardArtifact> osInfoArtifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO);
 
  103         for (BlackboardArtifact osInfoArt : osInfoArtifacts) {
 
  105             if (osInfoArt.getDataSource().getId() == dataSource.getId()) {
 
  106                 BlackboardAttribute progNameAttr = osInfoArt.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
 
  107                 if (progNameAttr != null) {
 
  108                     if (progNameAttr.getValueString().isEmpty()) {
 
  110                     } 
else if (progNameAttr.getDisplayString().toLowerCase().contains(
"windows")) { 
 
  111                         windowsOsDetected = 
true;
 
  113                         createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
 
  115                         ExtractOs.OS_TYPE osType = ExtractOs.OS_TYPE.fromOsInfoLabel(progNameAttr.getValueString());
 
  116                         if (osType != null) {
 
  117                             createDataSourceUsageArtifact(osType.getDsUsageLabel());
 
  120                             createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
 
  126         if (!windowsOsDetected) {  
 
  127             checkIfOsSpecificVolume(ExtractOs.OS_TYPE.WINDOWS);
 
  140     private void createDataSourceUsageArtifact(String dataSourceUsageDescription) 
throws TskCoreException {
 
  142         List<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE, dataSource.getId());
 
  143         for (BlackboardArtifact artifact : artifacts) {
 
  144             if (artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)).getValueString().equals(dataSourceUsageDescription)) {
 
  148         Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  149         bbattributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION,
 
  151                 dataSourceUsageDescription)); 
 
  152         postArtifact(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DATA_SOURCE_USAGE, dataSource, bbattributes));
 
  162     private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException {
 
  163         for (String filePath : osType.getFilePaths()) {
 
  164             for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
 
  165                     FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
 
  166                 createDataSourceUsageArtifact(osType.getDsUsageLabel());
 
  181         "DataSourceUsage_AndroidMedia=Android Media Card",
 
  182         "DataSourceUsage_FlashDrive=Flash Drive" 
  184     private void createAndroidMediaCardArtifacts() {
 
  186         if (dataSource instanceof Image) {
 
  187             Image image = (Image) dataSource;
 
  189                 if (image.getSize() > HUNDRED_GB) {
 
  193                 List<FileSystem> fileSystems = image.getFileSystems();
 
  194                 if (fileSystems.isEmpty() || fileSystems.size() > 1) {
 
  198                 FileSystem fileSystem = fileSystems.get(0);
 
  199                 if (fileSystem == null || (fileSystem.getFsType().getValue() & FAT_EXFAT_FLAGS) == 0) {
 
  203                 if (hasAndroidMediaCardRootNames()) {
 
  208                 createDataSourceUsageArtifact(Bundle.DataSourceUsage_FlashDrive());
 
  210             } 
catch (TskCoreException ex) {
 
  211                 logger.log(Level.SEVERE, 
"Exception while checking image: {0} for Andriod media card", image.getName() + ex.getMessage()); 
 
  223     private boolean hasAndroidMediaCardRootNames() throws TskCoreException {
 
  224         FileManager fileManager = currentCase.getServices().getFileManager();
 
  225         for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) {
 
  226             for (AbstractFile file : fileManager.findFiles(dataSource, fileName, 
"/")) { 
 
  227                 if (file.getParentPath().equals(
"/") && file.getName().equalsIgnoreCase(fileName)) { 
 
  228                     createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia());
 
  246         "DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card" 
  248     private void createDJIDroneDATArtitifacts() throws TskCoreException {
 
  249         FileManager fileManager = currentCase.getServices().getFileManager();
 
  251         List<AbstractFile> files = fileManager.findFiles(dataSource, 
"FLY___.DAT");
 
  252         if (files != null && !files.isEmpty()) {
 
  253             createDataSourceUsageArtifact(Bundle.DataSourceUsage_DJU_Drone_DAT());