Files
ghidra/GhidraBuild/Skeleton/src/main/java/skeleton/SkeletonFileSystem.java
dev747368 0b1398c5a8 GP-5208 improve library name lookups
Expose the nameComparator feature in Gfilesystems to allow
faster lookups of libraries (especially on windows where
isDirectory is 10x slower)
2024-12-27 10:37:35 -05:00

185 lines
5.3 KiB
Java

/* ###
* 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 skeleton;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.ByteProviderWrapper;
import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider;
import ghidra.formats.gfilesystem.factory.GFileSystemProbeByteProvider;
import ghidra.formats.gfilesystem.fileinfo.FileAttributeType;
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* Provide class-level documentation that describes what this file system does.
*/
@FileSystemInfo(type = "fstypegoeshere", // ([a-z0-9]+ only)
description = "File system description goes here", factory = SkeletonFileSystem.MyFileSystemFactory.class)
public class SkeletonFileSystem implements GFileSystem {
private final FSRLRoot fsFSRL;
private FileSystemIndexHelper<MyMetadata> fsih;
private FileSystemRefManager refManager = new FileSystemRefManager(this);
private ByteProvider provider;
/**
* File system constructor.
*
* @param fsFSRL The root {@link FSRL} of the file system.
* @param provider The file system provider.
*/
public SkeletonFileSystem(FSRLRoot fsFSRL, ByteProvider provider) {
this.fsFSRL = fsFSRL;
this.provider = provider;
this.fsih = new FileSystemIndexHelper<>(this, fsFSRL);
}
/**
* Mounts (opens) the file system.
*
* @param monitor A cancellable task monitor.
*/
public void mount(TaskMonitor monitor) {
monitor.setMessage("Opening " + SkeletonFileSystem.class.getSimpleName() + "...");
// Customize how things in the file system are stored. The following should be
// treated as pseudo-code.
for (MyMetadata metadata : new MyMetadata[10]) {
if (monitor.isCancelled()) {
break;
}
fsih.storeFile(metadata.path, fsih.getFileCount(), false, metadata.size, metadata);
}
}
@Override
public void close() throws IOException {
refManager.onClose();
if (provider != null) {
provider.close();
provider = null;
}
fsih.clear();
}
@Override
public String getName() {
return fsFSRL.getContainer().getName();
}
@Override
public FSRLRoot getFSRL() {
return fsFSRL;
}
@Override
public boolean isClosed() {
return provider == null;
}
@Override
public int getFileCount() {
return fsih.getFileCount();
}
@Override
public FileSystemRefManager getRefManager() {
return refManager;
}
@Override
public GFile lookup(String path) throws IOException {
return fsih.lookup(path);
}
@Override
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
return fsih.lookup(null, path, nameComp);
}
@Override
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
throws IOException, CancelledException {
// Get an ByteProvider for a file. The following is an example of how the metadata
// might be used to get an sub-ByteProvider from a stored provider offset.
MyMetadata metadata = fsih.getMetadata(file);
return (metadata != null)
? new ByteProviderWrapper(provider, metadata.offset, metadata.size, file.getFSRL())
: null;
}
@Override
public List<GFile> getListing(GFile directory) throws IOException {
return fsih.getListing(directory);
}
@Override
public FileAttributes getFileAttributes(GFile file, TaskMonitor monitor) {
MyMetadata metadata = fsih.getMetadata(file);
FileAttributes result = new FileAttributes();
if (metadata != null) {
result.add(FileAttributeType.NAME_ATTR, metadata.name);
result.add(FileAttributeType.SIZE_ATTR, metadata.size);
}
return result;
}
// Customize for the real file system.
public static class MyFileSystemFactory
implements GFileSystemFactoryByteProvider<SkeletonFileSystem>,
GFileSystemProbeByteProvider {
@Override
public SkeletonFileSystem create(FSRLRoot targetFSRL,
ByteProvider byteProvider, FileSystemService fsService, TaskMonitor monitor)
throws IOException, CancelledException {
SkeletonFileSystem fs = new SkeletonFileSystem(targetFSRL, byteProvider);
fs.mount(monitor);
return fs;
}
@Override
public boolean probe(ByteProvider byteProvider, FileSystemService fsService,
TaskMonitor monitor) throws IOException, CancelledException {
// Quickly and efficiently examine the bytes in 'byteProvider' to determine if
// it's a valid file system. If it is, return true.
return false;
}
}
// Customize with metadata from files in the real file system. This is just a stub.
// The elements of the file system will most likely be modeled by Java classes external to this
// file.
private static class MyMetadata {
private String name;
private String path;
private long offset;
private long size;
}
}