ghidra/Ghidra/Features/Base/developer_scripts/CleanupMergeDatabasesScript...

148 lines
4.4 KiB
Java

/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* 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.
*/
import ghidra.app.script.GhidraScript;
import ghidra.framework.data.ProjectFileManager;
import ghidra.framework.model.Project;
import ghidra.framework.store.FileSystem;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.framework.store.local.LocalFolderItem;
import java.io.IOException;
import java.lang.reflect.Method;
public class CleanupMergeDatabasesScript extends GhidraScript {
@Override
protected void run() throws Exception {
Project project = state.getProject();
ProjectFileManager fileMgr = (ProjectFileManager) project.getProjectData();
LocalFileSystem fs = (LocalFileSystem) fileMgr.getPrivateFileSystem();
int cnt = cleanupFolder(fs, "/");
if (cnt == 0) {
popup("No merge databases found");
}
else {
popup("Removed " + cnt + " merge databases");
}
}
private String getPath(String folderPath, String name) {
String path = FileSystem.SEPARATOR + name;
if (!FileSystem.SEPARATOR.equals(folderPath)) {
path = folderPath + path;
}
return path;
}
private int cleanupFolder(LocalFileSystem fs, String folderPath) throws IOException {
int cnt = 0;
for (String subfolderName : fs.getFolderNames(folderPath)) {
cnt += cleanupFolder(fs, getPath(folderPath, subfolderName));
}
// fs.getItemNames(folderPath, true)
String[] itemNames =
(String[]) invokeInstanceMethod("getItemNames", fs, new Class[] { String.class,
boolean.class }, new Object[] { folderPath, true });
for (String itemName : itemNames) {
if (!itemName.startsWith(LocalFileSystem.HIDDEN_ITEM_PREFIX)) {
continue;
}
println("Removing temp file: " + getPath(folderPath, itemName));
LocalFolderItem item = fs.getItem(folderPath, itemName);
if (item != null) {
// item.deleteContent();
invokeInstanceMethod("deleteContent", item, null, null);
}
else {
// make sure we get item out of index
//fs.deallocateItemStorage(folderPath, itemName);
invokeInstanceMethod("deallocateItemStorage", fs, new Class[] { String.class,
String.class }, new Object[] { folderPath, itemName });
}
++cnt;
}
return cnt;
}
private static Object invokeInstanceMethod(String methodName, Object ownerInstance,
Class<?>[] parameterTypes, Object[] args) throws RuntimeException {
if (ownerInstance == null) {
throw new NullPointerException("Owner of instance field cannot be null");
}
Class<?> objectClass =
(ownerInstance instanceof Class) ? (Class<?>) ownerInstance : ownerInstance.getClass();
Object result = null;
try {
// get the method object to call
Method method = locateMethodObjectOnClass(methodName, objectClass, parameterTypes);
if (method == null) {
throw new NoSuchMethodException("Unable to find a method by " + "the name \"" +
methodName + "\" on the class " + objectClass + " or any of its parent " +
"implementations.");
}
// make sure we have access
method.setAccessible(true);
// execute the method and get the result
result = method.invoke(ownerInstance, args);
}
catch (Exception e) {
throw new RuntimeException("Unable to use reflection to call " + "method: " +
methodName + " from class: " + objectClass, e);
}
return result;
}
private static Method locateMethodObjectOnClass(String methodName, Class<?> containingClass,
Class<?>[] parameterTypes) {
Method method = null;
try {
// if we get an exception here, then the current class does not
// declare the method, but its parent may
method = containingClass.getDeclaredMethod(methodName, parameterTypes);
}
catch (NoSuchMethodException nsme) {
// O.K., the method may be located on a parent class. So, we
// will call this method on the parent class
Class<?> parentClass = containingClass.getSuperclass();
if (parentClass != null) {
method = locateMethodObjectOnClass(methodName, parentClass, parameterTypes);
}
}
return method;
}
}