Skip to content

Commit

Permalink
Changes for handling virtual keys (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz authored Feb 29, 2024
1 parent e0297e5 commit c31e081
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 261 deletions.
4 changes: 2 additions & 2 deletions config/dpkg/changelog
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
dfwinreg (20240223-1) unstable; urgency=low
dfwinreg (20240229-1) unstable; urgency=low

* Auto-generated

-- Log2Timeline maintainers <[email protected]> Fri, 23 Feb 2024 06:25:43 +0100
-- Log2Timeline maintainers <[email protected]> Thu, 29 Feb 2024 19:21:02 +0100
2 changes: 1 addition & 1 deletion dfwinreg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
provides read-only access to Windows Registry objects.
"""

__version__ = '20240223'
__version__ = '20240229'
57 changes: 42 additions & 15 deletions dfwinreg/creg.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def GetKeyByPath(self, key_path):
key_path (str): Windows Registry key path.
Returns:
WinRegistryKey: Registry key or None if not available.
WinRegistryKey: Windows Registry key or None if not available.
"""
key_path_upper = key_path.upper()
if key_path_upper.startswith(self._key_path_prefix_upper):
Expand All @@ -54,10 +54,13 @@ def GetKeyByPath(self, key_path):
creg_key = self._creg_file.get_key_by_path(relative_key_path)
except IOError:
creg_key = None

if not creg_key:
return None

return CREGWinRegistryKey(creg_key, key_path=key_path)
return CREGWinRegistryKey(
creg_key, key_path_prefix=self._key_path_prefix,
relative_key_path=relative_key_path)

def GetRootKey(self):
"""Retrieves the root key.
Expand All @@ -69,7 +72,9 @@ def GetRootKey(self):
if not creg_key:
return None

return CREGWinRegistryKey(creg_key, key_path=self._key_path_prefix)
return CREGWinRegistryKey(
creg_key, key_path_prefix=self._key_path_prefix,
relative_key_path='')

def Open(self, file_object):
"""Opens the Windows Registry file using a file-like object.
Expand All @@ -88,14 +93,20 @@ def Open(self, file_object):
class CREGWinRegistryKey(interface.WinRegistryKey):
"""Implementation of a Windows Registry key using pycreg."""

def __init__(self, pycreg_key, key_path=''):
"""Initializes a Windows Registry key object.
def __init__(
self, pycreg_key, key_helper=None, key_path_prefix='',
relative_key_path=''):
"""Initializes a Windows Registry key.
Args:
pycreg_key (pycreg.key): pycreg key object.
key_path (Optional[str]): Windows Registry key path.
key_helper (Optional[WinRegistryKeyHelper]): Windows Registry key helper.
key_path_prefix (Optional[str]): Windows Registry key path prefix.
relative_key_path (Optional[str]): relative Windows Registry key path.
"""
super(CREGWinRegistryKey, self).__init__(key_path=key_path)
super(CREGWinRegistryKey, self).__init__(
key_helper=key_helper, key_path_prefix=key_path_prefix,
relative_key_path=relative_key_path)
self._pycreg_key = pycreg_key

@property
Expand Down Expand Up @@ -144,8 +155,12 @@ def GetSubkeyByIndex(self, index):
raise IndexError('Index out of bounds.')

pycreg_key = self._pycreg_key.get_sub_key(index)
key_path = key_paths.JoinKeyPath([self._key_path, pycreg_key.name])
return CREGWinRegistryKey(pycreg_key, key_path=key_path)
relative_key_path = key_paths.JoinKeyPath([
self._relative_key_path, pycreg_key.name])
return CREGWinRegistryKey(
pycreg_key, key_helper=self._key_helper,
key_path_prefix=self._key_path_prefix,
relative_key_path=relative_key_path)

def GetSubkeyByName(self, name):
"""Retrieves a subkey by name.
Expand All @@ -160,8 +175,12 @@ def GetSubkeyByName(self, name):
if not pycreg_key:
return None

key_path = key_paths.JoinKeyPath([self._key_path, pycreg_key.name])
return CREGWinRegistryKey(pycreg_key, key_path=key_path)
relative_key_path = key_paths.JoinKeyPath([
self._relative_key_path, pycreg_key.name])
return CREGWinRegistryKey(
pycreg_key, key_helper=self._key_helper,
key_path_prefix=self._key_path_prefix,
relative_key_path=relative_key_path)

def GetSubkeyByPath(self, key_path):
"""Retrieves a subkey by path.
Expand All @@ -176,8 +195,12 @@ def GetSubkeyByPath(self, key_path):
if not pycreg_key:
return None

key_path = key_paths.JoinKeyPath([self._key_path, key_path])
return CREGWinRegistryKey(pycreg_key, key_path=key_path)
relative_key_path = key_paths.JoinKeyPath([
self._relative_key_path, key_path])
return CREGWinRegistryKey(
pycreg_key, key_helper=self._key_helper,
key_path_prefix=self._key_path_prefix,
relative_key_path=relative_key_path)

def GetSubkeys(self):
"""Retrieves all subkeys within the key.
Expand All @@ -186,8 +209,12 @@ def GetSubkeys(self):
WinRegistryKey: Windows Registry subkey.
"""
for pycreg_key in self._pycreg_key.sub_keys:
key_path = key_paths.JoinKeyPath([self._key_path, pycreg_key.name])
yield CREGWinRegistryKey(pycreg_key, key_path=key_path)
relative_key_path = key_paths.JoinKeyPath([
self._relative_key_path, pycreg_key.name])
yield CREGWinRegistryKey(
pycreg_key, key_helper=self._key_helper,
key_path_prefix=self._key_path_prefix,
relative_key_path=relative_key_path)

def GetValueByName(self, name):
"""Retrieves a value by name.
Expand Down
27 changes: 19 additions & 8 deletions dfwinreg/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,29 @@ class FakeWinRegistryKey(interface.WinRegistryKey):
"""Fake implementation of a Windows Registry key."""

def __init__(
self, name, class_name=None, key_path='', last_written_time=None,
offset=None, subkeys=None, values=None):
self, name, class_name=None, key_helper=None, key_path_prefix='',
last_written_time=None, offset=None, relative_key_path='', subkeys=None,
values=None):
"""Initializes a Windows Registry key.
Subkeys and values with duplicate names are silently ignored.
Args:
name (str): name of the Windows Registry key.
key_path (Optional[str]): Windows Registry key path.
class_name (Optional[str]): class name of the Windows Registry key.
key_helper (Optional[WinRegistryKeyHelper]): Windows Registry key helper.
key_path_prefix (Optional[str]): Windows Registry key path prefix.
last_written_time (Optional[int]): last written time, formatted as
a FILETIME timestamp.
offset (Optional[int]): offset of the key within the Windows Registry
file.
relative_key_path (Optional[str]): relative Windows Registry key path.
subkeys (Optional[list[FakeWinRegistryKey]]): list of subkeys.
values (Optional[list[FakeWinRegistryValue]]): list of values.
"""
super(FakeWinRegistryKey, self).__init__(key_path=key_path)
super(FakeWinRegistryKey, self).__init__(
key_helper=key_helper, key_path_prefix=key_path_prefix,
relative_key_path=relative_key_path)
self._class_name = class_name
self._last_written_time = last_written_time
self._name = name
Expand Down Expand Up @@ -192,9 +197,12 @@ def _BuildKeyHierarchy(self, subkeys, values):
continue
self._subkeys[name] = registry_key

relative_key_path = key_paths.JoinKeyPath([
self._relative_key_path, registry_key.name])

# pylint: disable=protected-access
registry_key._key_path = key_paths.JoinKeyPath([
self._key_path, registry_key.name])
registry_key._key_path_prefix = self._key_path_prefix
registry_key._relative_key_path = relative_key_path

if values:
for registry_value in values:
Expand All @@ -219,8 +227,11 @@ def AddSubkey(self, name, registry_key):

self._subkeys[name_upper] = registry_key

key_path = key_paths.JoinKeyPath([self._key_path, name])
registry_key._key_path = key_path # pylint: disable=protected-access
relative_key_path = key_paths.JoinKeyPath([self._relative_key_path, name])

# pylint: disable=protected-access
registry_key._key_path_prefix = self._key_path_prefix
registry_key._relative_key_path = relative_key_path

def AddValue(self, registry_value):
"""Adds a value.
Expand Down
17 changes: 13 additions & 4 deletions dfwinreg/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,18 @@ def Open(self, path, ascii_codepage='cp1252'):
class WinRegistryKey(object):
"""Windows Registry key interface."""

def __init__(self, key_path=''):
def __init__(self, key_helper=None, key_path_prefix='', relative_key_path=''):
"""Initializes a Windows Registry key.
Args:
key_path (Optional[str]): Windows Registry key path.
key_helper (Optional[WinRegistryKeyHelper]): Windows Registry key helper.
key_path_prefix (Optional[str]): Windows Registry key path prefix.
relative_key_path (Optional[str]): relative Windows Registry key path.
"""
super(WinRegistryKey, self).__init__()
self._key_path = key_paths.JoinKeyPath([key_path])
self._key_helper = key_helper
self._key_path_prefix = key_path_prefix
self._relative_key_path = relative_key_path

@property
@abc.abstractmethod
Expand Down Expand Up @@ -143,7 +147,8 @@ def offset(self):
@property
def path(self):
"""str: Windows Registry key path."""
return self._key_path
return key_paths.JoinKeyPath([
self._key_path_prefix, self._relative_key_path])

@abc.abstractmethod
def GetSubkeyByIndex(self, index):
Expand Down Expand Up @@ -220,6 +225,10 @@ def RecurseKeys(self):
yield key


class WinRegistryKeyHelper(object):
"""Windows Registry key helper."""


class WinRegistryValue(object):
"""Windows Registry value interface."""

Expand Down
Loading

0 comments on commit c31e081

Please sign in to comment.