19 package org.sleuthkit.autopsy.modules.photoreccarver;
 
   22 import java.io.FileNotFoundException;
 
   23 import java.io.IOException;
 
   24 import java.nio.file.Path;
 
   25 import java.nio.file.Paths;
 
   26 import java.util.ArrayList;
 
   27 import java.util.Collections;
 
   28 import java.util.List;
 
   29 import java.util.logging.Level;
 
   30 import org.openide.util.NbBundle;
 
   43 import org.w3c.dom.Document;
 
   44 import org.w3c.dom.Element;
 
   45 import org.w3c.dom.NodeList;
 
   46 import org.w3c.dom.Node;
 
   52 class PhotoRecCarverOutputParser {
 
   54     private final Path basePath;
 
   55     private static final Logger logger = Logger.getLogger(PhotoRecCarverFileIngestModule.class.getName());
 
   57     PhotoRecCarverOutputParser(Path base) {
 
   77     List<LayoutFile> parse(File xmlInputFile, AbstractFile af, IngestJobContext context) 
throws FileNotFoundException, IOException {
 
   79             final Document doc = XMLUtil.loadDoc(PhotoRecCarverOutputParser.class, xmlInputFile.toString());
 
   81                 return new ArrayList<>();
 
   84             Element root = doc.getDocumentElement();
 
   86                 logger.log(Level.SEVERE, 
"Error loading config file: invalid file format (bad root)."); 
 
   87                 return new ArrayList<>();
 
   90             NodeList fileObjects = root.getElementsByTagName(
"fileobject"); 
 
   91             final int numberOfFiles = fileObjects.getLength();
 
   93             if (numberOfFiles == 0) {
 
   94                 return new ArrayList<>();
 
  103             FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
 
  106             List<CarvingResult.CarvedFile> carvedFiles = 
new ArrayList<>();
 
  107             for (
int fileIndex = 0; fileIndex < numberOfFiles; ++fileIndex) {
 
  108                 if (context.fileIngestIsCancelled() == 
true) {
 
  110                     logger.log(Level.INFO, 
"PhotoRec cancelled by user"); 
 
  111                     MessageNotifyUtil.Notify.info(PhotoRecCarverIngestModuleFactory.getModuleName(), NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, 
"PhotoRecIngestModule.cancelledByUser"));
 
  114                 entry = (Element) fileObjects.item(fileIndex);
 
  115                 fileNames = entry.getElementsByTagName(
"filename"); 
 
  116                 fileSizes = entry.getElementsByTagName(
"filesize"); 
 
  117                 fileRanges = entry.getElementsByTagName(
"byte_run"); 
 
  119                 fileSize = Long.parseLong(fileSizes.item(0).getTextContent());
 
  120                 fileName = fileNames.item(0).getTextContent();
 
  121                 filePath = Paths.get(fileName);
 
  122                 if (filePath.startsWith(basePath)) {
 
  123                     fileName = filePath.getFileName().toString();
 
  126                 List<TskFileRange> tskRanges = 
new ArrayList<>();
 
  127                 for (
int rangeIndex = 0; rangeIndex < fileRanges.getLength(); ++rangeIndex) {
 
  129                     Long unallocFileOffset = null;
 
  133                     Node rangeNode = fileRanges.item(rangeIndex);
 
  134                     if (rangeNode instanceof Element) {
 
  135                         Element rangeElement = (Element) rangeNode;
 
  136                         String imgOffsetStr = rangeElement.getAttribute(
"img_offset");
 
  137                         String lenStr = rangeElement.getAttribute(
"len");
 
  140                             unallocFileOffset = Long.parseLong(imgOffsetStr);
 
  141                             len = Long.parseLong(lenStr);
 
  142                         } 
catch (NumberFormatException ex) {
 
  143                             logger.log(Level.SEVERE,
 
  144                                     String.format(
"There was an error parsing ranges in %s with file index: %d and range index: %d.",
 
  145                                             xmlInputFile.getPath(), fileIndex, rangeIndex), ex);
 
  148                         logger.log(Level.SEVERE,
 
  149                                 String.format(
"Malformed node in %s with file index: %d and range index: %d.",
 
  150                                         xmlInputFile.getPath(), fileIndex, rangeIndex));
 
  154                     if (unallocFileOffset != null && unallocFileOffset >= 0 && len != null && len > 0) {
 
  155                         for (TskFileRange rangeToAdd : af.convertToImgRanges(unallocFileOffset, len)) {
 
  156                             tskRanges.add(
new TskFileRange(rangeToAdd.getByteStart(), rangeToAdd.getByteLen(), tskRanges.size()));
 
  162                 if (!tskRanges.isEmpty()) {
 
  163                     carvedFiles.add(
new CarvingResult.CarvedFile(fileName, fileSize, tskRanges));
 
  166             return fileManager.addCarvedFiles(
new CarvingResult(af, carvedFiles));
 
  167         } 
catch (NumberFormatException | TskCoreException | NoCurrentCaseException ex) {
 
  168             logger.log(Level.SEVERE, 
"Error parsing PhotoRec output and inserting it into the database", ex); 
 
  171         List<LayoutFile> empty = Collections.emptyList();