GP-2509 GP-2644 Improved Ghidra URL support. Added support for Ghidra

URL linked files and folders within project.
This commit is contained in:
ghidra1 2022-08-30 18:31:11 -04:00
parent 8d6cf5e310
commit 5a422c4502
153 changed files with 7083 additions and 1732 deletions

View file

@ -24,7 +24,8 @@ import db.DBHandle;
import db.buffers.BufferFile;
import db.buffers.ManagedBufferFile;
import generic.theme.GIcon;
import ghidra.framework.data.*;
import ghidra.framework.data.DBContentHandler;
import ghidra.framework.data.DomainObjectMergeManager;
import ghidra.framework.model.ChangeSet;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.*;
@ -39,13 +40,19 @@ import ghidra.util.task.TaskMonitor;
* and FolderItem storage. This class also produces the appropriate Icon for
* DataTypeArchive files.
*/
public class DataTypeArchiveContentHandler extends DBContentHandler {
public class DataTypeArchiveContentHandler extends DBContentHandler<DataTypeArchiveDB> {
private static Icon DATA_TYPE_ARCHIVE_ICON;
static Icon DATA_TYPE_ARCHIVE_ICON = new GIcon("icon.content.handler.archive.dt");
private final static String PROGRAM_ICON_ID = "icon.content.handler.archive.dt";
public final static String DATA_TYPE_ARCHIVE_CONTENT_TYPE = "Archive";
final static Class<DataTypeArchiveDB> DATA_TYPE_ARCHIVE_DOMAIN_OBJECT_CLASS =
DataTypeArchiveDB.class;
final static String DATA_TYPE_ARCHIVE_CONTENT_DEFAULT_TOOL = "CodeBrowser";
private static final DataTypeArchiveLinkContentHandler linkHandler =
new DataTypeArchiveLinkContentHandler();
@Override
public long createFile(FileSystem fs, FileSystem userfs, String path, String name,
DomainObject obj, TaskMonitor monitor)
@ -59,7 +66,7 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
}
@Override
public DomainObjectAdapter getImmutableObject(FolderItem item, Object consumer, int version,
public DataTypeArchiveDB getImmutableObject(FolderItem item, Object consumer, int version,
int minChangeVersion, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
String contentType = item.getContentType();
@ -113,7 +120,7 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
}
@Override
public DomainObjectAdapter getReadOnlyObject(FolderItem item, int version, boolean okToUpgrade,
public DataTypeArchiveDB getReadOnlyObject(FolderItem item, int version, boolean okToUpgrade,
Object consumer, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
@ -168,7 +175,7 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
}
@Override
public DomainObjectAdapter getDomainObject(FolderItem item, FileSystem userfs, long checkoutId,
public DataTypeArchiveDB getDomainObject(FolderItem item, FileSystem userfs, long checkoutId,
boolean okToUpgrade, boolean recover, Object consumer, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
@ -323,8 +330,8 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
}
@Override
public Class<? extends DomainObject> getDomainObjectClass() {
return DataTypeArchiveDB.class;
public Class<DataTypeArchiveDB> getDomainObjectClass() {
return DATA_TYPE_ARCHIVE_DOMAIN_OBJECT_CLASS;
}
@Override
@ -339,16 +346,11 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
@Override
public String getDefaultToolName() {
return "CodeBrowser";
return DATA_TYPE_ARCHIVE_CONTENT_DEFAULT_TOOL;
}
@Override
public Icon getIcon() {
synchronized (DataTypeArchiveContentHandler.class) {
if (DATA_TYPE_ARCHIVE_ICON == null) {
DATA_TYPE_ARCHIVE_ICON = new GIcon(PROGRAM_ICON_ID);
}
}
return DATA_TYPE_ARCHIVE_ICON;
}
@ -364,4 +366,9 @@ public class DataTypeArchiveContentHandler extends DBContentHandler {
originalObj, latestObj);
}
@Override
public DataTypeArchiveLinkContentHandler getLinkHandler() {
return linkHandler;
}
}

View file

@ -0,0 +1,71 @@
/* ###
* 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.program.database;
import java.io.IOException;
import javax.swing.Icon;
import ghidra.framework.data.LinkHandler;
import ghidra.framework.data.URLLinkObject;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.FileSystem;
import ghidra.util.InvalidNameException;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class DataTypeArchiveLinkContentHandler extends LinkHandler<DataTypeArchiveDB> {
public static final String ARCHIVE_LINK_CONTENT_TYPE = "ArchiveLink";
@Override
public long createFile(FileSystem fs, FileSystem userfs, String path, String name,
DomainObject obj, TaskMonitor monitor)
throws IOException, InvalidNameException, CancelledException {
if (!(obj instanceof URLLinkObject)) {
throw new IOException("Unsupported domain object: " + obj.getClass().getName());
}
return createFile((URLLinkObject) obj, ARCHIVE_LINK_CONTENT_TYPE, fs, path, name,
monitor);
}
@Override
public String getContentType() {
return ARCHIVE_LINK_CONTENT_TYPE;
}
@Override
public String getContentTypeDisplayString() {
return "Data Type Archive Link";
}
@Override
public Class<DataTypeArchiveDB> getDomainObjectClass() {
// return linked content class
return DataTypeArchiveContentHandler.DATA_TYPE_ARCHIVE_DOMAIN_OBJECT_CLASS;
}
@Override
public Icon getIcon() {
return DataTypeArchiveContentHandler.DATA_TYPE_ARCHIVE_ICON;
}
@Override
public String getDefaultToolName() {
return DataTypeArchiveContentHandler.DATA_TYPE_ARCHIVE_CONTENT_DEFAULT_TOOL;
}
}

View file

@ -23,7 +23,8 @@ import db.*;
import db.buffers.BufferFile;
import db.buffers.ManagedBufferFile;
import generic.theme.GIcon;
import ghidra.framework.data.*;
import ghidra.framework.data.DBWithUserDataContentHandler;
import ghidra.framework.data.DomainObjectMergeManager;
import ghidra.framework.model.ChangeSet;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.*;
@ -38,11 +39,16 @@ import ghidra.util.task.TaskMonitor;
* and FolderItem storage. This class also produces the appropriate Icon for
* Program files.
*/
public class ProgramContentHandler extends DBContentHandler {
public class ProgramContentHandler extends DBWithUserDataContentHandler<ProgramDB> {
public static final String PROGRAM_CONTENT_TYPE = "Program";
public static Icon PROGRAM_ICON = new GIcon("icon.content.handler.program");
public static final String PROGRAM_CONTENT_TYPE = "Program";
static final Class<ProgramDB> PROGRAM_DOMAIN_OBJECT_CLASS = ProgramDB.class;
static final String PROGRAM_CONTENT_DEFAULT_TOOL = "CodeBrowser";
private static final ProgramLinkContentHandler linkHandler = new ProgramLinkContentHandler();
@Override
public long createFile(FileSystem fs, FileSystem userfs, String path, String name,
@ -52,11 +58,12 @@ public class ProgramContentHandler extends DBContentHandler {
if (!(obj instanceof ProgramDB)) {
throw new IOException("Unsupported domain object: " + obj.getClass().getName());
}
return createFile((ProgramDB) obj, PROGRAM_CONTENT_TYPE, fs, path, name, monitor);
return createFile((ProgramDB) obj, PROGRAM_CONTENT_TYPE, fs, path, name,
monitor);
}
@Override
public DomainObjectAdapter getImmutableObject(FolderItem item, Object consumer, int version,
public ProgramDB getImmutableObject(FolderItem item, Object consumer, int version,
int minChangeVersion, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
String contentType = item.getContentType();
@ -107,7 +114,7 @@ public class ProgramContentHandler extends DBContentHandler {
}
@Override
public DomainObjectAdapter getReadOnlyObject(FolderItem item, int version, boolean okToUpgrade,
public ProgramDB getReadOnlyObject(FolderItem item, int version, boolean okToUpgrade,
Object consumer, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
@ -161,7 +168,7 @@ public class ProgramContentHandler extends DBContentHandler {
}
@Override
public DomainObjectAdapter getDomainObject(FolderItem item, FileSystem userfs, long checkoutId,
public ProgramDB getDomainObject(FolderItem item, FileSystem userfs, long checkoutId,
boolean okToUpgrade, boolean recover, Object consumer, TaskMonitor monitor)
throws IOException, VersionException, CancelledException {
@ -316,8 +323,8 @@ public class ProgramContentHandler extends DBContentHandler {
}
@Override
public Class<? extends DomainObject> getDomainObjectClass() {
return ProgramDB.class;
public Class<ProgramDB> getDomainObjectClass() {
return PROGRAM_DOMAIN_OBJECT_CLASS;
}
@Override
@ -327,12 +334,12 @@ public class ProgramContentHandler extends DBContentHandler {
@Override
public String getContentTypeDisplayString() {
return "Program";
return PROGRAM_CONTENT_TYPE;
}
@Override
public String getDefaultToolName() {
return "CodeBrowser";
return PROGRAM_CONTENT_DEFAULT_TOOL;
}
@Override
@ -352,4 +359,9 @@ public class ProgramContentHandler extends DBContentHandler {
originalObj, latestObj);
}
@Override
public ProgramLinkContentHandler getLinkHandler() {
return linkHandler;
}
}

View file

@ -0,0 +1,71 @@
/* ###
* 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.program.database;
import java.io.IOException;
import javax.swing.Icon;
import ghidra.framework.data.LinkHandler;
import ghidra.framework.data.URLLinkObject;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.FileSystem;
import ghidra.util.InvalidNameException;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class ProgramLinkContentHandler extends LinkHandler<ProgramDB> {
public static final String PROGRAM_LINK_CONTENT_TYPE = "ProgramLink";
@Override
public long createFile(FileSystem fs, FileSystem userfs, String path, String name,
DomainObject obj, TaskMonitor monitor)
throws IOException, InvalidNameException, CancelledException {
if (!(obj instanceof URLLinkObject)) {
throw new IOException("Unsupported domain object: " + obj.getClass().getName());
}
return createFile((URLLinkObject) obj, PROGRAM_LINK_CONTENT_TYPE, fs, path, name,
monitor);
}
@Override
public String getContentType() {
return PROGRAM_LINK_CONTENT_TYPE;
}
@Override
public String getContentTypeDisplayString() {
return PROGRAM_LINK_CONTENT_TYPE;
}
@Override
public Class<ProgramDB> getDomainObjectClass() {
// return linked content class
return ProgramContentHandler.PROGRAM_DOMAIN_OBJECT_CLASS;
}
@Override
public Icon getIcon() {
return ProgramContentHandler.PROGRAM_ICON;
}
@Override
public String getDefaultToolName() {
return ProgramContentHandler.PROGRAM_CONTENT_DEFAULT_TOOL;
}
}

View file

@ -19,7 +19,6 @@ import java.io.IOException;
import java.util.*;
import db.*;
import ghidra.framework.data.ContentHandler;
import ghidra.framework.data.DomainObjectAdapterDB;
import ghidra.framework.store.FileSystem;
import ghidra.program.database.map.AddressMapDB;
@ -44,6 +43,8 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
// TODO: WARNING! This implementation does not properly handle undo/redo in terms of cache invalidation
private static ProgramContentHandler programContentHandler = new ProgramContentHandler();
/**
* DB_VERSION should be incremented any time a change is made to the overall
* database schema associated with any of the managers.
@ -669,10 +670,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
else {
FileSystem userfs = program.getAssociatedUserFilesystem();
if (userfs != null) {
ContentHandler contentHandler = getContentHandler(program);
if (contentHandler != null) {
contentHandler.saveUserDataFile(program, dbh, userfs, monitor);
}
programContentHandler.saveUserDataFile(program, dbh, userfs, monitor);
setChanged(false);
}
}