19 package org.sleuthkit.autopsy.modules.embeddedfileextractor;
 
   22 import java.io.FileOutputStream;
 
   23 import java.io.IOException;
 
   24 import java.io.OutputStream;
 
   25 import java.nio.file.Files;
 
   26 import java.nio.file.Paths;
 
   27 import java.util.ArrayList;
 
   28 import java.util.Collections;
 
   29 import java.util.Date;
 
   30 import java.util.List;
 
   31 import java.util.logging.Level;
 
   32 import net.sf.sevenzipjbinding.ArchiveFormat;
 
   33 import static net.sf.sevenzipjbinding.ArchiveFormat.RAR;
 
   34 import net.sf.sevenzipjbinding.ISequentialOutStream;
 
   35 import net.sf.sevenzipjbinding.ISevenZipInArchive;
 
   36 import net.sf.sevenzipjbinding.SevenZip;
 
   37 import net.sf.sevenzipjbinding.SevenZipException;
 
   38 import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
 
   39 import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
 
   40 import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
 
   41 import org.netbeans.api.progress.ProgressHandle;
 
   42 import org.openide.util.NbBundle;
 
   43 import org.openide.util.NbBundle.Messages;
 
   66 class SevenZipExtractor {
 
   68     private static final Logger logger = Logger.getLogger(SevenZipExtractor.class.getName());
 
   69     private IngestServices services = IngestServices.getInstance();
 
   70     private final IngestJobContext context;
 
   71     private final FileTypeDetector fileTypeDetector;
 
   72     static final String[] SUPPORTED_EXTENSIONS = {
"zip", 
"rar", 
"arj", 
"7z", 
"7zip", 
"gzip", 
"gz", 
"bzip2", 
"tar", 
"tgz",}; 
 
   74     private static final String ENCRYPTION_FILE_LEVEL = NbBundle.getMessage(EmbeddedFileExtractorIngestModule.class,
 
   75             "EmbeddedFileExtractorIngestModule.ArchiveExtractor.encryptionFileLevel");
 
   76     private static final String ENCRYPTION_FULL = NbBundle.getMessage(EmbeddedFileExtractorIngestModule.class,
 
   77             "EmbeddedFileExtractorIngestModule.ArchiveExtractor.encryptionFull");
 
   79     private static final int MAX_DEPTH = 4;
 
   80     private static final int MAX_COMPRESSION_RATIO = 600;
 
   81     private static final long MIN_COMPRESSION_RATIO_SIZE = 500 * 1000000L;
 
   82     private static final long MIN_FREE_DISK_SPACE = 1 * 1000 * 1000000L; 
 
   84     private ArchiveDepthCountTree archiveDepthCountTree;
 
   86     private String moduleDirRelative;
 
   87     private String moduleDirAbsolute;
 
   89     private Blackboard blackboard;
 
   91     private String getLocalRootAbsPath(String uniqueArchiveFileName) {
 
   92         return moduleDirAbsolute + File.separator + uniqueArchiveFileName;
 
  107         XRAR(
"application/x-rar-compressed"); 
 
  112             this.mimeType = mimeType;
 
  117             return this.mimeType;
 
  122     SevenZipExtractor(
IngestJobContext context, 
FileTypeDetector fileTypeDetector, String moduleDirRelative, String moduleDirAbsolute) 
throws SevenZipNativeInitializationException {
 
  123         if (!SevenZip.isInitializedSuccessfully() && (SevenZip.getLastInitializationException() == null)) {
 
  124             SevenZip.initSevenZipFromPlatformJAR();
 
  126         this.context = context;
 
  127         this.fileTypeDetector = fileTypeDetector;
 
  128         this.moduleDirRelative = moduleDirRelative;
 
  129         this.moduleDirAbsolute = moduleDirAbsolute;
 
  130         this.archiveDepthCountTree = 
new ArchiveDepthCountTree();
 
  143     boolean isSevenZipExtractionSupported(AbstractFile abstractFile) {
 
  145             String abstractFileMimeType = fileTypeDetector.getFileType(abstractFile);
 
  146             for (SupportedArchiveExtractionFormats s : SupportedArchiveExtractionFormats.values()) {
 
  147                 if (s.toString().equals(abstractFileMimeType)) {
 
  152         } 
catch (TskCoreException ex) {
 
  153             logger.log(Level.WARNING, 
"Error executing FileTypeDetector.getFileType()", ex); 
 
  157         final String extension = abstractFile.getNameExtension();
 
  158         for (String supportedExtension : SUPPORTED_EXTENSIONS) {
 
  159             if (extension.equals(supportedExtension)) {
 
  179     private boolean isZipBombArchiveItemCheck(AbstractFile archiveFile, ISimpleInArchiveItem archiveFileItem) {
 
  181             final Long archiveItemSize = archiveFileItem.getSize();
 
  184             if (archiveItemSize == null || archiveItemSize < MIN_COMPRESSION_RATIO_SIZE) {
 
  188             final Long archiveItemPackedSize = archiveFileItem.getPackedSize();
 
  190             if (archiveItemPackedSize == null || archiveItemPackedSize <= 0) {
 
  191                 logger.log(Level.WARNING, 
"Cannot getting compression ratio, cannot detect if zipbomb: {0}, item: {1}", 
new Object[]{archiveFile.getName(), archiveFileItem.getPath()}); 
 
  195             int cRatio = (int) (archiveItemSize / archiveItemPackedSize);
 
  197             if (cRatio >= MAX_COMPRESSION_RATIO) {
 
  198                 String itemName = archiveFileItem.getPath();
 
  199                 logger.log(Level.INFO, 
"Possible zip bomb detected, compression ration: {0} for in archive item: {1}", 
new Object[]{cRatio, itemName}); 
 
  200                 String msg = NbBundle.getMessage(SevenZipExtractor.class,
 
  201                         "EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg", archiveFile.getName(), itemName);
 
  204                     path = archiveFile.getUniquePath();
 
  205                 } 
catch (TskCoreException ex) {
 
  206                     path = archiveFile.getParentPath() + archiveFile.getName();
 
  208                 String details = NbBundle.getMessage(SevenZipExtractor.class,
 
  209                         "EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails", cRatio, path);
 
  211                 services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
 
  217         } 
catch (SevenZipException ex) {
 
  218             logger.log(Level.WARNING, 
"Error getting archive item size and cannot detect if zipbomb. ", ex); 
 
  231     private ArchiveFormat get7ZipOptions(AbstractFile archiveFile) {
 
  233         String detectedFormat = null;
 
  234         detectedFormat = archiveFile.getMIMEType();
 
  236         if (detectedFormat == null) {
 
  237             logger.log(Level.WARNING, 
"Could not detect format for file: {0}", archiveFile); 
 
  240             String extension = archiveFile.getNameExtension();
 
  241             if (
"rar".equals(extension)) 
 
  250         } 
else if (detectedFormat.contains(
"application/x-rar-compressed")) 
 
  269     @Messages({
"SevenZipExtractor.indexError.message=Failed to index encryption detected artifact for keyword search."})
 
  270     void unpack(AbstractFile archiveFile) {
 
  271         blackboard = Case.getCurrentCase().getServices().getBlackboard();
 
  272         String archiveFilePath;
 
  274             archiveFilePath = archiveFile.getUniquePath();
 
  275         } 
catch (TskCoreException ex) {
 
  276             archiveFilePath = archiveFile.getParentPath() + archiveFile.getName();
 
  281             if (archiveFile.hasChildren()) {
 
  283                 if (
new File(EmbeddedFileExtractorIngestModule.getUniqueName(archiveFile)).exists()) {
 
  284                     logger.log(Level.INFO, 
"File already has been processed as it has children and local unpacked file, skipping: {0}", archiveFilePath); 
 
  288         } 
catch (TskCoreException e) {
 
  289             logger.log(Level.INFO, 
"Error checking if file already has been processed, skipping: {0}", archiveFilePath); 
 
  293         List<AbstractFile> unpackedFiles = Collections.<AbstractFile>emptyList();
 
  296         final long archiveId = archiveFile.getId();
 
  297         SevenZipExtractor.ArchiveDepthCountTree.Archive parentAr = archiveDepthCountTree.findArchive(archiveId);
 
  298         if (parentAr == null) {
 
  299             parentAr = archiveDepthCountTree.addArchive(null, archiveId);
 
  300         } 
else if (parentAr.getDepth() == MAX_DEPTH) {
 
  301             String msg = NbBundle.getMessage(SevenZipExtractor.class,
 
  302                     "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb", archiveFile.getName());
 
  303             String details = NbBundle.getMessage(SevenZipExtractor.class,
 
  304                     "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb",
 
  305                     parentAr.getDepth(), archiveFilePath);
 
  307             services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
 
  311         boolean hasEncrypted = 
false;
 
  312         boolean fullEncryption = 
true;
 
  314         ISevenZipInArchive inArchive = null;
 
  315         SevenZipContentReadStream stream = null;
 
  317         final ProgressHandle progress = ProgressHandle.createHandle(Bundle.EmbeddedFileExtractorIngestModule_ArchiveExtractor_moduleName());
 
  318         int processedItems = 0;
 
  320         boolean progressStarted = 
false;
 
  322             stream = 
new SevenZipContentReadStream(
new ReadContentInputStream(archiveFile));
 
  327             ArchiveFormat options = get7ZipOptions(archiveFile);
 
  328             inArchive = SevenZip.openInArchive(options, stream);
 
  330             int numItems = inArchive.getNumberOfItems();
 
  331             logger.log(Level.INFO, 
"Count of items in archive: {0}: {1}", 
new Object[]{archiveFilePath, numItems}); 
 
  332             progress.start(numItems);
 
  333             progressStarted = 
true;
 
  335             final ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
 
  338             final String uniqueArchiveFileName = FileUtil.escapeFileName(EmbeddedFileExtractorIngestModule.getUniqueName(archiveFile));
 
  339             final String localRootAbsPath = getLocalRootAbsPath(uniqueArchiveFileName);
 
  340             final File localRoot = 
new File(localRootAbsPath);
 
  341             if (!localRoot.exists()) {
 
  344                 } 
catch (SecurityException e) {
 
  345                     logger.log(Level.SEVERE, 
"Error setting up output path for archive root: {0}", localRootAbsPath); 
 
  352             SevenZipExtractor.UnpackedTree unpackedTree = 
new SevenZipExtractor.UnpackedTree(moduleDirRelative + 
"/" + uniqueArchiveFileName, archiveFile);
 
  354             long freeDiskSpace = services.getFreeDiskSpace();
 
  358             for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
 
  359                 String pathInArchive = item.getPath();
 
  361                 if (pathInArchive == null || pathInArchive.isEmpty()) {
 
  367                     String archName = archiveFile.getName();
 
  368                     int dotI = archName.lastIndexOf(
".");
 
  369                     String useName = null;
 
  371                         String base = archName.substring(0, dotI);
 
  372                         String ext = archName.substring(dotI);
 
  373                         int colonIndex = ext.lastIndexOf(
":");
 
  374                         if (colonIndex != -1) {
 
  377                             ext = ext.substring(0, colonIndex);
 
  384                                 useName = base + 
".tar"; 
 
  392                     if (useName == null) {
 
  393                         pathInArchive = 
"/" + archName + 
"/" + Integer.toString(itemNumber);
 
  395                         pathInArchive = 
"/" + useName;
 
  398                     String msg = NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg",
 
  399                             archiveFilePath, pathInArchive);
 
  400                     logger.log(Level.WARNING, msg);
 
  403                 archiveFilePath = FileUtil.escapeFileName(archiveFilePath);
 
  407                 if (isZipBombArchiveItemCheck(archiveFile, item)) {
 
  412                 SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode = unpackedTree.addNode(pathInArchive);
 
  414                 String fileName = unpackedNode.getFileName();
 
  417                 progress.progress(archiveFile.getName() + 
": " + fileName, processedItems);
 
  419                 final boolean isEncrypted = item.isEncrypted();
 
  420                 final boolean isDir = item.isFolder();
 
  423                     logger.log(Level.WARNING, 
"Skipping encrypted file in archive: {0}", pathInArchive); 
 
  427                     fullEncryption = 
false;
 
  432                 Long size = item.getSize();
 
  436                 if (freeDiskSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN && size != null && size > 0) { 
 
  437                     long newDiskSpace = freeDiskSpace - size;
 
  438                     if (newDiskSpace < MIN_FREE_DISK_SPACE) {
 
  439                         String msg = NbBundle.getMessage(SevenZipExtractor.class,
 
  440                                 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg",
 
  441                                 archiveFilePath, fileName);
 
  442                         String details = NbBundle.getMessage(SevenZipExtractor.class,
 
  443                                 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details");
 
  445                         services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
 
  446                         logger.log(Level.INFO, 
"Skipping archive item due to insufficient disk space: {0}, {1}", 
new Object[]{archiveFilePath, fileName}); 
 
  447                         logger.log(Level.INFO, 
"Available disk space: {0}", 
new Object[]{freeDiskSpace}); 
 
  451                         freeDiskSpace = newDiskSpace;
 
  455                 final String uniqueExtractedName = FileUtil.escapeFileName(uniqueArchiveFileName + File.separator + (item.getItemIndex() / 1000) + File.separator + item.getItemIndex() + 
"_" + 
new File(pathInArchive).getName());
 
  458                 final String localRelPath = moduleDirRelative + File.separator + uniqueExtractedName;
 
  459                 final String localAbsPath = moduleDirAbsolute + File.separator + uniqueExtractedName;
 
  462                 File localFile = 
new java.io.File(localAbsPath);
 
  464                 if (!localFile.exists()) {
 
  469                             localFile.getParentFile().mkdirs();
 
  471                                 localFile.createNewFile();
 
  472                             } 
catch (IOException e) {
 
  473                                 logger.log(Level.SEVERE, 
"Error creating extracted file: " + localFile.getAbsolutePath(), e); 
 
  476                     } 
catch (SecurityException e) {
 
  477                         logger.log(Level.SEVERE, 
"Error setting up output path for unpacked file: {0}", pathInArchive); 
 
  483                 if (localFile.exists() == 
false) {
 
  487                 final Date createTime = item.getCreationTime();
 
  488                 final Date accessTime = item.getLastAccessTime();
 
  489                 final Date writeTime = item.getLastWriteTime();
 
  490                 final long createtime = createTime == null ? 0L : createTime.getTime() / 1000;
 
  491                 final long modtime = writeTime == null ? 0L : writeTime.getTime() / 1000;
 
  492                 final long accesstime = accessTime == null ? 0L : accessTime.getTime() / 1000;
 
  495                 SevenZipExtractor.UnpackStream unpackStream = null;
 
  499                             unpackStream = 
new SevenZipExtractor.KnownSizeUnpackStream(localAbsPath, size);
 
  501                             unpackStream = 
new SevenZipExtractor.UnknownSizeUnpackStream(localAbsPath, freeDiskSpace);
 
  503                         item.extractSlow(unpackStream);
 
  504                     } 
catch (Exception e) {
 
  506                         logger.log(Level.WARNING, 
"Could not extract file from archive: " + localAbsPath, e); 
 
  508                         if (unpackStream != null) {
 
  510                             unpackedNode.addDerivedInfo(unpackStream.getSize(), !isDir,
 
  511                                     0L, createtime, accesstime, modtime, localRelPath);
 
  512                             unpackStream.close();
 
  516                     unpackedNode.addDerivedInfo(0, !isDir,
 
  517                             0L, createtime, accesstime, modtime, localRelPath);
 
  527                 unpackedTree.addDerivedFilesToCase();
 
  528                 unpackedFiles = unpackedTree.getAllFileObjects();
 
  531                 for (AbstractFile unpackedFile : unpackedFiles) {
 
  532                     if (isSevenZipExtractionSupported(unpackedFile)) {
 
  533                         archiveDepthCountTree.addArchive(parentAr, unpackedFile.getId());
 
  537             } 
catch (TskCoreException e) {
 
  538                 logger.log(Level.SEVERE, 
"Error populating complete derived file hierarchy from the unpacked dir structure"); 
 
  542         } 
catch (SevenZipException ex) {
 
  543             logger.log(Level.WARNING, 
"Error unpacking file: {0}", archiveFile); 
 
  547             if (archiveFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
 
  548                 String msg = NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg",
 
  549                         archiveFile.getName());
 
  550                 String details = NbBundle.getMessage(SevenZipExtractor.class,
 
  551                         "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.details",
 
  552                         archiveFilePath, ex.getMessage());
 
  553                 services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
 
  556             if (inArchive != null) {
 
  559                 } 
catch (SevenZipException e) {
 
  560                     logger.log(Level.SEVERE, 
"Error closing archive: " + archiveFile, e); 
 
  564             if (stream != null) {
 
  567                 } 
catch (IOException ex) {
 
  568                     logger.log(Level.SEVERE, 
"Error closing stream after unpacking archive: " + archiveFile, ex); 
 
  573             if (progressStarted) {
 
  580             String encryptionType = fullEncryption ? ENCRYPTION_FULL : ENCRYPTION_FILE_LEVEL;
 
  582                 BlackboardArtifact artifact = archiveFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED);
 
  583                 artifact.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, EmbeddedFileExtractorModuleFactory.getModuleName(), encryptionType));
 
  587                     blackboard.indexArtifact(artifact);
 
  588                 } 
catch (Blackboard.BlackboardException ex) {
 
  589                     logger.log(Level.SEVERE, 
"Unable to index blackboard artifact " + artifact.getArtifactID(), ex); 
 
  590                     MessageNotifyUtil.Notify.error(
 
  591                             Bundle.SevenZipExtractor_indexError_message(), artifact.getDisplayName());
 
  594                 services.fireModuleDataEvent(
new ModuleDataEvent(EmbeddedFileExtractorModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED));
 
  595             } 
catch (TskCoreException ex) {
 
  596                 logger.log(Level.SEVERE, 
"Error creating blackboard artifact for encryption detected for file: " + archiveFilePath, ex); 
 
  599             String msg = NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.encrFileDetected.msg");
 
  600             String details = NbBundle.getMessage(SevenZipExtractor.class,
 
  601                     "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.encrFileDetected.details",
 
  602                     archiveFile.getName(), EmbeddedFileExtractorModuleFactory.getModuleName());
 
  603             services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
 
  607         if (!unpackedFiles.isEmpty()) {
 
  609             services.fireModuleContentEvent(
new ModuleContentEvent(archiveFile));
 
  610             context.addFilesToJob(unpackedFiles);
 
  617     private abstract static class UnpackStream implements ISequentialOutStream {
 
  625                 output = 
new EncodedFileOutputStream(
new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
 
  626             } 
catch (IOException ex) {
 
  627                 logger.log(Level.SEVERE, 
"Error writing extracted file: " + localAbsPath, ex); 
 
  632         public abstract long getSize();
 
  634         OutputStream getOutput() {
 
  638         String getLocalAbsPath() {
 
  643             if (output != null) {
 
  647                 } 
catch (IOException e) {
 
  648                     logger.log(Level.SEVERE, 
"Error closing unpack stream for file: {0}", localAbsPath); 
 
  674         public int write(byte[] bytes) 
throws SevenZipException {
 
  680                     getOutput().write(bytes);
 
  684                     this.bytesWritten += bytes.length;
 
  685                     this.freeDiskSpace -= bytes.length;
 
  687                     this.outOfSpace = 
true;
 
  688                     logger.log(Level.INFO, NbBundle.getMessage(
 
  689                             SevenZipExtractor.class,
 
  690                             "EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.noSpace.msg"));
 
  691                     throw new SevenZipException(
 
  692                             NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.noSpace.msg"));
 
  694             } 
catch (IOException ex) {
 
  695                 throw new SevenZipException(
 
  696                         NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.exception.msg",
 
  697                                 getLocalAbsPath()), ex);
 
  704             if (getOutput() != null) {
 
  708                     if (this.outOfSpace) {
 
  709                         Files.delete(Paths.get(getLocalAbsPath()));
 
  711                 } 
catch (IOException e) {
 
  712                     logger.log(Level.SEVERE, 
"Error closing unpack stream for file: {0}", getLocalAbsPath()); 
 
  736         public int write(byte[] bytes) 
throws SevenZipException {
 
  738                 getOutput().write(bytes);
 
  739             } 
catch (IOException ex) {
 
  740                 throw new SevenZipException(
 
  741                         NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.exception.msg",
 
  742                                 getLocalAbsPath()), ex);
 
  766         UnpackedTree(String localPathRoot, AbstractFile archiveFile) {
 
  768             this.rootNode.setFile(archiveFile);
 
  783             String[] toks = filePath.split(
"[\\/\\\\]");
 
  784             List<String> tokens = 
new ArrayList<>();
 
  785             for (
int i = 0; i < toks.length; ++i) {
 
  786                 if (!toks[i].isEmpty()) {
 
  790             return addNode(rootNode, tokens);
 
  803             if (tokenPath.isEmpty()) {
 
  808             String childName = tokenPath.remove(0);
 
  816             return addNode(child, tokenPath);
 
  825         List<AbstractFile> getRootFileObjects() {
 
  826             List<AbstractFile> ret = 
new ArrayList<>();
 
  827             for (UnpackedNode child : rootNode.
children) {
 
  828                 ret.add(child.getFile());
 
  839         List<AbstractFile> getAllFileObjects() {
 
  840             List<AbstractFile> ret = 
new ArrayList<>();
 
  841             for (UnpackedNode child : rootNode.
children) {
 
  858         void addDerivedFilesToCase() throws TskCoreException {
 
  860             for (UnpackedNode child : rootNode.
children) {
 
  866             final String fileName = node.getFileName();
 
  869                 DerivedFile df = fileManager.
addDerivedFile(fileName, node.getLocalRelPath(), node.getSize(),
 
  870                         node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(),
 
  872                         "", 
"", TskData.EncodingType.XOR1);
 
  875             } 
catch (TskCoreException ex) {
 
  876                 logger.log(Level.SEVERE, 
"Error adding a derived file to db:" + fileName, ex); 
 
  877                 throw new TskCoreException(
 
  878                         NbBundle.getMessage(SevenZipExtractor.class, 
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackedTree.exception.msg",
 
  895             private List<UnpackedNode> 
children = 
new ArrayList<>();
 
  896             private String localRelPath = 
"";
 
  898             private long ctime, crtime, atime, mtime;
 
  940             void addDerivedInfo(
long size,
 
  942                     long ctime, 
long crtime, 
long atime, 
long mtime, String relLocalPath) {
 
  946                 this.crtime = crtime;
 
  949                 this.localRelPath = relLocalPath;
 
  952             void setFile(AbstractFile file) {
 
  963             UnpackedNode getChild(String childFileName) {
 
  964                 UnpackedNode ret = null;
 
  965                 for (UnpackedNode child : children) {
 
  966                     if (child.fileName.equals(childFileName)) {
 
 1002         private final List<Archive> 
archives = 
new ArrayList<>();
 
 1011         Archive findArchive(
long objectId) {
 
 1013                 if (ar.objectId == objectId) {
 
 1029         Archive addArchive(Archive parent, 
long objectId) {
 
 1030             Archive child = 
new Archive(parent, objectId);
 
 1031             archives.add(child);
 
 1040             List<Archive> children;
 
 1043                 this.parent = parent;
 
 1044                 this.objectId = objectId;
 
 1045                 children = 
new ArrayList<>();
 
 1046                 if (parent != null) {
 
 1047                     parent.children.add(
this);
 
 1048                     this.depth = parent.depth + 1;
 
FileManager getFileManager()
static final int DISK_FREE_SPACE_UNKNOWN
synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parentFile, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)
static Case getCurrentCase()