From 1d5023ec5f5c23d90bc4ed36a2bccdfbc579406d Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 25 May 2021 13:43:07 -0400 Subject: [PATCH 01/11] Test transaction --- .../SevenZipExtractor.java | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index 6fdb53a5c3..75215da282 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -77,6 +77,7 @@ import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.EncodedFileOutputStream; import org.sleuthkit.datamodel.ReadContentInputStream; import org.sleuthkit.datamodel.Score; +import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -782,8 +783,13 @@ class SevenZipExtractor { // add them to the DB. We wait until the end so that we have the metadata on all of the // intermediate nodes since the order is not guaranteed + CaseDbTransaction trans = null; try { - unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath); + trans = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); + unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath, trans); + trans.commit(); + trans = null; + if (checkForIngestCancellation(archiveFile)) { return false; } @@ -809,6 +815,14 @@ class SevenZipExtractor { } catch (TskCoreException | NoCurrentCaseException e) { logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", e); //NON-NLS //TODO decide if anything to cleanup, for now bailing + + if (trans != null) { + try { + trans.rollback(); + } catch (Exception ignored) { + // Ignore exception + } + } } } catch (SevenZipException | IllegalArgumentException ex) { @@ -1390,10 +1404,10 @@ class SevenZipExtractor { * Traverse the tree top-down after unzipping is done and create derived * files for the entire hierarchy */ - void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath) throws TskCoreException, NoCurrentCaseException { + void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath, CaseDbTransaction trans) throws TskCoreException, NoCurrentCaseException { final FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager(); for (UnpackedNode child : rootNode.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath); + updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath, trans); } } @@ -1411,7 +1425,7 @@ class SevenZipExtractor { * * @throws TskCoreException */ - private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath) throws TskCoreException { + private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath, CaseDbTransaction trans) throws TskCoreException { DerivedFile df; progress.progress(String.format("%s: Adding/updating files in case database (%d of %d)", currentArchiveName, ++nodesProcessed, numItems)); try { @@ -1421,7 +1435,7 @@ class SevenZipExtractor { df = fileManager.addDerivedFile(node.getFileName(), node.getLocalRelPath(), node.getSize(), node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(), node.isIsFile(), node.getParent().getFile(), "", MODULE_NAME, - "", "", TskData.EncodingType.XOR1); + "", "", TskData.EncodingType.XOR1, trans); statusMap.put(getKeyAbstractFile(df), new ZipFileStatusWrapper(df, ZipFileStatus.EXISTS)); } else { String key = getKeyAbstractFile(existingFile.getFile()); From 26e5cf1e1e076b5bce050259932757b017d86237 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 26 May 2021 15:09:37 -0400 Subject: [PATCH 02/11] Finished transaction --- .../modules/embeddedfileextractor/SevenZipExtractor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index 75215da282..db0a6b366c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -1432,7 +1432,7 @@ class SevenZipExtractor { String nameInDatabase = getKeyFromUnpackedNode(node, archiveFilePath); ZipFileStatusWrapper existingFile = nameInDatabase == null ? null : statusMap.get(nameInDatabase); if (existingFile == null) { - df = fileManager.addDerivedFile(node.getFileName(), node.getLocalRelPath(), node.getSize(), + df = Case.getCurrentCaseThrows().getSleuthkitCase().addDerivedFile(node.getFileName(), node.getLocalRelPath(), node.getSize(), node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(), node.isIsFile(), node.getParent().getFile(), "", MODULE_NAME, "", "", TskData.EncodingType.XOR1, trans); @@ -1457,7 +1457,7 @@ class SevenZipExtractor { } } node.setFile(df); - } catch (TskCoreException ex) { + } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Error adding a derived file to db:" + node.getFileName(), ex); //NON-NLS throw new TskCoreException( NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackedTree.exception.msg", @@ -1491,7 +1491,7 @@ class SevenZipExtractor { //recurse adding the children if this file was incomplete the children presumably need to be added for (UnpackedNode child : node.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath)); + updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath), trans); } } From 883e805299ef349ad72fca2e9f3b96f685a04003 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 8 Jun 2021 07:54:45 -0400 Subject: [PATCH 03/11] Multiple transactions - untested --- .../SevenZipExtractor.java | 117 ++++++++++++------ 1 file changed, 76 insertions(+), 41 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index 55491b0fa6..5c3fedf015 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -789,48 +789,38 @@ class SevenZipExtractor { // add them to the DB. We wait until the end so that we have the metadata on all of the // intermediate nodes since the order is not guaranteed - CaseDbTransaction trans = null; + //CaseDbTransaction trans = null; try { - trans = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); - unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath, trans); - trans.commit(); - trans = null; + //trans = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); + unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath); + unpackedTree.commitCurrentTransaction(); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", ex); //NON-NLS + //TODO decide if anything to cleanup, for now bailing + unpackedTree.rollbackCurrentTransaction(); + } + if (checkForIngestCancellation(archiveFile)) { + return false; + } + unpackedFiles = unpackedTree.getAllFileObjects(); + //check if children are archives, update archive depth tracking + for (int i = 0; i < unpackedFiles.size(); i++) { if (checkForIngestCancellation(archiveFile)) { return false; } - unpackedFiles = unpackedTree.getAllFileObjects(); - //check if children are archives, update archive depth tracking - for (int i = 0; i < unpackedFiles.size(); i++) { - if (checkForIngestCancellation(archiveFile)) { - return false; - } - progress.progress(String.format("%s: Searching for nested archives (%d of %d)", currentArchiveName, i + 1, unpackedFiles.size())); - AbstractFile unpackedFile = unpackedFiles.get(i); - if (unpackedFile == null) { - continue; - } - if (isSevenZipExtractionSupported(unpackedFile)) { - Archive child = new Archive(parentAr.getDepth() + 1, parentAr.getRootArchiveId(), archiveFile); - parentAr.addChild(child); - depthMap.put(unpackedFile.getId(), child); - } - unpackedFile.close(); + progress.progress(String.format("%s: Searching for nested archives (%d of %d)", currentArchiveName, i + 1, unpackedFiles.size())); + AbstractFile unpackedFile = unpackedFiles.get(i); + if (unpackedFile == null) { + continue; } - - } catch (TskCoreException | NoCurrentCaseException e) { - logger.log(Level.SEVERE, "Error populating complete derived file hierarchy from the unpacked dir structure", e); //NON-NLS - //TODO decide if anything to cleanup, for now bailing - - if (trans != null) { - try { - trans.rollback(); - } catch (Exception ignored) { - // Ignore exception - } + if (isSevenZipExtractionSupported(unpackedFile)) { + Archive child = new Archive(parentAr.getDepth() + 1, parentAr.getRootArchiveId(), archiveFile); + parentAr.addChild(child); + depthMap.put(unpackedFile.getId(), child); } + unpackedFile.close(); } - } catch (SevenZipException | IllegalArgumentException ex) { logger.log(Level.WARNING, "Error unpacking file: " + archiveFile, ex); //NON-NLS //inbox message @@ -1275,6 +1265,10 @@ class SevenZipExtractor { final UnpackedNode rootNode; private int nodesProcessed = 0; + + private CaseDbTransaction currentTransaction = null; + private long transactionCounter = 0; + private final static long MAX_TRANSACTION_SIZE = 1000; /** * @@ -1427,10 +1421,10 @@ class SevenZipExtractor { * Traverse the tree top-down after unzipping is done and create derived * files for the entire hierarchy */ - void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath, CaseDbTransaction trans) throws TskCoreException, NoCurrentCaseException { + void updateOrAddFileToCaseRec(HashMap statusMap, String archiveFilePath) throws TskCoreException, NoCurrentCaseException { final FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager(); for (UnpackedNode child : rootNode.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath, trans); + updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath); } } @@ -1448,7 +1442,7 @@ class SevenZipExtractor { * * @throws TskCoreException */ - private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath, CaseDbTransaction trans) throws TskCoreException { + private void updateOrAddFileToCaseRec(UnpackedNode node, FileManager fileManager, HashMap statusMap, String archiveFilePath) throws TskCoreException { DerivedFile df; progress.progress(String.format("%s: Adding/updating files in case database (%d of %d)", currentArchiveName, ++nodesProcessed, numItems)); try { @@ -1458,7 +1452,7 @@ class SevenZipExtractor { df = Case.getCurrentCaseThrows().getSleuthkitCase().addDerivedFile(node.getFileName(), node.getLocalRelPath(), node.getSize(), node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(), node.isIsFile(), node.getParent().getFile(), "", MODULE_NAME, - "", "", TskData.EncodingType.XOR1, trans); + "", "", TskData.EncodingType.XOR1, getCurrentTransaction()); statusMap.put(getKeyAbstractFile(df), new ZipFileStatusWrapper(df, ZipFileStatus.EXISTS)); } else { String key = getKeyAbstractFile(existingFile.getFile()); @@ -1469,10 +1463,10 @@ class SevenZipExtractor { if (existingFile.getStatus() == ZipFileStatus.UPDATE) { //if the we are updating a file and its mime type was octet-stream we want to re-type it String mimeType = existingFile.getFile().getMIMEType().equalsIgnoreCase("application/octet-stream") ? null : existingFile.getFile().getMIMEType(); - df = fileManager.updateDerivedFile((DerivedFile) existingFile.getFile(), node.getLocalRelPath(), node.getSize(), + df = Case.getCurrentCaseThrows().getSleuthkitCase().updateDerivedFile((DerivedFile) existingFile.getFile(), node.getLocalRelPath(), node.getSize(), node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(), node.isIsFile(), mimeType, "", MODULE_NAME, - "", "", TskData.EncodingType.XOR1); + "", "", TskData.EncodingType.XOR1, node.getParent(), getCurrentTransaction()); } else { //ALREADY CURRENT - SKIP statusMap.put(key, new ZipFileStatusWrapper(existingFile.getFile(), ZipFileStatus.SKIP)); @@ -1514,7 +1508,48 @@ class SevenZipExtractor { //recurse adding the children if this file was incomplete the children presumably need to be added for (UnpackedNode child : node.getChildren()) { - updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath), trans); + updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath)); + } + } + + private CaseDbTransaction getCurrentTransaction() throws TskCoreException { + + if (currentTransaction == null) { + startTransaction(); + } + + if (transactionCounter > MAX_TRANSACTION_SIZE) { + commitCurrentTransaction(); + startTransaction(); + } + + return currentTransaction; + } + + private void startTransaction() throws TskCoreException { + try { + currentTransaction = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); + transactionCounter = 0; + } catch (NoCurrentCaseException ex) { + throw new TskCoreException("Case is closed"); + } + } + + private void commitCurrentTransaction() throws TskCoreException { + if (currentTransaction != null) { + currentTransaction.commit(); + currentTransaction = null; + } + } + + private void rollbackCurrentTransaction() { + if (currentTransaction != null) { + try { + currentTransaction.rollback(); + currentTransaction = null; + } catch (TskCoreException ex) { + // Ignored + } } } From 417582205af4411ffc8e992dc771379dd360836e Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 18 Jun 2021 12:53:24 -0400 Subject: [PATCH 04/11] Cleanup and commenting --- .../casemodule/Bundle.properties-MERGED | 27 ++++++++++++----- .../SevenZipExtractor.java | 30 +++++++++++++++++-- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index 9a43ffe229..528d3a5088 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -247,10 +247,15 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi AddImageWizardIngestConfigVisual.getName.text=Configure Ingest AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ +this case are missing. Would you like to search for them now?\n\ +Previously, the image was located at:\n\ +{0}\n\ +Please note that you will still be able to browse directories and generate reports\n\ +if you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -269,9 +274,12 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ + Case Name: {0}\n\ + Case Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ +Close the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -303,7 +311,8 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ + Do you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -332,6 +341,7 @@ OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone: OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range. RecentCases.getName.text=Clear Recent Cases +# {0} - case name RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists. SelectDataSourceProcessorPanel.name.text=Select Data Source Type StartupWindow.title.text=Welcome @@ -344,6 +354,7 @@ StartupWindowProvider.openCase.noFile=Unable to open previously open case becaus UnpackagePortableCaseDialog.title.text=Unpackage Portable Case UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001) UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001 +# {0} - case folder UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist @@ -358,8 +369,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source @@ -367,7 +378,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index b06764dd69..273737ff18 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -799,9 +799,7 @@ class SevenZipExtractor { // add them to the DB. We wait until the end so that we have the metadata on all of the // intermediate nodes since the order is not guaranteed - //CaseDbTransaction trans = null; try { - //trans = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath, parentAr, archiveFile, depthMap); unpackedTree.commitCurrentTransaction(); } catch (TskCoreException | NoCurrentCaseException ex) { @@ -1274,6 +1272,11 @@ class SevenZipExtractor { final UnpackedNode rootNode; private int nodesProcessed = 0; + // It is significantly faster to add the DerivedFiles to the case on a transaction, + // but we don't want to hold the transaction (and case write lock) for the entire + // stage. Instead, we use the same transaction for MAX_TRANSACTION_SIZE database operations + // and then commit that transaction and start a new one, giving at least a short window + // for other processes. private CaseDbTransaction currentTransaction = null; private long transactionCounter = 0; private final static long MAX_TRANSACTION_SIZE = 1000; @@ -1527,6 +1530,16 @@ class SevenZipExtractor { } } + /** + * Get the current transaction being used in updateOrAddFileToCaseRec(). + * If there is no transaction, one will be started. After the + * transaction has been used MAX_TRANSACTION_SIZE, it will be committed and a + * new transaction will be opened. + * + * @return The open transaction. + * + * @throws TskCoreException + */ private CaseDbTransaction getCurrentTransaction() throws TskCoreException { if (currentTransaction == null) { @@ -1542,6 +1555,11 @@ class SevenZipExtractor { return currentTransaction; } + /** + * Open a transaction. + * + * @throws TskCoreException + */ private void startTransaction() throws TskCoreException { try { currentTransaction = Case.getCurrentCaseThrows().getSleuthkitCase().beginTransaction(); @@ -1551,6 +1569,11 @@ class SevenZipExtractor { } } + /** + * Commit the current transaction. + * + * @throws TskCoreException + */ private void commitCurrentTransaction() throws TskCoreException { if (currentTransaction != null) { currentTransaction.commit(); @@ -1558,6 +1581,9 @@ class SevenZipExtractor { } } + /** + * Rollback the current transaction. + */ private void rollbackCurrentTransaction() { if (currentTransaction != null) { try { From 32736b26546dcfb37b10bbfdf45ab9eb536784bb Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 18 Jun 2021 13:06:24 -0400 Subject: [PATCH 05/11] Restore bundle --- .../casemodule/Bundle.properties-MERGED | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index 528d3a5088..9a43ffe229 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -247,15 +247,10 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi AddImageWizardIngestConfigVisual.getName.text=Configure Ingest AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ -this case are missing. Would you like to search for them now?\n\ -Previously, the image was located at:\n\ -{0}\n\ -Please note that you will still be able to browse directories and generate reports\n\ -if you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -274,12 +269,9 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ - Case Name: {0}\n\ - Case Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ -Close the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -311,8 +303,7 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ - Do you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -341,7 +332,6 @@ OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone: OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range. RecentCases.getName.text=Clear Recent Cases -# {0} - case name RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists. SelectDataSourceProcessorPanel.name.text=Select Data Source Type StartupWindow.title.text=Welcome @@ -354,7 +344,6 @@ StartupWindowProvider.openCase.noFile=Unable to open previously open case becaus UnpackagePortableCaseDialog.title.text=Unpackage Portable Case UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001) UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001 -# {0} - case folder UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist @@ -369,8 +358,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source @@ -378,7 +367,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! From 3769b77ed607ae7c15aaf8c26c5ccaf0c9c9f4db Mon Sep 17 00:00:00 2001 From: apriestman Date: Mon, 21 Jun 2021 13:00:22 -0400 Subject: [PATCH 06/11] Read beginning of file once --- .../autopsy/modules/filetypeid/FileType.java | 18 ++++++++++--- .../modules/filetypeid/FileTypeDetector.java | 25 ++++++++++++----- .../filetypeid/FileTypeIdIngestModule.java | 27 ++++++++++++++++++- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java index acad818f09..2d8119b809 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java @@ -133,9 +133,9 @@ class FileType implements Serializable { * * @return True or false. */ - boolean matches(final AbstractFile file) { + boolean matches(final AbstractFile file, byte[] startOfFileBuffer, int bufLen) { for (Signature sig : this.signatures) { - if (!sig.containedIn(file)) { + if (!sig.containedIn(file, startOfFileBuffer, bufLen)) { return false; } } @@ -327,7 +327,7 @@ class FileType implements Serializable { * * @return True or false. */ - boolean containedIn(final AbstractFile file) { + boolean containedIn(final AbstractFile file, byte[] startOfFileBuffer, int bufLen) { if (offset >= file.getSize()) { return false; // File is too small, offset lies outside file. } @@ -340,7 +340,17 @@ class FileType implements Serializable { } try { byte[] buffer = new byte[signatureBytes.length]; - int bytesRead = file.read(buffer, actualOffset, signatureBytes.length); + int bytesRead; + if (actualOffset + signatureBytes.length < bufLen) { + // The signature is contained in the buffer we've already read, so + // just copy the appropriate section. + for (int i = 0; i < signatureBytes.length;i++) { + buffer[i] = startOfFileBuffer[(int)actualOffset + i]; + } + bytesRead = signatureBytes.length; + } else { + bytesRead = file.read(buffer, actualOffset, signatureBytes.length); + } return ((bytesRead == signatureBytes.length) && (Arrays.equals(buffer, signatureBytes))); } catch (TskCoreException ex) { /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index edd61eb4d1..965570c18c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -51,6 +51,7 @@ public class FileTypeDetector { private final List userDefinedFileTypes; private final List autopsyDefinedFileTypes; private static SortedSet tikaDetectedTypes; + private final int defaultBufferSize = 2048; // Number of bytes to initially read from the file. Should cover most signatures. /** * Gets a sorted set of the file types that can be detected: the MIME types @@ -203,12 +204,24 @@ public class FileTypeDetector { mimeType = MimeTypes.OCTET_STREAM; } + /* + * Read in the beginning of the file and store it. + */ + byte[] buf = new byte[defaultBufferSize]; + int bufLen; + try { + bufLen = file.read(buf, 0, defaultBufferSize); + } catch (TskCoreException ex) { + // Proceed for now - the error will likely get logged next time the file is read. + bufLen = 0; + } + /* * If the file is a regular file, give precedence to user-defined custom * file types. */ if (null == mimeType) { - mimeType = detectUserDefinedType(file); + mimeType = detectUserDefinedType(file, buf, bufLen); } /* @@ -216,7 +229,7 @@ public class FileTypeDetector { * custom file types defined by Autopsy. */ if (null == mimeType) { - mimeType = detectAutopsyDefinedType(file); + mimeType = detectAutopsyDefinedType(file, buf, bufLen); } /* @@ -352,11 +365,11 @@ public class FileTypeDetector { * * @return The MIME type as a string if a match is found; otherwise null. */ - private String detectUserDefinedType(AbstractFile file) { + private String detectUserDefinedType(AbstractFile file, byte[] startOfFileBuffer, int bufLen) { String retValue = null; for (FileType fileType : userDefinedFileTypes) { - if (fileType.matches(file)) { + if (fileType.matches(file, startOfFileBuffer, bufLen)) { retValue = fileType.getMimeType(); break; } @@ -372,9 +385,9 @@ public class FileTypeDetector { * * @return The MIME type as a string if a match is found; otherwise null. */ - private String detectAutopsyDefinedType(AbstractFile file) { + private String detectAutopsyDefinedType(AbstractFile file, byte[] startOfFileBuffer, int bufLen) { for (FileType fileType : autopsyDefinedFileTypes) { - if (fileType.matches(file)) { + if (fileType.matches(file, startOfFileBuffer, bufLen)) { return fileType.getMimeType(); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java index d5aa0d86fb..ba49d492d1 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java @@ -128,12 +128,37 @@ public class FileTypeIdIngestModule implements FileIngestModule { * of CustomFileTypesManager. */ private FileType detectUserDefinedFileType(AbstractFile file) throws CustomFileTypesManager.CustomFileTypesException { + /* + * Read in the beginning of the file once. + */ + byte[] buf = new byte[1024]; + int bufLen; + try { + bufLen = file.read(buf, 0, 1024); + } catch (TskCoreException ex) { + // Proceed for now - the error will likely get logged next time the file is read. + bufLen = 0; + } + return detectUserDefinedFileType(file, buf, bufLen); + } + + /** + * Determines whether or not a file matches a user-defined custom file type. + * + * @param file The file to test. + * + * @return The file type if a match is found; otherwise null. + * + * @throws CustomFileTypesException If there is an issue getting an instance + * of CustomFileTypesManager. + */ + private FileType detectUserDefinedFileType(AbstractFile file, byte[] startOfFileBuffer, int bufLen) throws CustomFileTypesManager.CustomFileTypesException { FileType retValue = null; CustomFileTypesManager customFileTypesManager = CustomFileTypesManager.getInstance(); List fileTypesList = customFileTypesManager.getUserDefinedFileTypes(); for (FileType fileType : fileTypesList) { - if (fileType.matches(file)) { + if (fileType.matches(file, startOfFileBuffer, bufLen)) { retValue = fileType; break; } From a9ac434e880269244cbc88c7d282044664583470 Mon Sep 17 00:00:00 2001 From: apriestman Date: Mon, 21 Jun 2021 13:25:51 -0400 Subject: [PATCH 07/11] Add timing --- .../modules/filetypeid/FileTypeDetector.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index 965570c18c..03b9e41353 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -53,6 +53,10 @@ public class FileTypeDetector { private static SortedSet tikaDetectedTypes; private final int defaultBufferSize = 2048; // Number of bytes to initially read from the file. Should cover most signatures. + private static final Object timingLock = new Object(); + private long totalFiles = 0; + private long totalMs = 0; + /** * Gets a sorted set of the file types that can be detected: the MIME types * detected by Tika (without optional parameters), the custom MIME types @@ -190,7 +194,7 @@ public class FileTypeDetector { // optional parameter attached. return removeOptionalParameter(mimeType); } - + long startTime = java.lang.System.currentTimeMillis(); /* * Mark non-regular files (refer to TskData.TSK_FS_META_TYPE_ENUM), * zero-sized files, unallocated space, and unused blocks (refer to @@ -310,6 +314,18 @@ public class FileTypeDetector { */ file.setMIMEType(mimeType); + long endTime = java.lang.System.currentTimeMillis(); + long elapsed = endTime - startTime; + synchronized(timingLock) { + totalFiles++; + totalMs+= elapsed; + + if (totalFiles % 1000 == 0) { + double ave = totalMs / totalFiles; + System.out.println("### " + totalFiles + " processed - average time: " + ave + " ms (" + totalFiles + " files, " + totalMs + " total ms)"); + } + } + return mimeType; } From e36417be26ea568200735e4dda55a3228352eb1c Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 22 Jun 2021 10:02:49 -0400 Subject: [PATCH 08/11] Don't load file if not needed --- .../autopsy/modules/filetypeid/FileTypeDetector.java | 6 +++--- .../autopsy/modules/filetypeid/FileTypeIdIngestModule.java | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index 03b9e41353..958f8f6ef5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -51,7 +51,7 @@ public class FileTypeDetector { private final List userDefinedFileTypes; private final List autopsyDefinedFileTypes; private static SortedSet tikaDetectedTypes; - private final int defaultBufferSize = 2048; // Number of bytes to initially read from the file. Should cover most signatures. + private final int defaultBufferSize = 600; // Number of bytes to initially read from the file. Should cover most signatures. private static final Object timingLock = new Object(); private long totalFiles = 0; @@ -219,7 +219,7 @@ public class FileTypeDetector { // Proceed for now - the error will likely get logged next time the file is read. bufLen = 0; } - + /* * If the file is a regular file, give precedence to user-defined custom * file types. @@ -314,7 +314,7 @@ public class FileTypeDetector { */ file.setMIMEType(mimeType); - long endTime = java.lang.System.currentTimeMillis(); + long endTime = java.lang.System.currentTimeMillis(); long elapsed = endTime - startTime; synchronized(timingLock) { totalFiles++; diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java index ba49d492d1..5dd6f49410 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdIngestModule.java @@ -128,6 +128,11 @@ public class FileTypeIdIngestModule implements FileIngestModule { * of CustomFileTypesManager. */ private FileType detectUserDefinedFileType(AbstractFile file) throws CustomFileTypesManager.CustomFileTypesException { + + if (CustomFileTypesManager.getInstance().getUserDefinedFileTypes().isEmpty()) { + return null; + } + /* * Read in the beginning of the file once. */ From ef26e072f48ae39c0894cbf78973514026cec055 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 22 Jun 2021 10:57:12 -0400 Subject: [PATCH 09/11] Removing timing --- .../modules/filetypeid/FileTypeDetector.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index 958f8f6ef5..a4c8b430d3 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -194,7 +194,6 @@ public class FileTypeDetector { // optional parameter attached. return removeOptionalParameter(mimeType); } - long startTime = java.lang.System.currentTimeMillis(); /* * Mark non-regular files (refer to TskData.TSK_FS_META_TYPE_ENUM), * zero-sized files, unallocated space, and unused blocks (refer to @@ -313,18 +312,6 @@ public class FileTypeDetector { * Documented side effect: write the result to the AbstractFile object. */ file.setMIMEType(mimeType); - - long endTime = java.lang.System.currentTimeMillis(); - long elapsed = endTime - startTime; - synchronized(timingLock) { - totalFiles++; - totalMs+= elapsed; - - if (totalFiles % 1000 == 0) { - double ave = totalMs / totalFiles; - System.out.println("### " + totalFiles + " processed - average time: " + ave + " ms (" + totalFiles + " files, " + totalMs + " total ms)"); - } - } return mimeType; } From 6096f31cb464b56da0b31ac9e27e3a2f73a12a70 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 22 Jun 2021 10:59:24 -0400 Subject: [PATCH 10/11] Remove timing variables --- .../autopsy/modules/filetypeid/FileTypeDetector.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index a4c8b430d3..52b6d9e191 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -52,10 +52,6 @@ public class FileTypeDetector { private final List autopsyDefinedFileTypes; private static SortedSet tikaDetectedTypes; private final int defaultBufferSize = 600; // Number of bytes to initially read from the file. Should cover most signatures. - - private static final Object timingLock = new Object(); - private long totalFiles = 0; - private long totalMs = 0; /** * Gets a sorted set of the file types that can be detected: the MIME types From 938157c0552f4c5800b1947733d3873190f651e0 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 22 Jun 2021 12:48:06 -0400 Subject: [PATCH 11/11] 7747 OS acct instance events --- .../events/OsAcctInstancesAddedEvent.java | 21 +++++++------------ .../eventlisteners/CaseEventListener.java | 13 +++++++++++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAcctInstancesAddedEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAcctInstancesAddedEvent.java index 17b8f31e9a..d752bf27fb 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAcctInstancesAddedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAcctInstancesAddedEvent.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.casemodule.events; -import java.util.ArrayList; import java.util.List; import static org.sleuthkit.autopsy.casemodule.Case.Events.OS_ACCT_INSTANCES_ADDED; import org.sleuthkit.datamodel.OsAccountInstance; @@ -26,16 +25,16 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * An application event published when OS accounts are added to the Sleuth Kit - * data model for a case. + * An application event published when OS account instances are added to the + * Sleuth Kit data model for a case. */ public final class OsAcctInstancesAddedEvent extends TskDataModelChangedEvent { private static final long serialVersionUID = 1L; /** - * Constructs an application event published when OS account instances are added to - * the Sleuth Kit data model for a case. + * Constructs an application event published when OS account instances are + * added to the Sleuth Kit data model for a case. * * @param osAcctInstances The OS account instances that were added. */ @@ -44,9 +43,9 @@ public final class OsAcctInstancesAddedEvent extends TskDataModelChangedEvent getOsAccountInstances() { return getNewValue(); @@ -54,11 +53,7 @@ public final class OsAcctInstancesAddedEvent extends TskDataModelChangedEvent getNewValueObjects(SleuthkitCase caseDb, List ids) throws TskCoreException { - List osAccountInstances = new ArrayList<>(); - for (Long id : ids) { - //RJCTODO - } - return osAccountInstances; + return caseDb.getOsAccountManager().getOsAccountInstances(ids); } -} \ No newline at end of file +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 806d18c63f..218a0101e8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -37,6 +37,7 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent; import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent; +import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent; import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; @@ -56,6 +57,7 @@ import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.datamodel.Tag; import org.sleuthkit.autopsy.events.AutopsyEvent; +import org.sleuthkit.datamodel.OsAccountInstance; /** * Listen for case events and update entries in the Central Repository database @@ -75,7 +77,8 @@ public final class CaseEventListener implements PropertyChangeListener { Case.Events.DATA_SOURCE_ADDED, Case.Events.TAG_DEFINITION_CHANGED, Case.Events.CURRENT_CASE, - Case.Events.DATA_SOURCE_NAME_CHANGED); + Case.Events.DATA_SOURCE_NAME_CHANGED, + Case.Events.OS_ACCT_INSTANCES_ADDED); public CaseEventListener() { jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build()); @@ -130,6 +133,14 @@ public final class CaseEventListener implements PropertyChangeListener { jobProcessingExecutor.submit(new DataSourceNameChangedTask(dbManager, evt)); } break; + case OS_ACCT_INSTANCES_ADDED: { + // STUB, TO BE REPLACED + List osAcctInstances = ((OsAcctInstancesAddedEvent) evt).getOsAccountInstances(); + for (OsAccountInstance instance : osAcctInstances) { + LOGGER.log(Level.INFO, String.format("Received OS account instance added message (instance ID = %d)", instance.getInstanceId())); + } + } + break; } }