23 package org.sleuthkit.autopsy.recentactivity;
 
   25 import java.io.BufferedReader;
 
   27 import java.io.FileInputStream;
 
   28 import java.io.FileNotFoundException;
 
   29 import java.io.FileReader;
 
   30 import java.io.FileWriter;
 
   31 import java.io.IOException;
 
   32 import java.io.StringReader;
 
   33 import java.text.ParseException;
 
   34 import java.text.SimpleDateFormat;
 
   35 import java.util.logging.Level;
 
   36 import javax.xml.parsers.DocumentBuilder;
 
   37 import javax.xml.parsers.DocumentBuilderFactory;
 
   38 import javax.xml.parsers.ParserConfigurationException;
 
   39 import org.openide.modules.InstalledFileLocator;
 
   40 import org.openide.util.NbBundle;
 
   48 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
 
   49 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
 
   50 import org.w3c.dom.Document;
 
   51 import org.w3c.dom.Element;
 
   52 import org.w3c.dom.Node;
 
   53 import org.w3c.dom.NodeList;
 
   54 import org.xml.sax.InputSource;
 
   55 import org.xml.sax.SAXException;
 
   56 import java.nio.file.Path;
 
   57 import java.util.AbstractMap;
 
   58 import java.util.ArrayList;
 
   59 import java.util.List;
 
   60 import java.util.Collection;
 
   61 import java.util.HashMap;
 
   63 import java.util.Scanner;
 
   65 import java.util.HashSet;
 
   66 import static java.util.TimeZone.getTimeZone;
 
   67 import org.openide.util.Lookup;
 
   75 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
 
   86     "RegRipperNotFound=Autopsy RegRipper executable not found.",
 
   87     "RegRipperFullNotFound=Full version RegRipper executable not found.",
 
   88     "Progress_Message_Analyze_Registry=Analyzing Registry Files" 
   90 class ExtractRegistry extends Extract {
 
   92     private static final String USERNAME_KEY = 
"Username"; 
 
   93     private static final String SID_KEY = 
"SID"; 
 
   94     private static final String RID_KEY = 
"RID"; 
 
   95     private static final String ACCOUNT_CREATED_KEY = 
"Account Created"; 
 
   96     private static final String LAST_LOGIN_KEY = 
"Last Login Date"; 
 
   97     private static final String LOGIN_COUNT_KEY = 
"Login Count"; 
 
   98     private static final String FULL_NAME_KEY = 
"Full Name"; 
 
   99     private static final String USER_COMMENT_KEY = 
"User Comment"; 
 
  100     private static final String ACCOUNT_TYPE_KEY = 
"Account Type"; 
 
  101     private static final String NAME_KEY = 
"Name"; 
 
  102     private static final String PWD_RESET_KEY = 
"Pwd Rest Date"; 
 
  103     private static final String PWD_FAILE_KEY = 
"Pwd Fail Date"; 
 
  104     private static final String INTERNET_NAME_KEY = 
"InternetName"; 
 
  105     private static final String PWD_DOES_NOT_EXPIRE_KEY = 
"Password does not expire"; 
 
  106     private static final String ACCOUNT_DISABLED_KEY = 
"Account Disabled"; 
 
  107     private static final String PWD_NOT_REQUIRED_KEY = 
"Password not required"; 
 
  108     private static final String NORMAL_ACCOUNT_KEY = 
"Normal user account"; 
 
  109     private static final String HOME_DIRECTORY_REQUIRED_KEY = 
"Home directory required";
 
  110     private static final String TEMPORARY_DUPLICATE_ACCOUNT = 
"Temporary duplicate account";
 
  111     private static final String MNS_LOGON_ACCOUNT_KEY = 
"MNS logon user account";
 
  112     private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY = 
"Interdomain trust account";
 
  113     private static final String WORKSTATION_TRUST_ACCOUNT = 
"Workstation trust account";
 
  114     private static final String SERVER_TRUST_ACCOUNT = 
"Server trust account";
 
  115     private static final String ACCOUNT_AUTO_LOCKED = 
"Account auto locked";
 
  116     private static final String PASSWORD_HINT = 
"Password Hint";
 
  118     private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
 
  119     private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
 
  120     private static final String[] ACCOUNT_TYPE_FLAGS = {NORMAL_ACCOUNT_KEY, SERVER_TRUST_ACCOUNT, WORKSTATION_TRUST_ACCOUNT, INTERDOMAIN_TRUST_ACCOUNT_KEY, MNS_LOGON_ACCOUNT_KEY, TEMPORARY_DUPLICATE_ACCOUNT};
 
  122     final private static UsbDeviceIdMapper USB_MAPPER = 
new UsbDeviceIdMapper();
 
  123     final private static String RIP_EXE = 
"rip.exe";
 
  124     final private static String RIP_PL = 
"rip.pl";
 
  125     final private static int MS_IN_SEC = 1000;
 
  126     final private static String NEVER_DATE = 
"Never";
 
  127     final private static String SECTION_DIVIDER = 
"-------------------------";
 
  128     final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
 
  129     private final List<String> rrCmd = 
new ArrayList<>();
 
  130     private final List<String> rrFullCmd = 
new ArrayList<>();
 
  131     private final Path rrHome;  
 
  132     private final Path rrFullHome; 
 
  133     private Content dataSource;
 
  134     private IngestJobContext context;
 
  136     ExtractRegistry() throws IngestModuleException {
 
  137         moduleName = NbBundle.getMessage(ExtractIE.class, 
"ExtractRegistry.moduleName.text");
 
  139         final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(), 
false); 
 
  140         if (rrRoot == null) {
 
  141             throw new IngestModuleException(Bundle.RegRipperNotFound());
 
  144         final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(), 
false); 
 
  145         if (rrFullRoot == null) {
 
  146             throw new IngestModuleException(Bundle.RegRipperFullNotFound());
 
  149         String executableToRun = RIP_EXE;
 
  150         if (!PlatformUtil.isWindowsOS()) {
 
  151             executableToRun = RIP_PL;
 
  153         rrHome = rrRoot.toPath();
 
  154         String rrPath = rrHome.resolve(executableToRun).toString();
 
  155         rrFullHome = rrFullRoot.toPath();
 
  157         if (!(
new File(rrPath).exists())) {
 
  158             throw new IngestModuleException(Bundle.RegRipperNotFound());
 
  160         String rrFullPath = rrFullHome.resolve(executableToRun).toString();
 
  161         if (!(
new File(rrFullPath).exists())) {
 
  162             throw new IngestModuleException(Bundle.RegRipperFullNotFound());
 
  164         if (PlatformUtil.isWindowsOS()) {
 
  166             rrFullCmd.add(rrFullPath);
 
  169             File usrBin = 
new File(
"/usr/bin/perl");
 
  170             File usrLocalBin = 
new File(
"/usr/local/bin/perl");
 
  171             if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
 
  172                 perl = 
"/usr/bin/perl";
 
  173             } 
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
 
  174                 perl = 
"/usr/local/bin/perl";
 
  176                 throw new IngestModuleException(
"perl not found in your system");
 
  181             rrFullCmd.add(rrFullPath);
 
  188     private List<AbstractFile> findRegistryFiles() {
 
  189         List<AbstractFile> allRegistryFiles = 
new ArrayList<>();
 
  194             allRegistryFiles.addAll(fileManager.findFiles(dataSource, 
"ntuser.dat")); 
 
  195         } 
catch (TskCoreException ex) {
 
  196             logger.log(Level.WARNING, 
"Error fetching 'ntuser.dat' file."); 
 
  200         String[] regFileNames = 
new String[]{
"system", 
"software", 
"security", 
"sam"}; 
 
  201         for (String regFileName : regFileNames) {
 
  203                 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName, 
"/system32/config")); 
 
  204             } 
catch (TskCoreException ex) {
 
  205                 String msg = NbBundle.getMessage(this.getClass(),
 
  206                         "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
 
  207                 logger.log(Level.WARNING, msg);
 
  208                 this.addErrorMessage(this.getName() + 
": " + msg);
 
  211         return allRegistryFiles;
 
  218     private void analyzeRegistryFiles() {
 
  219         List<AbstractFile> allRegistryFiles = findRegistryFiles();
 
  222         FileWriter logFile = null;
 
  224             logFile = 
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase, 
"reg") + File.separator + 
"regripper-info.txt"); 
 
  225         } 
catch (IOException ex) {
 
  226             logger.log(Level.SEVERE, null, ex);
 
  229         for (AbstractFile regFile : allRegistryFiles) {
 
  230             String regFileName = regFile.getName();
 
  231             long regFileId = regFile.getId();
 
  232             String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, 
"reg") + File.separator + regFileName;
 
  233             String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase, 
"reg") + File.separator + regFileName + 
"-regripper-" + Long.toString(regFileId); 
 
  234             File regFileNameLocalFile = 
new File(regFileNameLocal);
 
  236                 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
 
  237             } 
catch (ReadContentInputStreamException ex) {
 
  238                 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
 
  239                         regFile.getName(), regFileId), ex); 
 
  240                 this.addErrorMessage(
 
  241                         NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
 
  242                                 this.getName(), regFileName));
 
  244             } 
catch (IOException ex) {
 
  245                 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
 
  246                         regFileNameLocal, regFile.getName(), regFileId), ex); 
 
  247                 this.addErrorMessage(
 
  248                         NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
 
  249                                 this.getName(), regFileName));
 
  253             if (context.dataSourceIngestIsCancelled()) {
 
  258                 if (logFile != null) {
 
  259                     logFile.write(Long.toString(regFileId) + 
"\t" + regFile.getUniquePath() + 
"\n");
 
  261             } 
catch (TskCoreException | IOException ex) {
 
  262                 logger.log(Level.SEVERE, null, ex);
 
  265             logger.log(Level.INFO, 
"{0}- Now getting registry information from {1}", 
new Object[]{moduleName, regFileNameLocal}); 
 
  266             RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
 
  267             if (context.dataSourceIngestIsCancelled()) {
 
  272             if (regOutputFiles.autopsyPlugins.isEmpty() == 
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) == 
false) {
 
  273                 this.addErrorMessage(
 
  274                         NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
 
  275                                 this.getName(), regFileName));
 
  279             if (!regOutputFiles.fullPlugins.isEmpty()) {
 
  281                 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) == 
false) {
 
  282                     this.addErrorMessage(
 
  283                             NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
 
  284                                     this.getName(), regFileName));
 
  287                     Report report = currentCase.addReport(regOutputFiles.fullPlugins,
 
  288                             NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.parentModuleName.noSpace"),
 
  289                             "RegRipper " + regFile.getUniquePath(), regFile); 
 
  292                     KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
 
  293                     if (null == searchService) {
 
  294                         logger.log(Level.WARNING, 
"Keyword search service not found. Report will not be indexed");
 
  296                         searchService.index(report);
 
  299                 } 
catch (TskCoreException e) {
 
  300                     this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage()); 
 
  304             regFileNameLocalFile.delete();
 
  308             if (logFile != null) {
 
  311         } 
catch (IOException ex) {
 
  312             logger.log(Level.SEVERE, null, ex);
 
  323     private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
 
  324         String autopsyType = 
"";    
 
  327         RegOutputFiles regOutputFiles = 
new RegOutputFiles();
 
  329         if (regFilePath.toLowerCase().contains(
"system")) { 
 
  330             autopsyType = 
"autopsysystem"; 
 
  332         } 
else if (regFilePath.toLowerCase().contains(
"software")) { 
 
  333             autopsyType = 
"autopsysoftware"; 
 
  334             fullType = 
"software"; 
 
  335         } 
else if (regFilePath.toLowerCase().contains(
"ntuser")) { 
 
  336             autopsyType = 
"autopsyntuser"; 
 
  338         } 
else if (regFilePath.toLowerCase().contains(
"sam")) { 
 
  341         } 
else if (regFilePath.toLowerCase().contains(
"security")) { 
 
  342             fullType = 
"security"; 
 
  344             return regOutputFiles;
 
  348         if (!autopsyType.isEmpty()) {
 
  349             regOutputFiles.autopsyPlugins = outFilePathBase + 
"-autopsy.txt"; 
 
  350             String errFilePath = outFilePathBase + 
"-autopsy.err.txt"; 
 
  351             logger.log(Level.INFO, 
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins); 
 
  352             executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
 
  354         if (context.dataSourceIngestIsCancelled()) {
 
  355             return regOutputFiles;
 
  359         if (!fullType.isEmpty()) {
 
  360             regOutputFiles.fullPlugins = outFilePathBase + 
"-full.txt"; 
 
  361             String errFilePath = outFilePathBase + 
"-full.err.txt"; 
 
  362             logger.log(Level.INFO, 
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins); 
 
  363             executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
 
  365         return regOutputFiles;
 
  368     private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
 
  370             List<String> commandLine = 
new ArrayList<>();
 
  371             for (String cmd : regRipperPath) {
 
  372                 commandLine.add(cmd);
 
  374             commandLine.add(
"-r"); 
 
  375             commandLine.add(hiveFilePath);
 
  376             commandLine.add(
"-f"); 
 
  377             commandLine.add(hiveFileType);
 
  379             ProcessBuilder processBuilder = 
new ProcessBuilder(commandLine);
 
  380             processBuilder.directory(regRipperHomeDir.toFile()); 
 
  381             processBuilder.redirectOutput(
new File(outputFile));
 
  382             processBuilder.redirectError(
new File(errFile));
 
  383             ExecUtil.execute(processBuilder, 
new DataSourceIngestModuleProcessTerminator(context));
 
  384         } 
catch (IOException ex) {
 
  385             logger.log(Level.SEVERE, 
"Unable to run RegRipper", ex); 
 
  386             this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName()));
 
  399     private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
 
  400         FileInputStream fstream = null;
 
  403             File regfile = 
new File(regFilePath);
 
  404             fstream = 
new FileInputStream(regfile);
 
  405             String regString = 
new Scanner(fstream, 
"UTF-8").useDelimiter(
"\\Z").next(); 
 
  406             String startdoc = 
"<?xml version=\"1.0\"?><document>"; 
 
  407             String result = regString.replaceAll(
"----------------------------------------", 
"");
 
  408             result = result.replaceAll(
"\\n", 
""); 
 
  409             result = result.replaceAll(
"\\r", 
""); 
 
  410             result = result.replaceAll(
"'", 
"'"); 
 
  411             result = result.replaceAll(
"&", 
"&"); 
 
  412             result = result.replace(
'\0', 
' '); 
 
  413             String enddoc = 
"</document>"; 
 
  414             String stringdoc = startdoc + result + enddoc;
 
  415             DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 
  416             Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
 
  419             Element oroot = doc.getDocumentElement();
 
  420             NodeList children = oroot.getChildNodes();
 
  421             int len = children.getLength();
 
  422             for (
int i = 0; i < len; i++) {
 
  424                 if (context.dataSourceIngestIsCancelled()) {
 
  428                 Element tempnode = (Element) children.item(i);
 
  430                 String dataType = tempnode.getNodeName();
 
  431                 NodeList timenodes = tempnode.getElementsByTagName(
"mtime"); 
 
  433                 if (timenodes.getLength() > 0) {
 
  434                     Element timenode = (Element) timenodes.item(0);
 
  435                     String etime = timenode.getTextContent();
 
  437                     if (etime != null && !etime.isEmpty()) {
 
  439                             mtime = 
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
 
  440                             String Tempdate = mtime.toString();
 
  441                             mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
 
  442                         } 
catch (ParseException ex) {
 
  443                             logger.log(Level.WARNING, 
"Failed to parse epoch time when parsing the registry.", ex); 
 
  448                 NodeList artroots = tempnode.getElementsByTagName(
"artifacts"); 
 
  449                 if (artroots.getLength() == 0) {
 
  454                 Element artroot = (Element) artroots.item(0);
 
  455                 NodeList myartlist = artroot.getChildNodes();
 
  456                 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
 
  462                         String systemRoot = 
"";
 
  463                         String productId = 
"";
 
  464                         String regOwner = 
"";
 
  466                         Long installtime = null;
 
  467                         for (
int j = 0; j < myartlist.getLength(); j++) {
 
  468                             Node artchild = myartlist.item(j);
 
  470                             if (artchild.hasAttributes()) {
 
  471                                 Element artnode = (Element) artchild;
 
  473                                 String value = artnode.getTextContent();
 
  475                                     value = value.trim();
 
  477                                 String name = artnode.getAttribute(
"name"); 
 
  487                                         version = version + 
" " + value;
 
  495                                     case "RegisteredOwner": 
 
  498                                     case "RegisteredOrganization": 
 
  502                                         if (value != null && !value.isEmpty()) {
 
  504                                                 installtime = 
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
 
  505                                                 String Tempdate = installtime.toString();
 
  506                                                 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
 
  507                                             } 
catch (ParseException e) {
 
  508                                                 logger.log(Level.SEVERE, 
"RegRipper::Conversion on DateTime -> ", e); 
 
  518                             Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  519                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
 
  520                             if (installtime != null) {
 
  521                                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
 
  523                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
 
  524                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
 
  525                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
 
  526                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
 
  529                             ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
 
  530                             if (results.isEmpty()) {
 
  531                                 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
 
  532                                 bbart.addAttributes(bbattributes);
 
  537                                 results.get(0).addAttributes(bbattributes);
 
  540                         } 
catch (TskCoreException ex) {
 
  541                             logger.log(Level.SEVERE, 
"Error adding installed program artifact to blackboard."); 
 
  546                         String procArch = 
"";
 
  548                         for (
int j = 0; j < myartlist.getLength(); j++) {
 
  549                             Node artchild = myartlist.item(j);
 
  551                             if (artchild.hasAttributes()) {
 
  552                                 Element artnode = (Element) artchild;
 
  554                                 String value = artnode.getTextContent().trim();
 
  555                                 String name = artnode.getAttribute(
"name"); 
 
  560                                     case "PROCESSOR_ARCHITECTURE": 
 
  563                                     case "PROCESSOR_IDENTIFIER": 
 
  574                             Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  575                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
 
  576                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
 
  577                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
 
  580                             ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
 
  581                             if (results.isEmpty()) {
 
  582                                 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
 
  583                                 bbart.addAttributes(bbattributes);
 
  588                                 results.get(0).addAttributes(bbattributes);
 
  590                         } 
catch (TskCoreException ex) {
 
  591                             logger.log(Level.SEVERE, 
"Error adding os info artifact to blackboard."); 
 
  595                         String compName = 
"";
 
  597                         for (
int j = 0; j < myartlist.getLength(); j++) {
 
  598                             Node artchild = myartlist.item(j);
 
  600                             if (artchild.hasAttributes()) {
 
  601                                 Element artnode = (Element) artchild;
 
  603                                 String value = artnode.getTextContent().trim();
 
  604                                 String name = artnode.getAttribute(
"name"); 
 
  606                                 if (name.equals(
"ComputerName")) { 
 
  608                                 } 
else if (name.equals(
"Domain")) { 
 
  614                             Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  615                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
 
  616                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
 
  619                             ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
 
  620                             if (results.isEmpty()) {
 
  621                                 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
 
  622                                 bbart.addAttributes(bbattributes);
 
  627                                 results.get(0).addAttributes(bbattributes);
 
  629                         } 
catch (TskCoreException ex) {
 
  630                             logger.log(Level.SEVERE, 
"Error adding os info artifact to blackboard."); 
 
  634                         for (
int j = 0; j < myartlist.getLength(); j++) {
 
  635                             Node artchild = myartlist.item(j);
 
  637                             if (artchild.hasAttributes()) {
 
  638                                 Element artnode = (Element) artchild;
 
  640                                 String value = artnode.getTextContent().trim();
 
  641                                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  654                                             Long usbMtime = Long.parseLong(artnode.getAttribute(
"mtime")); 
 
  655                                             usbMtime = Long.valueOf(usbMtime.toString());
 
  657                                             BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
 
  658                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
 
  659                                             String dev = artnode.getAttribute(
"dev"); 
 
  662                                             if (dev.toLowerCase().contains(
"vid")) { 
 
  663                                                 USBInfo info = USB_MAPPER.parseAndLookup(dev);
 
  664                                                 if (info.getVendor() != null) {
 
  665                                                     make = info.getVendor();
 
  667                                                 if (info.getProduct() != null) {
 
  668                                                     model = info.getProduct();
 
  671                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
 
  672                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
 
  673                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
 
  674                                             bbart.addAttributes(bbattributes);
 
  678                                         } 
catch (TskCoreException ex) {
 
  679                                             logger.log(Level.SEVERE, 
"Error adding device attached artifact to blackboard.", ex); 
 
  683                                         Long itemMtime = null;
 
  685                                             String mTimeAttr = artnode.getAttribute(
"mtime");
 
  686                                             if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
 
  687                                                 itemMtime = 
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(mTimeAttr).getTime(); 
 
  688                                                 itemMtime /= MS_IN_SEC;
 
  690                                         } 
catch (ParseException ex) {
 
  691                                             logger.log(Level.WARNING, 
"Failed to parse epoch time for installed program artifact.", ex); 
 
  695                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
 
  696                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
 
  697                                             BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
 
  698                                             bbart.addAttributes(bbattributes);
 
  702                                         } 
catch (TskCoreException ex) {
 
  703                                             logger.log(Level.SEVERE, 
"Error adding installed program artifact to blackboard.", ex); 
 
  707                                         String officeName = artnode.getAttribute(
"name"); 
 
  710                                             BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
 
  713                                                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
 
  715                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
 
  716                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
 
  717                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
 
  718                                             bbart.addAttributes(bbattributes);
 
  722                                         } 
catch (TskCoreException ex) {
 
  723                                             logger.log(Level.SEVERE, 
"Error adding recent object artifact to blackboard.", ex); 
 
  727                                     case "ProcessorArchitecture": 
 
  744                                             String homeDir = value;
 
  745                                             String sid = artnode.getAttribute(
"sid"); 
 
  746                                             String username = artnode.getAttribute(
"username"); 
 
  747                                             BlackboardArtifact bbart = null;
 
  750                                                 ArrayList<BlackboardArtifact> existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
 
  751                                                 for (BlackboardArtifact artifact : existingArtifacts) {
 
  752                                                     if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) {
 
  753                                                         BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
 
  754                                                         if (attribute != null && attribute.getValueString().equals(sid)) {
 
  760                                             } 
catch (TskCoreException ex) {
 
  761                                                 logger.log(Level.WARNING, 
"Error getting existing os account artifact", ex);
 
  765                                                 bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
 
  766                                                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  767                                                         parentModuleName, username));
 
  768                                                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
 
  769                                                         parentModuleName, sid));
 
  770                                                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  771                                                         parentModuleName, homeDir));
 
  774                                                 BlackboardAttribute bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
 
  776                                                 if (bbattr == null) {
 
  777                                                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  778                                                             parentModuleName, username));
 
  780                                                 bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH));
 
  781                                                 if (bbattr == null) {
 
  782                                                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  783                                                             parentModuleName, homeDir));
 
  786                                             bbart.addAttributes(bbattributes);
 
  789                                         } 
catch (TskCoreException ex) {
 
  790                                             logger.log(Level.SEVERE, 
"Error adding account artifact to blackboard.", ex); 
 
  794                                     case "NtuserNetwork": 
 
  796                                             String localPath = artnode.getAttribute(
"localPath"); 
 
  797                                             String remoteName = value;
 
  798                                             BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
 
  799                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
 
  800                                                     parentModuleName, localPath));
 
  801                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
 
  802                                                     parentModuleName, remoteName));
 
  803                                             bbart.addAttributes(bbattributes);
 
  806                                         } 
catch (TskCoreException ex) {
 
  807                                             logger.log(Level.SEVERE, 
"Error adding network artifact to blackboard.", ex); 
 
  811                                         String adapter = artnode.getAttribute(
"adapter"); 
 
  813                                             Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime")); 
 
  814                                             lastWriteTime = Long.valueOf(lastWriteTime.toString());
 
  815                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
 
  816                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
 
  817                                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
 
  818                                             BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK);
 
  819                                             bbart.addAttributes(bbattributes);
 
  822                                         } 
catch (TskCoreException ex) {
 
  823                                             logger.log(Level.SEVERE, 
"Error adding SSID artifact to blackboard.", ex); 
 
  833                                         logger.log(Level.WARNING, 
"Unrecognized node name: {0}", dataType); 
 
  842         } 
catch (FileNotFoundException ex) {
 
  843             logger.log(Level.SEVERE, 
"Error finding the registry file.", ex); 
 
  844         } 
catch (SAXException ex) {
 
  845             logger.log(Level.SEVERE, 
"Error parsing the registry XML.", ex); 
 
  846         } 
catch (IOException ex) {
 
  847             logger.log(Level.SEVERE, 
"Error building the document parser.", ex); 
 
  848         } 
catch (ParserConfigurationException ex) {
 
  849             logger.log(Level.SEVERE, 
"Error configuring the registry parser.", ex); 
 
  852                 if (fstream != null) {
 
  855             } 
catch (IOException ex) {
 
  870     private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
 
  871         File regfile = 
new File(regFilePath);
 
  872         try (BufferedReader bufferedReader = 
new BufferedReader(
new FileReader(regfile))) {
 
  874             String userInfoSection = 
"User Information";
 
  875             String previousLine = null;
 
  876             String line = bufferedReader.readLine();
 
  877             Set<Map<String, String>> userSet = 
new HashSet<>();
 
  878             Map<String, List<String>> groupMap = null;
 
  879             while (line != null) {
 
  880                 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
 
  881                     readUsers(bufferedReader, userSet);
 
  884                 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(
"Group Membership Information")) {
 
  885                     groupMap = readGroups(bufferedReader);
 
  889                 line = bufferedReader.readLine();
 
  891             Map<String, Map<String, String>> userInfoMap = 
new HashMap<>();
 
  893             for (Map<String, String> userInfo : userSet) {
 
  894                 userInfoMap.put(userInfo.get(SID_KEY), userInfo);
 
  897             List<BlackboardArtifact> existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
 
  898             for (BlackboardArtifact osAccount : existingOsAccounts) {
 
  900                 if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) {
 
  901                     BlackboardAttribute existingUserId = osAccount.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
 
  902                     if (existingUserId != null) {
 
  903                         String userID = existingUserId.getValueString().trim();
 
  904                         Map<String, String> userInfo = userInfoMap.remove(userID);
 
  906                         if (userInfo != null) {
 
  907                             osAccount.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userID), 
true));
 
  913             for (Map<String, String> userInfo : userInfoMap.values()) {
 
  914                 BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
 
  915                 bbart.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userInfo.get(SID_KEY)), 
false));
 
  921         } 
catch (FileNotFoundException ex) {
 
  922             logger.log(Level.SEVERE, 
"Error finding the registry file.", ex); 
 
  923         } 
catch (IOException ex) {
 
  924             logger.log(Level.SEVERE, 
"Error building the document parser: {0}", ex); 
 
  925         } 
catch (ParseException ex) {
 
  926             logger.log(Level.SEVERE, 
"Error parsing the the date from the registry file", ex); 
 
  927         } 
catch (TskCoreException ex) {
 
  928             logger.log(Level.SEVERE, 
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); 
 
  944     Collection<BlackboardAttribute> getAttributesForAccount(Map<String, String> userInfo, List<String> groupList, 
boolean existingUser) 
throws ParseException {
 
  945         Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  947         SimpleDateFormat regRipperTimeFormat = 
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'");
 
  948         regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
 
  951             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
 
  952                     getRAModuleName(), userInfo.get(SID_KEY)));
 
  954             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  955                     this.moduleName, userInfo.get(USERNAME_KEY)));
 
  958         String value = userInfo.get(ACCOUNT_CREATED_KEY);
 
  959         if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
 
  960             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  961                     getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
 
  964         value = userInfo.get(LAST_LOGIN_KEY);
 
  965         if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
 
  966             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  967                     getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
 
  970         value = userInfo.get(LOGIN_COUNT_KEY);
 
  971         if (value != null && !value.isEmpty()) {
 
  972             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
 
  973                     getRAModuleName(), Integer.parseInt(value)));
 
  976         value = userInfo.get(ACCOUNT_TYPE_KEY);
 
  977         if (value != null && !value.isEmpty()) {
 
  978             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE,
 
  979                     getRAModuleName(), value));
 
  982         value = userInfo.get(USER_COMMENT_KEY);
 
  983         if (value != null && !value.isEmpty()) {
 
  984             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
 
  985                     getRAModuleName(), value));
 
  988         value = userInfo.get(NAME_KEY);
 
  989         if (value != null && !value.isEmpty()) {
 
  990             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  991                     getRAModuleName(), value));
 
  994         value = userInfo.get(INTERNET_NAME_KEY);
 
  995         if (value != null && !value.isEmpty()) {
 
  996             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
 
  997                     getRAModuleName(), value));
 
 1000         value = userInfo.get(FULL_NAME_KEY);
 
 1001         if (value != null && !value.isEmpty()) {
 
 1002             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DISPLAY_NAME,
 
 1003                     getRAModuleName(), value));
 
 1006         value = userInfo.get(PWD_RESET_KEY);
 
 1007         if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
 
 1008             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
 
 1009                     getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
 
 1012         value = userInfo.get(PASSWORD_HINT);
 
 1013         if (value != null && !value.isEmpty()) {
 
 1014             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
 
 1015                     getRAModuleName(), value));
 
 1018         value = userInfo.get(PWD_FAILE_KEY);
 
 1019         if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
 
 1020             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
 
 1021                     getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
 
 1024         String settingString = 
"";
 
 1025         for (String setting : PASSWORD_SETTINGS_FLAGS) {
 
 1026             if (userInfo.containsKey(setting)) {
 
 1027                 settingString += setting + 
", ";
 
 1031         if (!settingString.isEmpty()) {
 
 1032             settingString = settingString.substring(0, settingString.length() - 2);
 
 1033             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
 
 1034                     getRAModuleName(), settingString));
 
 1038         for (String setting : ACCOUNT_SETTINGS_FLAGS) {
 
 1039             if (userInfo.containsKey(setting)) {
 
 1040                 settingString += setting + 
", ";
 
 1044         if (!settingString.isEmpty()) {
 
 1045             settingString = settingString.substring(0, settingString.length() - 2);
 
 1046             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
 
 1047                     getRAModuleName(), settingString));
 
 1051         for (String setting : ACCOUNT_TYPE_FLAGS) {
 
 1052             if (userInfo.containsKey(setting)) {
 
 1053                 settingString += setting + 
", ";
 
 1057         if (!settingString.isEmpty()) {
 
 1058             settingString = settingString.substring(0, settingString.length() - 2);
 
 1059             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
 
 1060                     getRAModuleName(), settingString));
 
 1063         if (groupList != null && groupList.isEmpty()) {
 
 1065             for (String group : groupList) {
 
 1066                 groups += group + 
", ";
 
 1069             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
 
 1070                     getRAModuleName(), groups.substring(0, groups.length() - 2)));
 
 1073         return bbattributes;
 
 1087     private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users) throws IOException {
 
 1088         String line = bufferedReader.readLine();
 
 1090         String userName = 
"";
 
 1091         String user_rid = 
"";
 
 1092         while (line != null && !line.contains(SECTION_DIVIDER)) {
 
 1094             if (line.contains(USERNAME_KEY)) {
 
 1095                 String regx = USERNAME_KEY + 
"\\s*?:";
 
 1096                 String userNameAndIdString = line.replaceAll(regx, 
"");
 
 1097                 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
 
 1098                 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
 
 1099             } 
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
 
 1100                 Map.Entry<String, String> entry = getSAMKeyValue(line);
 
 1102                 HashMap<String, String> userInfo = 
new HashMap<>();
 
 1103                 userInfo.put(USERNAME_KEY, userName);
 
 1104                 userInfo.put(RID_KEY, user_rid);
 
 1105                 userInfo.put(entry.getKey(), entry.getValue());
 
 1108                 line = bufferedReader.readLine();
 
 1109                 while (line != null && !line.isEmpty()) {
 
 1110                     entry = getSAMKeyValue(line);
 
 1111                     userInfo.put(entry.getKey(), entry.getValue());
 
 1112                     line = bufferedReader.readLine();
 
 1114                 users.add(userInfo);
 
 1118             line = bufferedReader.readLine();
 
 1131     Map<String, List<String>> readGroups(BufferedReader bufferedReader) 
throws IOException {
 
 1132         Map<String, List<String>> groupMap = 
new HashMap<>();
 
 1134         String line = bufferedReader.readLine();
 
 1137         String groupName = null;
 
 1139         while (line != null && !line.contains(SECTION_DIVIDER)) {
 
 1141             if (line.contains(
"Group Name")) {
 
 1142                 String value = line.replaceAll(
"Group Name\\s*?:", 
"").trim();
 
 1143                 groupName = (value.replaceAll(
"\\[\\d*?\\]", 
"")).trim();
 
 1144                 int startIndex = value.indexOf(
'[');
 
 1145                 int endIndex = value.indexOf(
']');
 
 1147                 if (startIndex != -1 && endIndex != -1) {
 
 1148                     String countStr = value.substring(startIndex + 1, endIndex);
 
 1149                     userCount = Integer.parseInt(countStr);
 
 1151             } 
else if (line.matches(
"Users\\s*?:")) {
 
 1152                 for (
int i = 0; i < userCount; i++) {
 
 1153                     line = bufferedReader.readLine();
 
 1155                         String sid = line.trim();
 
 1156                         List<String> groupList = groupMap.get(sid);
 
 1157                         if (groupList == null) {
 
 1158                             groupList = 
new ArrayList<>();
 
 1159                             groupMap.put(sid, groupList);
 
 1161                         groupList.add(groupName);
 
 1166             line = bufferedReader.readLine();
 
 1180     private Map.Entry<String, String> getSAMKeyValue(String line) {
 
 1181         int index = line.indexOf(
':');
 
 1182         Map.Entry<String, String> returnValue = null;
 
 1184         String value = null;
 
 1187             key = line.substring(0, index).trim();
 
 1188             if (index + 1 < line.length()) {
 
 1189                 value = line.substring(index + 1).trim();
 
 1194         } 
else if (line.contains(
"-->")) {
 
 1195             key = line.replace(
"-->", 
"").trim();
 
 1200             returnValue = 
new AbstractMap.SimpleEntry<>(key, value);
 
 1207     public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
 
 1208         this.dataSource = dataSource;
 
 1209         this.context = context;
 
 1211         progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
 
 1212         analyzeRegistryFiles();
 
 1221         public String autopsyPlugins = 
"";
 
 1222         public String fullPlugins = 
"";