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;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NodeList;
47 class PhotoRecCarverOutputParser {
49 private final Path basePath;
50 private static final Logger logger = Logger.getLogger(PhotoRecCarverFileIngestModule.class.getName());
52 PhotoRecCarverOutputParser(Path base) {
73 List<LayoutFile> parse(File xmlInputFile,
long id, AbstractFile af)
throws FileNotFoundException, IOException {
75 final Document doc = XMLUtil.loadDoc(PhotoRecCarverOutputParser.class, xmlInputFile.toString());
80 Element root = doc.getDocumentElement();
82 logger.log(Level.SEVERE,
"Error loading config file: invalid file format (bad root).");
86 NodeList fileObjects = root.getElementsByTagName(
"fileobject");
87 final int numberOfFiles = fileObjects.getLength();
89 if (numberOfFiles == 0) {
99 FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
102 List<CarvedFileContainer> carvedFileContainer =
new ArrayList<>();
104 for (
int fileIndex = 0; fileIndex < numberOfFiles; ++fileIndex) {
105 entry = (Element) fileObjects.item(fileIndex);
106 fileNames = entry.getElementsByTagName(
"filename");
107 fileSizes = entry.getElementsByTagName(
"filesize");
108 fileRanges = entry.getElementsByTagName(
"byte_run");
110 fileSize = Long.parseLong(fileSizes.item(0).getTextContent());
111 fileName = fileNames.item(0).getTextContent();
112 filePath = Paths.get(fileName);
113 if (filePath.startsWith(basePath)) {
114 fileName = filePath.getFileName().toString();
117 List<TskFileRange> tskRanges =
new ArrayList<>();
118 for (
int rangeIndex = 0; rangeIndex < fileRanges.getLength(); ++rangeIndex) {
120 Long img_offset = Long.parseLong(((Element) fileRanges.item(rangeIndex)).getAttribute(
"img_offset"));
121 Long len = Long.parseLong(((Element) fileRanges.item(rangeIndex)).getAttribute(
"len"));
124 long fileByteStart = af.convertToImgOffset(img_offset);
125 if (fileByteStart == -1) {
127 logger.log(Level.INFO,
"Error while parsing PhotoRec output for file {0}", fileName);
132 long fileByteEnd = img_offset + len;
133 if (fileByteEnd > af.getSize()) {
134 long overshoot = fileByteEnd - af.getSize();
135 if (fileSize > overshoot) {
136 fileSize = fileSize - overshoot;
143 tskRanges.add(
new TskFileRange(fileByteStart, len, rangeIndex));
146 if (!tskRanges.isEmpty()) {
147 carvedFileContainer.add(
new CarvedFileContainer(fileName, fileSize,
id, tskRanges));
150 return fileManager.addCarvedFiles(carvedFileContainer);
151 }
catch (NumberFormatException | TskCoreException ex) {
152 logger.log(Level.SEVERE,
"Error parsing PhotoRec output and inserting it into the database: {0}", ex);
155 List<LayoutFile> empty = Collections.emptyList();