Source code for dfvfs.file_io.vhdi_file_io

# -*- coding: utf-8 -*-
"""The Virtual Hard Disk image file-like object."""

import pyvhdi

from dfvfs.file_io import file_object_io
from dfvfs.lib import errors
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver


[docs] class VHDIFile(file_object_io.FileObjectIO): """File input/output (IO) object using pyvhdi."""
[docs] def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. Args: resolver_context (Context): resolver context. path_spec (PathSpec): a path specification. """ super(VHDIFile, self).__init__(resolver_context, path_spec) self._parent_vhdi_files = [] self._sub_file_objects = []
def _Close(self): """Closes the file-like object.""" super(VHDIFile, self)._Close() for vhdi_file in self._parent_vhdi_files: vhdi_file.close() self._parent_vhdi_files = [] self._sub_file_objects = [] def _OpenFileObject(self, path_spec): """Opens the file-like object defined by path specification. Args: path_spec (PathSpec): path specification. Returns: pyvhdi.file: a file-like object. Raises: PathSpecError: if the path specification is incorrect. """ if not path_spec.HasParent(): raise errors.PathSpecError( 'Unsupported path specification without parent.') file_object = resolver.Resolver.OpenFileObject( path_spec.parent, resolver_context=self._resolver_context) vhdi_file = pyvhdi.file() vhdi_file.open_file_object(file_object) if vhdi_file.parent_identifier: # pylint: disable=using-constant-test file_system = resolver.Resolver.OpenFileSystem( path_spec.parent, resolver_context=self._resolver_context) self._OpenParentFile(file_system, path_spec.parent, vhdi_file) self._sub_file_objects.append(file_object) self._parent_vhdi_files.reverse() self._sub_file_objects.reverse() return vhdi_file def _OpenParentFile(self, file_system, path_spec, vhdi_file): """Opens the parent file. Args: file_system (FileSystem): file system of the VHDI file. path_spec (PathSpec): path specification of the VHDI file. vhdi_file (pyvhdi.file): VHDI file. Raises: PathSpecError: if the path specification is incorrect. """ location = getattr(path_spec, 'location', None) if not location: raise errors.PathSpecError( 'Unsupported path specification without location.') location_path_segments = file_system.SplitPath(location) parent_filename = vhdi_file.parent_filename _, _, parent_filename = parent_filename.rpartition('\\') location_path_segments.pop() location_path_segments.append(parent_filename) parent_file_location = file_system.JoinPath(location_path_segments) # Note that we don't want to set the keyword arguments when not used # because the path specification base class will check for unused # keyword arguments and raise. kwargs = path_spec_factory.Factory.GetProperties(path_spec) kwargs['location'] = parent_file_location if path_spec.parent is not None: kwargs['parent'] = path_spec.parent parent_file_path_spec = path_spec_factory.Factory.NewPathSpec( path_spec.type_indicator, **kwargs) if not file_system.FileEntryExistsByPathSpec(parent_file_path_spec): return file_object = resolver.Resolver.OpenFileObject( parent_file_path_spec, resolver_context=self._resolver_context) vhdi_parent_file = pyvhdi.file() vhdi_parent_file.open_file_object(file_object) if vhdi_parent_file.parent_identifier: # pylint: disable=using-constant-test self._OpenParentFile( file_system, parent_file_path_spec, vhdi_parent_file) vhdi_file.set_parent(vhdi_parent_file) self._parent_vhdi_files.append(vhdi_parent_file) self._sub_file_objects.append(file_object)
[docs] def get_size(self): """Retrieves the size of the file-like object. Returns: int: size of the file-like object data. Raises: IOError: if the file-like object has not been opened. OSError: if the file-like object has not been opened. """ if not self._is_open: raise IOError('Not opened.') return self._file_object.get_media_size()