aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--unixreg/__init__.py2
-rw-r--r--unixreg/constants.py14
-rw-r--r--unixreg/functions.py96
-rw-r--r--unixreg/key.py37
5 files changed, 105 insertions, 48 deletions
diff --git a/README.md b/README.md
index 287214a..a8c167c 100644
--- a/README.md
+++ b/README.md
@@ -10,9 +10,9 @@ Update your winreg imports with this
```py
try:
- import winreg
+ import winreg
except ImportError:
- import unixreg as winreg
+ import unixreg as winreg
```
simply importing unixreg should be enough though, winreg is imported if found
diff --git a/unixreg/__init__.py b/unixreg/__init__.py
index 21e4674..fdab30a 100644
--- a/unixreg/__init__.py
+++ b/unixreg/__init__.py
@@ -1,4 +1,4 @@
-__version__ = "0.0.0"
+__version__ = "0.1.0"
# upwards compatibility with winreg
diff --git a/unixreg/constants.py b/unixreg/constants.py
index b073707..4a1e4b9 100644
--- a/unixreg/constants.py
+++ b/unixreg/constants.py
@@ -1,11 +1,11 @@
# HKEY_*
-HKEY_CLASSES_ROOT = 1
-HKEY_CURRENT_USER = 2
-HKEY_LOCAL_MACHINE = 3
-HKEY_USERS = 4
-HKEY_PERFORMANCE_DATA = 5
-HKEY_CURRENT_CONFIG = 6
-HKEY_DYN_DATA = 7
+HKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT"
+HKEY_CURRENT_USER = "HKEY_CURRENT_USER"
+HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE"
+HKEY_USERS = "HKEY_USERS"
+HKEY_PERFORMANCE_DATA = "HKEY_PERFORMANCE_DATA"
+HKEY_CURRENT_CONFIG = "HKEY_CURRENT_CONFIG"
+HKEY_DYN_DATA = "HKEY_DYN_DATA"
# https://docs.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
STANDARD_RIGHTS_REQUIRED = 1
diff --git a/unixreg/functions.py b/unixreg/functions.py
index 9b6de32..50d4be5 100644
--- a/unixreg/functions.py
+++ b/unixreg/functions.py
@@ -1,79 +1,115 @@
import os
from typing import Union
-from .constants import *
+from .key import RegKey
+from .constants import KEY_WOW64_64KEY, KEY_WRITE, KEY_READ
-KEY_TYPE = Union[str]
+KEY_TYPE = Union[str, RegKey]
+SUBKEY_TYPE = KEY_TYPE | Union[None]
_KEY_CACHE = {}
_ENV_REPLACE = {
- "USERPROFILE": "HOME"
+ "USERPROFILE": os.getenv("HOME")
}
-def CloseKey(key):
- pass
+_CONFIG_DIR = os.getenv("XDG_CONFIG_HOME")
+if not _CONFIG_DIR:
+ _CONFIG_DIR = os.path.join(os.getenv("HOME"), ".config")
+_CONFIG_DIR = os.path.join(_CONFIG_DIR, "unixreg")
-def ConnectRegistry(computer: Union[str, None], key: str):
+def __init_values(key: KEY_TYPE, sub_key, access):
+ if isinstance(key, str):
+ key = RegKey(key)
+
+ if sub_key:
+ key = key + sub_key
+ key.access = access
+
+ return key
+
+def __create_key(key: RegKey):
+ path = os.path.join(_CONFIG_DIR, key.key)
+
+ os.makedirs(path, exist_ok=True)
+
+def CloseKey(key: KEY_TYPE):
+ if isinstance(key, RegKey):
+ key.Close()
+
+def ConnectRegistry(computer: SUBKEY_TYPE, key: str):
if not computer:
return OpenKey(key, None)
+ # ConnectRegistry is expected to throw an OSError on failure
+ # any program that fails to catch this is to blame
raise OSError("Not Implemented")
-def CreateKey(key: KEY_TYPE, sub_key: Union[str, None]):
+def CreateKey(key: KEY_TYPE, sub_key: SUBKEY_TYPE):
return CreateKeyEx(key, sub_key)
-def CreateKeyEx(key: KEY_TYPE, sub_key: Union[str, None], reserved=0, access=KEY_WRITE):
- pass
+def CreateKeyEx(key: KEY_TYPE, sub_key: SUBKEY_TYPE, reserved=0, access=KEY_WRITE):
+ key = __init_values(key, sub_key, access)
+
+ __create_key(key)
+
+ return key
-def DeleteKey(key: KEY_TYPE, sub_key: Union[str, None]):
+
+def DeleteKey(key: KEY_TYPE, sub_key: SUBKEY_TYPE):
return DeleteKeyEx(key, sub_key)
-def DeleteKeyEx(key: KEY_TYPE, sub_key: Union[str, None], access=KEY_WOW64_64KEY, reserved=0):
- pass
+def DeleteKeyEx(key: KEY_TYPE, sub_key: SUBKEY_TYPE, access=KEY_WOW64_64KEY, reserved=0):
+ key = __init_values(key, sub_key, access)
+
+ path = os.path.join(_CONFIG_DIR, key.key)
+ if os.path.isfile(path):
+ os.remove(path)
def DeleteValue(key: KEY_TYPE, value: str):
- pass
+ raise NotImplementedError("Not Implemented")
def EnumKey(key: KEY_TYPE, index: int):
- pass
+ raise NotImplementedError("Not Implemented")
def EnumValue(key: KEY_TYPE, index: int):
- pass
+ raise NotImplementedError("Not Implemented")
def ExpandEnvironmentStrings(env: str):
- """
- TODO Jan: correctly implement
- %HOME%/whatever => /home/sentry/whatever
- """
- return os.getenv(env)
+ for var in _ENV_REPLACE:
+ env = env.replace(f"%{var}%", _ENV_REPLACE[var])
+ env.replace("\\", os.path.sep)
+ return env
def FlushKey(key: KEY_TYPE):
- pass
+ raise NotImplementedError("Not Implemented")
-def LoadKey(key: KEY_TYPE, sub_key: Union[str, None], file_name: str):
- pass
+def LoadKey(key: KEY_TYPE, sub_key: SUBKEY_TYPE, file_name: str):
+ raise NotImplementedError("Not Implemented")
-def OpenKeyEx(key: KEY_TYPE, sub_key: Union[str, None], reserved=0, access=KEY_READ):
- pass
+def OpenKeyEx(key: KEY_TYPE, sub_key: SUBKEY_TYPE, reserved=0, access=KEY_READ):
+ return CreateKeyEx(key, sub_key, reserved, access)
OpenKey = OpenKeyEx
def QueryInfoKey(key: KEY_TYPE):
- pass
+ QueryValueEx(key, None)
-def QueryValueEx(key: KEY_TYPE, sub_key: Union[str, None]):
- pass
+def QueryValueEx(key: KEY_TYPE, sub_key: SUBKEY_TYPE):
+ return "bla"
QueryValue = QueryValueEx
def SaveKey(key: KEY_TYPE, file_name: str):
- pass
+ raise NotImplementedError("Not Implemented")
def SetValue(key: KEY_TYPE, sub_key: str, typei: int, value: str):
return SetValueEx(key, sub_key, 0, typei, value)
def SetValueEx(key: KEY_TYPE, value_name: str, reserved: int, type: int, value: str):
- pass
+ print("BLABLABLA", key, value_name, value)
+ filepath = os.path.join(_CONFIG_DIR, key.key, value_name)
+ with open(filepath, "w") as file:
+ file.write(value)
def DisableReflectionKey(key: KEY_TYPE):
raise NotImplementedError("Not Implemented")
diff --git a/unixreg/key.py b/unixreg/key.py
index 36d65e6..e50415b 100644
--- a/unixreg/key.py
+++ b/unixreg/key.py
@@ -1,29 +1,50 @@
+import os
from copy import deepcopy
-from typing import Union
+from typing import TypeVar, Union
+
+from .constants import STANDARD_RIGHTS_REQUIRED
+
+RegKeyT = TypeVar("RegKeyT", bound="RegKey")
_HANDLE_COUNTER = 0
class RegKey:
- def __init__(self):
- pass
+ def __init__(self, key: str = "", access: int = STANDARD_RIGHTS_REQUIRED):
+ global _HANDLE_COUNTER
+ _HANDLE_COUNTER += 1
+
+ self.key = key
+ self.handle = _HANDLE_COUNTER
+ self.access = access
- def __add__(self, other: Union[str]):
+ def __add__(self, other: Union[str, RegKeyT]) -> RegKeyT:
if isinstance(other, __class__):
other = other.key
if isinstance(other, str):
+ other = other.replace("\\\\", "\\").replace("\\", os.path.sep)
retval = deepcopy(self)
- retval.key = f"{self.key}/{other}"
+ retval.key = os.path.join(self.key, other)
+ return retval
return None
- def __enter__(self):
- pass
+ def __access(self, access):
+ self.access = access
+
+ def __enter__(self) -> RegKeyT:
+ return self
- def __exit__(self):
+ def __exit__(self, *args, **kwargs):
pass
+ def __repr__(self):
+ return __class__.__name__
+
+ def __str__(self):
+ return f"{__class__.__name__}({self.key}, {self.handle}, {self.access})"
+
def Close(self):
pass