From f3360d1ec679a1a0d7d8154d22db5b89e82cbced Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 1 Dec 2017 13:19:48 -0500 Subject: [PATCH 01/11] 3226 add memory setting to Application Options panel --- .../corecomponents/AutopsyOptionsPanel.form | 185 +++++++-- .../corecomponents/AutopsyOptionsPanel.java | 372 +++++++++++++++++- 2 files changed, 512 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index 2e618379e4..aebb685756 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -23,17 +23,14 @@ - + - - - - + @@ -53,12 +50,13 @@ - + + - + @@ -68,6 +66,8 @@ + + @@ -79,7 +79,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -185,7 +185,7 @@ - + @@ -201,24 +201,39 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + - @@ -382,6 +397,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 435bdc99b4..86750ba738 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -21,6 +21,14 @@ package org.sleuthkit.autopsy.corecomponents; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.StringJoiner; import java.util.logging.Level; import javax.imageio.ImageIO; import javax.swing.ImageIcon; @@ -33,6 +41,8 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.GeneralFilter; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.report.ReportBranding; /** @@ -42,12 +52,30 @@ import org.sleuthkit.autopsy.report.ReportBranding; "AutopsyOptionsPanel.logoPanel.border.title=Logo", "AutopsyOptionsPanel.viewPanel.border.title=View", "AutopsyOptionsPanel.invalidImageFile.msg=The selected file was not able to be used as an agency logo.", - "AutopsyOptionsPanel.invalidImageFile.title=Invalid Image File"}) + "AutopsyOptionsPanel.invalidImageFile.title=Invalid Image File", + "AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any changes to max memory to take effect.", + "AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory in Gigabytes:", + "AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:", + "AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB", + "AutopsyOptionsPanel.runtimePanel.border.title=Runtime", + "AutopsyOptionsPanel.invalidReasonLabel.not64BitInstall.text=JVM memory settings only enabled for installed 64 bit version", + "AutopsyOptionsPanel.invalidReasonLabel.noValueEntered.text=No value entered", + "AutopsyOptionsPanel.invalidReasonLabel.invalidCharacters.text=Invalid characters, value must be a positive integer", + "# {0} - minimumMemory", + "AutopsyOptionsPanel.invalidReasonLabel.underMinMemory.text=Value must be at least {0}GB", + "# {0} - systemMemory", + "AutopsyOptionsPanel.invalidReasonLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB"}) + final class AutopsyOptionsPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; private final JFileChooser fc; + private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes + private static final long MEGA_IN_GIGA = 1024; //used to convert memory settings saved as megabytes to gigabytes + private static final int HARD_MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes + private static final int SOFT_MIN_MEMORY_IN_GB = 4; //the minimum memory we inform the user is required in gigabytes private static final Logger logger = Logger.getLogger(AutopsyOptionsPanel.class.getName()); + private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION); AutopsyOptionsPanel() { initComponents(); @@ -56,8 +84,137 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { fc.setMultiSelectionEnabled(false); fc.setAcceptAllFileFilterUsed(false); fc.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR)); + if (!PlatformUtil.is64BitJVM()) { + //32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS + //So disabling the setting of heap size when the JVM is not 64 bit + //Is the safest course of action + memField.setEnabled(false); + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text()); + + } + systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB())); } + private long getSystemMemoryInGB() { + long memorySize = ((com.sun.management.OperatingSystemMXBean) ManagementFactory + .getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); + return memorySize / ONE_BILLION; + } + + private long getCurrentJvmMaxMemoryInGB() throws IOException { + String currentXmx = getCurrentXmxValue(); + char units = '-'; + Long value = 0L; + if (currentXmx.length() > 1) { + units = currentXmx.charAt(currentXmx.length() - 1); + value = Long.parseLong(currentXmx.substring(0, currentXmx.length() - 1)); + } else { + throw new IOException("No memory setting found in String: " + currentXmx); + } + switch (units) { + case 'g': + case 'G': + return value; + case 'm': + case 'M': + return value / MEGA_IN_GIGA; + default: + throw new IOException("Units were not recognized as parsed: " + units); + } + } + + private String getCurrentXmxValue() throws IOException { + File userFolder = PlatformUtil.getUserDirectory(); + File userEtcFolder = new File(userFolder, "etc"); + String confFile = Version.getName() + ".conf"; + File userEtcConfigFile = new File(userEtcFolder, confFile); + String[] settings; + String currentSetting = ""; + if (!userEtcConfigFile.exists()) { + String installFolder = PlatformUtil.getInstallPath(); + File installFolderEtc = new File(installFolder, "etc"); + File installFolderConfigFile = new File(installFolderEtc, confFile); + if (installFolderConfigFile.exists()) { + settings = getDefaultsFromFileContents(readConfFile(installFolderConfigFile)); + //copy install folder config + } else { + throw new IOException("Conf file could not be found, software may not be properly installed. " + installFolderConfigFile.toString()); + } + } else { + settings = getDefaultsFromFileContents(readConfFile(userEtcConfigFile)); + } + for (String option : settings) { + System.out.println("Setting: " + option); + if (option.startsWith("-J-Xmx")) { + currentSetting = option.replace("-J-Xmx", "").trim(); + } + } + return currentSetting; + } + + private void writeEtcConfFile() throws IOException { + String confFileName = Version.getName() + ".conf"; + File userFolder = PlatformUtil.getUserDirectory(); + File userEtcFolder = new File(userFolder, "etc"); + File userEtcConfigFile = new File(userEtcFolder, confFileName); + String installFolder = PlatformUtil.getInstallPath(); + File installFolderEtc = new File(installFolder, "etc"); + File installFolderConfigFile = new File(installFolderEtc, confFileName); + StringBuilder content = new StringBuilder(); + if (installFolderConfigFile.exists()) { + List confFile = readConfFile(installFolderConfigFile); + for (String line : confFile) { + if (line.contains("-J-Xmx")) { + // content.append("default_options=\""); + String[] splitLine = line.split(" "); + //.replace("default_options=", "").replaceAll("\"", "") + StringJoiner modifiedLine = new StringJoiner(" "); + + for (String piece : splitLine) { + if (piece.contains("-J-Xmx")) { + piece = "-J-Xmx" + memField.getText() + "g"; + } + modifiedLine.add(piece); + } + content.append(modifiedLine.toString()); + // content.append("\""); + } else { + content.append(line); + } + content.append("\n"); + } + Files.write(userEtcConfigFile.toPath(), content.toString().getBytes()); + //copy install folder config + } else { + throw new IOException("Conf file could not be found, software may not be properly installed. " + installFolderConfigFile.toString()); + } + } + + private static List readConfFile(File ctConfigFile) { + List lines = new ArrayList<>(); + if (null != ctConfigFile) { + Path filePath = ctConfigFile.toPath(); + Charset charset = Charset.forName("UTF-8"); + try { + lines = Files.readAllLines(filePath, charset); + } catch (IOException e) { + logger.log(Level.SEVERE, "Error reading config file contents. {}", ctConfigFile.getAbsolutePath()); + } + } + return lines; + } + + private static String[] getDefaultsFromFileContents(List list) { + Optional defaultSettings = list.stream().filter(line -> line.startsWith("default_options=")).findFirst(); + + if (defaultSettings.isPresent()) { + return defaultSettings.get().replace("default_options=", "").replaceAll("\"", "").split(" "); + } + return new String[]{}; + } + + @Messages({"# {0} - installedFolder", + "AutopsyOptionsPanel.invalidReasonLabel.configFileMissing.text=Unable to find JVM memory settings in installed folder {0}"}) void load() { boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); keepCurrentViewerRB.setSelected(keepPreferredViewer); @@ -75,6 +232,16 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } catch (IOException ex) { logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex); } + if (PlatformUtil.is64BitJVM()) { + try { + initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB()); + } catch (IOException ex) { + logger.log(Level.INFO, "Can't read current Jvm setting from file", ex); + memField.setEnabled(false); + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_configFileMissing_text(PlatformUtil.getInstallPath())); + } + memField.setText(initialMemValue); + } } private void updateAgencyLogo(String path) throws IOException { @@ -87,7 +254,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { BufferedImage image = ImageIO.read(file); //create it as an image first to support BMP files if (image == null) { throw new IOException("Unable to read file as a BufferedImage for file " + file.toString()); - } + } agencyLogoIcon = new ImageIcon(image.getScaledInstance(64, 64, 4)); agencyLogoPreview.setText(""); } @@ -109,10 +276,17 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, agencyLogoPathField.getText()); } } + try { + if (memField.isEnabled()) { //if the field can't of been changed we don't need to save it + writeEtcConfFile(); + } + } catch (IOException ex) { + logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\etc", ex); + } } boolean valid() { - return true; + return validateMemField(); } /** @@ -145,6 +319,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { jLabelTimeDisplay = new javax.swing.JLabel(); useLocalTimeRB = new javax.swing.JRadioButton(); useGMTTimeRB = new javax.swing.JRadioButton(); + runtimePanel = new javax.swing.JPanel(); + maxMemoryLabel = new javax.swing.JLabel(); + maxMemoryUnitsLabel = new javax.swing.JLabel(); + totalMemoryLabel = new javax.swing.JLabel(); + systemMemoryTotal = new javax.swing.JLabel(); + restartNecessaryWarning = new javax.swing.JLabel(); + memField = new javax.swing.JTextField(); + invalidReasonLabel = new javax.swing.JLabel(); jScrollPane1.setBorder(null); @@ -187,7 +369,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(browseLogosButton))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(149, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); logoPanelLayout.setVerticalGroup( logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -286,20 +468,29 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(viewPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(useGMTTimeRB) - .addComponent(keepCurrentViewerRB) - .addComponent(useBestViewerRB) - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(viewPanelLayout.createSequentialGroup() + .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCB) + .addComponent(viewsHideSlackCB)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(viewPanelLayout.createSequentialGroup() + .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(useGMTTimeRB) + .addComponent(keepCurrentViewerRB) + .addComponent(useBestViewerRB) + .addComponent(dataSourcesHideKnownCB) + .addComponent(viewsHideKnownCB)) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(viewPanelLayout.createSequentialGroup() .addComponent(useLocalTimeRB) - .addComponent(dataSourcesHideSlackCB) - .addComponent(viewsHideSlackCB) - .addComponent(dataSourcesHideKnownCB) - .addComponent(viewsHideKnownCB)))) - .addComponent(jLabelHideSlackFiles) - .addComponent(jLabelTimeDisplay) - .addComponent(jLabelHideKnownFiles) - .addComponent(jLabelSelectFile)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(viewPanelLayout.createSequentialGroup() + .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabelHideSlackFiles) + .addComponent(jLabelTimeDisplay) + .addComponent(jLabelHideKnownFiles) + .addComponent(jLabelSelectFile)) + .addGap(30, 30, 30)))) ); viewPanelLayout.setVerticalGroup( viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -330,6 +521,82 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(useGMTTimeRB)) ); + runtimePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.runtimePanel.border.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(maxMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(maxMemoryUnitsLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryUnitsLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(totalMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.totalMemoryLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(restartNecessaryWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartNecessaryWarning.text")); // NOI18N + + memField.setHorizontalAlignment(javax.swing.JTextField.TRAILING); + memField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + memFieldActionPerformed(evt); + } + }); + memField.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyPressed(java.awt.event.KeyEvent evt) { + memFieldKeyPressed(evt); + } + public void keyReleased(java.awt.event.KeyEvent evt) { + memFieldKeyReleased(evt); + } + public void keyTyped(java.awt.event.KeyEvent evt) { + memFieldKeyTyped(evt); + } + }); + + invalidReasonLabel.setForeground(new java.awt.Color(255, 0, 0)); + + javax.swing.GroupLayout runtimePanelLayout = new javax.swing.GroupLayout(runtimePanel); + runtimePanel.setLayout(runtimePanelLayout); + runtimePanelLayout.setHorizontalGroup( + runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(totalMemoryLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + runtimePanelLayout.setVerticalGroup( + runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(maxMemoryLabel)) + .addComponent(invalidReasonLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(totalMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addGap(11, 11, 11) + .addComponent(restartNecessaryWarning))) + .addGap(0, 0, 0)) + ); + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( @@ -338,6 +605,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(runtimePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); @@ -347,6 +615,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) + .addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0)) ); @@ -358,14 +628,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE) + .addComponent(jScrollPane1) .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 489, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) ); }// //GEN-END:initComponents @@ -424,6 +692,59 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } }//GEN-LAST:event_browseLogosButtonActionPerformed + private void up() { + String memText = memField.getText(); + if (memText.equals(initialMemValue)) { + System.out.println("hasn't changed don't fire"); + return; + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } + private void memFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyPressed + up(); + }//GEN-LAST:event_memFieldKeyPressed + + private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased + up(); + }//GEN-LAST:event_memFieldKeyReleased + + private void memFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyTyped + up(); + }//GEN-LAST:event_memFieldKeyTyped + + private void memFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_memFieldActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_memFieldActionPerformed + + private boolean validateMemField() { + String memText = memField.getText(); + invalidReasonLabel.setText(""); + if (!memField.isEnabled()) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text()); + return true; + } + + if (memText.length() == 0) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_noValueEntered_text()); + return false; + } + if (memText.replaceAll("[^\\d]", "").length() != memText.length()) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_invalidCharacters_text()); + return false; + } + int parsedInt = Integer.parseInt(memText); + if (parsedInt < HARD_MIN_MEMORY_IN_GB) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_underMinMemory_text(SOFT_MIN_MEMORY_IN_GB)); + return false; + } + if (parsedInt >= getSystemMemoryInGB()) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_overMaxMemory_text(getSystemMemoryInGB())); + return false; + } + + return true; + } + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel agencyLogoImageLabel; private javax.swing.JTextField agencyLogoPathField; @@ -433,6 +754,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.ButtonGroup buttonGroup3; private javax.swing.JCheckBox dataSourcesHideKnownCB; private javax.swing.JCheckBox dataSourcesHideSlackCB; + private javax.swing.JLabel invalidReasonLabel; private javax.swing.JLabel jLabelHideKnownFiles; private javax.swing.JLabel jLabelHideSlackFiles; private javax.swing.JLabel jLabelSelectFile; @@ -441,6 +763,13 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JScrollPane jScrollPane1; private javax.swing.JRadioButton keepCurrentViewerRB; private javax.swing.JPanel logoPanel; + private javax.swing.JLabel maxMemoryLabel; + private javax.swing.JLabel maxMemoryUnitsLabel; + private javax.swing.JTextField memField; + private javax.swing.JLabel restartNecessaryWarning; + private javax.swing.JPanel runtimePanel; + private javax.swing.JLabel systemMemoryTotal; + private javax.swing.JLabel totalMemoryLabel; private javax.swing.JRadioButton useBestViewerRB; private javax.swing.JRadioButton useGMTTimeRB; private javax.swing.JRadioButton useLocalTimeRB; @@ -448,4 +777,5 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JCheckBox viewsHideKnownCB; private javax.swing.JCheckBox viewsHideSlackCB; // End of variables declaration//GEN-END:variables + } From 80705a39f7109a8b6cc4a9c21f01bc298c03f447 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 1 Dec 2017 13:24:05 -0500 Subject: [PATCH 02/11] 3226 add 4 gigabyte default JVM heap size for developers --- nbproject/project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nbproject/project.properties b/nbproject/project.properties index ac6c347444..04a6d5800b 100755 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -16,7 +16,7 @@ update_versions=false #custom JVM options #Note: can be higher on 64 bit systems, should be in sync with build.xml # for Japanese version add: -J-Duser.language=ja -run.args.extra=-J-Xms24m -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication +run.args.extra=-J-Xms24m -J-Xmx4g -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2 auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false From e7c38d3f263c6936b53768289e200fabff50a11e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 1 Dec 2017 14:30:04 -0500 Subject: [PATCH 03/11] 3226 clean up memory settings code and add additional comments --- .../corecomponents/AutopsyOptionsPanel.form | 3 - .../corecomponents/AutopsyOptionsPanel.java | 209 +++++++++++------- 2 files changed, 124 insertions(+), 88 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index aebb685756..5f3ea9f6e6 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -504,10 +504,7 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 86750ba738..91e3b179b9 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -70,6 +70,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; private final JFileChooser fc; + private static final String ETC_FOLDER_NAME = "etc"; + private static final String CONFIG_FILE_EXTENSION = ".conf"; private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes private static final long MEGA_IN_GIGA = 1024; //used to convert memory settings saved as megabytes to gigabytes private static final int HARD_MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes @@ -95,12 +97,23 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB())); } + /** + * Get the total system memory in gigabytes which exists on the machine + * which the application is running. + * + * @return the total system memory + */ private long getSystemMemoryInGB() { long memorySize = ((com.sun.management.OperatingSystemMXBean) ManagementFactory .getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); return memorySize / ONE_BILLION; } + /** + * Gets the currently saved max java heap space in gigabytes. + * + * @return @throws IOException when unable to get a valid setting + */ private long getCurrentJvmMaxMemoryInGB() throws IOException { String currentXmx = getCurrentXmxValue(); char units = '-'; @@ -111,6 +124,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } else { throw new IOException("No memory setting found in String: " + currentXmx); } + //some older .conf files might have the units as megabytes instead of gigabytes switch (units) { case 'g': case 'G': @@ -123,28 +137,27 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } } + /* + * The value currently saved in the conf file as the max java heap space + * available to this application. Form will be an integer followed by a + * character indicating units. Helper method for + * getCurrentJvmMaxMemoryInGB() + * + * @return the saved value for the max java heap space + * + * @throws IOException if the conf file does not exist in either the user + * directory or the install directory + */ private String getCurrentXmxValue() throws IOException { - File userFolder = PlatformUtil.getUserDirectory(); - File userEtcFolder = new File(userFolder, "etc"); - String confFile = Version.getName() + ".conf"; - File userEtcConfigFile = new File(userEtcFolder, confFile); String[] settings; String currentSetting = ""; - if (!userEtcConfigFile.exists()) { - String installFolder = PlatformUtil.getInstallPath(); - File installFolderEtc = new File(installFolder, "etc"); - File installFolderConfigFile = new File(installFolderEtc, confFile); - if (installFolderConfigFile.exists()) { - settings = getDefaultsFromFileContents(readConfFile(installFolderConfigFile)); - //copy install folder config - } else { - throw new IOException("Conf file could not be found, software may not be properly installed. " + installFolderConfigFile.toString()); - } + File userConfFile = getInstallFolderConfFile(); + if (!userConfFile.exists()) { + settings = getDefaultsFromFileContents(readConfFile(getInstallFolderConfFile())); } else { - settings = getDefaultsFromFileContents(readConfFile(userEtcConfigFile)); + settings = getDefaultsFromFileContents(readConfFile(userConfFile)); } for (String option : settings) { - System.out.println("Setting: " + option); if (option.startsWith("-J-Xmx")) { currentSetting = option.replace("-J-Xmx", "").trim(); } @@ -152,58 +165,106 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return currentSetting; } - private void writeEtcConfFile() throws IOException { - String confFileName = Version.getName() + ".conf"; - File userFolder = PlatformUtil.getUserDirectory(); - File userEtcFolder = new File(userFolder, "etc"); - File userEtcConfigFile = new File(userEtcFolder, confFileName); + /** + * Get the conf file from the install directory which stores the default + * values for the settings. + * + * @return the file which has the applications default .conf file + * + * @throws IOException when the file does not exist. + */ + private static File getInstallFolderConfFile() throws IOException { + String confFileName = Version.getName() + CONFIG_FILE_EXTENSION; String installFolder = PlatformUtil.getInstallPath(); - File installFolderEtc = new File(installFolder, "etc"); + File installFolderEtc = new File(installFolder, ETC_FOLDER_NAME); File installFolderConfigFile = new File(installFolderEtc, confFileName); - StringBuilder content = new StringBuilder(); - if (installFolderConfigFile.exists()) { - List confFile = readConfFile(installFolderConfigFile); - for (String line : confFile) { - if (line.contains("-J-Xmx")) { - // content.append("default_options=\""); - String[] splitLine = line.split(" "); - //.replace("default_options=", "").replaceAll("\"", "") - StringJoiner modifiedLine = new StringJoiner(" "); - - for (String piece : splitLine) { - if (piece.contains("-J-Xmx")) { - piece = "-J-Xmx" + memField.getText() + "g"; - } - modifiedLine.add(piece); - } - content.append(modifiedLine.toString()); - // content.append("\""); - } else { - content.append(line); - } - content.append("\n"); - } - Files.write(userEtcConfigFile.toPath(), content.toString().getBytes()); - //copy install folder config - } else { + if (!installFolderConfigFile.exists()) { throw new IOException("Conf file could not be found, software may not be properly installed. " + installFolderConfigFile.toString()); } + return installFolderConfigFile; } - private static List readConfFile(File ctConfigFile) { + /** + * Get the conf file from the directory which stores the currently in use + * settings. Creates the directory for the file if the directory does not + * exist. + * + * @return the file which has the applications current .conf file + */ + private static File getUserFolderConfFile() { + String confFileName = Version.getName() + CONFIG_FILE_EXTENSION; + File userFolder = PlatformUtil.getUserDirectory(); + File userEtcFolder = new File(userFolder, ETC_FOLDER_NAME); + if (!userEtcFolder.exists()) { + userEtcFolder.mkdir(); + } + return new File(userEtcFolder, confFileName); + } + + /** + * Take the conf file in the install directory and save a copy of it to the + * user directory. The copy will be modified to include the current memory + * setting. + * + * @throws IOException when unable to write a conf file or access the + * install folders conf file + */ + private void writeEtcConfFile() throws IOException { + StringBuilder content = new StringBuilder(); + List confFile = readConfFile(getInstallFolderConfFile()); + for (String line : confFile) { + if (line.contains("-J-Xmx")) { + String[] splitLine = line.split(" "); + StringJoiner modifiedLine = new StringJoiner(" "); + for (String piece : splitLine) { + if (piece.contains("-J-Xmx")) { + piece = "-J-Xmx" + memField.getText() + "g"; + } + modifiedLine.add(piece); + } + content.append(modifiedLine.toString()); + } else { + content.append(line); + } + content.append("\n"); + } + Files.write(getUserFolderConfFile().toPath(), content.toString().getBytes()); + } + + /** + * Reads a conf file line by line putting each line into a list of strings + * which will be returned. + * + * @param configFile the .conf file which you wish to read. + * + * @return a list of strings with a string for each line in the conf file + * specified. + */ + private static List readConfFile(File configFile) { List lines = new ArrayList<>(); - if (null != ctConfigFile) { - Path filePath = ctConfigFile.toPath(); + if (null != configFile) { + Path filePath = configFile.toPath(); Charset charset = Charset.forName("UTF-8"); try { lines = Files.readAllLines(filePath, charset); } catch (IOException e) { - logger.log(Level.SEVERE, "Error reading config file contents. {}", ctConfigFile.getAbsolutePath()); + logger.log(Level.SEVERE, "Error reading config file contents. {}", configFile.getAbsolutePath()); } } return lines; } + /** + * Find the string in the list of strings which contains the default options + * settings and split it into an array of strings containing one element for + * each setting specified. + * + * @param list a list of string representing lines of a .conf file + * + * @return an array of strings for each argument on the line which has the + * default options, returns an empty array of Strings if default + * options is not present. + */ private static String[] getDefaultsFromFileContents(List list) { Optional defaultSettings = list.stream().filter(line -> line.startsWith("default_options=")).findFirst(); @@ -281,12 +342,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { writeEtcConfFile(); } } catch (IOException ex) { - logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\etc", ex); + logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex); } } boolean valid() { - return validateMemField(); + return isMemFieldValid(); } /** @@ -532,21 +593,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(restartNecessaryWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartNecessaryWarning.text")); // NOI18N memField.setHorizontalAlignment(javax.swing.JTextField.TRAILING); - memField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - memFieldActionPerformed(evt); - } - }); memField.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { memFieldKeyPressed(evt); } - public void keyReleased(java.awt.event.KeyEvent evt) { - memFieldKeyReleased(evt); - } - public void keyTyped(java.awt.event.KeyEvent evt) { - memFieldKeyTyped(evt); - } }); invalidReasonLabel.setForeground(new java.awt.Color(255, 0, 0)); @@ -692,38 +742,28 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } }//GEN-LAST:event_browseLogosButtonActionPerformed - private void up() { + private void memFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyPressed String memText = memField.getText(); if (memText.equals(initialMemValue)) { - System.out.println("hasn't changed don't fire"); + //if it is still the initial value don't fire change return; } firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } - private void memFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyPressed - up(); }//GEN-LAST:event_memFieldKeyPressed - private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased - up(); - }//GEN-LAST:event_memFieldKeyReleased - - private void memFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyTyped - up(); - }//GEN-LAST:event_memFieldKeyTyped - - private void memFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_memFieldActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_memFieldActionPerformed - - private boolean validateMemField() { + /** + * Checks that if the mem field is enabled it has a valid value. + * + * @return true if the memfield is valid false if it is not + */ + private boolean isMemFieldValid() { String memText = memField.getText(); invalidReasonLabel.setText(""); if (!memField.isEnabled()) { invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text()); + //the panel should be valid when the memfield is disabled return true; } - if (memText.length() == 0) { invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_noValueEntered_text()); return false; @@ -741,7 +781,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_overMaxMemory_text(getSystemMemoryInGB())); return false; } - return true; } From 81c677d828bdfad674307e24a9aaae1428c6b95a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 1 Dec 2017 15:56:02 -0500 Subject: [PATCH 04/11] 3226 check Developer mode for enabling of memory settings --- .../corecomponents/AutopsyOptionsPanel.form | 5 +- .../corecomponents/AutopsyOptionsPanel.java | 47 ++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index 5f3ea9f6e6..9d8fc97508 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -494,6 +494,9 @@ + + + @@ -504,7 +507,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 91e3b179b9..b1a9eeb627 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -58,13 +58,14 @@ import org.sleuthkit.autopsy.report.ReportBranding; "AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:", "AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB", "AutopsyOptionsPanel.runtimePanel.border.title=Runtime", - "AutopsyOptionsPanel.invalidReasonLabel.not64BitInstall.text=JVM memory settings only enabled for installed 64 bit version", + "AutopsyOptionsPanel.invalidReasonLabel.not64BitInstall.text=JVM memory settings only enabled for 64 bit version", "AutopsyOptionsPanel.invalidReasonLabel.noValueEntered.text=No value entered", "AutopsyOptionsPanel.invalidReasonLabel.invalidCharacters.text=Invalid characters, value must be a positive integer", "# {0} - minimumMemory", "AutopsyOptionsPanel.invalidReasonLabel.underMinMemory.text=Value must be at least {0}GB", "# {0} - systemMemory", - "AutopsyOptionsPanel.invalidReasonLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB"}) + "AutopsyOptionsPanel.invalidReasonLabel.overMaxMemory.text=Value must be less than the total system memory of {0}GB", + "AutopsyOptionsPanel.invalidReasonLabel.developerMode.text=Memory settings are not available while running in developer mode"}) final class AutopsyOptionsPanel extends javax.swing.JPanel { @@ -86,13 +87,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { fc.setMultiSelectionEnabled(false); fc.setAcceptAllFileFilterUsed(false); fc.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR)); - if (!PlatformUtil.is64BitJVM()) { + if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) { //32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS //So disabling the setting of heap size when the JVM is not 64 bit //Is the safest course of action + //And the file won't exist in the install folder when running through netbeans memField.setEnabled(false); - invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text()); - } systemMemoryTotal.setText(Long.toString(getSystemMemoryInGB())); } @@ -179,7 +179,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { File installFolderEtc = new File(installFolder, ETC_FOLDER_NAME); File installFolderConfigFile = new File(installFolderEtc, confFileName); if (!installFolderConfigFile.exists()) { - throw new IOException("Conf file could not be found, software may not be properly installed. " + installFolderConfigFile.toString()); + throw new IOException("Conf file could not be found" + installFolderConfigFile.toString()); } return installFolderConfigFile; } @@ -274,8 +274,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return new String[]{}; } - @Messages({"# {0} - installedFolder", - "AutopsyOptionsPanel.invalidReasonLabel.configFileMissing.text=Unable to find JVM memory settings in installed folder {0}"}) void load() { boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); keepCurrentViewerRB.setSelected(keepPreferredViewer); @@ -293,16 +291,16 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } catch (IOException ex) { logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex); } - if (PlatformUtil.is64BitJVM()) { + if (memField.isEnabled()) { try { initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB()); } catch (IOException ex) { - logger.log(Level.INFO, "Can't read current Jvm setting from file", ex); + logger.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex); memField.setEnabled(false); - invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_configFileMissing_text(PlatformUtil.getInstallPath())); } memField.setText(initialMemValue); } + isMemFieldValid(); //ensure the error message is up to date } private void updateAgencyLogo(String path) throws IOException { @@ -337,12 +335,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, agencyLogoPathField.getText()); } } - try { - if (memField.isEnabled()) { //if the field can't of been changed we don't need to save it + if (memField.isEnabled()) { //if the field could of been changed we need to try and save it + try { writeEtcConfFile(); + } catch (IOException ex) { + logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex); } - } catch (IOException ex) { - logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex); } } @@ -590,12 +588,13 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(totalMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.totalMemoryLabel.text")); // NOI18N + restartNecessaryWarning.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/warning16.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(restartNecessaryWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartNecessaryWarning.text")); // NOI18N memField.setHorizontalAlignment(javax.swing.JTextField.TRAILING); memField.addKeyListener(new java.awt.event.KeyAdapter() { - public void keyPressed(java.awt.event.KeyEvent evt) { - memFieldKeyPressed(evt); + public void keyReleased(java.awt.event.KeyEvent evt) { + memFieldKeyReleased(evt); } }); @@ -742,14 +741,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } }//GEN-LAST:event_browseLogosButtonActionPerformed - private void memFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyPressed + private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased String memText = memField.getText(); if (memText.equals(initialMemValue)) { //if it is still the initial value don't fire change return; } firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_memFieldKeyPressed + }//GEN-LAST:event_memFieldKeyReleased /** * Checks that if the mem field is enabled it has a valid value. @@ -759,9 +758,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private boolean isMemFieldValid() { String memText = memField.getText(); invalidReasonLabel.setText(""); - if (!memField.isEnabled()) { + if (!PlatformUtil.is64BitJVM()) { invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_not64BitInstall_text()); - //the panel should be valid when the memfield is disabled + //the panel should be valid when it is a 32 bit jvm because the memfield will be disabled. + return true; + } + if (Version.getBuildType() == Version.Type.DEVELOPMENT) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_developerMode_text()); + //the panel should be valid when you are running in developer mode because the memfield will be disabled return true; } if (memText.length() == 0) { @@ -783,7 +787,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } return true; } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel agencyLogoImageLabel; private javax.swing.JTextField agencyLogoPathField; From 6bb0c8b70c3967d3b0b9a39496b9b39cb391ecea Mon Sep 17 00:00:00 2001 From: benhbasis <31926879+benhbasis@users.noreply.github.com> Date: Mon, 4 Dec 2017 07:49:32 -0500 Subject: [PATCH 05/11] Update StringsTextExtractor.java At the request of Brian Carrier, as suggested and tested in VIK-2979 --- .../sleuthkit/autopsy/keywordsearch/StringsTextExtractor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/StringsTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/StringsTextExtractor.java index 4ccc8d76c5..7183cf7346 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/StringsTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/StringsTextExtractor.java @@ -152,7 +152,7 @@ class StringsTextExtractor extends FileTextExtractor { private static final Logger logger = Logger.getLogger(EnglishOnlyStream.class.getName()); private static final String NLS = Character.toString((char) 10); //new line - private static final int READ_BUF_SIZE = 256; + private static final int READ_BUF_SIZE = 65536; private static final int MIN_PRINTABLE_CHARS = 4; //num. of chars needed to qualify as a char string //args From 87167854da55e673c9e63249328428cfa1dc961a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 4 Dec 2017 15:42:25 -0500 Subject: [PATCH 06/11] Remove completion check from DataSourceIngestJob.cancel --- .../autopsy/ingest/DataSourceIngestJob.java | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java index f9caad7683..d07e764be5 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2016 Basis Technology Corp. + * Copyright 2014-2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -125,10 +125,9 @@ final class DataSourceIngestJob { * class. */ private volatile boolean currentDataSourceIngestModuleCancelled; + private final List cancelledDataSourceIngestModules = new CopyOnWriteArrayList<>(); private volatile boolean cancelled; private volatile IngestJob.CancellationReason cancellationReason = IngestJob.CancellationReason.NOT_CANCELLED; - private final Object cancellationStateMonitor = new Object(); - private final List cancelledDataSourceIngestModules = new CopyOnWriteArrayList<>(); /** * A data source ingest job uses the task scheduler singleton to create and @@ -989,6 +988,10 @@ final class DataSourceIngestJob { * @param reason The cancellation reason. */ void cancel(IngestJob.CancellationReason reason) { + this.cancelled = true; + this.cancellationReason = reason; + DataSourceIngestJob.taskScheduler.cancelPendingTasksForIngestJob(this); + if (this.doUI) { /** * Put a cancellation message on data source level ingest progress @@ -1023,32 +1026,9 @@ final class DataSourceIngestJob { "IngestJob.progress.fileIngest.cancelMessage", this.currentFileIngestModule, this.currentFileIngestTask)); } - } } } - - /* - * If the work is not already done, show this job as cancelled for the - * given reason. - */ - if (Stages.FINALIZATION != stage) { - synchronized (cancellationStateMonitor) { - /* - * These fields are volatile for reading, synchronized on the - * monitor here for writing. - */ - this.cancelled = true; - this.cancellationReason = reason; - } - } - - /** - * Tell the task scheduler to cancel all pending tasks, i.e., tasks not - * not being performed by an ingest thread. - */ - DataSourceIngestJob.taskScheduler.cancelPendingTasksForIngestJob(this); - this.checkForStageCompleted(); } /** From 4151082c5aed55eff589f4fc1cce8d17e729f624 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 4 Dec 2017 16:26:14 -0500 Subject: [PATCH 07/11] Remove inaccurate ingest job cancellatino msg details --- .../autopsy/ingest/Bundle.properties | 3 +- .../autopsy/ingest/Bundle_ja.properties | 3 +- .../autopsy/ingest/DataSourceIngestJob.java | 36 ++++--------------- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties index f23dd57f84..d240310b1c 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -20,8 +20,7 @@ IngestMessagePanel.totalUniqueMessagesNameVal.text=- IngestJob.progress.dataSourceIngest.initialDisplayName=Analyzing {0} IngestJob.progress.dataSourceIngest.displayName={0} for {1} IngestJob.progress.fileIngest.displayName=Analyzing files from {0} -IngestJob.progress.fileIngest.cancelMessage=Waiting for {0} on {1} -IngestJob.progress.cancelling={0} (Cancelling...) +IngestJob.progress.cancelling=Cancelling... IngestJob.cancellationDialog.title=Cancel Ingest IngestDialog.startButton.title=Start IngestDialog.closeButton.title=Close diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties index f7af8964cc..2fc82d0dd9 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties @@ -2,7 +2,7 @@ CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8 HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6 IngestDialog.closeButton.title=\u9589\u3058\u308b IngestDialog.startButton.title=\u958b\u59cb -IngestJob.progress.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09 +IngestJob.progress.cancelling=\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026 IngestJob.progress.dataSourceIngest.displayName={1}\u306e{0} IngestJob.progress.fileIngest.displayName={0}\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d IngestManager.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc @@ -90,7 +90,6 @@ IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.jobID=\u30b8\u30e7\u30d ModuleTableModel.colName.module=\u30e2\u30b8\u30e5\u30fc\u30eb Menu/Tools/RunIngestModules=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c -IngestJob.progress.fileIngest.cancelMessage={1}\u306e{0}\u3092\u5f85\u3063\u3066\u3044\u307e\u3059 IngestManager.OpenEventChannel.Fail.ErrMsg=\u3053\u306e\u30b1\u30fc\u30b9\u3067\u4f7f\u308f\u308c\u3066\u3044\u308b\u304b\u3082\u3057\u308c\u306a\u3044\u4ed6\u306e\u30ce\u30fc\u30c9\u306b\u89e3\u6790\u30d7\u30ed\u30bb\u30b9\u304c\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 IngestManager.OpenEventChannel.Fail.Title=\u63a5\u7d9a\u5931\u6557 IngestJobSettings.moduleSettingsSave.warning={1}\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e{0}\u30e2\u30b8\u30e5\u30fc\u30eb\u7528\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java index d07e764be5..b8d5b7e359 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java @@ -991,41 +991,19 @@ final class DataSourceIngestJob { this.cancelled = true; this.cancellationReason = reason; DataSourceIngestJob.taskScheduler.cancelPendingTasksForIngestJob(this); - + if (this.doUI) { - /** - * Put a cancellation message on data source level ingest progress - * bar, if it is still running. - */ synchronized (this.dataSourceIngestProgressLock) { - if (dataSourceIngestProgress != null) { - final String displayName = NbBundle.getMessage(this.getClass(), - "IngestJob.progress.dataSourceIngest.initialDisplayName", - dataSource.getName()); - dataSourceIngestProgress.setDisplayName( - NbBundle.getMessage(this.getClass(), - "IngestJob.progress.cancelling", - displayName)); + if (null != dataSourceIngestProgress) { + dataSourceIngestProgress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestJob.progress.dataSourceIngest.initialDisplayName", dataSource.getName())); + dataSourceIngestProgress.progress(NbBundle.getMessage(this.getClass(), "IngestJob.progress.cancelling")); } } - /** - * Put a cancellation message on the file level ingest progress bar, - * if it is still running. - */ synchronized (this.fileIngestProgressLock) { - if (this.fileIngestProgress != null) { - final String displayName = NbBundle.getMessage(this.getClass(), - "IngestJob.progress.fileIngest.displayName", - this.dataSource.getName()); - this.fileIngestProgress.setDisplayName( - NbBundle.getMessage(this.getClass(), "IngestJob.progress.cancelling", - displayName)); - if (!this.currentFileIngestModule.isEmpty() && !this.currentFileIngestTask.isEmpty()) { - this.fileIngestProgress.progress(NbBundle.getMessage(this.getClass(), - "IngestJob.progress.fileIngest.cancelMessage", - this.currentFileIngestModule, this.currentFileIngestTask)); - } + if (null != this.fileIngestProgress) { + this.fileIngestProgress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestJob.progress.fileIngest.displayName", this.dataSource.getName())); + this.fileIngestProgress.progress(NbBundle.getMessage(this.getClass(), "IngestJob.progress.cancelling")); } } } From 5f338c4f13dcdcd3b150afa736fb5e721e3703e5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 5 Dec 2017 11:32:15 -0500 Subject: [PATCH 08/11] 3226 Fixed error displaying current memory setting, and layout issues --- .../corecomponents/AutopsyOptionsPanel.form | 101 +++++++++--------- .../corecomponents/AutopsyOptionsPanel.java | 88 +++++++-------- 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index 9d8fc97508..2457e1be71 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -49,12 +49,12 @@ - + - - - + + + @@ -201,13 +201,6 @@ - - - - - - - @@ -218,9 +211,13 @@ - - - + + + + + + + @@ -401,7 +398,7 @@ - + @@ -414,25 +411,25 @@ - - - - - - - - - - - - + + - + + + + + + - - + + - + + + + + + @@ -440,28 +437,22 @@ - - - - - - - + + + + - + + - - - - - - - - - - - + + + + + + + @@ -491,6 +482,9 @@ + + + @@ -517,6 +511,13 @@ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index b1a9eeb627..9fd8f10734 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -54,7 +54,7 @@ import org.sleuthkit.autopsy.report.ReportBranding; "AutopsyOptionsPanel.invalidImageFile.msg=The selected file was not able to be used as an agency logo.", "AutopsyOptionsPanel.invalidImageFile.title=Invalid Image File", "AutopsyOptionsPanel.restartNecessaryWarning.text=A restart is necessary for any changes to max memory to take effect.", - "AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory in Gigabytes:", + "AutopsyOptionsPanel.totalMemoryLabel.text=Total System Memory:", "AutopsyOptionsPanel.maxMemoryLabel.text=Maximum JVM Memory:", "AutopsyOptionsPanel.maxMemoryUnitsLabel.text=GB", "AutopsyOptionsPanel.runtimePanel.border.title=Runtime", @@ -75,8 +75,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private static final String CONFIG_FILE_EXTENSION = ".conf"; private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes private static final long MEGA_IN_GIGA = 1024; //used to convert memory settings saved as megabytes to gigabytes - private static final int HARD_MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes - private static final int SOFT_MIN_MEMORY_IN_GB = 4; //the minimum memory we inform the user is required in gigabytes + private static final int MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes private static final Logger logger = Logger.getLogger(AutopsyOptionsPanel.class.getName()); private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION); @@ -151,7 +150,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private String getCurrentXmxValue() throws IOException { String[] settings; String currentSetting = ""; - File userConfFile = getInstallFolderConfFile(); + File userConfFile = getUserFolderConfFile(); if (!userConfFile.exists()) { settings = getDefaultsFromFileContents(readConfFile(getInstallFolderConfFile())); } else { @@ -386,6 +385,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { restartNecessaryWarning = new javax.swing.JLabel(); memField = new javax.swing.JTextField(); invalidReasonLabel = new javax.swing.JLabel(); + maxMemoryUnitsLabel1 = new javax.swing.JLabel(); jScrollPane1.setBorder(null); @@ -527,11 +527,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(viewPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(viewPanelLayout.createSequentialGroup() - .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCB) - .addComponent(viewsHideSlackCB)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(viewPanelLayout.createSequentialGroup() .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(useGMTTimeRB) @@ -541,7 +536,10 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(viewsHideKnownCB)) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(viewPanelLayout.createSequentialGroup() - .addComponent(useLocalTimeRB) + .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourcesHideSlackCB) + .addComponent(viewsHideSlackCB) + .addComponent(useLocalTimeRB)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addGroup(viewPanelLayout.createSequentialGroup() .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -588,6 +586,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(totalMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.totalMemoryLabel.text")); // NOI18N + systemMemoryTotal.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + restartNecessaryWarning.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/warning16.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(restartNecessaryWarning, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartNecessaryWarning.text")); // NOI18N @@ -600,6 +600,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { invalidReasonLabel.setForeground(new java.awt.Color(255, 0, 0)); + org.openide.awt.Mnemonics.setLocalizedText(maxMemoryUnitsLabel1, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryUnitsLabel.text")); // NOI18N + javax.swing.GroupLayout runtimePanelLayout = new javax.swing.GroupLayout(runtimePanel); runtimePanel.setLayout(runtimePanelLayout); runtimePanelLayout.setHorizontalGroup( @@ -607,42 +609,39 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(runtimePanelLayout.createSequentialGroup() .addContainerGap() .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(runtimePanelLayout.createSequentialGroup() - .addComponent(totalMemoryLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(runtimePanelLayout.createSequentialGroup() - .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(totalMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(memField, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(invalidReasonLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); runtimePanelLayout.setVerticalGroup( runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(runtimePanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(maxMemoryLabel)) - .addComponent(invalidReasonLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(runtimePanelLayout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(totalMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGroup(runtimePanelLayout.createSequentialGroup() - .addGap(11, 11, 11) - .addComponent(restartNecessaryWarning))) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(maxMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(totalMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(0, 0, 0)) ); @@ -650,12 +649,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(runtimePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(runtimePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( @@ -777,8 +776,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return false; } int parsedInt = Integer.parseInt(memText); - if (parsedInt < HARD_MIN_MEMORY_IN_GB) { - invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_underMinMemory_text(SOFT_MIN_MEMORY_IN_GB)); + if (parsedInt < MIN_MEMORY_IN_GB) { + invalidReasonLabel.setText(Bundle.AutopsyOptionsPanel_invalidReasonLabel_underMinMemory_text(MIN_MEMORY_IN_GB)); return false; } if (parsedInt >= getSystemMemoryInGB()) { @@ -807,6 +806,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JPanel logoPanel; private javax.swing.JLabel maxMemoryLabel; private javax.swing.JLabel maxMemoryUnitsLabel; + private javax.swing.JLabel maxMemoryUnitsLabel1; private javax.swing.JTextField memField; private javax.swing.JLabel restartNecessaryWarning; private javax.swing.JPanel runtimePanel; From b69bc2731ef9474254f92b9eb70918e6e4e40f00 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 5 Dec 2017 12:05:20 -0500 Subject: [PATCH 09/11] 3226 fix horizontal allignment of notifications --- .../corecomponents/AutopsyOptionsPanel.form | 13 ++++++------- .../corecomponents/AutopsyOptionsPanel.java | 15 +++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index 2457e1be71..00881c2ca7 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -65,9 +65,9 @@ - + - + @@ -424,12 +424,12 @@ - + - - + + - + @@ -454,7 +454,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 9fd8f10734..a62ae4400c 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -619,11 +619,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(18, 18, 18) .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(invalidReasonLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE) + .addComponent(invalidReasonLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); runtimePanelLayout.setVerticalGroup( runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -641,8 +641,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(totalMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(0, 0, 0)) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); @@ -662,9 +661,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(jPanel1Layout.createSequentialGroup() .addGap(0, 0, 0) .addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0)) ); From f2d31e588236ffe649fbe64393a53a0627fe6ed5 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 5 Dec 2017 12:19:36 -0500 Subject: [PATCH 10/11] Make search responsive to both job and thread cancellation --- .../KeywordSearchIngestModule.java | 2 +- .../autopsy/keywordsearch/SearchRunner.java | 32 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java index 830c93325a..dbbca6394b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java @@ -280,7 +280,7 @@ public final class KeywordSearchIngestModule implements FileIngestModule { return ProcessResult.OK; } List keywordListNames = settings.getNamesOfEnabledKeyWordLists(); - SearchRunner.getInstance().startJob(jobId, dataSourceId, keywordListNames); + SearchRunner.getInstance().startJob(context, keywordListNames); startedSearching = true; } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index b998294fe4..da1d5092a7 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 - 2017 Basis Technology Corp. + * Copyright 2014 - 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,6 +43,7 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.StopWatch; +import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestServices; @@ -79,19 +80,15 @@ public final class SearchRunner { } /** - * Add a new job. Searches will be periodically performed after this is - * called. * - * @param jobId Job ID that this is associated with - * @param dataSourceId Data source that is being indexed and that - * searches should be restricted to. - * @param keywordListNames List of keyword lists that will be searched. List - * contents will be refreshed each search. + * @param jobContext + * @param keywordListNames */ - public synchronized void startJob(long jobId, long dataSourceId, List keywordListNames) { + public synchronized void startJob(IngestJobContext jobContext, List keywordListNames) { + long jobId = jobContext.getJobId(); if (jobs.containsKey(jobId) == false) { logger.log(Level.INFO, "Adding job {0}", jobId); //NON-NLS - SearchJobInfo jobData = new SearchJobInfo(jobId, dataSourceId, keywordListNames); + SearchJobInfo jobData = new SearchJobInfo(jobContext, keywordListNames); jobs.put(jobId, jobData); } @@ -266,6 +263,7 @@ public final class SearchRunner { */ private class SearchJobInfo { + private final IngestJobContext jobContext; private final long jobId; private final long dataSourceId; // mutable state: @@ -278,15 +276,20 @@ public final class SearchRunner { private AtomicLong moduleReferenceCount = new AtomicLong(0); private final Object finalSearchLock = new Object(); //used for a condition wait - private SearchJobInfo(long jobId, long dataSourceId, List keywordListNames) { - this.jobId = jobId; - this.dataSourceId = dataSourceId; + private SearchJobInfo(IngestJobContext jobContext, List keywordListNames) { + this.jobContext = jobContext; + this.jobId = jobContext.getJobId(); + this.dataSourceId = jobContext.getDataSource().getId(); this.keywordListNames = new ArrayList<>(keywordListNames); currentResults = new HashMap<>(); workerRunning = false; currentSearcher = null; } + private IngestJobContext getJobContext() { + return jobContext; + } + private long getJobId() { return jobId; } @@ -435,7 +438,7 @@ public final class SearchRunner { int keywordsSearched = 0; for (Keyword keyword : keywords) { - if (this.isCancelled()) { + if (this.isCancelled() || this.job.getJobContext().fileIngestIsCancelled()) { logger.log(Level.INFO, "Cancel detected, bailing before new keyword processed: {0}", keyword.getSearchTerm()); //NON-NLS return null; } @@ -480,7 +483,6 @@ public final class SearchRunner { if (!newResults.getKeywords().isEmpty()) { // Write results to BB - //scale progress bar more more granular, per result sub-progress, within per keyword int totalUnits = newResults.getKeywords().size(); subProgresses[keywordsSearched].start(totalUnits); From ec2a6bf3ba9d80d5be9b5bea9e50979261984dc9 Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 5 Dec 2017 13:12:19 -0500 Subject: [PATCH 11/11] Update default JVM max heap size and document. --- build-windows-installer.xml | 6 +++--- build.xml | 2 +- docs/doxygen-user/images/runtime_settings.PNG | Bin 0 -> 2747 bytes docs/doxygen-user/installation.dox | 6 +++++- 4 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 docs/doxygen-user/images/runtime_settings.PNG diff --git a/build-windows-installer.xml b/build-windows-installer.xml index e3f0401632..b82e28ca24 100755 --- a/build-windows-installer.xml +++ b/build-windows-installer.xml @@ -109,7 +109,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -170,7 +170,7 @@ - + diff --git a/build.xml b/build.xml index bba4207f1b..4eaa7df1c8 100755 --- a/build.xml +++ b/build.xml @@ -92,7 +92,7 @@ - + diff --git a/docs/doxygen-user/images/runtime_settings.PNG b/docs/doxygen-user/images/runtime_settings.PNG new file mode 100644 index 0000000000000000000000000000000000000000..1d02f96a4238ea84b199d34527e4db9d378b8f9c GIT binary patch literal 2747 zcmb7G3s6&M7QSlLVnw$28XgU6XJ{>x)&)%fdA3z720;iRT%KwO!2}2x0Yd=YbylmD zMwb$mNa9vONl0iC5+32T+cl|RxUD6G1QJvRQiw^4X%Zj=_A+f}XJ=<;+JELg{<-JB z=R4o||8u@8#}kiuZt>j$0Dx!wCx=o1U_AzYKl%D5_^#MF&43^4XemcN0))f4S-wf0S(Y-PGW_$u|!3HYK@zAmnQ6SDv5l@P3@v6ny2tzf%0t8!puQe>E_0A~yDG zd39xKe3L`a&2^*P@~8J0!;Crq$v#BH&hZAd*;Td~c3zwB0RVSnC9eU%@w?!90NDF2 zavcEdC}6=Kw;WiDWMe}h09;tF@&IE8G@Bq_12wED9Q@}PMof5Xd*{%QoRWP zVP&78G1?3{qef3!LD2lz=^FsxD=#rvx%k4gN}%vg&t|gg_@y%Fp%M0d>+K@e3nE1j zJipvm82v7Os+`%{{QSkwBV#Uz9Vnggs~fwYXAAH0RaV1DTp@h$s;#gnQK-;H!> z#jI1KikvJa4Yyk(5s9|00lLRt!;AUox5o76-$wy#UKh1Gw;2DNvI~yx0OnRJYA^o0 z{Gf-KzR<7{c)3C4{f;Dmc8AarS-u%K5f58jgI$z(6tMo}1GD(d`&;D65SY|~!1Q)7 zLy#6xtv!x)9wS2JnBwL6YT@W9)--7D3Qv=a7_xhGwz1w*R>P|QLpVCxQ`J+^n2iUW zs*vuIAR#iO3T_BwRLqkhf-}J}Oj!9tO)&rrfjuD4f<{M6L|m7A-j*I4Oypstj;slH!h!?F7PTQF>oCRb2C;tMfGDQ@*XgZJx33(wI^czl`!WUX~R|@&XjtvSzA2 zuWUu>Q^^V?CI#4$Sgsd}(MB)`CJC<8@&c2Ub2gx6No+y~$cihbSS`9I(cJTMUFtqU zuZa-x0IKFel`Xjuv;;coV<*yWdlO>QR#G6@%@{CaX(PWoFlQiT-**&}f`+?9ABk|# z0{OSkjDBh8nJZpd)C!YzRaH{E*i_SNF3wqQ%Iv4NIA1q+Iqfg8P}G7va)a@w#6&x| z*zHRljPUCw&2pLN40midD`gi^nD_T%L;Uc!2dBd0RG0Hh^)}R8F`o>R!wT!w6Y{&P9-0XrQgC=aSd+4pJE*i^?b<9N)^SLNu$H#Y1YwQWZYv{)n!~#C zTZlPnyBB?>ZM9S3WW=NH!qyN}v2!oqPT=C`le&*@^fIsIQrAv)6&KETU$P(jT>8*`ZD~K8QjH* zHc}bPtAs9_Y%hbv>D!ee#ls$J`}E4P}BT2a;KKBNq#|5phP01FUxn zT6(BCL=MF3?#xk-={1k&_vgfgSL?{EOQY}gHS09u!fdrN(vP1|tLEJD(%ys%lhdtRh1_h`iDyr%!l+>+qnRWWI3KzkZwmxav=NKdBuo`FkhWmX-MM2{O zGOoJ3nWuWyI@)eepV}{Ne$|JnC)o&&AH< z$Bu+>imXH9oD6z4Ww*3VqGQgl$cyUQ>8s~VbE99f%wCThlC%U_{+ZmUP)wg literal 0 HcmV?d00001 diff --git a/docs/doxygen-user/installation.dox b/docs/doxygen-user/installation.dox index c924708201..aa67e55d7a 100755 --- a/docs/doxygen-user/installation.dox +++ b/docs/doxygen-user/installation.dox @@ -6,12 +6,16 @@ It is _highly_ recommended to remove or disable any antivirus software from computers that will be processing or reviewing cases. Antivirus software will often conflict with forensic software, and may quarantine or even delete some of your results before you get a chance to look at them.

- \section install Deployment Types Starting with Autopsy 4.0, there are two ways to deploy Autopsy: - **Single-User**: Cases can be open by only a single instance of Autopsy at a time. Autopsy installations do not communicate with each other. This is the easiest to install and deploy. This page outlines that installation process. - **Multi-User**: Cases can be open by multiple users at the same time and users can see what each other is doing. This collaborative deployment requires installation and configuration of other network-based services. The installation of this deployment is covered in \ref install_multiuser_page. +\section sysreqs System Memory Requirements +The 64 bit version of Autopsy requires a minimum of 8GB RAM (16 GB recommended). +When the 64 bit version of Autopsy is installed on Windows it will be limited to a maximum heap size of 4GB leaving the remaining memory for the operating system, the internal Solr text indexing service and other applications. If you wish to change the maximum heap size you can do so after installation by changing the Maximum JVM Memory value in the Runtime section under Tools -> Options -> Application. + +\image html runtime_settings.PNG \section download Download Download Autopsy from the website: