diff --git a/Ghidra/Features/Base/ghidra_scripts/FixupCompositeDataTypesScript.java b/Ghidra/Features/Base/ghidra_scripts/FixupCompositeDataTypesScript.java index d58ce6ec9c..f060066835 100644 --- a/Ghidra/Features/Base/ghidra_scripts/FixupCompositeDataTypesScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/FixupCompositeDataTypesScript.java @@ -23,25 +23,84 @@ // // This script can be run multiple times without harm //@category Data Types +import java.util.ArrayList; + import ghidra.app.script.GhidraScript; -import ghidra.program.database.data.DataTypeManagerDB; +import ghidra.app.services.DataTypeManagerService; +import ghidra.framework.model.DomainFile; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.database.data.*; +import ghidra.program.model.data.BuiltInDataTypeManager; +import ghidra.program.model.data.DataTypeManager; +import ghidra.program.model.listing.Program; public class FixupCompositeDataTypesScript extends GhidraScript { @Override protected void run() throws Exception { - if (currentProgram == null) { + PluginTool tool = state.getTool(); + if (tool == null) { + print("This script does not support headless use"); + } + + DataTypeManagerService service = tool.getService(DataTypeManagerService.class); + if (service == null) { + popup("This script requires the DataTypeManagerService"); return; } - if (!currentProgram.hasExclusiveAccess()) { - popup("This script requires an exclusive checkout of the program"); + ArrayList dtms = new ArrayList<>(); + + for (DataTypeManager dtm : service.getDataTypeManagers()) { + if (dtm instanceof BuiltInDataTypeManager) { + continue; + } + if (dtm instanceof ProgramDataTypeManager) { + dtms.add(0, new DTMWrapper((ProgramDataTypeManager) dtm)); + } + else if (dtm instanceof DataTypeManagerDB) { + dtms.add(new DTMWrapper((DataTypeManagerDB) dtm)); + } + } + + DataTypeManagerDB dtm = + askChoice("Fixup All Composites", "Select Data Type Manager: ", dtms, dtms.get(0)).dtm; + + if (dtm instanceof ProgramDataTypeManager) { + Program program = ((ProgramDataTypeManager) dtm).getProgram(); + if (!program.hasExclusiveAccess()) { + popup("Shared program must have an exclusive checkout."); + return; + } + } + else if (dtm instanceof ProjectDataTypeManager) { + DomainFile df = ((ProjectDataTypeManager) dtm).getDomainFile(); + if (df.isVersioned() && !df.isCheckedOutExclusive()) { + popup("Shared project archive must have an exclusive checkout."); + return; + } + } + + if (!dtm.isUpdatable()) { + popup("Selected archive must be open for update."); return; } - DataTypeManagerDB dtm = (DataTypeManagerDB) currentProgram.getDataTypeManager(); dtm.fixupComposites(monitor); } + private class DTMWrapper { + DataTypeManagerDB dtm; + + DTMWrapper(DataTypeManagerDB dtm) { + this.dtm = dtm; + } + + @Override + public String toString() { + return dtm.getName(); + } + } + }