diff --git a/Ghidra/Features/PDB/certification.manifest b/Ghidra/Features/PDB/certification.manifest index dce9dc413e..8ae04a48be 100644 --- a/Ghidra/Features/PDB/certification.manifest +++ b/Ghidra/Features/PDB/certification.manifest @@ -16,13 +16,14 @@ src/main/help/help/shared/redo.png||GHIDRA||||END| src/main/help/help/shared/tip.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END| src/main/help/help/shared/undo.png||GHIDRA||||END| src/main/help/help/shared/warning.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END| -src/main/help/help/topics/Pdb/LoadPDBNew.html||GHIDRA||||END| +src/main/help/help/topics/Pdb/LoadPDB.html||GHIDRA||||END| src/main/help/help/topics/Pdb/PDB.htm||GHIDRA||||END| src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/Plus2.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/SymbolServerConfig_AddButtonMenu.png||GHIDRA||||END| +src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/SymbolServerConfig_Screenshot.png||GHIDRA||||END| src/main/help/help/topics/Pdb/images/disk.png||FAMFAMFAM Icons - CC 2.5||||END| src/main/help/help/topics/Pdb/images/down.png||GHIDRA||||END| diff --git a/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml b/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml index 16c4f1abb5..3ddcfbbd9b 100644 --- a/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml +++ b/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml @@ -51,7 +51,7 @@ - + diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDBNew.html b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDB.html similarity index 88% rename from Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDBNew.html rename to Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDB.html index 6d8ff3b3d9..5d63a9cb10 100644 --- a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDBNew.html +++ b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/LoadPDB.html @@ -33,7 +33,7 @@
  • myprogram.pdb/012345670123012301230123456789AB1/myprogram.pdb.
  • myprogram.pdb is the name of the file and the name of the initial subdirectory off the root of the server.
  • 012345670123012301230123456789AB is the 32 character hexadecimal value (made up for this example) of the GUID - "012345678-0123-0123-0123-0123456789AB" of the PDB file.
  • + "01234567-0123-0123-0123-0123456789AB" of the PDB file.
  • 1 is the hexadecimal value of the 'age' (build number) of the PDB file. Note: most PDB files will have an age value of 1.
  • @@ -56,14 +56,8 @@
  • Unorganized directories:
  • @@ -88,16 +82,10 @@ which PDB file to choose.
  • If needed, click the Advanced button:
  • -
  • The Local Symbol Storage location is required to enable searching. If missing, set it to a directory where Ghidra can store PDB files.
  • - -
  • Add additional search locations by clicking the button. - The Microsoft symbol server and Program's Import Location are good defaults.
  • -
  • Save any changes to the configuration by clicking the button.
  • +
  • The Local Symbol Storage location (in the Symbol Server Config screen) is required + to enable searching. If missing, click the Config... button.
  • Set search options as needed.
  • -
  • Click the Search button to search the configured locations.
  • +
  • Click the Search Local or Search All button to search the configured locations.
  • The Local Symbol Storage location is searched first, followed by any locations listed in the Additional Search Paths list, in listed order.
  • @@ -111,7 +99,7 @@

    Symbol Server Config

    Allows the user to configure the location where PDB symbol files are stored and additional locations to search for - existing PDB files. This is also available in the Load PDB File, Advanced screen.

    + existing PDB files.

    Steps:

     (Add)

    diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/PDB.htm b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/PDB.htm index c349ce849f..278e99af73 100644 --- a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/PDB.htm +++ b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/PDB.htm @@ -37,7 +37,7 @@

    PDB files can be loaded in two ways:

      -
    • File → Load PDB File
    • +
    • File → Load PDB File
    • PDB Analyzer via Analysis → Auto Analyze or Analysis → One Shot. @@ -124,7 +124,7 @@

      Related Topics:

      diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png index d713737905..5b016a1932 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png index 14c0387613..bbc03dd825 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png index 3c89aaaf55..79763a7b45 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png new file mode 100644 index 0000000000..ec5d9ea547 Binary files /dev/null and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png differ diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java index 159aa9c1e4..49c66c8f69 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java @@ -204,26 +204,22 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor List matches = new ArrayList<>(); - // search for exact matches using the built-in logic in AbstractSymbolServer if (storageLevel != 0) { + // search for exact matches using the built-in logic in AbstractSymbolServer matches.addAll(super.find(symbolFileInfo, options, monitor)); - } - if (storageLevel == 0 || options.contains(FindOption.ANY_AGE) || - options.contains(FindOption.ANY_ID)) { - - try { - if (storageLevel == 0) { - searchLevel0(rootDir, this, symbolFileInfo, options, matches, monitor); - } - else { + if (options.contains(FindOption.ANY_AGE) || options.contains(FindOption.ANY_ID)) { + try { searchLevelN(symbolFileInfo, options, matches, monitor); } + catch (IOException ioe) { + Msg.warn(this, + "Error searching for " + symbolFileInfo.getName() + " in " + rootDir, ioe); + } } - catch (IOException ioe) { - Msg.warn(this, "Error searching for " + symbolFileInfo.getName() + " in " + rootDir, - ioe); - } + } + else { + searchLevel0(rootDir, this, symbolFileInfo, options, matches, monitor); } return matches; @@ -232,18 +228,14 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor static void searchLevel0(File rootDir, SymbolStore symbolStore, SymbolFileInfo symbolFileInfo, Set options, List matches, TaskMonitor monitor) { - // if its a "0 level" bag-of-files, we have to open each Pdb to find its UID and - // AGE (after filtering for similar filenames as requested pdb file) - for (File f : list(rootDir, - ff -> ff.isFile() && isFilenameStartsWithMatch(symbolFileInfo, ff))) { - if (monitor.isCancelled()) { - break; - } - SymbolFileInfo fileInfo = SymbolFileInfo.fromFile(f, monitor); - if (fileInfo != null) { - if (hasSymbolFileInfoMatch(symbolFileInfo, fileInfo, options)) { - matches.add(new SymbolFileLocation(f.getName(), symbolStore, fileInfo)); - } + File f = new File(rootDir, symbolFileInfo.getName()); + if (!f.isFile()) { + return; + } + SymbolFileInfo fileInfo = SymbolFileInfo.fromFile(f, monitor); + if (fileInfo != null) { + if (hasSymbolFileInfoMatch(symbolFileInfo, fileInfo, options)) { + matches.add(new SymbolFileLocation(f.getName(), symbolStore, fileInfo)); } } } @@ -402,24 +394,6 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor return files != null ? files : new File[] {}; } - static boolean isFilenameStartsWithMatch(SymbolFileInfo symbolFileInfo, File file) { - String symbolFilenameNoExtension = FilenameUtils.getBaseName(symbolFileInfo.getName()); - String fileNoExtension = FilenameUtils.getBaseName(file.getName()); - - // use case-insensitive compare since these are PDB files, which - // come from a Windows env - if (!fileNoExtension.toLowerCase().startsWith(symbolFilenameNoExtension.toLowerCase())) { - return false; - } - - // match on ext ("pdb"), compressed ext ("pd_") - String symbolFilenameExtension = - FilenameUtils.getExtension(symbolFileInfo.getName()).toLowerCase(); - String fileExtension = FilenameUtils.getExtension(file.getName()).toLowerCase(); - return fileExtension.equals(symbolFilenameExtension) || - fileExtension.equals(makeCompressedExtension(symbolFilenameExtension)); - } - static boolean hasSymbolFileInfoMatch(SymbolFileInfo symbolFileInfo, SymbolFileInfo otherSymbolFileInfo, Set options) { boolean idMatches = diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java index 18034e8399..0c1655d752 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java @@ -15,9 +15,8 @@ */ package pdb.symbolserver; -import java.util.*; - import java.io.*; +import java.util.*; import ghidra.util.task.TaskMonitor; @@ -25,8 +24,6 @@ import ghidra.util.task.TaskMonitor; * A Pdb symbol server / symbol store, similar to the {@link LocalSymbolStore}, * but limited to searching just the single directory that the original executable is located in. *

      - * Matches symbol files that have a similar name to the requested symbol file (but the identifier - * info - guid/id & age must still match as per the find options specified). * */ public class SameDirSymbolStore implements SymbolStore { @@ -105,8 +102,8 @@ public class SameDirSymbolStore implements SymbolStore { @Override public String getDescriptiveName() { - return String.format(PROGRAMS_IMPORT_LOCATION_DESCRIPTION_STR + " - %s", - isValid() ? rootDir.getPath() : "unspecified"); + return PROGRAMS_IMPORT_LOCATION_DESCRIPTION_STR + + (isValid() ? " - " + rootDir.getPath() : ""); } @Override diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java index cbeb0de846..ce2d6f46d4 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java @@ -15,23 +15,25 @@ */ package pdb.symbolserver.ui; +import java.util.List; + import docking.DialogComponentProvider; import docking.DockingWindowManager; -import docking.widgets.OptionDialog; -import pdb.symbolserver.SymbolServerInstanceCreatorRegistry; -import pdb.symbolserver.SymbolServerService; +import pdb.symbolserver.*; /** * Dialog that allows the user to configure the Pdb search locations and symbol directory */ public class ConfigPdbDialog extends DialogComponentProvider { - public static void showSymbolServerConfig() { + public static boolean showSymbolServerConfig() { ConfigPdbDialog choosePdbDialog = new ConfigPdbDialog(); DockingWindowManager.showDialog(choosePdbDialog); + return choosePdbDialog.wasSuccess; } private SymbolServerPanel symbolServerConfigPanel; + private boolean wasSuccess; public ConfigPdbDialog() { super("Configure Symbol Server Search", true, false, true, false); @@ -46,12 +48,10 @@ public class ConfigPdbDialog extends DialogComponentProvider { @Override protected void okCallback() { - if (symbolServerConfigPanel.isConfigChanged() && - OptionDialog.showYesNoDialog(getComponent(), - "Save Configuration", - "Symbol server configuration changed. Save?") == OptionDialog.YES_OPTION) { + if (symbolServerConfigPanel.isConfigChanged()) { symbolServerConfigPanel.saveConfig(); } + wasSuccess = true; close(); } @@ -76,4 +76,23 @@ public class ConfigPdbDialog extends DialogComponentProvider { addCancelButton(); setDefaultButton(cancelButton); } + + /** + * Screen shot usage only + */ + public void pushAddLocationButton() { + symbolServerConfigPanel.pushAddLocationButton(); + } + + /** + * Screen shot only + * + * @param fakeDirectoryText fake text to display in the storage directory text field + * @param symbolServers list of symbol servers to force set + */ + public void setSymbolServerService(String fakeDirectoryText, + List symbolServers) { + symbolServerConfigPanel.setSymbolServers(symbolServers); + symbolServerConfigPanel.setSymbolStorageDirectoryTextOnly(fakeDirectoryText); + } } diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java index cf234ea194..516effa84e 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java @@ -107,10 +107,10 @@ public class LoadPdbDialog extends DialogComponentProvider { private List> statusTextSuppliers = new ArrayList<>(); private Set lastSearchOptions; private boolean searchCanceled; + private boolean hasShownAdvanced; private Program program; - private SymbolServerPanel symbolServerConfigPanel; private SymbolFilePanel symbolFilePanel; private JTextField programNameTextField; @@ -123,6 +123,7 @@ public class LoadPdbDialog extends DialogComponentProvider { private HintTextField pdbLocationTextField; private GIconLabel exactMatchIconLabel; + private JButton configButton; private JToggleButton advancedToggleButton; private GhidraFileChooser chooser; @@ -153,14 +154,17 @@ public class LoadPdbDialog extends DialogComponentProvider { if (programSymbolFileInfo == null) { programSymbolFileInfo = SymbolFileInfo.unknown("missing"); } - this.symbolServerInstanceCreatorContext = - SymbolServerInstanceCreatorRegistry.getInstance().getContext(program); - this.symbolServerService = - PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); - + updateSymbolServerServiceInstanceFromPreferences(); build(); } + private void updateSymbolServerServiceInstanceFromPreferences() { + symbolServerInstanceCreatorContext = + SymbolServerInstanceCreatorRegistry.getInstance().getContext(program); + symbolServerService = + PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); + } + @Override protected void dialogShown() { pdbPathTextField.setText(programSymbolFileInfo.getPath()); @@ -169,32 +173,7 @@ public class LoadPdbDialog extends DialogComponentProvider { programNameTextField.setText(program.getName()); cancelButton.requestFocusInWindow(); - executeMonitoredRunnable("Search for PDB using built-in locations", true, true, 0, - this::doInitialDefaultSearch); - } - - private void doInitialDefaultSearch(TaskMonitor monitor) { - try { - List results = - symbolServerService.find(programSymbolFileInfo, FindOption.NO_OPTIONS, monitor); - if (!results.isEmpty()) { - SymbolFileLocation symbolFileLocation = - symbolServerService.getLocalSymbolFileLocation(results.get(0), monitor); - File symbolFile = getLocalSymbolFile(symbolFileLocation); - Swing.runLater(() -> { - setSearchResults(results, null); - setPdbLocationValue(symbolFileLocation, symbolFile); - setSelectedPdbFile(symbolFileLocation); - selectRowByLocation(symbolFileLocation); - updateStatusText(); - updateButtonEnablement(); - updateParserOptionEnablement(true); - }); - } - } - catch (CancelledException | IOException e) { - // ignore - } + searchForPdbs(false); } @Override @@ -212,33 +191,9 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolFilePanel.setFindOptions(options); } - /** - * For screenshot use only - * - * @param pathStr path of symbol storage directory - */ - public void setSymbolStorageDirectoryTextOnly(String pathStr) { - symbolServerConfigPanel.setSymbolStorageDirectoryTextOnly(pathStr); - } - - /** - * For screenshot use only - * - * @param symbolServers list of symbol servers - */ - public void setSymbolServers(List symbolServers) { - symbolServerConfigPanel.setSymbolServers(symbolServers); - } - - /** - * For screenshot use only - */ - public void pushAddLocationBution() { - symbolServerConfigPanel.pushAddLocationButton(); - } - private void setSelectedPdbFile(SymbolFileLocation symbolFileLocation) { this.selectedSymbolFile = symbolFileLocation; + setPdbLocationValue(symbolFileLocation, getLocalSymbolFile(symbolFileLocation)); } /** @@ -247,6 +202,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Public only for screenshot usage, treat as private otherwise. * * @param results list of {@link SymbolFileLocation}s to add to results + * @param findOptions the options used to search */ public void setSearchResults(List results, Set findOptions) { lastSearchOptions = findOptions; @@ -304,13 +260,11 @@ public class LoadPdbDialog extends DialogComponentProvider { private void updateButtonEnablement() { boolean hasLocation = selectedSymbolFile != null; + boolean hasGoodService = symbolServerService.isValid(); loadPdbButton.setEnabled(hasLocation); - } - - private void setSymbolServerService(SymbolServerService symbolServerService) { - this.symbolServerService = symbolServerService; - symbolFilePanel.setEnablement(symbolServerService != null); - updateStatusText(); + configButton.setIcon(hasGoodService ? null : MATCH_BAD_ICON); + configButton.setToolTipText(hasGoodService ? null : "Missing configuration"); + symbolFilePanel.setEnablement(hasGoodService); } private SymbolFileInfo getCurrentSymbolFileInfo() { @@ -322,9 +276,6 @@ public class LoadPdbDialog extends DialogComponentProvider { } private void searchForPdbs(boolean allowRemote) { - if (symbolServerService == null || !symbolServerService.isValid()) { - return; - } if (pdbAgeTextField.getText().isBlank() || pdbAgeTextField.getValue() > NumericUtilities.MAX_UNSIGNED_INT32_AS_LONG) { Msg.showWarn(this, null, "Bad PDB Age", "Invalid PDB Age value"); @@ -347,11 +298,12 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolServerService.find(symbolFileInfo, findOptions, monitor); Swing.runLater(() -> { setSearchResults(results, findOptions); - if (results.size() == 1) { + if (!results.isEmpty()) { selectRowByLocation(results.get(0)); } updateStatusText(); updateButtonEnablement(); + updateParserOptionEnablement(true); }); } catch (CancelledException e1) { @@ -364,17 +316,15 @@ public class LoadPdbDialog extends DialogComponentProvider { private void build() { buildSymbolFilePanel(); - buildSSConfigPanel(); buildPdbLocationPanel(); buildProgramPdbPanel(); buildParserOptionsPanel(); setHelpLocation(new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "Load PDB File")); addStatusTextSupplier(() -> lastSearchOptions != null && advancedToggleButton.isSelected() - ? symbolServerConfigPanel.getSymbolServerWarnings() + ? SymbolServerPanel.getSymbolServerWarnings(symbolServerService.getSymbolServers()) : null); addStatusTextSupplier(this::getSelectedPdbNoticeText); - addStatusTextSupplier(this::getConfigChangedWarning); addStatusTextSupplier(this::getAllowRemoteWarning); addStatusTextSupplier(this::getFoundCountInfo); @@ -386,11 +336,6 @@ public class LoadPdbDialog extends DialogComponentProvider { // later dialogShow() will be called } - private void buildSSConfigPanel() { - symbolServerConfigPanel = - new SymbolServerPanel(this::setSymbolServerService, symbolServerInstanceCreatorContext); - } - private void buildSymbolFilePanel() { // panel will be added in layoutAdvanced() symbolFilePanel = new SymbolFilePanel(this::searchForPdbs); @@ -398,7 +343,7 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolFilePanel.getTable() .getSelectionModel() .addListSelectionListener(e -> updateSelectedRow()); - symbolFilePanel.addMouseListener(new GMouseListenerAdapter() { + symbolFilePanel.getTable().addMouseListener(new GMouseListenerAdapter() { @Override public void doubleClickTriggered(MouseEvent e) { if (loadPdbButton.isEnabled()) { @@ -618,6 +563,17 @@ public class LoadPdbDialog extends DialogComponentProvider { addCancelButton(); setDefaultButton(cancelButton); + configButton = new JButton("Config..."); + configButton.addActionListener(e -> { + if (ConfigPdbDialog.showSymbolServerConfig()) { + updateSymbolServerServiceInstanceFromPreferences(); + updateButtonEnablement(); + updateStatusText(); + searchForPdbs(false); + } + }); + addButton(configButton); + advancedToggleButton = new JToggleButton("Advanced >>"); advancedToggleButton.addActionListener(e -> toggleAdvancedSearch()); buttonPanel.add(advancedToggleButton); @@ -625,7 +581,7 @@ public class LoadPdbDialog extends DialogComponentProvider { private void prepareSelectedSymbolFileAndClose(TaskMonitor monitor) { try { - if (selectedSymbolFile != null && symbolServerService != null) { + if (selectedSymbolFile != null) { selectedSymbolFile = symbolServerService.getLocalSymbolFileLocation(selectedSymbolFile, monitor); } @@ -640,17 +596,8 @@ public class LoadPdbDialog extends DialogComponentProvider { } } - private StatusText getConfigChangedWarning() { - return advancedToggleButton.isSelected() && symbolServerConfigPanel.isConfigChanged() - ? new StatusText( - "Symbol Server Search Config Changed. Click \"Save Configuration\" button to save.", - MessageType.INFO, false) - : null; - } - private StatusText getAllowRemoteWarning() { - int remoteSymbolServerCount = - symbolServerService != null ? symbolServerService.getRemoteSymbolServerCount() : 0; + int remoteSymbolServerCount = symbolServerService.getRemoteSymbolServerCount(); return lastSearchOptions != null && advancedToggleButton.isSelected() && remoteSymbolServerCount != 0 && !lastSearchOptions.contains(FindOption.ALLOW_REMOTE) ? new StatusText( @@ -681,31 +628,21 @@ public class LoadPdbDialog extends DialogComponentProvider { overridePdbAgeCheckBox.setVisible(isAdvanced); overridePdbPathCheckBox.setVisible(isAdvanced); overridePdbUniqueIdCheckBox.setVisible(isAdvanced); - setPdbLocationValue(null, null); if (isAdvanced) { - if (symbolServerService == null || !symbolServerService.isValid()) { - setSelectedPdbFile(null); - } layoutAdvanced(); } else { - if (selectedSymbolFile != null) { - File localSymbolFile = getLocalSymbolFile(selectedSymbolFile); - if (localSymbolFile != null) { - setPdbLocationValue(selectedSymbolFile, localSymbolFile); - } - } - else { - setSelectedPdbFile(null); - } layoutSimple(); } updateStatusText(); updateButtonEnablement(); updateParserOptionEnablement(false); - repack(); + if (isAdvanced && !hasShownAdvanced) { + hasShownAdvanced = true; + repack(); + } } private void layoutSimple() { @@ -720,21 +657,17 @@ public class LoadPdbDialog extends DialogComponentProvider { overrideWorkPanel(panel); } - private void overrideWorkPanel(JComponent workComp) { + private void overrideWorkPanel(JComponent newWorkComp) { if (this.workComp != null && this.workComp.getParent() != null) { this.workComp.getParent().remove(this.workComp); } - this.workComp = workComp; - addWorkPanel(workComp); + this.workComp = newWorkComp; + addWorkPanel(newWorkComp); } private void layoutAdvanced() { - Box topPanel = Box.createHorizontalBox(); - topPanel.add(programPdbPanel); - topPanel.add(symbolServerConfigPanel); - JPanel mainPanel = new JPanel(new BorderLayout()); - mainPanel.add(topPanel, BorderLayout.NORTH); + mainPanel.add(programPdbPanel, BorderLayout.NORTH); mainPanel.add(symbolFilePanel, BorderLayout.CENTER); mainPanel.add(parserOptionsPanel, BorderLayout.SOUTH); diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java index 2dc709a66f..dfca92f5d0 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java @@ -117,7 +117,7 @@ class SymbolFilePanel extends JPanel { private JPanel buildWelcomePanel() { welcomePanel = new JPanel(); welcomePanel.add(new GHtmlLabel( - "

      Local Symbol Storage location must be set first!")); + "
      Configuration must be set first!")); welcomePanel.setPreferredSize(tablePanel.getPreferredSize()); return welcomePanel; diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java index 985ffc1da6..423f6e0325 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java @@ -52,7 +52,7 @@ import utilities.util.FileUtilities; class SymbolServerPanel extends JPanel { private static final String MS_SYMBOLSERVER_ENVVAR = "_NT_SYMBOL_PATH"; - private List knownSymbolServers = + private static List knownSymbolServers = WellKnownSymbolServerLocation.loadAll(); private SymbolStore localSymbolStore; @@ -297,23 +297,6 @@ class SymbolServerPanel extends JPanel { updateLayout(hasLocalSymbolStore); } - StatusText getSymbolServerWarnings() { - Map warningsByLocation = new HashMap<>(); - for (WellKnownSymbolServerLocation ssloc : knownSymbolServers) { - if (ssloc.getWarning() != null && !ssloc.getWarning().isBlank()) { - warningsByLocation.put(ssloc.getLocation(), ssloc.getWarning()); - } - } - String warning = tableModel.getDataSource() - .stream() - .map(row -> warningsByLocation.get(row.getSymbolServer().getName())) - .filter(Objects::nonNull) - .distinct() - .collect(Collectors.joining("
      \n")); - - return !warning.isEmpty() ? new StatusText(warning, MessageType.WARNING, false) : null; - } - private void setSymbolStorageLocation(File symbolStorageDir, boolean allowGUIPrompt) { if (symbolStorageDir == null) { return; @@ -601,5 +584,22 @@ class SymbolServerPanel extends JPanel { return button; } + + static StatusText getSymbolServerWarnings(List symbolServers) { + Map warningsByLocation = new HashMap<>(); + for (WellKnownSymbolServerLocation ssloc : knownSymbolServers) { + if (ssloc.getWarning() != null && !ssloc.getWarning().isBlank()) { + warningsByLocation.put(ssloc.getLocation(), ssloc.getWarning()); + } + } + String warning = symbolServers + .stream() + .map(symbolServer -> warningsByLocation.get(symbolServer.getName())) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.joining("
      \n")); + + return !warning.isEmpty() ? new StatusText(warning, MessageType.WARNING, false) : null; + } } diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java index a59dd267c3..280d9d7c78 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java @@ -69,11 +69,30 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); showDialogWithoutBlocking(tool, configPdbDialog); waitForSwing(); - captureDialog(ConfigPdbDialog.class); + captureDialog(ConfigPdbDialog.class, 410, 280); } @Test - public void testLoadPdb_Initial_Screenshot() throws IOException { + public void testSymbolServerConfig_Configured() throws IOException { + File localSymbolStore1Root = new File(temporaryDir, "symbols"); + LocalSymbolStore.create(localSymbolStore1Root, 1); + LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root); + SameDirSymbolStore sameDirSymbolStore = new SameDirSymbolStore(null); + List symbolServers = List.of(sameDirSymbolStore, + new HttpSymbolServer(URI.create("https://msdl.microsoft.com/download/symbols/"))); + SymbolServerService symbolServerService = + new SymbolServerService(localSymbolStore1, symbolServers); + PdbPlugin.saveSymbolServerServiceConfig(symbolServerService); + + ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); + configPdbDialog.setSymbolServerService("/home/user/symbols", symbolServers); + showDialogWithoutBlocking(tool, configPdbDialog); + waitForSwing(); + captureDialog(ConfigPdbDialog.class, 410, 280); + } + + @Test + public void testLoadPdb_Initial_Screenshot() { LoadPdbDialog loadPdbDialog = new LoadPdbDialog(program); showDialogWithoutBlocking(tool, loadPdbDialog); captureDialog(loadPdbDialog); @@ -84,32 +103,30 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { public void testSymbolServerConfig_AddButtonMenu() throws IOException { File localSymbolStore1Root = new File(temporaryDir, "symbols"); LocalSymbolStore.create(localSymbolStore1Root, 1); - LocalSymbolStore localSymbolStore1 = - new LocalSymbolStoreWithFakePath(localSymbolStore1Root, "/home/user/symbols"); + LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root); SymbolServerService symbolServerService = new SymbolServerService(localSymbolStore1, List.of()); PdbPlugin.saveSymbolServerServiceConfig(symbolServerService); - LoadPdbDialog choosePdbDialog = new LoadPdbDialog(program); - showDialogWithoutBlocking(tool, choosePdbDialog); + ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); + showDialogWithoutBlocking(tool, configPdbDialog); waitForSwing(); - pressButtonByText(choosePdbDialog, "Advanced >>"); runSwing(() -> { - choosePdbDialog.pushAddLocationBution(); + configPdbDialog.pushAddLocationButton(); }); waitForSwing(); captureMenu(); } @Test - public void testLoadPdb_Advanced_NeedsConfig() throws IOException { + public void testLoadPdb_Advanced_NeedsConfig() { PdbPlugin.saveSymbolServerServiceConfig(null); LoadPdbDialog choosePdbDialog = new LoadPdbDialog(program); showDialogWithoutBlocking(tool, choosePdbDialog); waitForSwing(); pressButtonByText(choosePdbDialog, "Advanced >>"); waitForSwing(); - captureDialog(LoadPdbDialog.class); + captureDialog(LoadPdbDialog.class, 600, 500); pressButtonByText(choosePdbDialog, "Cancel"); } @@ -140,19 +157,15 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { new SymbolFileLocation("HelloWorld.pdb/" + GUID1_STR + "2/HelloWorld.pdb", localSymbolStore1, SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 2)), new SymbolFileLocation("HelloWorld.pdb", sameDirSymbolStoreWithFakePath, - SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1)), - new SymbolFileLocation("HelloWorld_ver2.pdb", sameDirSymbolStoreWithFakePath, - SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 2))); + SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1))); Set findOptions = FindOption.of(FindOption.ALLOW_REMOTE, FindOption.ANY_AGE); runSwing(() -> { loadPdbDialog.setSearchOptions(findOptions); - loadPdbDialog.setSymbolServers(symbolServers); - loadPdbDialog.setSymbolStorageDirectoryTextOnly("/home/user/symbols"); loadPdbDialog.setSearchResults(symbolFileLocations, findOptions); loadPdbDialog.selectRowByLocation(symbolFileLocations.get(0)); }); waitForSwing(); - captureDialog(LoadPdbDialog.class); + captureDialog(LoadPdbDialog.class, 600, 600); pressButtonByText(loadPdbDialog, "Cancel"); }