/* ### * 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 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 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 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, 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; } }