mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-28 15:11:44 +00:00
start connecting OSGi to bundlestatusmanager
- minimize access to BundleHost instance (JavaScriptProvider is still bad) - BundlePath - restrict construction to osgi package - remove "editable" attribute and fix incorrect reference - remove references in GhidraScriptUtil - BundlePath attribute choice came down only to system or user - user filtering on "enabled" were redundant - move compilation from JavaScriptProvider to BundheHost
This commit is contained in:
parent
36f4a219d9
commit
f39d55cca1
@ -39,9 +39,9 @@ import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.support.BreadthFirstIterator;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.util.Path;
|
||||
import ghidra.app.plugin.core.script.osgi.*;
|
||||
import ghidra.app.script.*;
|
||||
import ghidra.app.script.osgi.BundleHost;
|
||||
import ghidra.app.services.ConsoleService;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||
@ -97,9 +97,10 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
};
|
||||
|
||||
GhidraScriptComponentProvider(GhidraScriptMgrPlugin plugin) {
|
||||
GhidraScriptComponentProvider(GhidraScriptMgrPlugin plugin, BundleHost bundleHost) {
|
||||
super(plugin.getTool(), "Script Manager", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
this.bundleHost=bundleHost;
|
||||
|
||||
setHelpLocation(new HelpLocation(plugin.getName(), plugin.getName()));
|
||||
setIcon(ResourceManager.loadImage("images/play.png"));
|
||||
@ -161,8 +162,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
void renameScript() {
|
||||
ResourceFile script = getSelectedScript();
|
||||
ResourceFile directory = script.getParentFile();
|
||||
Path path = GhidraScriptUtil.getScriptPath(directory);
|
||||
if (path == null || path.isReadOnly()) {
|
||||
if (!bundleStatusProvider.getModel().isWriteable(directory)) {
|
||||
Msg.showWarn(getClass(), getComponent(), getName(),
|
||||
"Unable to rename scripts in '" + directory + "'.");
|
||||
return;
|
||||
@ -297,8 +297,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
ResourceFile directory = script.getParentFile();
|
||||
|
||||
Path path = GhidraScriptUtil.getScriptPath(directory);
|
||||
if (path == null || path.isReadOnly()) {
|
||||
if (!bundleStatusProvider.getModel().isWriteable(directory)) {
|
||||
Msg.showWarn(getClass(), getComponent(), getName(),
|
||||
"Unable to delete scripts in '" + directory + "'.");
|
||||
return;
|
||||
@ -339,9 +338,9 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public List<BundlePath> getScriptDirectories() {
|
||||
public List<ResourceFile> getScriptDirectories() {
|
||||
return bundleStatusProvider.getModel().getPaths().stream().filter(
|
||||
BundlePath::isDirectory).collect(Collectors.toList());
|
||||
ResourceFile::isDirectory).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void enableScriptDirectory(ResourceFile scriptDir) {
|
||||
@ -396,9 +395,9 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
|
||||
void runScript(String scriptName, TaskListener listener) {
|
||||
List<BundlePath> dirPaths = bundleStatusProvider.getModel().getPaths();
|
||||
for (Path dir : dirPaths) {
|
||||
ResourceFile scriptSource = new ResourceFile(dir.getPath(), scriptName);
|
||||
List<ResourceFile> dirPaths = bundleStatusProvider.getModel().getPaths();
|
||||
for (ResourceFile dir : dirPaths) {
|
||||
ResourceFile scriptSource = new ResourceFile(dir, scriptName);
|
||||
if (scriptSource.exists()) {
|
||||
runScript(scriptSource, listener);
|
||||
return;
|
||||
@ -536,11 +535,11 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
private void updateAvailableScriptFilesForAllPaths() {
|
||||
List<ResourceFile> scriptsToRemove = tableModel.getScripts();
|
||||
List<ResourceFile> scriptAccumulator = new ArrayList<>();
|
||||
List<BundlePath> bundlePaths = bundleStatusProvider.getModel().getPaths();
|
||||
for (BundlePath bundlePath : bundlePaths) {
|
||||
List<ResourceFile> bundlePaths = bundleStatusProvider.getModel().getPaths();
|
||||
for (ResourceFile bundlePath : bundlePaths) {
|
||||
if (bundlePath.isDirectory()) {
|
||||
updateAvailableScriptFilesForDirectory(scriptsToRemove, scriptAccumulator,
|
||||
bundlePath.getPath());
|
||||
bundlePath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,8 +730,33 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void build() {
|
||||
final private BundleHost bundleHost;
|
||||
|
||||
void startActivateDeactiveTask(BundlePath path, boolean activate) {
|
||||
path.setBusy(true);
|
||||
bundleStatusProvider.notifyTableChanged();
|
||||
|
||||
new TaskLauncher(new Task((activate ? "Activating" : "Deactivating ") + " bundle...") {
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) throws CancelledException {
|
||||
try {
|
||||
bundleHost.setActive(path, activate);
|
||||
path.setActive(activate);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(this, GhidraScriptComponentProvider.this.getComponent(),
|
||||
"activation failed", e);
|
||||
}
|
||||
finally {
|
||||
path.setBusy(false);
|
||||
bundleStatusProvider.notifyTableChanged();
|
||||
}
|
||||
}
|
||||
}, null, 1000);
|
||||
|
||||
}
|
||||
|
||||
private void build() {
|
||||
bundleStatusProvider = new BundleStatusProvider(plugin.getTool(), plugin.getName());
|
||||
|
||||
bundleStatusProvider.addListener(new BundlePathManagerListener() {
|
||||
@ -744,8 +768,10 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
|
||||
@Override
|
||||
public void bundleEnablementChanged(BundlePath path, boolean enabled) {
|
||||
System.err.printf("XXXX %s is now %s\n", path.toString(),
|
||||
enabled ? "enabled" : "disabled");
|
||||
if (path.isActive()) {
|
||||
startActivateDeactiveTask(path, false);
|
||||
}
|
||||
|
||||
if (path.isDirectory()) {
|
||||
performRefresh();
|
||||
}
|
||||
@ -753,8 +779,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
|
||||
@Override
|
||||
public void bundleActivationChanged(BundlePath path, boolean newValue) {
|
||||
System.err.printf("XXXX %s is now %s\n", path.toString(),
|
||||
newValue ? "active" : "inactive");
|
||||
startActivateDeactiveTask(path, newValue);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1026,7 +1051,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
bundleStatusProvider.restoreState(saveState);
|
||||
|
||||
// pull in the just-loaded paths
|
||||
List<BundlePath> paths = bundleStatusProvider.getModel().getPaths();
|
||||
List<ResourceFile> paths = bundleStatusProvider.getModel().getPaths();
|
||||
GhidraScriptUtil.setScriptBundlePaths(paths);
|
||||
actionManager.restoreUserDefinedKeybindings(saveState);
|
||||
actionManager.restoreScriptsThatAreInTool(saveState);
|
||||
@ -1162,4 +1187,10 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public List<ResourceFile> getWritableScriptDirectories() {
|
||||
BundleStatusModel m = bundleStatusProvider.getModel();
|
||||
return m.getPaths().stream().filter(ResourceFile::isDirectory).filter(
|
||||
m::isWriteable).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.app.plugin.core.eclipse.EclipseConnection;
|
||||
import ghidra.app.plugin.core.eclipse.EclipseIntegrationOptionsPlugin;
|
||||
import ghidra.app.script.GhidraState;
|
||||
import ghidra.app.script.osgi.BundleHost;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
@ -48,12 +49,15 @@ import ghidra.util.task.TaskListener;
|
||||
//@formatter:on
|
||||
public class GhidraScriptMgrPlugin extends ProgramPlugin implements GhidraScriptService {
|
||||
|
||||
private GhidraScriptComponentProvider provider;
|
||||
final private GhidraScriptComponentProvider provider;
|
||||
|
||||
final private BundleHost bundleHost;
|
||||
|
||||
public GhidraScriptMgrPlugin(PluginTool tool) {
|
||||
super(tool, true, true, true);
|
||||
|
||||
provider = new GhidraScriptComponentProvider(this);
|
||||
bundleHost = BundleHost.getInstance();
|
||||
provider = new GhidraScriptComponentProvider(this, bundleHost);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,8 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
@ -31,7 +32,6 @@ import docking.widgets.MultiLineLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import docking.widgets.list.ListPanel;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.util.Path;
|
||||
import ghidra.app.script.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
@ -49,7 +49,7 @@ public class SaveDialog extends DialogComponentProvider implements ListSelection
|
||||
public SaveDialog(Component parent, String title,
|
||||
GhidraScriptComponentProvider componentProvider, ResourceFile scriptFile,
|
||||
HelpLocation help) {
|
||||
this(parent, title, componentProvider, getScriptPaths(), scriptFile, help);
|
||||
this(parent, title, componentProvider, componentProvider.getWritableScriptDirectories(), scriptFile, help);
|
||||
}
|
||||
|
||||
public SaveDialog(Component parent, String title,
|
||||
@ -85,21 +85,6 @@ public class SaveDialog extends DialogComponentProvider implements ListSelection
|
||||
DockingWindowManager.showDialog(parent, this);
|
||||
}
|
||||
|
||||
private static List<ResourceFile> getScriptPaths() {
|
||||
List<ResourceFile> newPaths = new ArrayList<>();
|
||||
|
||||
List<ResourceFile> scriptPaths = GhidraScriptUtil.getScriptSourceDirectories();
|
||||
for (ResourceFile directory : scriptPaths) {
|
||||
Path path = GhidraScriptUtil.getScriptPath(directory);
|
||||
if (path != null && !path.isReadOnly()) {
|
||||
newPaths.add(directory);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(newPaths);
|
||||
return newPaths;
|
||||
}
|
||||
|
||||
private JPanel buildNamePanel() {
|
||||
nameField = new JTextField(20);
|
||||
nameField.setText(scriptFile == null ? "" : scriptFile.getName());
|
||||
|
@ -21,7 +21,10 @@ import generic.jar.ResourceFile;
|
||||
import generic.util.Path;
|
||||
|
||||
public class BundlePath extends Path {
|
||||
final Type type;
|
||||
|
||||
boolean active = false;
|
||||
boolean busy = false;
|
||||
|
||||
public static enum Type {
|
||||
BndScript, Jar, SourceDir, INVALID
|
||||
@ -55,47 +58,43 @@ public class BundlePath extends Path {
|
||||
return Type.INVALID;
|
||||
}
|
||||
|
||||
final Type type;
|
||||
|
||||
public BundlePath(File path) {
|
||||
super(path);
|
||||
type = getType(getPath());
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public BundlePath(ResourceFile rf) {
|
||||
super(rf);
|
||||
BundlePath(String path, boolean enabled, boolean readonly) {
|
||||
super(path, enabled, false /*editable */, readonly);
|
||||
type = getType(getPath());
|
||||
}
|
||||
|
||||
public BundlePath(String absolutePath) {
|
||||
super(absolutePath);
|
||||
BundlePath(ResourceFile path, boolean enabled, boolean readonly) {
|
||||
super(path, enabled, false /* editable */, readonly);
|
||||
type = getType(getPath());
|
||||
}
|
||||
|
||||
public BundlePath(String a, boolean b, boolean c, boolean d) {
|
||||
super(a, b, c, d);
|
||||
type = getType(getPath());
|
||||
}
|
||||
|
||||
public BundlePath(ResourceFile a, boolean b, boolean c, boolean d) {
|
||||
super(a, b, c, d);
|
||||
type = getType(getPath());
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(Boolean b) {
|
||||
active = b;
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return getPath().isDirectory();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setActive(boolean b) {
|
||||
active = b;
|
||||
}
|
||||
|
||||
public void setBusy(boolean b) {
|
||||
busy = b;
|
||||
}
|
||||
|
||||
public boolean getBusy() {
|
||||
return busy;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.script.osgi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import docking.widgets.table.AbstractSortedTableModel;
|
||||
import generic.jar.ResourceFile;
|
||||
@ -41,20 +41,25 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
}
|
||||
|
||||
boolean editable(BundlePath path) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Object getValue(BundlePath path) {
|
||||
return path;
|
||||
return null;
|
||||
}
|
||||
|
||||
void setValue(BundlePath path, Object aValue) {
|
||||
// do nothing
|
||||
throw new RuntimeException(name + " is not editable!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Column enabledColumn = new Column("Enabled", Boolean.class) {
|
||||
@Override
|
||||
boolean editable(BundlePath path) {
|
||||
return path.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
Object getValue(BundlePath path) {
|
||||
return path.isEnabled();
|
||||
@ -67,6 +72,11 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
}
|
||||
};
|
||||
Column activeColumn = new Column("Active", Boolean.class) {
|
||||
@Override
|
||||
boolean editable(BundlePath path) {
|
||||
return path.exists(); // XXX maybe only if it's already enabled
|
||||
}
|
||||
|
||||
@Override
|
||||
Object getValue(BundlePath path) {
|
||||
return path.isActive();
|
||||
@ -93,15 +103,12 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
Column pathColumn = new Column("Path", BundlePath.class) {
|
||||
@Override
|
||||
boolean editable(BundlePath path) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setValue(BundlePath path, Object aValue) {
|
||||
if (path.isEditable()) {
|
||||
BundlePath newpath = (BundlePath) aValue;
|
||||
path.setPath(newpath.getPath());
|
||||
}
|
||||
Object getValue(BundlePath path) {
|
||||
return path;
|
||||
}
|
||||
};
|
||||
Column badColumn = new Column("INVALID", Object.class);
|
||||
@ -118,26 +125,21 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
}
|
||||
|
||||
private BundleStatusProvider provider;
|
||||
private List<BundlePath> paths = new ArrayList<>();
|
||||
private List<BundlePath> paths;
|
||||
|
||||
BundleStatusModel(BundleStatusProvider provider) {
|
||||
super();
|
||||
this.provider = provider;
|
||||
this.paths.addAll(dedupPaths(GhidraScriptUtil.getDefaultScriptBundles()));
|
||||
|
||||
// add unmodifiable paths
|
||||
this.paths = GhidraScriptUtil.getSystemScriptPaths().stream().distinct().map(
|
||||
f -> new BundlePath(f, true, true)).collect(Collectors.toList());
|
||||
// add user path
|
||||
this.paths.add(0, new BundlePath(GhidraScriptUtil.getUserScriptDirectory(), true, false));
|
||||
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
private List<BundlePath> dedupPaths(List<BundlePath> newPaths) {
|
||||
List<BundlePath> dedupedPaths = new ArrayList<>();
|
||||
for (BundlePath path : newPaths) {
|
||||
if (!dedupedPaths.contains(path)) {
|
||||
dedupedPaths.add(path);
|
||||
}
|
||||
}
|
||||
return dedupedPaths;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
paths.clear();
|
||||
}
|
||||
@ -146,21 +148,16 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
return new ArrayList<BundlePath>(paths);
|
||||
}
|
||||
|
||||
public List<BundlePath> getPaths() {
|
||||
List<BundlePath> list = new ArrayList<>();
|
||||
public List<ResourceFile> getPaths() {
|
||||
List<ResourceFile> list = new ArrayList<>();
|
||||
for (BundlePath path : paths) {
|
||||
if (path.isEnabled()) {
|
||||
list.add(path);
|
||||
list.add(path.getPath());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setPaths(List<BundlePath> paths) {
|
||||
this.paths = new ArrayList<>(paths);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
void addPath(BundlePath path) {
|
||||
if (paths.contains(path)) {
|
||||
return;
|
||||
@ -176,7 +173,7 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
list.add(paths.get(selectedRow));
|
||||
}
|
||||
for (BundlePath path : list) {
|
||||
if (path.isEditable()) {
|
||||
if (!path.isReadOnly()) {
|
||||
paths.remove(path);
|
||||
}
|
||||
else {
|
||||
@ -259,11 +256,48 @@ public class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
BundlePath p = new BundlePath(dir);
|
||||
p.setEnabled(true);
|
||||
BundlePath p = new BundlePath(dir, true, false);
|
||||
addPath(p);
|
||||
Preferences.setProperty(BundleStatusProvider.preferenceForLastSelectedBundle, dir.getAbsolutePath());
|
||||
Preferences.setProperty(BundleStatusProvider.preferenceForLastSelectedBundle,
|
||||
dir.getAbsolutePath());
|
||||
provider.fireBundlesChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given <code>bundle</code> is managed and not marked readonly
|
||||
* @param bundle the path to test
|
||||
* @return true if the bundle is managed and not marked readonly
|
||||
*/
|
||||
public boolean isWriteable(ResourceFile bundle) {
|
||||
Optional<BundlePath> o = paths.stream().filter(
|
||||
bp -> bp.isDirectory() && bp.getPath().equals(bundle)).findFirst();
|
||||
return o.isPresent() && !o.get().isReadOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for testing only!
|
||||
*
|
||||
* each path is marked editable and non-readonly
|
||||
*
|
||||
* @param testingPaths the paths to use
|
||||
*/
|
||||
public void setPathsForTesting(List<String> testingPaths) {
|
||||
this.paths = testingPaths.stream().map(f -> new BundlePath(f, true, false)).collect(
|
||||
Collectors.toList());
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for testing only!
|
||||
*
|
||||
* insert path, marked editable and non-readonly
|
||||
* @param index index to insert at
|
||||
* @param path the path to insert
|
||||
*/
|
||||
public void insertPathForTesting(int index, String path) {
|
||||
paths.add(0, new BundlePath(path, true, false));
|
||||
fireTableRowsInserted(0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,11 +22,13 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.table.*;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
@ -51,6 +53,10 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
private GhidraFileFilter filter;
|
||||
private ArrayList<BundlePathManagerListener> listeners = new ArrayList<>();
|
||||
|
||||
public void notifyTableChanged() {
|
||||
bundlePathTable.notifyTableChanged(new TableModelEvent(bundleStatusModel));
|
||||
}
|
||||
|
||||
void fireBundlesChanged() {
|
||||
for (BundlePathManagerListener listener : listeners) {
|
||||
listener.bundlesChanged();
|
||||
@ -108,7 +114,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
panel = new JPanel(new BorderLayout(5, 5));
|
||||
|
||||
selectionColor = new Color(204, 204, 255);
|
||||
|
||||
|
||||
addButton = new JButton(ResourceManager.loadImage("images/Plus.png"));
|
||||
addButton.setName("AddBundle");
|
||||
addButton.setToolTipText("Display file chooser to add bundles to list");
|
||||
@ -138,6 +144,9 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
bundlePathTable.setSelectionForeground(Color.BLACK);
|
||||
bundlePathTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
|
||||
// to allow custom cell renderers
|
||||
bundlePathTable.setAutoCreateColumnsFromModel(false);
|
||||
|
||||
int skinnyWidth = 50;
|
||||
|
||||
TableColumn column =
|
||||
@ -152,6 +161,27 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
column.setMinWidth(skinnyWidth);
|
||||
column.setMaxWidth(skinnyWidth);
|
||||
column.setWidth(skinnyWidth);
|
||||
column.setCellRenderer(new GBooleanCellRenderer() {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
BundlePath path = (BundlePath) data.getRowObject();
|
||||
Component x = super.getTableCellRendererComponent(data);
|
||||
if (path.getBusy()) {
|
||||
cb.setVisible(false);
|
||||
cb.setEnabled(false);
|
||||
setHorizontalAlignment(SwingConstants.CENTER);
|
||||
setText("...");
|
||||
}
|
||||
else {
|
||||
cb.setVisible(true);
|
||||
cb.setEnabled(true);
|
||||
setText("");
|
||||
}
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
column = bundlePathTable.getColumnModel().getColumn(bundleStatusModel.typeColumn.index);
|
||||
|
||||
@ -163,13 +193,13 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
column.setCellRenderer(new GTableCellRenderer() {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
|
||||
JLabel renderer = (JLabel) super.getTableCellRendererComponent(data);
|
||||
JLabel c = (JLabel) super.getTableCellRendererComponent(data);
|
||||
|
||||
BundlePath path = (BundlePath) data.getValue();
|
||||
if (!path.exists()) {
|
||||
renderer.setForeground(Color.RED);
|
||||
c.setForeground(Color.RED);
|
||||
}
|
||||
return renderer;
|
||||
return c;
|
||||
}
|
||||
});
|
||||
|
||||
@ -262,7 +292,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
Preferences.setProperty(preferenceForLastSelectedBundle,
|
||||
files.get(0).getAbsolutePath());
|
||||
for (File element : files) {
|
||||
BundlePath p = new BundlePath(element);
|
||||
BundlePath p = new BundlePath(new ResourceFile(element), true, false);
|
||||
bundleStatusModel.addPath(p);
|
||||
}
|
||||
fireBundlesChanged();
|
||||
@ -283,22 +313,19 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
|
||||
String[] pathArr = new String[paths.size()];
|
||||
boolean[] enableArr = new boolean[paths.size()];
|
||||
boolean[] editArr = new boolean[paths.size()];
|
||||
boolean[] readArr = new boolean[paths.size()];
|
||||
|
||||
int index = 0;
|
||||
for (BundlePath path : paths) {
|
||||
pathArr[index] = path.getPathAsString();
|
||||
enableArr[index] = path.isEnabled();
|
||||
editArr[index] = path.isEditable();
|
||||
readArr[index] = path.isReadOnly();
|
||||
++index;
|
||||
}
|
||||
|
||||
ss.putStrings("BundleManagerPanel_PATH", pathArr);
|
||||
ss.putBooleans("BundleManagerPanel_ENABLE", enableArr);
|
||||
ss.putBooleans("BundleManagerPanel_EDIT", editArr);
|
||||
ss.putBooleans("BundleManagerPanel_READ", readArr);
|
||||
ss.putStrings("BundleStatus_PATH", pathArr);
|
||||
ss.putBooleans("BundleStatus_ENABLE", enableArr);
|
||||
ss.putBooleans("BundleStatus_READ", readArr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,22 +333,21 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
* @param ss the SaveState object
|
||||
*/
|
||||
public void restoreState(SaveState ss) {
|
||||
String[] pathArr = ss.getStrings("BundleManagerPanel_PATH", new String[0]);
|
||||
String[] pathArr = ss.getStrings("BundleStatus_PATH", new String[0]);
|
||||
|
||||
if (pathArr.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean[] enableArr =
|
||||
ss.getBooleans("BundleManagerPanel_ENABLE", new boolean[pathArr.length]);
|
||||
boolean[] editArr = ss.getBooleans("BundleManagerPanel_EDIT", new boolean[pathArr.length]);
|
||||
boolean[] readArr = ss.getBooleans("BundleManagerPanel_READ", new boolean[pathArr.length]);
|
||||
ss.getBooleans("BundleStatus_ENABLE", new boolean[pathArr.length]);
|
||||
boolean[] readArr = ss.getBooleans("BundleStatus_READ", new boolean[pathArr.length]);
|
||||
|
||||
List<BundlePath> oldPaths = bundleStatusModel.getAllPaths();
|
||||
bundleStatusModel.clear();
|
||||
|
||||
for (int i = 0; i < pathArr.length; i++) {
|
||||
BundlePath path = new BundlePath(pathArr[i], enableArr[i], editArr[i], readArr[i]);
|
||||
BundlePath path = new BundlePath(pathArr[i], enableArr[i], readArr[i]);
|
||||
BundlePath oldPath = getPath(path.getPathAsString(), oldPaths);
|
||||
if (oldPath != null) {
|
||||
if (!oldPath.isEditable()) {
|
||||
@ -361,7 +387,4 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
|
||||
bundlePathTable.dispose();
|
||||
}
|
||||
|
||||
void selectRow(int rowIndex) {
|
||||
bundlePathTable.selectRow(rowIndex);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.collections4.map.LazyMap;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
@ -48,7 +47,7 @@ public class GhidraScriptUtil {
|
||||
*/
|
||||
public static String USER_SCRIPTS_DIR = buildUserScriptsDirectory();
|
||||
|
||||
private static List<BundlePath> scriptBundlePaths = new ArrayList<>();
|
||||
private static List<ResourceFile> scriptBundlePaths = new ArrayList<>();
|
||||
|
||||
private static Map<ResourceFile, ScriptInfo> scriptFileToInfoMap = new HashMap<>();
|
||||
|
||||
@ -56,7 +55,8 @@ public class GhidraScriptUtil {
|
||||
LazyMap.lazyMap(new HashMap<String, List<ResourceFile>>(), () -> new ArrayList<>());
|
||||
|
||||
static {
|
||||
scriptBundlePaths = getDefaultScriptBundles();
|
||||
scriptBundlePaths = getSystemScriptPaths();
|
||||
scriptBundlePaths.add(0, getUserScriptDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,25 +81,22 @@ public class GhidraScriptUtil {
|
||||
* Returns a list of the default script directories.
|
||||
* @return a list of the default script directories
|
||||
*/
|
||||
public static List<BundlePath> getDefaultScriptBundles() {
|
||||
|
||||
List<BundlePath> pathsList = new ArrayList<>();
|
||||
public static List<ResourceFile> getSystemScriptPaths() {
|
||||
List<ResourceFile> pathsList = new ArrayList<>();
|
||||
|
||||
addScriptPaths(pathsList, SCRIPTS_SUBDIR_NAME);
|
||||
addScriptPaths(pathsList, DEV_SCRIPTS_SUBDIR_NAME);
|
||||
|
||||
Collections.sort(pathsList);
|
||||
|
||||
// this one should always be first
|
||||
pathsList.add(0, new BundlePath(new ResourceFile(USER_SCRIPTS_DIR), true, false, false));
|
||||
return pathsList;
|
||||
}
|
||||
|
||||
private static void addScriptPaths(List<BundlePath> pathsList, String directoryName) {
|
||||
Iterable<ResourceFile> files = Application.findModuleSubDirectories(directoryName);
|
||||
for (ResourceFile file : files) {
|
||||
pathsList.add(new BundlePath(file, true, false, true));
|
||||
}
|
||||
public static ResourceFile getUserScriptDirectory() {
|
||||
return new ResourceFile(USER_SCRIPTS_DIR);
|
||||
}
|
||||
|
||||
private static void addScriptPaths(List<ResourceFile> pathsList, String directoryName) {
|
||||
pathsList.addAll(Application.findModuleSubDirectories(directoryName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,39 +141,18 @@ public class GhidraScriptUtil {
|
||||
* @return a list of the current script directories
|
||||
*/
|
||||
public static List<ResourceFile> getScriptSourceDirectories() {
|
||||
ArrayList<ResourceFile> dirs = new ArrayList<>();
|
||||
for (BundlePath path : scriptBundlePaths) {
|
||||
if (path.isDirectory()) {
|
||||
dirs.add(path.getPath());
|
||||
}
|
||||
}
|
||||
return dirs;
|
||||
return scriptBundlePaths.stream().filter(ResourceFile::isDirectory).collect(
|
||||
Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the script bundle paths
|
||||
* @param newPaths the new script bundle paths
|
||||
*/
|
||||
public static void setScriptBundlePaths(List<BundlePath> newPaths) {
|
||||
public static void setScriptBundlePaths(List<ResourceFile> newPaths) {
|
||||
scriptBundlePaths = new ArrayList<>(newPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PATH for the specified directory.
|
||||
* @param directory the directory
|
||||
* @return the path for the specified directory
|
||||
*/
|
||||
public static BundlePath getScriptPath(ResourceFile directory) {
|
||||
if (directory.isDirectory()) {
|
||||
for (BundlePath path : scriptBundlePaths) {
|
||||
if (path.getPath().equals(directory)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Path getOsgiDir() {
|
||||
Path usersettings = Application.getUserSettingsDirectory().toPath();
|
||||
return usersettings.resolve("osgi");
|
||||
@ -218,7 +194,7 @@ public class GhidraScriptUtil {
|
||||
}
|
||||
|
||||
Set<ResourceFile> dirs = new HashSet<>();
|
||||
for (BundlePath path : scriptBundlePaths) {
|
||||
for (ResourceFile scriptDir : scriptBundlePaths) {
|
||||
//
|
||||
// Assumed structure of script dir path:
|
||||
// /some/path/Ghidra/Features/Module/ghidra_scripts
|
||||
@ -226,7 +202,6 @@ public class GhidraScriptUtil {
|
||||
// Desired path:
|
||||
// /some/path/Ghidra/Features/Module/bin/scripts
|
||||
|
||||
ResourceFile scriptDir = path.getPath();
|
||||
ResourceFile moduleDir = scriptDir.getParentFile();
|
||||
dirs.add(new ResourceFile(moduleDir, BIN_DIR_NAME + File.separator + "scripts"));
|
||||
}
|
||||
@ -381,14 +356,14 @@ public class GhidraScriptUtil {
|
||||
* @throws IOException if an i/o error occurs
|
||||
*/
|
||||
public static ResourceFile createNewScript(GhidraScriptProvider provider,
|
||||
ResourceFile parentDirectory, List<BundlePath> scriptDirectories) throws IOException {
|
||||
ResourceFile parentDirectory, List<ResourceFile> scriptDirectories) throws IOException {
|
||||
String baseName = GhidraScriptConstants.DEFAULT_SCRIPT_NAME;
|
||||
String extension = provider.getExtension();
|
||||
return createNewScript(baseName, extension, parentDirectory, scriptDirectories);
|
||||
}
|
||||
|
||||
private static ResourceFile createNewScript(String scriptName, String extension,
|
||||
ResourceFile parentDirctory, List<BundlePath> scriptDirectories) throws IOException {
|
||||
ResourceFile parentDirctory, List<ResourceFile> scriptDirectories) throws IOException {
|
||||
String baseName = scriptName;
|
||||
String className = baseName + extension;
|
||||
|
||||
@ -409,13 +384,12 @@ public class GhidraScriptUtil {
|
||||
}
|
||||
|
||||
/** Returns true if the given filename exists in any of the given directories */
|
||||
private static ResourceFile findScriptFileInPaths(List<BundlePath> scriptDirectories,
|
||||
private static ResourceFile findScriptFileInPaths(List<ResourceFile> scriptDirectories,
|
||||
String filename) {
|
||||
|
||||
String validatedName = fixupName(filename);
|
||||
|
||||
for (BundlePath path : scriptDirectories) {
|
||||
ResourceFile resourceFile = path.getPath();
|
||||
for (ResourceFile resourceFile : scriptDirectories) {
|
||||
if (resourceFile.isDirectory()) {
|
||||
ResourceFile file = new ResourceFile(resourceFile, validatedName);
|
||||
if (file.exists()) {
|
||||
@ -477,8 +451,8 @@ public class GhidraScriptUtil {
|
||||
|
||||
public static List<ResourceFile> getAllScripts() {
|
||||
List<ResourceFile> scriptList = new ArrayList<>();
|
||||
for (BundlePath dirPath : scriptBundlePaths) {
|
||||
updateAvailableScriptFilesForDirectory(scriptList, dirPath.getPath());
|
||||
for (ResourceFile dirPath : scriptBundlePaths) {
|
||||
updateAvailableScriptFilesForDirectory(scriptList, dirPath);
|
||||
}
|
||||
return scriptList;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import ghidra.app.script.osgi.*;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class JavaScriptProvider extends GhidraScriptProvider {
|
||||
public SourceBundleInfo getBundleInfoForSource(ResourceFile sourceFile) {
|
||||
static public SourceBundleInfo getBundleInfoForSource(ResourceFile sourceFile) {
|
||||
ResourceFile sourceDir = getSourceDirectoryContaining(sourceFile);
|
||||
if (sourceDir == null) {
|
||||
return null;
|
||||
@ -87,7 +87,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> loadClass(ResourceFile sourceFile, PrintWriter writer)
|
||||
static public Class<?> loadClass(ResourceFile sourceFile, PrintWriter writer)
|
||||
throws IOException, OSGiException, ClassNotFoundException, InterruptedException {
|
||||
|
||||
if (writer == null) {
|
||||
@ -95,72 +95,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
|
||||
}
|
||||
|
||||
SourceBundleInfo bi = getBundleInfoForSource(sourceFile);
|
||||
|
||||
bi.updateFromFilesystem(writer);
|
||||
|
||||
// needsCompile => needsBundleActivate
|
||||
boolean needsCompile = false;
|
||||
boolean needsBundleActivate = false;
|
||||
|
||||
int failing = bi.getFailingSourcesCount();
|
||||
int newSourcecount = bi.getNewSourcesCount();
|
||||
|
||||
long lastBundleActivation = 0; // XXX record last bundle activation in pathmanager
|
||||
if (failing > 0 && (lastBundleActivation > bi.getLastCompileAttempt())) {
|
||||
needsCompile = true;
|
||||
}
|
||||
|
||||
if (newSourcecount == 0) {
|
||||
if (failing > 0) {
|
||||
writer.printf("%s hasn't changed, with %d file%s failing in previous build(s):\n",
|
||||
bi.getSourceDir().toString(), failing, failing > 1 ? "s" : "");
|
||||
writer.printf("%s\n", bi.getPreviousBuildErrors());
|
||||
}
|
||||
if (bi.newManifestFile()) {
|
||||
needsCompile = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
needsCompile = true;
|
||||
}
|
||||
|
||||
needsBundleActivate |= needsCompile;
|
||||
|
||||
BundleHost bundle_host = BundleHost.getInstance();
|
||||
if (needsBundleActivate) {
|
||||
writer.printf("%s has %d new/updated %d failed in previous build(s)%s\n",
|
||||
bi.getSourceDir().toString(), newSourcecount, failing,
|
||||
bi.newManifestFile() ? " and the manifest is new" : "");
|
||||
|
||||
// if there a bundle is currently active, uninstall it
|
||||
Bundle b = bi.getBundle();
|
||||
if (b != null) {
|
||||
bundle_host.synchronousUninstall(b);
|
||||
}
|
||||
|
||||
// once we've committed to recompile and regenerate generated classes, delete the old stuff
|
||||
if (needsCompile) {
|
||||
bi.deleteOldBinaries();
|
||||
|
||||
BundleCompiler bc = new BundleCompiler(bundle_host);
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
bc.compileToExplodedBundle(bi, writer);
|
||||
long endTime = System.nanoTime();
|
||||
writer.printf("%3.2f seconds compile time.\n", (endTime - startTime) / 1e9);
|
||||
}
|
||||
}
|
||||
// as much source as possible built, install bundle and start it if necessary
|
||||
Bundle b = bi.getBundle();
|
||||
if (b == null) {
|
||||
b = bi.install();
|
||||
needsBundleActivate = true;
|
||||
}
|
||||
|
||||
if (needsBundleActivate) {
|
||||
bundle_host.synchronousStart(b);
|
||||
}
|
||||
|
||||
Bundle b = BundleHost.getInstance().activate(bi, writer);
|
||||
String classname = bi.classNameForScript(sourceFile);
|
||||
Class<?> clazz = b.loadClass(classname); // throws ClassNotFoundException
|
||||
return clazz;
|
||||
|
@ -36,6 +36,7 @@ import org.osgi.framework.wiring.*;
|
||||
import org.osgi.service.log.*;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.script.GhidraScriptUtil;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
@ -532,4 +533,101 @@ public class BundleHost {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the status of the bundle referenced by <code>path</code>
|
||||
*
|
||||
* @param path the bundle path to activate/deactivate
|
||||
* @param value the new activation value
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setActive(BundlePath path, boolean value) throws InterruptedException {
|
||||
if (path.isDirectory()) {
|
||||
SourceBundleInfo sbi = getSourceBundleInfo(path.getPath());
|
||||
}
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* synchronously perform steps necessary to activate bundle:
|
||||
* <ol>
|
||||
* <li>if source bundle, checkCompile</li>
|
||||
* <li>b</li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* @param bi the bundle info
|
||||
* @param writer where to write issues
|
||||
* @throws OSGiException if bundle operations fail
|
||||
* @throws IOException if there are issues with the contents of the bundle
|
||||
* @return the activated bundle
|
||||
* @throws InterruptedException if interrupted while waiting for bundle state change
|
||||
*/
|
||||
public Bundle activate(SourceBundleInfo bi, PrintWriter writer)
|
||||
throws OSGiException, IOException, InterruptedException {
|
||||
bi.updateFromFilesystem(writer);
|
||||
|
||||
// needsCompile => needsBundleActivate
|
||||
boolean needsCompile = false;
|
||||
boolean needsBundleActivate = false;
|
||||
|
||||
int failing = bi.getFailingSourcesCount();
|
||||
int newSourcecount = bi.getNewSourcesCount();
|
||||
|
||||
long lastBundleActivation = 0; // XXX record last bundle activation in bundlestatusmodel
|
||||
if (failing > 0 && (lastBundleActivation > bi.getLastCompileAttempt())) {
|
||||
needsCompile = true;
|
||||
}
|
||||
|
||||
if (newSourcecount == 0) {
|
||||
if (failing > 0) {
|
||||
writer.printf("%s hasn't changed, with %d file%s failing in previous build(s):\n",
|
||||
bi.getSourceDir().toString(), failing, failing > 1 ? "s" : "");
|
||||
writer.printf("%s\n", bi.getPreviousBuildErrors());
|
||||
}
|
||||
if (bi.newManifestFile()) {
|
||||
needsCompile = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
needsCompile = true;
|
||||
}
|
||||
|
||||
needsBundleActivate |= needsCompile;
|
||||
|
||||
if (needsBundleActivate) {
|
||||
writer.printf("%s has %d new/updated %d failed in previous build(s)%s\n",
|
||||
bi.getSourceDir().toString(), newSourcecount, failing,
|
||||
bi.newManifestFile() ? " and the manifest is new" : "");
|
||||
|
||||
// if there a bundle is currently active, uninstall it
|
||||
Bundle b = bi.getBundle();
|
||||
if (b != null) {
|
||||
synchronousUninstall(b);
|
||||
}
|
||||
|
||||
// once we've committed to recompile and regenerate generated classes, delete the old stuff
|
||||
if (needsCompile) {
|
||||
bi.deleteOldBinaries();
|
||||
|
||||
BundleCompiler bc = new BundleCompiler(this);
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
bc.compileToExplodedBundle(bi, writer);
|
||||
long endTime = System.nanoTime();
|
||||
writer.printf("%3.2f seconds compile time.\n", (endTime - startTime) / 1e9);
|
||||
}
|
||||
}
|
||||
// as much source as possible built, install bundle and start it if necessary
|
||||
Bundle b = bi.getBundle();
|
||||
if (b == null) {
|
||||
b = bi.install();
|
||||
needsBundleActivate = true;
|
||||
}
|
||||
|
||||
if (needsBundleActivate) {
|
||||
synchronousStart(b);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import java.util.List;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraLaunchable;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.script.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.HeadlessGhidraApplicationConfiguration;
|
||||
@ -31,7 +30,7 @@ import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import utility.application.ApplicationLayout;
|
||||
|
||||
/**
|
||||
@ -76,7 +75,7 @@ public class GhidraScriptRunner implements GhidraLaunchable {
|
||||
try {
|
||||
PrintWriter writer = new PrintWriter(System.out);
|
||||
Msg.info(this, "SCRIPT: " + scriptName);
|
||||
script.execute(scriptState, TaskMonitorAdapter.DUMMY_MONITOR, writer);
|
||||
script.execute(scriptState, TaskMonitor.DUMMY, writer);
|
||||
writer.flush();
|
||||
}
|
||||
catch (Exception exc) {
|
||||
@ -100,8 +99,8 @@ public class GhidraScriptRunner implements GhidraLaunchable {
|
||||
GhidraScriptProvider provider = GhidraScriptUtil.getProvider(scriptSourceFile);
|
||||
|
||||
if (provider == null) {
|
||||
throw new IOException("Missing plugin needed to run scripts of this type. Please "
|
||||
+ "ensure you have installed the necessary plugin.");
|
||||
throw new IOException("Missing plugin needed to run scripts of this type. Please " +
|
||||
"ensure you have installed the necessary plugin.");
|
||||
}
|
||||
|
||||
PrintWriter writer = new PrintWriter(System.out);
|
||||
@ -192,20 +191,18 @@ public class GhidraScriptRunner implements GhidraLaunchable {
|
||||
* Gather paths where scripts may be found.
|
||||
*/
|
||||
private void initializeScriptPaths() {
|
||||
List<BundlePath> paths;
|
||||
List<ResourceFile> paths;
|
||||
if (scriptPaths == null || scriptPaths.isEmpty()) {
|
||||
paths = GhidraScriptUtil.getDefaultScriptBundles();
|
||||
paths = GhidraScriptUtil.getSystemScriptPaths();
|
||||
paths.add(0, GhidraScriptUtil.getUserScriptDirectory());
|
||||
}
|
||||
else {
|
||||
paths = new ArrayList<>();
|
||||
for (String path : scriptPaths) {
|
||||
paths.add(new BundlePath(path, true, false, true));
|
||||
}
|
||||
for (BundlePath path : GhidraScriptUtil.getDefaultScriptBundles()) {
|
||||
if (path.isEnabled() && !paths.contains(path)) {
|
||||
paths.add(path);
|
||||
}
|
||||
paths.add(new ResourceFile(path));
|
||||
}
|
||||
paths.addAll(GhidraScriptUtil.getSystemScriptPaths());
|
||||
paths.add(0, GhidraScriptUtil.getUserScriptDirectory());
|
||||
}
|
||||
GhidraScriptUtil.setScriptBundlePaths(paths);
|
||||
|
||||
|
@ -26,7 +26,6 @@ import generic.util.Path;
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraJarApplicationLayout;
|
||||
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.script.*;
|
||||
import ghidra.app.util.headless.HeadlessScript.HeadlessContinuationOption;
|
||||
import ghidra.app.util.importer.AutoImporter;
|
||||
@ -661,20 +660,18 @@ public class HeadlessAnalyzer {
|
||||
*/
|
||||
private void initializeScriptPaths() {
|
||||
|
||||
List<BundlePath> paths;
|
||||
List<ResourceFile> paths;
|
||||
if (options.scriptPaths == null || options.scriptPaths.isEmpty()) {
|
||||
paths = GhidraScriptUtil.getDefaultScriptBundles();
|
||||
paths = GhidraScriptUtil.getSystemScriptPaths();
|
||||
paths.add(0, GhidraScriptUtil.getUserScriptDirectory());
|
||||
}
|
||||
else {
|
||||
paths = new ArrayList<>();
|
||||
for (String path : options.scriptPaths) {
|
||||
paths.add(new BundlePath(path, true, false, true));
|
||||
}
|
||||
for (BundlePath path : GhidraScriptUtil.getDefaultScriptBundles()) {
|
||||
if (path.isEnabled() && !paths.contains(path)) {
|
||||
paths.add(path);
|
||||
}
|
||||
paths.add(new ResourceFile(path));
|
||||
}
|
||||
paths.addAll(GhidraScriptUtil.getSystemScriptPaths());
|
||||
paths.add(0, GhidraScriptUtil.getUserScriptDirectory());
|
||||
}
|
||||
GhidraScriptUtil.setScriptBundlePaths(paths);
|
||||
|
||||
|
@ -48,7 +48,6 @@ import generic.jar.ResourceFile;
|
||||
import generic.test.TestUtils;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.console.ConsoleComponentProvider;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.plugin.core.script.osgi.BundleStatusProvider;
|
||||
import ghidra.app.script.*;
|
||||
import ghidra.app.services.ConsoleService;
|
||||
@ -979,10 +978,10 @@ public abstract class AbstractGhidraScriptMgrPluginTest
|
||||
|
||||
// destroy any NewScriptxxx files...and Temp ones too
|
||||
BundleStatusProvider bundleStatusProvider =
|
||||
(BundleStatusProvider) TestUtils.getInstanceField("bundlePathManager", provider);
|
||||
List<BundlePath> paths = bundleStatusProvider.getModel().getPaths();
|
||||
for (BundlePath path : paths) {
|
||||
File file = path.getPath().getFile(false);
|
||||
(BundleStatusProvider) TestUtils.getInstanceField("bundleStatusProvider", provider);
|
||||
List<ResourceFile> paths = bundleStatusProvider.getModel().getPaths();
|
||||
for (ResourceFile path : paths) {
|
||||
File file = path.getFile(false);
|
||||
File[] listFiles = file.listFiles();
|
||||
if (listFiles == null) {
|
||||
continue;
|
||||
|
@ -19,9 +19,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@ -32,7 +30,6 @@ import docking.action.DockingActionIf;
|
||||
import docking.widgets.filter.FilterTextField;
|
||||
import docking.widgets.list.ListPanel;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.plugin.core.script.osgi.BundleStatusProvider;
|
||||
import ghidra.app.script.GhidraScriptUtil;
|
||||
import ghidra.app.script.JavaScriptProvider;
|
||||
@ -286,13 +283,11 @@ public class GhidraScriptMgrPlugin3Test extends AbstractGhidraScriptMgrPluginTes
|
||||
|
||||
final BundleStatusProvider bundleStatusProvider = waitForComponentProvider(BundleStatusProvider.class);
|
||||
|
||||
final File dir = new File(getTestDirectoryPath() + "/test_scripts");
|
||||
dir.mkdirs();
|
||||
final ResourceFile dir = new ResourceFile(getTestDirectoryPath() + "/test_scripts");
|
||||
dir.getFile(false).mkdirs();
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
List<BundlePath> paths = bundleStatusProvider.getModel().getPaths();
|
||||
paths.add(0, new BundlePath(dir));
|
||||
bundleStatusProvider.getModel().setPaths(paths);
|
||||
bundleStatusProvider.getModel().insertPathForTesting(0, dir.getAbsolutePath());
|
||||
});
|
||||
waitForSwing();
|
||||
|
||||
@ -333,7 +328,7 @@ public class GhidraScriptMgrPlugin3Test extends AbstractGhidraScriptMgrPluginTes
|
||||
assertTrue(newScript.exists());
|
||||
|
||||
assertNotNull(newScript);
|
||||
assertEquals(dir, newScript.getParentFile().getFile(false));
|
||||
assertEquals(dir.getAbsolutePath(), newScript.getParentFile().getFile(false).getAbsolutePath());
|
||||
|
||||
newScript.delete();
|
||||
dir.delete();
|
||||
|
@ -28,7 +28,6 @@ import docking.widgets.tree.GTreeNode;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.console.ConsoleComponentProvider;
|
||||
import ghidra.app.plugin.core.script.*;
|
||||
import ghidra.app.plugin.core.script.osgi.BundlePath;
|
||||
import ghidra.app.plugin.core.script.osgi.BundleStatusProvider;
|
||||
import ghidra.app.script.GhidraScriptUtil;
|
||||
import ghidra.app.services.ConsoleService;
|
||||
@ -50,10 +49,10 @@ public class GhidraScriptMgrPluginScreenShots extends GhidraScreenShotGenerator
|
||||
|
||||
performAction("New", "GhidraScriptMgrPlugin", false);
|
||||
|
||||
JDialog d = waitForJDialog(null, "New Script: Type", 5000);
|
||||
JDialog d = waitForJDialog("New Script: Type");
|
||||
pressButtonByText(d, "OK");
|
||||
|
||||
d = waitForJDialog(null, "New Script", 5000);
|
||||
d = waitForJDialog("New Script");
|
||||
pressButtonByText(d, "OK");
|
||||
|
||||
captureIsolatedProvider(GhidraScriptEditorComponentProvider.class, 597, 600);
|
||||
@ -111,13 +110,13 @@ public class GhidraScriptMgrPluginScreenShots extends GhidraScreenShotGenerator
|
||||
|
||||
@Test
|
||||
public void testScript_Dirs() throws Exception {
|
||||
List<BundlePath> paths = new ArrayList<>();
|
||||
paths.add(new BundlePath("$USER_HOME/ghidra_scripts"));
|
||||
paths.add(new BundlePath("$GHIDRA_HOME/Features/Base/ghidra_scripts"));
|
||||
paths.add(new BundlePath("/User/defined/invalid/directory"));
|
||||
List<String> paths = new ArrayList<>();
|
||||
paths.add("$USER_HOME/ghidra_scripts");
|
||||
paths.add("$GHIDRA_HOME/Features/Base/ghidra_scripts");
|
||||
paths.add("/User/defined/invalid/directory");
|
||||
|
||||
BundleStatusProvider bundleStatusProvider = showProvider(BundleStatusProvider.class);
|
||||
bundleStatusProvider.getModel().setPaths(paths);
|
||||
bundleStatusProvider.getModel().setPathsForTesting(paths);
|
||||
|
||||
waitForComponentProvider(BundleStatusProvider.class);
|
||||
captureComponent(bundleStatusProvider.getComponent());
|
||||
|
Loading…
Reference in New Issue
Block a user