GT-2758 - fix and normalize GFileSystem.getInfo()

Remove unnecessary boilerplate impls that returned null.
Build info string better, handle the GTree node where a sub-file system
is mounted so that both are included in the info display.
Fix missing img3 icon.
This commit is contained in:
dev747368 2019-04-17 13:51:47 -04:00
parent 4ce178c419
commit 203dacdecc
36 changed files with 290 additions and 343 deletions

View file

@ -14,7 +14,7 @@
<file_extension extension=".h" icon="images/oxygen/16x16/text-x-chdr.png" /> <file_extension extension=".h" icon="images/oxygen/16x16/text-x-chdr.png" />
<file_extension extension=".html" icon="images/famfamfam_silk_icons_v013/html.png" /> <file_extension extension=".html" icon="images/famfamfam_silk_icons_v013/html.png" />
<file_extension extension=".img" icon="images/famfamfam_silk_icons_v013/images.png" /> <file_extension extension=".img" icon="images/famfamfam_silk_icons_v013/images.png" />
<file_extension extension=".img3" icon="images/famfamfam_silk_icons_v013/bullet-orange.png" /> <file_extension extension=".img3" icon="images/famfamfam_silk_icons_v013/bullet_orange.png" />
<file_extension extension=".index" icon="images/oxygen/16x16/bookmarks.png" /> <file_extension extension=".index" icon="images/oxygen/16x16/bookmarks.png" />
<file_extension extension=".ipsw" icon="images/oxygen/16x16/multimedia-player-apple-ipod.png" /> <file_extension extension=".ipsw" icon="images/oxygen/16x16/multimedia-player-apple-ipod.png" />
<file_extension extension=".iso" icon="images/nuvola/16x16/cdimage.png" /> <file_extension extension=".iso" icon="images/nuvola/16x16/cdimage.png" />

View file

@ -108,7 +108,7 @@ public class FileSystemIndexHelper<METADATATYPE> {
* @return {@link GFile} instance or null if no file was added to the index at that path. * @return {@link GFile} instance or null if no file was added to the index at that path.
*/ */
public GFile lookup(String path) { public GFile lookup(String path) {
String[] nameparts = path.split("/"); String[] nameparts = (path != null ? path : "").split("/");
GFile parent = lookupParent(nameparts); GFile parent = lookupParent(nameparts);
if (nameparts.length == 0) { if (nameparts.length == 0) {
return parent; return parent;

View file

@ -15,14 +15,14 @@
*/ */
package ghidra.formats.gfilesystem; package ghidra.formats.gfilesystem;
import java.io.*;
import java.util.List;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo; import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.util.classfinder.ExtensionPoint; import ghidra.util.classfinder.ExtensionPoint;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import java.io.*;
import java.util.List;
/** /**
* Interface that represents a filesystem that contains files. * Interface that represents a filesystem that contains files.
* <p> * <p>
@ -155,9 +155,10 @@ public interface GFileSystem extends Closeable, ExtensionPoint {
* <p> * <p>
* @param file {@link GFile} to get info message for. * @param file {@link GFile} to get info message for.
* @param monitor {@link TaskMonitor} to watch and update progress. * @param monitor {@link TaskMonitor} to watch and update progress.
* @return multi-line formatted string with info about the file. * @return multi-line formatted string with info about the file, or null.
* @throws IOException if IO problem.
*/ */
public String getInfo(GFile file, TaskMonitor monitor) throws IOException; default public String getInfo(GFile file, TaskMonitor monitor) {
return null;
}
} }

View file

@ -129,9 +129,6 @@ public abstract class GFileSystemBase implements GFileSystem {
@Override @Override
abstract public List<GFile> getListing(GFile directory) throws IOException; abstract public List<GFile> getListing(GFile directory) throws IOException;
@Override
abstract public String getInfo(GFile file, TaskMonitor monitor) throws IOException;
/** /**
* Legacy implementation of {@link #getInputStream(GFile, TaskMonitor)}. * Legacy implementation of {@link #getInputStream(GFile, TaskMonitor)}.
* *

View file

@ -130,15 +130,20 @@ public class LocalFileSystemSub implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
try {
File localFile = getFileFromGFile(file); File localFile = getFileFromGFile(file);
StringBuilder buffer = new StringBuilder();
StringBuffer buffer = new StringBuffer();
buffer.append("Name: " + localFile.getName() + "\n"); buffer.append("Name: " + localFile.getName() + "\n");
buffer.append("Size: " + localFile.length() + "\n"); buffer.append("Size: " + localFile.length() + "\n");
buffer.append("Date: " + new Date(localFile.lastModified()).toString() + "\n"); buffer.append("Date: " + new Date(localFile.lastModified()).toString() + "\n");
return buffer.toString(); return buffer.toString();
} }
catch (IOException e) {
// fail and return null
}
return null;
}
@Override @Override
public String getName() { public String getName() {

View file

@ -472,42 +472,50 @@ class FSBActionManager {
* @param monitor {@link TaskMonitor} to monitor and update when accessing the filesystems. * @param monitor {@link TaskMonitor} to monitor and update when accessing the filesystems.
*/ */
private void showInfoForFile(FSRL fsrl, TaskMonitor monitor) { private void showInfoForFile(FSRL fsrl, TaskMonitor monitor) {
String title = " no title "; String title;
String info = " no information available "; String info;
String fileSystemName = " unknown ";
if (fsrl != null) { if (fsrl != null) {
info = "";
title = "Info about " + fsrl.getName();
if (fsrl instanceof FSRLRoot && ((FSRLRoot) fsrl).hasContainer()) { if (fsrl instanceof FSRLRoot && ((FSRLRoot) fsrl).hasContainer()) {
fsrl = ((FSRLRoot) fsrl).getContainer(); FSRL containerFSRL = ((FSRLRoot) fsrl).getContainer();
title = containerFSRL.getName();
info = getInfoStringFor(containerFSRL, monitor);
info += "------------------------------------\n";
} }
info += getInfoStringFor(fsrl, monitor);
}
else {
title = "Missing File";
info = "Unable to retrieve information";
}
MultiLineMessageDialog.showMessageDialog(plugin.getTool().getActiveWindow(), title, null,
info, MultiLineMessageDialog.INFORMATION_MESSAGE);
}
private String getInfoStringFor(FSRL fsrl, TaskMonitor monitor) {
try (RefdFile refdFile = FileSystemService.getInstance().getRefdFile(fsrl, monitor)) { try (RefdFile refdFile = FileSystemService.getInstance().getRefdFile(fsrl, monitor)) {
title = fsrl.getName();
GFileSystem fs = refdFile.fsRef.getFilesystem(); GFileSystem fs = refdFile.fsRef.getFilesystem();
fileSystemName = fs.getDescription(); String result = "File system: " + fs.getDescription() + "\n";
info = "FSRL: " + fsrl + "\n"; result += "FSRL: " + fsrl + "\n";
DomainFile associatedDomainFile = DomainFile associatedDomainFile = ProgramMappingService.getCachedDomainFileFor(fsrl);
ProgramMappingService.getCachedDomainFileFor(fsrl);
if (associatedDomainFile != null) { if (associatedDomainFile != null) {
info = info + "Project file: " + associatedDomainFile.getPathname() + "\n"; result += "Project file: " + associatedDomainFile.getPathname() + "\n";
} }
String nodeInfo = fs.getInfo(refdFile.file, monitor); String nodeInfo = fs.getInfo(refdFile.file, monitor);
if (nodeInfo != null) { if (nodeInfo != null) {
info += nodeInfo; result += nodeInfo;
} }
return result;
} }
catch (IOException | CancelledException e) { catch (IOException | CancelledException e) {
info = "Error retrieving information: " + e.getMessage(); return "Error retrieving information: " + e.getMessage() + "\n";
} }
} }
MultiLineMessageDialog.showMessageDialog(plugin.getTool().getActiveWindow(),
"Info about " + title, null, "File system: " + fileSystemName + '\n' + info,
MultiLineMessageDialog.INFORMATION_MESSAGE);
}
/** /**
* Shows a list of supported file system types and loaders. * Shows a list of supported file system types and loaders.
*/ */

View file

@ -55,11 +55,6 @@ public class ApkFileSystem extends GFileSystemBase {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
protected InputStream getData(GFile file, TaskMonitor monitor) protected InputStream getData(GFile file, TaskMonitor monitor)
throws IOException, CancelledException, CryptoException { throws IOException, CancelledException, CryptoException {

View file

@ -86,7 +86,7 @@ public class BootImageFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
if (file == kernelFile) { if (file == kernelFile) {
return "This is the actual KERNEL for the android device. You can analyze this file."; return "This is the actual KERNEL for the android device. You can analyze this file.";
} }

View file

@ -175,9 +175,4 @@ public class DexToJarFileSystem extends GFileSystemBase {
public void close() throws IOException { public void close() throws IOException {
super.close(); super.close();
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
} }

View file

@ -146,7 +146,6 @@ public class DexToSmaliFileSystem extends GFileSystemBase {
} }
} }
private void storeFile(GFile file, File entry) { private void storeFile(GFile file, File entry) {
if (file == null) { if (file == null) {
return; return;
@ -166,11 +165,6 @@ public class DexToSmaliFileSystem extends GFileSystemBase {
map.clear(); map.clear();
super.close(); super.close();
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
} }
/* DexHeader header = new DexHeader(provider); /* DexHeader header = new DexHeader(provider);

View file

@ -95,11 +95,6 @@ public class KernelFileSystem extends GFileSystemBase {
: Collections.emptyList(); : Collections.emptyList();
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
protected InputStream getData(GFile file, TaskMonitor monitor) protected InputStream getData(GFile file, TaskMonitor monitor)
throws IOException, CancelledException, CryptoException { throws IOException, CancelledException, CryptoException {

View file

@ -64,7 +64,7 @@ public class OdexFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Magic: " + odexHeader.getMagic()).append("\n"); builder.append("Magic: " + odexHeader.getMagic()).append("\n");
builder.append("Dex Offset: " + Integer.toHexString(odexHeader.getDexOffset())).append( builder.append("Dex Offset: " + Integer.toHexString(odexHeader.getDexOffset())).append(

View file

@ -96,11 +96,6 @@ public class AndroidXmlFileSystem extends GFileSystemBase {
return new ByteArrayInputStream(payloadBytes); return new ByteArrayInputStream(payloadBytes);
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
public List<GFile> getListing(GFile directory) throws IOException { public List<GFile> getListing(GFile directory) throws IOException {
List<GFile> tmp = new ArrayList<>(); List<GFile> tmp = new ArrayList<>();

View file

@ -104,7 +104,7 @@ public class CoffArchiveFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
CoffArchiveMemberHeader entry = fsih.getMetadata(file); CoffArchiveMemberHeader entry = fsih.getMetadata(file);
return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry)); return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry));
} }

View file

@ -55,11 +55,6 @@ public class CompLzssFileSystem extends GFileSystemBase {
return null; return null;
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
public List<GFile> getListing(GFile directory) throws IOException { public List<GFile> getListing(GFile directory) throws IOException {
return (directory == null || directory.equals(root)) ? Arrays.asList(decompressedFile) return (directory == null || directory.equals(root)) ? Arrays.asList(decompressedFile)

View file

@ -107,9 +107,9 @@ public class CpioFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
CpioArchiveEntry entry = map.get(file); CpioArchiveEntry entry = map.get(file);
StringBuffer buffer = new StringBuffer(); StringBuilder buffer = new StringBuilder();
try { try {
buffer.append("Name: " + entry.getName() + "\n"); buffer.append("Name: " + entry.getName() + "\n");
buffer.append("Checksum: " + Long.toHexString(entry.getChksum()) + "\n"); buffer.append("Checksum: " + Long.toHexString(entry.getChksum()) + "\n");
@ -126,6 +126,7 @@ public class CpioFileSystem extends GFileSystemBase {
buffer.append("Device ID: " + Long.toHexString(entry.getDevice()) + "\n"); buffer.append("Device ID: " + Long.toHexString(entry.getDevice()) + "\n");
} }
catch (Exception e) { catch (Exception e) {
// ignore
} }
return buffer.toString(); return buffer.toString();
} }

View file

@ -62,7 +62,8 @@ public class Ext4FileSystem implements GFileSystem {
numGroups++; numGroups++;
} }
boolean is64Bit = ( superBlock.getS_desc_size( ) > 32 ) && ( ( superBlock.getS_feature_incompat( ) & 0x80 ) > 0 ); boolean is64Bit =
(superBlock.getS_desc_size() > 32) && ((superBlock.getS_feature_incompat() & 0x80) > 0);
int groupDescriptorOffset = blockSize; int groupDescriptorOffset = blockSize;
reader.setPointerIndex(groupDescriptorOffset); reader.setPointerIndex(groupDescriptorOffset);
@ -90,13 +91,9 @@ public class Ext4FileSystem implements GFileSystem {
} }
} }
private void processDirectory( BinaryReader reader, private void processDirectory(BinaryReader reader, Ext4SuperBlock superBlock,
Ext4SuperBlock superBlock, Ext4Inode[] inodes, int index, String name, GFile parent, TaskMonitor monitor)
Ext4Inode[] inodes, throws IOException, CancelledException {
int index,
String name,
GFile parent,
TaskMonitor monitor ) throws IOException, CancelledException {
if (name != null && (name.equals(".") || name.equals(".."))) { if (name != null && (name.equals(".") || name.equals(".."))) {
return; return;
@ -109,12 +106,14 @@ public class Ext4FileSystem implements GFileSystem {
if (parent == null) { if (parent == null) {
parent = fsih.getRootDir(); parent = fsih.getRootDir();
} }
parent = fsih.storeFileWithParent( name, parent, -1, true, ( inode.getI_size_high( ) << 32 ) | inode.getI_size_lo( ), new Ext4File( name, inode ) ); parent = fsih.storeFileWithParent(name, parent, -1, true,
(inode.getI_size_high() << 32) | inode.getI_size_lo(), new Ext4File(name, inode));
} }
if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) == 0) { if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) == 0) {
return; return;
} }
boolean isDirEntry2 = ( superBlock.getS_feature_incompat( ) & Ext4Constants.INCOMPAT_FILETYPE ) != 0; boolean isDirEntry2 =
(superBlock.getS_feature_incompat() & Ext4Constants.INCOMPAT_FILETYPE) != 0;
// if uses extents // if uses extents
if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) != 0) { if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) != 0) {
Ext4IBlock i_block = inode.getI_block(); Ext4IBlock i_block = inode.getI_block();
@ -126,13 +125,9 @@ public class Ext4FileSystem implements GFileSystem {
inodes[index] = null; inodes[index] = null;
} }
private void processIBlock( BinaryReader reader, private void processIBlock(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode[] inodes,
Ext4SuperBlock superBlock, GFile parent, boolean isDirEntry2, Ext4IBlock i_block, TaskMonitor monitor)
Ext4Inode[] inodes, throws CancelledException, IOException {
GFile parent,
boolean isDirEntry2,
Ext4IBlock i_block,
TaskMonitor monitor ) throws CancelledException, IOException {
Ext4ExtentHeader header = i_block.getHeader(); Ext4ExtentHeader header = i_block.getHeader();
if (header.getEh_depth() == 0) { if (header.getEh_depth() == 0) {
short numEntries = header.getEh_entries(); short numEntries = header.getEh_entries();
@ -171,18 +166,15 @@ public class Ext4FileSystem implements GFileSystem {
reader.setPointerIndex(offset); reader.setPointerIndex(offset);
Ext4IBlock intermediateBlock = new Ext4IBlock(reader, true); Ext4IBlock intermediateBlock = new Ext4IBlock(reader, true);
processIBlock( reader, superBlock, inodes, parent, isDirEntry2, intermediateBlock, monitor ); processIBlock(reader, superBlock, inodes, parent, isDirEntry2, intermediateBlock,
monitor);
} }
} }
} }
private void processDirEntry( BinaryReader reader, private void processDirEntry(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode[] inodes,
Ext4SuperBlock superBlock, GFile parent, TaskMonitor monitor, Ext4Extent extent, long offset)
Ext4Inode [] inodes, throws CancelledException, IOException {
GFile parent,
TaskMonitor monitor,
Ext4Extent extent,
long offset ) throws CancelledException, IOException {
while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) { while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) {
monitor.checkCanceled(); monitor.checkCanceled();
@ -195,25 +187,24 @@ public class Ext4FileSystem implements GFileSystem {
if ((child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR) { if ((child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR) {
String childName = dirEnt.getName(); String childName = dirEnt.getName();
long readerOffset = reader.getPointerIndex(); long readerOffset = reader.getPointerIndex();
processDirectory( reader, superBlock, inodes, childIndex, childName, parent, monitor ); processDirectory(reader, superBlock, inodes, childIndex, childName, parent,
monitor);
reader.setPointerIndex(readerOffset); reader.setPointerIndex(readerOffset);
} }
else if ( ( child.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFREG || ( child.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFLNK ) { else if ((child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFREG ||
(child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFLNK) {
storeFile(inodes, dirEnt, parent); storeFile(inodes, dirEnt, parent);
} }
else { else {
throw new IOException( "Inode " + dirEnt.getInode( ) + " has unhandled file type: " + ( child.getI_mode( ) & 0xF000 ) ); throw new IOException("Inode " + dirEnt.getInode() + " has unhandled file type: " +
(child.getI_mode() & 0xF000));
} }
} }
} }
private void processDirEntry2( BinaryReader reader, private void processDirEntry2(BinaryReader reader, Ext4SuperBlock superBlock,
Ext4SuperBlock superBlock, Ext4Inode[] inodes, GFile parent, TaskMonitor monitor, Ext4Extent extent, long offset)
Ext4Inode [] inodes, throws CancelledException, IOException {
GFile parent,
TaskMonitor monitor,
Ext4Extent extent,
long offset ) throws CancelledException, IOException {
while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) { while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) {
monitor.checkCanceled(); monitor.checkCanceled();
@ -225,14 +216,17 @@ public class Ext4FileSystem implements GFileSystem {
int childInode = dirEnt2.getInode(); int childInode = dirEnt2.getInode();
String childName = dirEnt2.getName(); String childName = dirEnt2.getName();
long readerOffset = reader.getPointerIndex(); long readerOffset = reader.getPointerIndex();
processDirectory( reader, superBlock, inodes, childInode, childName, parent, monitor ); processDirectory(reader, superBlock, inodes, childInode, childName, parent,
monitor);
reader.setPointerIndex(readerOffset); reader.setPointerIndex(readerOffset);
} }
else if ( dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_REGULAR_FILE || dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_SYMBOLIC_LINK ) { else if (dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_REGULAR_FILE ||
dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_SYMBOLIC_LINK) {
storeFile(inodes, dirEnt2, parent); storeFile(inodes, dirEnt2, parent);
} }
else { else {
throw new IOException( "Inode " + dirEnt2.getInode( ) + " has unhandled file type: " + dirEnt2.getFile_type( ) ); throw new IOException("Inode " + dirEnt2.getInode() + " has unhandled file type: " +
dirEnt2.getFile_type());
} }
} }
} }
@ -241,7 +235,8 @@ public class Ext4FileSystem implements GFileSystem {
int fileInodeNum = dirEnt.getInode(); int fileInodeNum = dirEnt.getInode();
Ext4Inode fileInode = inodes[fileInodeNum]; Ext4Inode fileInode = inodes[fileInodeNum];
long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo(); long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo();
fsih.storeFileWithParent( dirEnt.getName( ), parent, -1, ( fileInode.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFDIR, fileSize, fsih.storeFileWithParent(dirEnt.getName(), parent, -1,
(fileInode.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR, fileSize,
new Ext4File(dirEnt.getName(), fileInode)); new Ext4File(dirEnt.getName(), fileInode));
inodes[fileInodeNum] = null; inodes[fileInodeNum] = null;
} }
@ -253,11 +248,14 @@ public class Ext4FileSystem implements GFileSystem {
return;//TODO return;//TODO
} }
long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo(); long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo();
fsih.storeFileWithParent( dirEnt2.getName( ), parent, -1, dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_DIRECTORY, fileSize, new Ext4File( dirEnt2.getName( ), fileInode ) ); fsih.storeFileWithParent(dirEnt2.getName(), parent, -1,
dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_DIRECTORY, fileSize,
new Ext4File(dirEnt2.getName(), fileInode));
inodes[fileInodeNum] = null; inodes[fileInodeNum] = null;
} }
private void processFile( BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode inode, TaskMonitor monitor ) { private void processFile(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode inode,
TaskMonitor monitor) {
} }
@ -272,7 +270,7 @@ public class Ext4FileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
Ext4File ext4File = fsih.getMetadata(file); Ext4File ext4File = fsih.getMetadata(file);
if (ext4File == null) { if (ext4File == null) {
return null; return null;
@ -369,9 +367,11 @@ public class Ext4FileSystem implements GFileSystem {
* *
* TODO better memory management? currently loads entire file into memory. * TODO better memory management? currently loads entire file into memory.
*/ */
private InputStream concatenateExtents( List< Ext4Extent > entries, long actualSize ) throws IOException { private InputStream concatenateExtents(List<Ext4Extent> entries, long actualSize)
throws IOException {
if (actualSize > Integer.MAX_VALUE) { if (actualSize > Integer.MAX_VALUE) {
throw new IOException( "File is >2GB, too large to extract. Please report to Ghidra team." ); throw new IOException(
"File is >2GB, too large to extract. Please report to Ghidra team.");
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -397,11 +397,9 @@ public class Ext4FileSystem implements GFileSystem {
return new ByteArrayInputStream(baos.toByteArray(), 0, (int) actualSize); return new ByteArrayInputStream(baos.toByteArray(), 0, (int) actualSize);
} }
private Ext4Inode [] getInodes( BinaryReader reader, private Ext4Inode[] getInodes(BinaryReader reader, Ext4SuperBlock superBlock,
Ext4SuperBlock superBlock, Ext4GroupDescriptor[] groupDescriptors, boolean is64Bit, TaskMonitor monitor)
Ext4GroupDescriptor [] groupDescriptors, throws IOException, CancelledException {
boolean is64Bit,
TaskMonitor monitor ) throws IOException, CancelledException {
int inodeCount = superBlock.getS_inodes_count(); int inodeCount = superBlock.getS_inodes_count();
Ext4Inode[] inodes = new Ext4Inode[inodeCount + 1]; Ext4Inode[] inodes = new Ext4Inode[inodeCount + 1];
@ -411,12 +409,14 @@ public class Ext4FileSystem implements GFileSystem {
monitor.checkCanceled(); monitor.checkCanceled();
long inodeTableBlockOffset = groupDescriptors[i].getBg_inode_table_lo() & 0xffffffffL; long inodeTableBlockOffset = groupDescriptors[i].getBg_inode_table_lo() & 0xffffffffL;
if (is64Bit) { if (is64Bit) {
inodeTableBlockOffset = ( groupDescriptors[ i ].getBg_inode_table_hi( ) << 32 ) | inodeTableBlockOffset; inodeTableBlockOffset =
(groupDescriptors[i].getBg_inode_table_hi() << 32) | inodeTableBlockOffset;
} }
long offset = inodeTableBlockOffset * blockSize; long offset = inodeTableBlockOffset * blockSize;
reader.setPointerIndex(offset); reader.setPointerIndex(offset);
int inodesPerGroup = superBlock.getS_inodes_per_group(); int inodesPerGroup = superBlock.getS_inodes_per_group();
monitor.setMessage( "Reading inode table " + i + " of " + ( groupDescriptors.length - 1 ) + "..." ); monitor.setMessage(
"Reading inode table " + i + " of " + (groupDescriptors.length - 1) + "...");
monitor.setMaximum(inodesPerGroup); monitor.setMaximum(inodesPerGroup);
monitor.setProgress(0); monitor.setProgress(0);
for (int j = 0; j < inodesPerGroup; j++) { for (int j = 0; j < inodesPerGroup; j++) {

View file

@ -147,12 +147,11 @@ public class GZipFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
if (payload.equals(file)) { if (payload.equals(file)) {
return FSUtilities.infoMapToString(getInfoMap()); return FSUtilities.infoMapToString(getInfoMap());
} }
return null; return null;
} }
public Map<String, String> getInfoMap() { public Map<String, String> getInfoMap() {

View file

@ -81,9 +81,4 @@ public class Apple8900FileSystem extends GFileSystemBase {
dataFile = GFileImpl.fromFilename(this, root, "DATA", false, header.getSizeOfData(), null); dataFile = GFileImpl.fromFilename(this, root, "DATA", false, header.getSizeOfData(), null);
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
} }

View file

@ -15,16 +15,16 @@
*/ */
package ghidra.file.formats.ios.dmg; package ghidra.file.formats.ios.dmg;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import ghidra.formats.gfilesystem.*; import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo; import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.*; import ghidra.util.task.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/** /**
* A {@link GFileSystem} that uses an external DMG server process to parse DMG files * A {@link GFileSystem} that uses an external DMG server process to parse DMG files
* and presents the contents as a filesystem. * and presents the contents as a filesystem.
@ -200,7 +200,7 @@ public class DmgClientFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile gFile, TaskMonitor monitor) throws IOException { public String getInfo(GFile gFile, TaskMonitor monitor) {
monitor.addCancelledListener(listener); monitor.addCancelledListener(listener);
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();

View file

@ -111,11 +111,6 @@ public class DyldCacheFileSystem extends GFileSystemBase {
} }
*/ */
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
public List<GFile> getListing(GFile directory) throws IOException { public List<GFile> getListing(GFile directory) throws IOException {
if (directory == null || directory.equals(root)) { if (directory == null || directory.equals(root)) {

View file

@ -32,8 +32,8 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.exception.CryptoException; import ghidra.util.exception.CryptoException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@FileSystemInfo(type = "ibootim", description = "iOS " @FileSystemInfo(type = "ibootim", description = "iOS " +
+ iBootImConstants.SIGNATURE, factory = GFileSystemBaseFactory.class) iBootImConstants.SIGNATURE, factory = GFileSystemBaseFactory.class)
public class iBootImFileSystem extends GFileSystemBase implements GIconProvider { public class iBootImFileSystem extends GFileSystemBase implements GIconProvider {
private iBootImHeader header; private iBootImHeader header;
@ -59,19 +59,15 @@ public class iBootImFileSystem extends GFileSystemBase implements GIconProvider
public Icon getIcon(GFile file, TaskMonitor monitor) throws IOException, CancelledException { public Icon getIcon(GFile file, TaskMonitor monitor) throws IOException, CancelledException {
File cacheFile = fsService.getFile(file.getFSRL(), monitor); File cacheFile = fsService.getFile(file.getFSRL(), monitor);
try (InputStream cacheInputStream = new FileInputStream(cacheFile)) { try (InputStream cacheInputStream = new FileInputStream(cacheFile)) {
GImageFormat format = (header.getFormat() == iBootImConstants.FORMAT_ARGB) ? GImageFormat.RGB_ALPHA_4BYTE GImageFormat format =
(header.getFormat() == iBootImConstants.FORMAT_ARGB) ? GImageFormat.RGB_ALPHA_4BYTE
: GImageFormat.GRAY_ALPHA_2BYTE; : GImageFormat.GRAY_ALPHA_2BYTE;
GImage image = new GImage(header.getWidth(), header.getHeight(), format, cacheInputStream, GImage image = new GImage(header.getWidth(), header.getHeight(), format,
cacheFile.length()); cacheInputStream, cacheFile.length());
return image.toPNG(); return image.toPNG();
} }
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
public List<GFile> getListing(GFile directory) throws IOException { public List<GFile> getListing(GFile directory) throws IOException {
if (directory == null || directory.equals(root)) { if (directory == null || directory.equals(root)) {

View file

@ -55,11 +55,6 @@ public class Img2FileSystem extends GFileSystemBase {
return null; return null;
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
public List<GFile> getListing(GFile directory) throws IOException { public List<GFile> getListing(GFile directory) throws IOException {
return (directory == null || directory.equals(root)) ? Arrays.asList(imageTypeFile) return (directory == null || directory.equals(root)) ? Arrays.asList(imageTypeFile)

View file

@ -57,11 +57,6 @@ public class IpswFileSystem extends GFileSystemBase {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
return null;
}
@Override @Override
protected InputStream getData(GFile file, TaskMonitor monitor) protected InputStream getData(GFile file, TaskMonitor monitor)
throws IOException, CancelledException, CryptoException { throws IOException, CancelledException, CryptoException {

View file

@ -92,7 +92,7 @@ public class CrushedPNGFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
return png.toString(); return png.toString();
} }

View file

@ -118,12 +118,9 @@ public class PrelinkFileSystem extends GFileSystemBase implements GFileSystemPro
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
PrelinkMap info = fileToPrelinkInfoMap.get(file); PrelinkMap info = fileToPrelinkInfoMap.get(file);
if (info != null) { return (info != null) ? info.toString() : null;
return info.toString();
}
return null;
} }
@Override @Override

View file

@ -160,7 +160,7 @@ public class ISO9660FileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
ISO9660Directory dir = fileToDirectoryMap.get(file); ISO9660Directory dir = fileToDirectoryMap.get(file);
if (dir != null) { if (dir != null) {
return dir.toString(); return dir.toString();

View file

@ -139,7 +139,7 @@ public class JavaClassDecompilerFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
if (fsIndexHelper.getPayloadFile().equals(file)) { if (fsIndexHelper.getPayloadFile().equals(file)) {
Map<String, String> info = new HashMap<>(); Map<String, String> info = new HashMap<>();
info.put("Class name", className); info.put("Class name", className);

View file

@ -110,7 +110,7 @@ public class OmfArchiveFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
OmfLibraryRecord.MemberHeader entry = fsih.getMetadata(file); OmfLibraryRecord.MemberHeader entry = fsih.getMetadata(file);
return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry)); return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry));
} }

View file

@ -180,7 +180,7 @@ public class SevenZipFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
ISimpleInArchiveItem entry = map.get(file); ISimpleInArchiveItem entry = map.get(file);
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
try { try {

View file

@ -15,15 +15,15 @@
*/ */
package ghidra.file.formats.sparseimage; package ghidra.file.formats.sparseimage;
import java.io.*;
import java.util.*;
import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.ByteProvider;
import ghidra.formats.gfilesystem.*; import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo; import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import java.io.*;
import java.util.*;
/** /**
* A pseudo filesystem that contains a single file that is the decompressed contents * A pseudo filesystem that contains a single file that is the decompressed contents
* of the sparse container file. * of the sparse container file.
@ -123,7 +123,7 @@ public class SparseImageFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
if (payload.equals(file)) { if (payload.equals(file)) {
return FSUtilities.infoMapToString(getInfoMap()); return FSUtilities.infoMapToString(getInfoMap());
} }

View file

@ -15,17 +15,17 @@
*/ */
package ghidra.file.formats.tar; package ghidra.file.formats.tar;
import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/** /**
* TAR file system implementation. * TAR file system implementation.
* <p> * <p>
@ -169,12 +169,9 @@ public class TarFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
TarMetadata tmd = fsih.getMetadata(file); TarMetadata tmd = fsih.getMetadata(file);
if (tmd == null) { return (tmd != null) ? FSUtilities.infoMapToString(getInfoMap(tmd.tarArchiveEntry)) : null;
throw new IOException("Unknown file " + file);
}
return FSUtilities.infoMapToString(getInfoMap(tmd.tarArchiveEntry));
} }
@Override @Override

View file

@ -45,12 +45,9 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
int index = list.indexOf(file); int index = list.indexOf(file);
if (index == -1) { return (index != -1) ? header.getArchitectures().get(index).toString() : null;
return null;
}
return header.getArchitectures().get(index).toString();
} }
@Override @Override
@ -79,7 +76,8 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
Processor processor = Processor processor =
CpuTypes.getProcessor(architecture.getCpuType(), architecture.getCpuSubType()); CpuTypes.getProcessor(architecture.getCpuType(), architecture.getCpuSubType());
int bitSize = CpuTypes.getProcessorBitSize(architecture.getCpuType()); int bitSize = CpuTypes.getProcessorBitSize(architecture.getCpuType());
String name = processor + "-" + bitSize + "-cpu0x" + Integer.toHexString(architecture.getCpuSubType()); String name = processor + "-" + bitSize + "-cpu0x" +
Integer.toHexString(architecture.getCpuSubType());
GFileImpl file = GFileImpl file =
GFileImpl.fromFilename(this, root, name, false, architecture.getSize(), null); GFileImpl.fromFilename(this, root, name, false, architecture.getSize(), null);
list.add(file); list.add(file);
@ -100,7 +98,8 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
FatArch architecture = architectures.get(index); FatArch architecture = architectures.get(index);
return new BoundedInputStream(provider.getInputStream(architecture.getOffset()), architecture.getSize()); return new BoundedInputStream(provider.getInputStream(architecture.getOffset()),
architecture.getSize());
} }
@Override @Override

View file

@ -98,7 +98,7 @@ public class YAFFS2FileSystem extends GFileSystemBase {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
return "YAFFS2, Yet Another Flash File System V2, commonly used for Android System and UserData images."; return "YAFFS2, Yet Another Flash File System V2, commonly used for Android System and UserData images.";
} }

View file

@ -117,9 +117,9 @@ public class ZipFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
ZipEntry zipEntry = fsIndexHelper.getMetadata(file); ZipEntry zipEntry = fsIndexHelper.getMetadata(file);
return FSUtilities.infoMapToString(getInfoMap(zipEntry)); return (zipEntry != null) ? FSUtilities.infoMapToString(getInfoMap(zipEntry)) : null;
} }
@Override @Override

View file

@ -30,10 +30,8 @@ import ghidra.util.task.TaskMonitor;
/** /**
* TODO: Provide class-level documentation that describes what this file system does. * TODO: Provide class-level documentation that describes what this file system does.
*/ */
@FileSystemInfo( @FileSystemInfo(type = "fstypegoeshere", // ([a-z0-9]+ only)
type = "fstypegoeshere", // ([a-z0-9]+ only) description = "File system description goes here", factory = SkeletonFileSystem.MyFileSystemFactory.class)
description = "File system description goes here",
factory = SkeletonFileSystem.MyFileSystemFactory.class)
public class SkeletonFileSystem implements GFileSystem { public class SkeletonFileSystem implements GFileSystem {
private final FSRLRoot fsFSRL; private final FSRLRoot fsFSRL;
@ -130,7 +128,7 @@ public class SkeletonFileSystem implements GFileSystem {
} }
@Override @Override
public String getInfo(GFile file, TaskMonitor monitor) throws IOException { public String getInfo(GFile file, TaskMonitor monitor) {
MyMetadata metadata = fsih.getMetadata(file); MyMetadata metadata = fsih.getMetadata(file);
return (metadata == null) ? null : FSUtilities.infoMapToString(getInfoMap(metadata)); return (metadata == null) ? null : FSUtilities.infoMapToString(getInfoMap(metadata));
} }