# -*- coding: utf-8 -*-
"""dfVFS helpers."""
from dfvfs.helpers import command_line as dfvfs_command_line
from dfvfs.helpers import volume_scanner as dfvfs_volume_scanner
from dfvfs.lib import definitions as dfvfs_definitions
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver as dfvfs_resolver
from winevtrc import file_system
[docs]
class DFVFSFileSystemHelper(
file_system.FileSystemHelper, dfvfs_volume_scanner.VolumeScanner):
"""dfVFS file system helper."""
[docs]
def __init__(self, mediator):
"""dfVFS file system helper.
Args:
mediator (dfvfs.VolumeScannerMediator): mediator.
"""
super(DFVFSFileSystemHelper, self).__init__()
self._file_system = None
self._parent_path_spec = None
self._mediator = mediator
[docs]
def BasenamePath(self, path):
"""Determines the basename of the path.
Args:
path (str): path.
Returns:
str: basename of the path.
"""
return self._file_system.BasenamePath(path)
[docs]
def CheckFileExistsByPath(self, path):
"""Checks if a specific file exists.
Args:
path (str): path of the file.
Returns:
bool: True if the file exists, False otherwise.
"""
path_spec = path_spec_factory.Factory.NewPathSpec(
self._file_system.type_indicator, location=path,
parent=self._parent_path_spec)
return self._file_system.FileEntryExistsByPathSpec(path_spec)
[docs]
def DirnamePath(self, path):
"""Determines the directory name of the path.
Args:
path (str): path.
Returns:
str: directory name of the path or None.
"""
return self._file_system.DirnamePath(path)
[docs]
def GetFileSizeByPath(self, path):
"""Retrieves the size of a specific file.
Args:
path (str): path of the file.
Returns:
int: size of the file in bytes or None if not available.
"""
path_spec = path_spec_factory.Factory.NewPathSpec(
self._file_system.type_indicator, location=path,
parent=self._parent_path_spec)
file_entry = self._file_system.GetFileEntryByPathSpec(path_spec)
if not file_entry:
return None
return file_entry.size
[docs]
def JoinPath(self, path_segments):
"""Joins the path segments into a path.
Args:
path_segments (list[str]): path segments.
Returns:
str: joined path segments prefixed with the path separator.
"""
return self._file_system.JoinPath(path_segments)
[docs]
def ListDirectory(self, path):
"""Lists the entries in a directory.
Args:
path (str): path of the directory.
Yields:
str: name of a directory entry.
"""
path_spec = path_spec_factory.Factory.NewPathSpec(
self._file_system.type_indicator, location=path,
parent=self._parent_path_spec)
file_entry = self._file_system.GetFileEntryByPathSpec(path_spec)
if file_entry:
for sub_file_entry in file_entry.sub_file_entries:
yield sub_file_entry.name
[docs]
def OpenFileByPath(self, path):
"""Opens a specific file.
Args:
path (str): path of the file.
Returns:
file: file-like object of the file.
"""
path_spec = path_spec_factory.Factory.NewPathSpec(
self._file_system.type_indicator, location=path,
parent=self._parent_path_spec)
return self._file_system.GetFileObjectByPathSpec(path_spec)
[docs]
def OpenFileSystem(self, path_spec):
"""Opens a file system.
Args:
path_spec (dfvfs.PathSpec): file system path specification.
"""
self._file_system = dfvfs_resolver.Resolver.OpenFileSystem(path_spec)
self._parent_path_spec = path_spec.parent
[docs]
def SplitPath(self, path):
"""Splits the path into path segments.
Args:
path (str): path.
Returns:
list[str]: path segments without the root path segment, which is
an empty string.
"""
return self._file_system.SplitPath(path)
[docs]
def SetDFVFSBackEnd(back_end):
"""Sets the dfVFS back-end.
Args:
back_end (str): dfVFS back-end.
"""
if back_end == 'APM':
dfvfs_definitions.PREFERRED_APM_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_APM)
elif back_end == 'EXT':
dfvfs_definitions.PREFERRED_EXT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_EXT)
elif back_end == 'FAT':
dfvfs_definitions.PREFERRED_FAT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_FAT)
elif back_end == 'GPT':
dfvfs_definitions.PREFERRED_GPT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_GPT)
elif back_end == 'HFS':
dfvfs_definitions.PREFERRED_HFS_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_HFS)
elif back_end == 'NTFS':
dfvfs_definitions.PREFERRED_NTFS_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_NTFS)
elif back_end == 'TSK':
dfvfs_definitions.PREFERRED_APM_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK)
dfvfs_definitions.PREFERRED_EXT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK)
dfvfs_definitions.PREFERRED_FAT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK)
dfvfs_definitions.PREFERRED_GPT_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION)
dfvfs_definitions.PREFERRED_HFS_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK)
dfvfs_definitions.PREFERRED_NTFS_BACK_END = (
dfvfs_definitions.TYPE_INDICATOR_TSK)
[docs]
def AddDFVFSCLIArguments(argument_parser):
"""Adds dfVFS command line arguments.
Args:
argument_parser (argparse.ArgumentParser): argument parser.
"""
argument_parser.add_argument(
'--back_end', '--back-end', dest='back_end', action='store',
metavar='NTFS', default=None, help='preferred dfVFS back-end.')
argument_parser.add_argument(
'--image', dest='image', action='store', type=str, default=None,
help='path of the storage media image.')
argument_parser.add_argument(
'--partitions', '--partition', dest='partitions', action='store',
type=str, default=None, help=(
'Define partitions to be processed. A range of partitions can be '
'defined as: "3..5". Multiple partitions can be defined as: "1,3,5" '
'(a list of comma separated values). Ranges and lists can also be '
'combined as: "1,3..5". The first partition is 1. All partitions '
'can be specified with: "all".'))
argument_parser.add_argument(
'--snapshots', '--snapshot', dest='snapshots', action='store', type=str,
default=None, help=(
'Define snapshots to be processed. A range of snapshots can be '
'defined as: "3..5". Multiple snapshots can be defined as: "1,3,5" '
'(a list of comma separated values). Ranges and lists can also be '
'combined as: "1,3..5". The first snapshot is 1. All snapshots can '
'be specified with: "all".'))
argument_parser.add_argument(
'--volumes', '--volume', dest='volumes', action='store', type=str,
default=None, help=(
'Define volumes to be processed. A range of volumes can be defined '
'as: "3..5". Multiple volumes can be defined as: "1,3,5" (a list '
'of comma separated values). Ranges and lists can also be combined '
'as: "1,3..5". The first volume is 1. All volumes can be specified '
'with: "all".'))
[docs]
def ParseDFVFSCLIArguments(options):
"""Parses dfVFS command line arguments.
Args:
options (argparse.Namespace): command line arguments.
Returns:
DFVFSFileSystemHelper: dfVFS file system helper or None if no file system
could be found.
"""
SetDFVFSBackEnd(options.back_end)
mediator = dfvfs_command_line.CLIVolumeScannerMediator()
volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions()
volume_scanner_options.partitions = mediator.ParseVolumeIdentifiersString(
options.partitions)
if options.snapshots == 'none':
volume_scanner_options.snapshots = ['none']
else:
volume_scanner_options.snapshots = mediator.ParseVolumeIdentifiersString(
options.snapshots)
volume_scanner_options.volumes = mediator.ParseVolumeIdentifiersString(
options.volumes)
file_system_helper = DFVFSFileSystemHelper(mediator)
base_path_specs = file_system_helper.GetBasePathSpecs(
options.image, options=volume_scanner_options)
if len(base_path_specs) != 1:
return None
file_system_helper.OpenFileSystem(base_path_specs[0])
return file_system_helper