22 package org.sleuthkit.autopsy.recentactivity;
 
   24 import java.io.BufferedReader;
 
   26 import java.io.FileInputStream;
 
   27 import java.io.FileNotFoundException;
 
   28 import java.io.IOException;
 
   29 import java.io.InputStreamReader;
 
   30 import java.nio.charset.StandardCharsets;
 
   31 import java.text.ParseException;
 
   32 import java.text.SimpleDateFormat;
 
   33 import java.util.ArrayList;
 
   34 import java.util.List;
 
   35 import java.util.Locale;
 
   36 import java.util.logging.Level;
 
   42 class ShellBagParser {
 
   43     private static final Logger logger = Logger.
getLogger(ShellBagParser.class.getName());
 
   45     private static final SimpleDateFormat DATE_TIME_FORMATTER = 
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
 
   47     private static final SimpleDateFormat DATE_TIME_FORMATTER2 = 
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyyy", Locale.getDefault());
 
   49     private ShellBagParser() {
 
   62     static List<ShellBag> parseShellbagOutput(String regFilePath) 
throws FileNotFoundException, IOException {
 
   63         List<ShellBag> shellbags = 
new ArrayList<>();
 
   64         File regfile = 
new File(regFilePath);
 
   66         ShellBagParser sbparser = 
new ShellBagParser();
 
   68         try (BufferedReader reader = 
new BufferedReader(
new InputStreamReader(
new FileInputStream(regfile), StandardCharsets.UTF_8))) {
 
   69             String line = reader.readLine();
 
   70             while (line != null) {
 
   73                 if (line.matches(
"^shellbags_xp v.*")) {
 
   74                     shellbags.addAll(sbparser.parseShellBagsXP(reader));
 
   75                 } 
else if (line.matches(
"^shellbags v.*")) {
 
   76                     shellbags.addAll(sbparser.parseShellBags(reader));
 
   77                 } 
else if (line.matches(
"^itempos.*")) {
 
   78                     shellbags.addAll(sbparser.parseItempos(reader));
 
   81                 line = reader.readLine();
 
   97     List<ShellBag> parseShellBagsXP(BufferedReader reader) 
throws IOException {
 
   98         List<ShellBag> shellbags = 
new ArrayList<>();
 
   99         String line = reader.readLine();
 
  101         while (line != null && !isSectionSeparator(line)) {
 
  103             if (isShellbagXPDataLine(line)) {
 
  104                 String[] tokens = line.split(
"\\|");
 
  105                 if (tokens.length >= 6) {
 
  106                     shellbags.add(
new ShellBag(tokens[5].trim(), 
"Software\\Microsoft\\Windows\\ShellNoRoam\\BagMRU", tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
 
  110             line = reader.readLine();
 
  124     List<ShellBag> parseShellBags(BufferedReader reader) 
throws IOException {
 
  125         List<ShellBag> shellbags = 
new ArrayList<>();
 
  126         String line = reader.readLine();
 
  127         String regPath = 
"Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU";
 
  129         while (line != null && !isSectionSeparator(line)) {
 
  131             if (isShellbagDataLine(line)) {
 
  132                 String[] tokens = line.split(
"\\|");
 
  133                 String path = tokens[6].replaceAll(
"\\[.*?\\]", 
"").trim();
 
  134                 int index = line.lastIndexOf(
'[');
 
  135                 String endstuff = 
"";
 
  137                     endstuff = line.substring(index, line.length() - 1).replace(
"[Desktop", 
"");
 
  139                 if (tokens.length >= 7) {
 
  140                     shellbags.add(
new ShellBag(path, regPath + endstuff, tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
 
  144             line = reader.readLine();
 
  159     List<ShellBag> parseItempos(BufferedReader reader) 
throws IOException {
 
  160         List<ShellBag> shellbags = 
new ArrayList<>();
 
  162         String lastWrite = 
"";
 
  163         String line = reader.readLine();
 
  165         while (line != null && !isSectionSeparator(line)) {
 
  167             if (isItemposDataLine(line)) {
 
  168                 String[] tokens = line.split(
"\\|");
 
  169                 if (tokens.length >= 5) {
 
  170                     shellbags.add(
new ShellBag(tokens[4].trim(), bagpath, lastWrite, tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
 
  172             } 
else if (line.contains(
"Software\\")) {
 
  173                 bagpath = line.trim();
 
  175             } 
else if (line.contains(
"LastWrite:")) {
 
  176                 lastWrite = line.replace(
"LastWrite:", 
"").trim();
 
  179             line = reader.readLine();
 
  197     boolean isSectionSeparator(String line) {
 
  198         if (line == null || line.isEmpty()) {
 
  202         return line.trim().matches(
"^-+");
 
  214     boolean isItemposDataLine(String line) {
 
  215         return line.matches(
"^\\d*?\\s*?\\|.*?\\|.*?\\|.*?\\|.*?");
 
  229     boolean isShellbagXPDataLine(String line) {
 
  230         return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
 
  244     boolean isShellbagDataLine(String line) {
 
  245         return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
 
  254         private final String resource;
 
  255         private final String key;
 
  256         private final String lastWrite;
 
  257         private final String modified;
 
  258         private final String accessed;
 
  259         private final String created;
 
  273         ShellBag(String resource, String key, String lastWrite, String modified, String accessed, String created) {
 
  274             this.resource = resource;
 
  276             this.lastWrite = lastWrite;
 
  277             this.accessed = accessed;
 
  278             this.modified = modified;
 
  279             this.created = created;
 
  287         String getResource() {
 
  288             return resource == null ? 
"" : resource;
 
  297             return key == null ? 
"" : key;
 
  306         long getLastWrite() {
 
  307             return parseDateTime(lastWrite);
 
  317             return parseDateTime(modified);
 
  327             return parseDateTime(accessed);
 
  337             return parseDateTime(created);
 
  348         long parseDateTime(String dateTimeString) {
 
  349             if (!dateTimeString.isEmpty()) {
 
  351                     return DATE_TIME_FORMATTER.parse(dateTimeString).getTime() / 1000;
 
  352                 } 
catch (ParseException ex) {
 
  357                     return DATE_TIME_FORMATTER2.parse(dateTimeString).getTime() / 1000;
 
  358                 } 
catch (ParseException ex) {
 
  359                     logger.log(Level.WARNING, String.format(
"ShellBag parse failure.  %s is not formated as expected.", dateTimeString), ex);
 
synchronized static Logger getLogger(String name)