Package ghidra.formats.gfilesystem

# Class FileSystemService

java.lang.Object
ghidra.formats.gfilesystem.FileSystemService

public class FileSystemService extends Object
Provides methods for dealing with GFilesystem files and `filesystems`.

Most methods take `FSRL` references to files as a way to decouple dependencies and reduce forced filesystem instantiation.

(ie. a `GFile` instance is only valid if its `GFileSystem` is open, which means that its parent probably also has to be open, recursively, etc, whereas a FSRL is always valid and does not force the instantiation of parent objects)

`Filesystems` should be used via `filesystem ref` handles that ensure the filesystem is pinned in memory and won't be closed while you are using it.

If you are working with `GFile` instances, you should have a `fs ref` that you are using to pin the filesystem.

Files written to the `fscache` directory are obfuscated to prevent interference from virus scanners. See `ObfuscatedInputStream` or `ObfuscatedOutputStream` or `ObfuscatedFileByteProvider`.

Thread-safe.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static interface`
  `FileSystemService.DerivedStreamProducer`
  Used by `getDerivedByteProvider()` to produce a derivative stream from a source file.
  `static interface`
  `FileSystemService.DerivedStreamPushProducer`
  Used by `getDerivedByteProviderPush()` to produce a derivative stream from a source file.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `FileSystemService()`
  Creates a FilesystemService instance, using the `Application`'s default value for `user cache directory` as the cache directory.
  `FileSystemService(File fscacheDir)`
  Creates a FilesystemService instance, using the supplied directory as its file caching root directory.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `clear()`
  Forcefully closes all open filesystems and clears caches.
  `void`
  `closeUnusedFileSystems()`
  Close unused filesystems.
  `File`
  `createPlaintextTempFile(ByteProvider provider, String filenamePrefix, TaskMonitor monitor)`
  Exports the bytes in a `ByteProvider` into normal `File` that can be used as the caller wishes.
  `FileCache.FileCacheEntryBuilder`
  `createTempFile(long sizeHint)`
  Returns a `FileCache.FileCacheEntryBuilder` that will allow the caller to write bytes to it.
  `List<String>`
  `getAllFilesystemNames()`
  Returns a list of all detected GFilesystem filesystem names.
  `ByteProvider`
  `getByteProvider(FSRL fsrl, boolean fullyQualifiedFSRL, TaskMonitor monitor)`
  Returns a `ByteProvider` with the contents of the requested `file`.
  `ByteProvider`
  `getDerivedByteProvider(FSRL containerFSRL, FSRL derivedFSRL, String derivedName, long sizeHint, FileSystemService.DerivedStreamProducer producer, TaskMonitor monitor)`
  Returns a `ByteProvider` that contains the derived (ie.
  `ByteProvider`
  `getDerivedByteProviderPush(FSRL containerFSRL, FSRL derivedFSRL, String derivedName, long sizeHint, FileSystemService.DerivedStreamPushProducer pusher, TaskMonitor monitor)`
  Returns a `ByteProvider` that contains the derived (ie.
  `File`
  `getFileIfAvailable(ByteProvider provider)`
  Converts a `ByteProvider` to the underlying File that contains the contents of the ByteProvider.
  `FileSystemRef`
  `getFilesystem(FSRLRoot fsFSRL, TaskMonitor monitor)`
  Returns a filesystem instance for the requested `FSRLRoot`, either from an already loaded instance in the global fscache, or by instantiating the requested filesystem from its container file (in a possibly recursive manner, depending on the depth of the FSLR)
  `FSRL`
  `getFullyQualifiedFSRL(FSRL fsrl, TaskMonitor monitor)`
  Returns a cloned copy of the `FSRL` that should have MD5 values specified.
  `static FileSystemService`
  `getInstance()`
  `LocalFileSystem`
  `getLocalFS()`
  Returns a direct reference to the `local filesystem`.
  `FSRL`
  `getLocalFSRL(File f)`
  Builds a `FSRL` of a `file` located on the local filesystem.
  `FileSystemRef`
  `getMountedFilesystem(FSRLRoot fsFSRL)`
  Returns a new FilesystemRef handle to an already mounted filesystem.
  `List<FSRLRoot>`
  `getMountedFilesystems()`
  Returns a list of all currently mounted filesystems.
  `ByteProvider`
  `getNamedTempFile(FileCache.FileCacheEntry tempFileCacheEntry, String name)`
  Returns a `ByteProvider` for the specified `FileCache.FileCacheEntry`, using the specified filename.
  `RefdFile`
  `getRefdFile(FSRL fsrl, TaskMonitor monitor)`
  Returns the `GFile` pointed to by the FSRL, along with a `FileSystemRef` that the caller is responsible for releasing (either explicitly via `result.fsRef.close()` or via the `RefdFile.close()`).
  `boolean`
  `hasDerivedFile(FSRL containerFSRL, String derivedName, TaskMonitor monitor)`
  Returns true if the specified derived file exists in the file cache.
  `boolean`
  `isFileFilesystemContainer(FSRL containerFSRL, TaskMonitor monitor)`
  Returns true if the container file probably holds one of the currently supported filesystem types.
  `boolean`
  `isFilesystemMountedAt(FSRL fsrl)`
  Returns true of there is a `filesystem` mounted at the requested `FSRL` location.
  `static boolean`
  `isInitialized()`
  Returns true if this service has been loaded
  `boolean`
  `isLocal(FSRL fsrl)`
  Returns true if the specified location is a path on the local computer's filesystem.
  `<FSTYPE extends GFileSystem>
  FSTYPE`
  `mountSpecificFileSystem(FSRL containerFSRL, Class<FSTYPE> fsClass, TaskMonitor monitor)`
  Mount a specific file system (by class) using a specified container file.
  `CryptoSession`
  `newCryptoSession()`
  Returns a new `CryptoSession` that the caller can use to query for passwords and such.
  `GFileSystem`
  `openFileSystemContainer(FSRL containerFSRL, TaskMonitor monitor)`
  Open the file system contained at the specified location.
  `FileSystemRef`
  `probeFileForFilesystem(FSRL containerFSRL, TaskMonitor monitor, FileSystemProbeConflictResolver conflictResolver)`
  Auto-detects a filesystem in the container file pointed to by the FSRL.
  `FileSystemRef`
  `probeFileForFilesystem(FSRL containerFSRL, TaskMonitor monitor, FileSystemProbeConflictResolver conflictResolver, int priorityFilter)`
  Auto-detects a filesystem in the container file pointed to by the FSRL.
  `ByteProvider`
  `pushFileToCache(File file, FSRL fsrl, TaskMonitor monitor)`
  Adds a plaintext (non-obfuscated) file to the cache, consuming it in the process, and returns a `ByteProvider` that contains the contents of the file.
  `void`
  `releaseFileCache(FSRL fsrl)`
  Allows the resources used by caching the specified file to be released.
  `void`
  `releaseFileSystemImmediate(FileSystemRef fsRef)`
  Releases the specified `FileSystemRef`, and if no other references remain, removes it from the shared cache of file system instances.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### FileSystemService

    public FileSystemService()
    Creates a FilesystemService instance, using the `Application`'s default value for `user cache directory` as the cache directory.

  - ### FileSystemService

    public FileSystemService(File fscacheDir)
    Creates a FilesystemService instance, using the supplied directory as its file caching root directory.
    Parameters:
      `fscacheDir` - `Root dir` to use to store files placed into cache.

- ## Method Details

  - ### getInstance

    public static FileSystemService getInstance()

  - ### isInitialized

    public static boolean isInitialized()
    Returns true if this service has been loaded
    Returns:
      true if this service has been loaded

  - ### clear

    public void clear()
    Forcefully closes all open filesystems and clears caches.

  - ### closeUnusedFileSystems

    public void closeUnusedFileSystems()
    Close unused filesystems.

  - ### releaseFileSystemImmediate

    public void releaseFileSystemImmediate(FileSystemRef fsRef)
    Releases the specified `FileSystemRef`, and if no other references remain, removes it from the shared cache of file system instances.
    Parameters:
      `fsRef` - the ref to release

  - ### getLocalFS

    public LocalFileSystem getLocalFS()
    Returns a direct reference to the `local filesystem`.
    Returns:
      A direct reference to the `local filesystem`.

  - ### isLocal

    public boolean isLocal(FSRL fsrl)
    Returns true if the specified location is a path on the local computer's filesystem.
    Parameters:
      `fsrl` - `FSRL` path to query
    Returns:
      true if local, false if the path points to an embedded file in a container.

  - ### getLocalFSRL

    public FSRL getLocalFSRL(File f)
    Builds a `FSRL` of a `file` located on the local filesystem.
    Parameters:
      `f` - `File` on the local filesystem
    Returns:
      `FSRL` pointing to the same file, never null

  - ### isFilesystemMountedAt

    public boolean isFilesystemMountedAt(FSRL fsrl)
    Returns true of there is a `filesystem` mounted at the requested `FSRL` location.
    Parameters:
      `fsrl` - `FSRL` container to query for mounted filesystem
    Returns:
      boolean true if filesystem mounted at location.

  - ### getRefdFile

    public RefdFile getRefdFile(FSRL fsrl, TaskMonitor monitor) throws CancelledException, IOException
    Returns the `GFile` pointed to by the FSRL, along with a `FileSystemRef` that the caller is responsible for releasing (either explicitly via `result.fsRef.close()` or via the `RefdFile.close()`).
    Parameters:
      `fsrl` - `FSRL` of the desired file
      `monitor` - `TaskMonitor` so the user can cancel
    Returns:
      a `RefdFile` which contains the resultant `GFile` and a `FileSystemRef` that needs to be closed, or `null` if the filesystem does not have the requested file.
    Throws:
      `CancelledException` - if the user cancels
      `IOException` - if there was a file io problem

  - ### getFilesystem

    public FileSystemRef getFilesystem(FSRLRoot fsFSRL, TaskMonitor monitor) throws IOException, CancelledException
    Returns a filesystem instance for the requested `FSRLRoot`, either from an already loaded instance in the global fscache, or by instantiating the requested filesystem from its container file (in a possibly recursive manner, depending on the depth of the FSLR)

    Never returns NULL, instead throws IOException if there is a problem.

    The caller is responsible for releasing the `FileSystemRef`.

    Parameters:
      `fsFSRL` - `FSRLRoot` of file system you want a reference to.
      `monitor` - `TaskMonitor` to allow the user to cancel.
    Returns:
      a new `FileSystemRef` that the caller is responsible for closing when no longer needed, never `null`.
    Throws:
      `IOException` - if there was an io problem.
      `CancelledException` - if the user cancels.

  - ### getByteProvider

    public ByteProvider getByteProvider(FSRL fsrl, boolean fullyQualifiedFSRL, TaskMonitor monitor) throws CancelledException, IOException
    Returns a `ByteProvider` with the contents of the requested `file`.

    Never returns null, throws IOException if there was a problem.

    Caller is responsible for `closing()` the ByteProvider when finished.

    Parameters:
      `fsrl` - `FSRL` file to wrap
      `fullyQualifiedFSRL` - if true, the returned ByteProvider's FSRL will always have a MD5 hash
      `monitor` - `TaskMonitor` to watch and update
    Returns:
      new `ByteProvider`
    Throws:
      `CancelledException` - if user cancels
      `IOException` - if IO problem

  - ### getDerivedByteProvider

    public ByteProvider getDerivedByteProvider(FSRL containerFSRL, FSRL derivedFSRL, String derivedName, long sizeHint, FileSystemService.DerivedStreamProducer producer, TaskMonitor monitor) throws CancelledException, IOException
    Returns a `ByteProvider` that contains the derived (ie. decompressed or decrypted) contents of the requested file.

    The resulting ByteProvider will be a cached file, either written to a temporary file, or a in-memory buffer if small enough (see `FileCache.MAX_INMEM_FILESIZE`).

    If the file was not present in the cache, the `producer` will be called and it will be responsible for returning an `InputStream` which has the derived contents, which will be added to the file cache for next time.

    Parameters:
      `containerFSRL` - `FSRL` w/hash of the source (or container) file that this derived file is based on
      `derivedFSRL` - (optional) `FSRL` to assign to the resulting ByteProvider
      `derivedName` - a unique string identifying the derived file inside the source (or container) file
      `sizeHint` - the expected size of the resulting ByteProvider, or -1 if unknown
      `producer` - supplies an InputStream if needed. See `FileSystemService.DerivedStreamProducer`
      `monitor` - `TaskMonitor` that will be monitor for cancel requests and updated with file io progress
    Returns:
      a `ByteProvider` containing the bytes of the requested file, that has the specified derivedFSRL, or a pseudo FSRL if not specified. Never null
    Throws:
      `CancelledException` - if the user cancels
      `IOException` - if there was an io error

  - ### getDerivedByteProviderPush

    public ByteProvider getDerivedByteProviderPush(FSRL containerFSRL, FSRL derivedFSRL, String derivedName, long sizeHint, FileSystemService.DerivedStreamPushProducer pusher, TaskMonitor monitor) throws CancelledException, IOException
    Returns a `ByteProvider` that contains the derived (ie. decompressed or decrypted) contents of the requested file.

    The resulting ByteProvider will be a cached file, either written to a temporary file, or a in-memory buffer if small enough (see `FileCache.MAX_INMEM_FILESIZE`).

    If the file was not present in the cache, the `pusher` will be called and it will be responsible for producing and writing the derived file's bytes to a `OutputStream`, which will be added to the file cache for next time.

    Parameters:
      `containerFSRL` - `FSRL` w/hash of the source (or container) file that this derived file is based on
      `derivedFSRL` - (optional) `FSRL` to assign to the resulting ByteProvider
      `derivedName` - a unique string identifying the derived file inside the source (or container) file
      `sizeHint` - the expected size of the resulting ByteProvider, or -1 if unknown
      `pusher` - writes bytes to the supplied OutputStream. See `FileSystemService.DerivedStreamPushProducer`
      `monitor` - `TaskMonitor` that will be monitor for cancel requests and updated with file io progress
    Returns:
      a `ByteProvider` containing the bytes of the requested file, that has the specified derivedFSRL, or a pseudo FSRL if not specified. Never null
    Throws:
      `CancelledException` - if the user cancels
      `IOException` - if there was an io error

  - ### createTempFile

    public FileCache.FileCacheEntryBuilder createTempFile(long sizeHint) throws IOException
    Returns a `FileCache.FileCacheEntryBuilder` that will allow the caller to write bytes to it.

    After calling `finish()`, the caller will have a `FileCache.FileCacheEntry` that can provide access to a `ByteProvider`.

    Temporary files that are written to disk are obfuscated to avoid interference from overzealous virus scanners. See `ObfuscatedInputStream` / `ObfuscatedOutputStream`.

    Parameters:
      `sizeHint` - the expected size of the file, or -1 if unknown
    Returns:
      `FileCache.FileCacheEntryBuilder` that must be finalized by calling `finish()`
    Throws:
      `IOException` - if error

  - ### getNamedTempFile

    public ByteProvider getNamedTempFile(FileCache.FileCacheEntry tempFileCacheEntry, String name) throws IOException
    Returns a `ByteProvider` for the specified `FileCache.FileCacheEntry`, using the specified filename.

    The returned ByteProvider's FSRL will be decorative and does not allow returning to the same ByteProvider at a later time.

    Parameters:
      `tempFileCacheEntry` - `FileCache.FileCacheEntry` (returned by `createTempFile(long)`)
      `name` - desired name
    Returns:
      new `ByteProvider` with decorative `FSRL`
    Throws:
      `IOException` - if io error

  - ### getFileIfAvailable

    public File getFileIfAvailable(ByteProvider provider)
    Converts a `ByteProvider` to the underlying File that contains the contents of the ByteProvider.

    Returns `null` if the underlying file is not available.

    Parameters:
      `provider` - `ByteProvider`
    Returns:
      a java `File` that is providing the bytes of the specified ByteProvider, or null if there is no available file

  - ### createPlaintextTempFile

    public File createPlaintextTempFile(ByteProvider provider, String filenamePrefix, TaskMonitor monitor) throws IOException
    Exports the bytes in a `ByteProvider` into normal `File` that can be used as the caller wishes.

    This method is labeled as 'plaintext' to differentiate it from the standard obfuscated temp files that are produced by this service.

    Parameters:
      `provider` - `ByteProvider` that will be written to a temp file
      `filenamePrefix` - filename prefix of the newly created File
      `monitor` - `TaskMonitor`
    Returns:
      temporary `File`
    Throws:
      `IOException` - if error copying data or if cancelled

  - ### releaseFileCache

    public void releaseFileCache(FSRL fsrl)
    Allows the resources used by caching the specified file to be released.
    Parameters:
      `fsrl` - `FSRL` file to release cache resources for

  - ### pushFileToCache

    public ByteProvider pushFileToCache(File file, FSRL fsrl, TaskMonitor monitor) throws CancelledException, IOException
    Adds a plaintext (non-obfuscated) file to the cache, consuming it in the process, and returns a `ByteProvider` that contains the contents of the file.

    NOTE: only use this if you have no other choice and are forced to deal with already existing files in the local filesystem.

    Parameters:
      `file` - `File` to add
      `fsrl` - `FSRL` of the file that is being added
      `monitor` - `TaskMonitor`
    Returns:
      `ByteProvider` (hosted in the FileCache) that contains the bytes of the specified file
    Throws:
      `CancelledException` - if cancelled
      `IOException` - if error

  - ### hasDerivedFile

    public boolean hasDerivedFile(FSRL containerFSRL, String derivedName, TaskMonitor monitor) throws CancelledException, IOException
    Returns true if the specified derived file exists in the file cache.
    Parameters:
      `containerFSRL` - `FSRL` w/hash of the container
      `derivedName` - name of the derived file inside of the container
      `monitor` - `TaskMonitor`
    Returns:
      boolean true if file exists at time of query, false if file is not in cache
    Throws:
      `CancelledException` - if user cancels
      `IOException` - if other IO error

  - ### isFileFilesystemContainer

    public boolean isFileFilesystemContainer(FSRL containerFSRL, TaskMonitor monitor) throws CancelledException, IOException
    Returns true if the container file probably holds one of the currently supported filesystem types.

    Parameters:
      `containerFSRL` - `FSRL` of the file being queried.
      `monitor` - `TaskMonitor` to watch and update progress.
    Returns:
      boolean true if the file probably is a container, false otherwise.
    Throws:
      `CancelledException` - if user cancels.
      `IOException` - if IO problem.

  - ### probeFileForFilesystem

    public FileSystemRef probeFileForFilesystem(FSRL containerFSRL, TaskMonitor monitor, FileSystemProbeConflictResolver conflictResolver) throws CancelledException, IOException
    Auto-detects a filesystem in the container file pointed to by the FSRL.

    Returns a filesystem instance for the requested container file, either from an already loaded instance in the Global fs cache, or by probing for a filesystem in the container file using the `FileSystemFactoryMgr`.

    Returns null if no filesystem implementation was found that could handle the container file.

    Parameters:
      `containerFSRL` - `FSRL` of the file container
      `monitor` - `TaskMonitor` to watch and update progress.
      `conflictResolver` - `FileSystemProbeConflictResolver` to handle choosing the correct file system type among multiple results, or null if you want `FileSystemProbeConflictResolver.CHOOSEFIRST` .
    Returns:
      new `FileSystemRef` or null
    Throws:
      `CancelledException` - if user cancels.
      `IOException` - if IO problem.

  - ### probeFileForFilesystem

    public FileSystemRef probeFileForFilesystem(FSRL containerFSRL, TaskMonitor monitor, FileSystemProbeConflictResolver conflictResolver, int priorityFilter) throws CancelledException, IOException
    Auto-detects a filesystem in the container file pointed to by the FSRL.

    Returns a filesystem instance for the requested container file, either from an already loaded instance in the Global fs cache, or by probing for a filesystem in the container file using a `FileSystemFactoryMgr`.

    Returns null if no filesystem implementation was found that could handle the container file.

    Parameters:
      `containerFSRL` - `FSRL` of the file container
      `monitor` - `TaskMonitor` to watch and update progress.
      `conflictResolver` - `FileSystemProbeConflictResolver` to handle choosing the correct file system type among multiple results, or null if you want `FileSystemProbeConflictResolver.CHOOSEFIRST` .
      `priorityFilter` - minimum filesystem `FileSystemInfo.priority()` to allow when using file system factories to probe the container.
    Returns:
      new `FileSystemRef` or null
    Throws:
      `CancelledException` - if user cancels.
      `IOException` - if IO problem.

  - ### mountSpecificFileSystem

    public <FSTYPE extends GFileSystem> FSTYPE mountSpecificFileSystem(FSRL containerFSRL, Class<FSTYPE> fsClass, TaskMonitor monitor) throws CancelledException, IOException
    Mount a specific file system (by class) using a specified container file.

    The newly constructed / mounted file system is not managed by this FileSystemService or controlled with `FileSystemRef`s.

    The caller is responsible for closing the resultant file system instance when it is no longer needed.

    Parameters:
      `containerFSRL` - a reference to the file that contains the file system image
      `fsClass` - the GFileSystem derived class that implements the specific file system
      `monitor` - `TaskMonitor` to allow the user to cancel
    Returns:
      new `GFileSystem` instance, caller is responsible for closing() when done.
    Throws:
      `CancelledException` - if user cancels
      `IOException` - if file io error or wrong file system type.

  - ### openFileSystemContainer

    public GFileSystem openFileSystemContainer(FSRL containerFSRL, TaskMonitor monitor) throws CancelledException, IOException
    Open the file system contained at the specified location.

    The newly constructed / mounted file system is not managed by this FileSystemService or controlled with `FileSystemRef`s.

    The caller is responsible for closing the resultant file system instance when it is no longer needed.

    Parameters:
      `containerFSRL` - a reference to the file that contains the file system image
      `monitor` - `TaskMonitor` to allow the user to cancel
    Returns:
      new `GFileSystem` instance, caller is responsible for closing() when done.
    Throws:
      `CancelledException` - if user cancels
      `IOException` - if file io error or wrong file system type.

  - ### getFullyQualifiedFSRL

    public FSRL getFullyQualifiedFSRL(FSRL fsrl, TaskMonitor monitor) throws CancelledException, IOException
    Returns a cloned copy of the `FSRL` that should have MD5 values specified. (excluding GFile objects that don't have data streams)

    Parameters:
      `fsrl` - `FSRL` of the file that should be forced to have a MD5
      `monitor` - `TaskMonitor` to watch and update with progress.
    Returns:
      possibly new `FSRL` instance with a MD5 value.
    Throws:
      `CancelledException` - if user cancels.
      `IOException` - if IO problem.

  - ### getAllFilesystemNames

    public List<String> getAllFilesystemNames()
    Returns a list of all detected GFilesystem filesystem names.

    See `FileSystemFactoryMgr.getAllFilesystemNames()`.

    Returns:
      `List` of strings.

  - ### getMountedFilesystems

    public List<FSRLRoot> getMountedFilesystems()
    Returns a list of all currently mounted filesystems.

    As a FSRL is returned, there is no guarantee that the filesystem will still be mounted when you later use values from the list.

    Returns:
      `List` of `FSRLRoot` of currently mounted filesystems.

  - ### getMountedFilesystem

    public FileSystemRef getMountedFilesystem(FSRLRoot fsFSRL)
    Returns a new FilesystemRef handle to an already mounted filesystem.

    The caller is responsible for releasing the ref.

    Returns null if there is no filesystem mounted at `fsFSRL`.

    Parameters:
      `fsFSRL` - `FSRLRoot` of file system to get a `FileSystemRef` to.
    Returns:
      new `FileSystemRef` or null if requested file system not mounted.

  - ### newCryptoSession

    public CryptoSession newCryptoSession()
    Returns a new `CryptoSession` that the caller can use to query for passwords and such. Caller is responsible for closing the instance when done.

    Later callers to this method will receive a nested CryptoSession that shares it's state with the initial CryptoSession, until the initial CryptoSession is closed().

    Returns:
      new `CryptoSession` instance, never null