mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Fixed menu names for archives that live inside of a distribution
This commit is contained in:
parent
db608a1a13
commit
8c6e50b54f
2 changed files with 77 additions and 58 deletions
|
@ -83,10 +83,8 @@ import ghidra.util.task.TaskMonitor;
|
||||||
servicesProvided = { DataTypeManagerService.class, DataTypeArchiveService.class }
|
servicesProvided = { DataTypeManagerService.class, DataTypeArchiveService.class }
|
||||||
)
|
)
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class DataTypeManagerPlugin extends ProgramPlugin implements DomainObjectListener,
|
public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
DataTypeManagerService, PopupActionProvider {
|
implements DomainObjectListener, DataTypeManagerService, PopupActionProvider {
|
||||||
|
|
||||||
private static final String EXTENSIONS_PATH_PREFIX = Path.GHIDRA_HOME + "/Extensions";
|
|
||||||
|
|
||||||
private static final String SEARCH_PROVIDER_NAME = "Search DataTypes Provider";
|
private static final String SEARCH_PROVIDER_NAME = "Search DataTypes Provider";
|
||||||
private static final int RECENTLY_USED_CACHE_SIZE = 10;
|
private static final int RECENTLY_USED_CACHE_SIZE = 10;
|
||||||
|
@ -192,6 +190,7 @@ public class DataTypeManagerPlugin extends ProgramPlugin implements DomainObject
|
||||||
|
|
||||||
// checking for the value maintains access-order of the archive
|
// checking for the value maintains access-order of the archive
|
||||||
if (recentlyOpenedArchiveMap.get(absoluteFilePath) == null) {
|
if (recentlyOpenedArchiveMap.get(absoluteFilePath) == null) {
|
||||||
|
|
||||||
RecentlyOpenedArchiveAction action =
|
RecentlyOpenedArchiveAction action =
|
||||||
new RecentlyOpenedArchiveAction(this, absoluteFilePath, RECENTLY_OPENED_MENU);
|
new RecentlyOpenedArchiveAction(this, absoluteFilePath, RECENTLY_OPENED_MENU);
|
||||||
action.setHelpLocation(new HelpLocation(getName(), "Recent_Archives"));
|
action.setHelpLocation(new HelpLocation(getName(), "Recent_Archives"));
|
||||||
|
@ -207,15 +206,17 @@ public class DataTypeManagerPlugin extends ProgramPlugin implements DomainObject
|
||||||
*/
|
*/
|
||||||
public void addRecentlyOpenedProjectArchive(String projectName, String pathname) {
|
public void addRecentlyOpenedProjectArchive(String projectName, String pathname) {
|
||||||
String projectPathname = DataTypeManagerHandler.getProjectPathname(projectName, pathname);
|
String projectPathname = DataTypeManagerHandler.getProjectPathname(projectName, pathname);
|
||||||
if (recentlyOpenedArchiveMap.get(projectPathname) == null) {
|
if (recentlyOpenedArchiveMap.get(projectPathname) != null) {
|
||||||
RecentlyOpenedArchiveAction action = null;
|
return;
|
||||||
if (getProjectArchiveFile(projectName, pathname) != null) {
|
|
||||||
action =
|
|
||||||
new RecentlyOpenedArchiveAction(this, projectPathname, RECENTLY_OPENED_MENU);
|
|
||||||
action.setHelpLocation(new HelpLocation(getName(), "Recent_Archives"));
|
|
||||||
}
|
|
||||||
recentlyOpenedArchiveMap.put(projectPathname, action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecentlyOpenedArchiveAction action = null;
|
||||||
|
if (getProjectArchiveFile(projectName, pathname) != null) {
|
||||||
|
action = new RecentlyOpenedArchiveAction(this, projectPathname, RECENTLY_OPENED_MENU);
|
||||||
|
action.setHelpLocation(new HelpLocation(getName(), "Recent_Archives"));
|
||||||
|
}
|
||||||
|
|
||||||
|
recentlyOpenedArchiveMap.put(projectPathname, action);
|
||||||
updateRecentlyOpenedArchivesMenu();
|
updateRecentlyOpenedArchivesMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,50 +419,25 @@ public class DataTypeManagerPlugin extends ProgramPlugin implements DomainObject
|
||||||
|
|
||||||
private void createStandardArchivesMenu() {
|
private void createStandardArchivesMenu() {
|
||||||
installArchiveMap = new TreeMap<>();
|
installArchiveMap = new TreeMap<>();
|
||||||
for (ResourceFile archiveFile : Application
|
String gdt = FileDataTypeManager.SUFFIX;
|
||||||
.findFilesByExtensionInApplication(FileDataTypeManager.SUFFIX)) {
|
List<ResourceFile> gdts = Application.findFilesByExtensionInApplication(gdt);
|
||||||
|
for (ResourceFile archiveFile : gdts) {
|
||||||
Path path = new Path(archiveFile);
|
Path path = new Path(archiveFile);
|
||||||
String absoluteFilePath = path.getPathAsString();
|
String absolutePath = path.getPathAsString();
|
||||||
if (absoluteFilePath.indexOf("data/typeinfo") < 0) {
|
if (!absolutePath.contains("/data/typeinfo/")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RecentlyOpenedArchiveAction action = new RecentlyOpenedArchiveAction(this,
|
|
||||||
absoluteFilePath, getShortArchivePath(absoluteFilePath), STANDARD_ARCHIVE_MENU);
|
RecentlyOpenedArchiveAction action =
|
||||||
|
new RecentlyOpenedArchiveAction(this, absolutePath, STANDARD_ARCHIVE_MENU);
|
||||||
action.setHelpLocation(new HelpLocation(getName(), "Standard_Archives"));
|
action.setHelpLocation(new HelpLocation(getName(), "Standard_Archives"));
|
||||||
installArchiveMap.put(absoluteFilePath, action);
|
installArchiveMap.put(absolutePath, action);
|
||||||
}
|
}
|
||||||
for (DockingAction action : installArchiveMap.values()) {
|
for (DockingAction action : installArchiveMap.values()) {
|
||||||
tool.addLocalAction(provider, action);
|
tool.addLocalAction(provider, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getShortArchivePath(String fullPath) {
|
|
||||||
String path = fullPath;
|
|
||||||
|
|
||||||
String extensionPrefix = "";
|
|
||||||
if (fullPath.startsWith(EXTENSIONS_PATH_PREFIX)) {
|
|
||||||
int index = fullPath.indexOf("/", EXTENSIONS_PATH_PREFIX.length() + 1);
|
|
||||||
if (index >= 0) {
|
|
||||||
extensionPrefix =
|
|
||||||
fullPath.substring(EXTENSIONS_PATH_PREFIX.length() + 1, index) + ": ";
|
|
||||||
fullPath = fullPath.substring(index + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int index1 = fullPath.lastIndexOf('/');
|
|
||||||
if (index1 >= 0) {
|
|
||||||
int index2 = fullPath.lastIndexOf('/', index1 - 1);
|
|
||||||
if (index2 >= 0) {
|
|
||||||
path = fullPath.substring(index2 + 1);
|
|
||||||
if (!path.startsWith("typeinfo/")) {
|
|
||||||
return extensionPrefix + path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path = fullPath.substring(index1 + 1);
|
|
||||||
}
|
|
||||||
return extensionPrefix + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the actions for the menu on the tool.
|
* Create the actions for the menu on the tool.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,17 +31,14 @@ import ghidra.util.task.TaskLauncher;
|
||||||
*/
|
*/
|
||||||
public class RecentlyOpenedArchiveAction extends DockingAction {
|
public class RecentlyOpenedArchiveAction extends DockingAction {
|
||||||
|
|
||||||
|
private static final String EXTENSIONS_PATH_PREFIX = Path.GHIDRA_HOME + "/Extensions/Ghidra";
|
||||||
|
|
||||||
private final String projectName; // only used for project archive path
|
private final String projectName; // only used for project archive path
|
||||||
private final String archivePath;
|
private final String archivePath;
|
||||||
private final DataTypeManagerPlugin plugin;
|
private final DataTypeManagerPlugin plugin;
|
||||||
|
|
||||||
public RecentlyOpenedArchiveAction(DataTypeManagerPlugin plugin, String archivePath,
|
public RecentlyOpenedArchiveAction(DataTypeManagerPlugin plugin, String archivePath,
|
||||||
String menuGroup) {
|
String menuGroup) {
|
||||||
this(plugin, archivePath, getDisplayPath(archivePath), menuGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RecentlyOpenedArchiveAction(DataTypeManagerPlugin plugin, String archivePath,
|
|
||||||
String displayedPath, String menuGroup) {
|
|
||||||
super(menuGroup + ": \"" + archivePath + "\"", plugin.getName(), false);
|
super(menuGroup + ": \"" + archivePath + "\"", plugin.getName(), false);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
String[] projectPathname = DataTypeManagerHandler.parseProjectPathname(archivePath);
|
String[] projectPathname = DataTypeManagerHandler.parseProjectPathname(archivePath);
|
||||||
|
@ -53,13 +50,20 @@ public class RecentlyOpenedArchiveAction extends DockingAction {
|
||||||
this.projectName = projectPathname[0];
|
this.projectName = projectPathname[0];
|
||||||
this.archivePath = projectPathname[1];
|
this.archivePath = projectPathname[1];
|
||||||
}
|
}
|
||||||
setMenuBarData(new MenuData(new String[] { menuGroup, displayedPath }, null, menuGroup));
|
|
||||||
|
String menuPath = getMenuPath(archivePath);
|
||||||
|
setMenuBarData(new MenuData(new String[] { menuGroup, menuPath }, null, menuGroup));
|
||||||
|
|
||||||
setDescription("Opens the indicated archive in the data type manager.");
|
setDescription("Opens the indicated archive in the data type manager.");
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getDisplayPath(String filepath) {
|
private static String getMenuPath(String filepath) {
|
||||||
|
|
||||||
|
if (filepath.contains("/data/typeinfo/")) {
|
||||||
|
return getTypeInfoRelativeName(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
String[] projectPathname = DataTypeManagerHandler.parseProjectPathname(filepath);
|
String[] projectPathname = DataTypeManagerHandler.parseProjectPathname(filepath);
|
||||||
if (projectPathname == null) {
|
if (projectPathname == null) {
|
||||||
return filepath;
|
return filepath;
|
||||||
|
@ -67,6 +71,44 @@ public class RecentlyOpenedArchiveAction extends DockingAction {
|
||||||
return projectPathname[0] + ":" + projectPathname[1];
|
return projectPathname[0] + ":" + projectPathname[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
$GHIDRA_HOME/Extensions/Ghidra/Extension1/data/typeinfo/foo.gdt -> "Extension1: "
|
||||||
|
$GHIDRA_HOME/Features/Base/data/typeinfo/foo.gdt -> ""
|
||||||
|
*/
|
||||||
|
private static String getExtensionName(String fullPath) {
|
||||||
|
|
||||||
|
if (!fullPath.startsWith(EXTENSIONS_PATH_PREFIX)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = EXTENSIONS_PATH_PREFIX.length() + 1;
|
||||||
|
int slashIndex = fullPath.indexOf("/", start);
|
||||||
|
if (slashIndex < 0) {
|
||||||
|
return ""; // no folder; shouldn't happen
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the first folder name, which is the extension name
|
||||||
|
return fullPath.substring(start, slashIndex) + ": ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input path is expected to contain '/data/typeinfo'. It may or may not be an extension path.
|
||||||
|
|
||||||
|
$GHIDRA_HOME/Extensions/Ghidra/Extension1/data/typeinfo/foo.gdt -> "Extension1: "
|
||||||
|
$GHIDRA_HOME/Features/Base/data/typeinfo/foo.gdt -> ""
|
||||||
|
*/
|
||||||
|
private static String getTypeInfoRelativeName(String fullPath) {
|
||||||
|
|
||||||
|
String[] parts = fullPath.split("/data/typeinfo/");
|
||||||
|
String relativePath = parts[1];
|
||||||
|
|
||||||
|
// e.g., "Extension1: " or ""
|
||||||
|
String extensionName = getExtensionName(fullPath);
|
||||||
|
return extensionName + relativePath;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
if (projectName == null) {
|
if (projectName == null) {
|
||||||
|
@ -88,22 +130,23 @@ public class RecentlyOpenedArchiveAction extends DockingAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OpenArchiveTask extends Task {
|
private class OpenArchiveTask extends Task {
|
||||||
private final Path archivePath;
|
private final Path taskArchivePath;
|
||||||
private final DataTypeManagerHandler archiveManager;
|
private final DataTypeManagerHandler archiveManager;
|
||||||
|
|
||||||
OpenArchiveTask(DataTypeManagerHandler archiveManager, Path archivePath) {
|
OpenArchiveTask(DataTypeManagerHandler archiveManager, Path archivePath) {
|
||||||
super("Opening Archive " + archivePath.getPath().getName(), false, false, true);
|
super("Opening Archive " + archivePath.getPath().getName(), false, false, true);
|
||||||
this.archiveManager = archiveManager;
|
this.archiveManager = archiveManager;
|
||||||
this.archivePath = archivePath;
|
this.taskArchivePath = archivePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(ghidra.util.task.TaskMonitor monitor) {
|
public void run(ghidra.util.task.TaskMonitor monitor) {
|
||||||
try {
|
try {
|
||||||
archiveManager.openArchive(archivePath.getPath(), false, true);
|
archiveManager.openArchive(taskArchivePath.getPath(), false, true);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Exception e) {
|
||||||
DataTypeManagerHandler.handleArchiveFileException(plugin, archivePath.getPath(), t);
|
DataTypeManagerHandler.handleArchiveFileException(plugin, taskArchivePath.getPath(),
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue