diff --git a/Ghidra/Features/GhidraGo/src/main/java/ghidra/app/plugin/core/go/GhidraGoPlugin.java b/Ghidra/Features/GhidraGo/src/main/java/ghidra/app/plugin/core/go/GhidraGoPlugin.java index 8b0f488cda..dff030734b 100644 --- a/Ghidra/Features/GhidraGo/src/main/java/ghidra/app/plugin/core/go/GhidraGoPlugin.java +++ b/Ghidra/Features/GhidraGo/src/main/java/ghidra/app/plugin/core/go/GhidraGoPlugin.java @@ -22,23 +22,26 @@ import ghidra.app.CorePluginPackage; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.go.ipc.GhidraGoListener; import ghidra.framework.main.*; -import ghidra.framework.model.ToolServices; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.protocol.ghidra.GhidraURL; import ghidra.util.Msg; -import ghidra.util.Swing; //@formatter:off @PluginInfo( category = PluginCategoryNames.COMMON, status = PluginStatus.UNSTABLE, packageName = CorePluginPackage.NAME, - shortDescription = "Listens for new GhidraURL's to launch using ToolServices", - description = "Polls the ghidraGo directory for any url files written by the GhidraGoClient and " + - "processes them in Ghidra", + shortDescription = "Listens for new GhidraURL's to launch using FrontEndTool's" + + " accept method", + description = "Polls the ghidraGo directory for any url files written by the " + + "GhidraGoSender and processes them in Ghidra", eventsConsumed = {ProjectPluginEvent.class}) //@formatter:on +/** + * Polls the ghidraGo directory located in the user's temporary directory for any url files written + * by the {@link GhidraGoSender} and processes them in Ghidra. + */ public class GhidraGoPlugin extends Plugin implements ApplicationLevelOnlyPlugin { private GhidraGoListener listener; @@ -69,7 +72,7 @@ public class GhidraGoPlugin extends Plugin implements ApplicationLevelOnlyPlugin else { try { listener = new GhidraGoListener((url) -> { - processGhidraURL(url); + accept(url); }); } catch (IOException e) { @@ -81,26 +84,14 @@ public class GhidraGoPlugin extends Plugin implements ApplicationLevelOnlyPlugin } /** - * If the active project is null, do nothing. - * Otherwise, try and open the url using {@link ToolServices} launchDefaultToolWithURL function. - * @param ghidraURL the GhidraURL to open. + * Accept the given url, which is then passed to the FrontEndTool to process. + * @param url a {@link GhidraURL} + * @return true if handled successfully, false otherwise. */ - private void processGhidraURL(URL ghidraURL) { - - Msg.info(this, "GhidraGo processing " + ghidraURL); - - try { - Msg.info(this, - "Accepting the resource at " + GhidraURL.getProjectURL(ghidraURL)); - Swing.runNow(() -> { - FrontEndTool frontEnd = AppInfo.getFrontEndTool(); - frontEnd.toFront(); - frontEnd.getToolServices().launchDefaultToolWithURL(ghidraURL); - }); - } - catch (IllegalArgumentException e) { - Msg.showError(this, null, "GhidraGo Unable to process GhidraURL", - "GhidraGo could not process " + ghidraURL, e); - } + public boolean accept(URL url) { + Msg.info(this, "GhidraGo accepting the resource at " + GhidraURL.getProjectURL(url)); + FrontEndTool frontEndTool = AppInfo.getFrontEndTool(); + frontEndTool.toFront(); + return frontEndTool.accept(url); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/AcceptUrlContentTask.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/AcceptUrlContentTask.java new file mode 100644 index 0000000000..cba6ca7ed0 --- /dev/null +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/AcceptUrlContentTask.java @@ -0,0 +1,68 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.framework.main; + +import java.io.IOException; +import java.net.URL; + +import ghidra.framework.data.FolderLinkContentHandler; +import ghidra.framework.main.datatree.ProjectDataTreePanel; +import ghidra.framework.model.DomainFile; +import ghidra.framework.model.DomainFolder; +import ghidra.framework.protocol.ghidra.GhidraURL; +import ghidra.framework.protocol.ghidra.GhidraURLQueryTask; +import ghidra.util.Swing; +import ghidra.util.task.TaskMonitor; + +public class AcceptUrlContentTask extends GhidraURLQueryTask { + + private FrontEndPlugin plugin; + + public AcceptUrlContentTask(URL url, FrontEndPlugin plugin) { + super("Accepting URL", url); + this.plugin = plugin; + } + + + @Override + public void processResult(DomainFile domainFile, URL url, TaskMonitor monitor) + throws IOException { + Swing.runNow(() -> { + + if (FolderLinkContentHandler.FOLDER_LINK_CONTENT_TYPE + .equals(domainFile.getContentType())) { + plugin.showLinkedFolder(domainFile); + return; + } + AppInfo.getFrontEndTool().getToolServices().launchDefaultToolWithURL(url); + }); + } + + @Override + public void processResult(DomainFolder domainFolder, URL url, TaskMonitor monitor) + throws IOException { + ProjectDataPanel projectDataPanel = plugin.getProjectDataPanel(); + + Swing.runNow(() -> { + ProjectDataTreePanel dtp = projectDataPanel.openView(GhidraURL.getProjectURL(url)); + if (dtp == null) { + return; + } + dtp.selectDomainFolder(domainFolder); + }); + } + +} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java index 085a147eeb..412e5ce45a 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java @@ -1109,11 +1109,11 @@ public class FrontEndPlugin extends Plugin "opens this type of file"); } - private void showLinkedFolder(DomainFile domainFile) { - + void showLinkedFolder(DomainFile domainFile) { try { LinkedGhidraFolder linkedFolder = FolderLinkContentHandler.getReadOnlyLinkedFolder(domainFile); + if (linkedFolder == null) { return; // unsupported use } @@ -1133,7 +1133,6 @@ public class FrontEndPlugin extends Plugin Msg.showError(this, projectDataPanel, "Linked-folder failure: " + domainFile.getName(), e); } - } private class MyToolChestChangeListener implements ToolChestChangeListener { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java index a6aaf0a3a3..fa25fc4789 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndTool.java @@ -64,6 +64,7 @@ import ghidra.framework.plugintool.util.*; import ghidra.framework.preferences.Preferences; import ghidra.framework.project.tool.GhidraTool; import ghidra.framework.project.tool.GhidraToolTemplate; +import ghidra.framework.protocol.ghidra.GhidraURL; import ghidra.util.*; import ghidra.util.bean.GGlassPane; import ghidra.util.classfinder.ClassSearcher; @@ -176,6 +177,15 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener { System.exit(0); } + @Override + public boolean accept(URL url) { + if (!GhidraURL.isLocalProjectURL(url) && !GhidraURL.isServerRepositoryURL(url)) { + return false; + } + Swing.runLater(() -> execute(new AcceptUrlContentTask(url, plugin))); + return true; + } + private void ensureSize() { JFrame frame = getToolFrame(); Dimension size = frame.getSize();