Windows registry PermissionError
Eryk Sun
eryksun at gmail.com
Thu May 12 23:42:25 EDT 2022
On 5/12/22, Mike Dewhirst <miked at dewhirst.com.au> wrote:
>
> access=wr.KEY_ALL_ACCESS + wr.KEY_WRITE,
The access parameter is a bit mask of access rights that combine via
bitwise OR (|), not via arithmetic addition.
KEY_ALL_ACCESS (0x000F_003F) is a superset of KEY_WRITE (0x0002_0006):
KEY_WRITE = (
READ_CONTROL | # 0x0002_0000
KEY_SET_VALUE | # 0x0000_0002
KEY_CREATE_SUB_KEY | # 0x0000_0004
) # 0x0002_0006
KEY_ALL_ACCESS = (
DELETE | # 0x0001_0000
READ_CONTROL | # 0x0002_0000
WRITE_DAC | # 0x0004_0000
WRITE_OWNER | # 0x0008_0000
KEY_QUERY_VALUE | # 0x0000_0001
KEY_SET_VALUE | # 0x0000_0002
KEY_CREATE_SUB_KEY | # 0x0000_0004
KEY_ENUMERATE_SUB_KEYS | # 0x0000_0008
KEY_NOTIFY | # 0x0000_0010
KEY_CREATE_LINK | # 0x0000_0020
) # 0x000F_003F
The result of the arithmetic addition `KEY_ALL_ACCESS + KEY_WRITE` is
0x0011_0045, which is wrong and meaningless. Registry key objects do
not support SYNCHRONIZE (0x0010_0000) access; DELETE (0x0001_0000)
access isn't needed; 0x0000_0040 is not a supported key right;
KEY_CREATE_SUB_KEY (0x0000_0004) access isn't needed; and
KEY_QUERY_VALUE (0x0000_0001) isn't sufficient.
You should limit the requested access to the specific access rights
that are required for querying and setting values in the key:
access=(wr.KEY_QUERY_VALUE | wr.KEY_SET_VALUE)
> def setvalue(self, vname, value):
> return wr.SetValueEx(self.select(), vname, 0, 1, value)
You shouldn't hard code the value of the data type constant. Use
wr.REG_SZ instead of 1.
The return value of self.select() is a winreg PyHKEY object that wraps
the OS handle for the key object. You're relying on implicit closing
of this handle based on referencing counting. It's cleaner to use it
in a `with` statement, as you would for a file object returned by
open(). For example:
with self.select() as hkey:
wr.SetValueEx(hkey, vname, 0, wr.REG_SZ, value)
> lmregistry = Registry(
> hkey=wr.HKEY_LOCAL_MACHINE,
> sub_key="SOFTWARE\WOW6432Node\XXX Technology\AppName",
You really shouldn't open the "WOW6432Node" key directly. It is an
implementation detail of the WOW64 subsystem that runs 32-bit
applications on a 64-bit system. If you need to operate on the
registry keys of 32-bit applications from a native 64-bit process,
open the normal path using the access right KEY_WOW64_32KEY
(0x0000_0200). For example:
hkey = wr.HKEY_LOCAL_MACHINE
subkey = r"SOFTWARE\XXX Technology\AppName"
access = (
wr.KEY_QUERY_VALUE |
wr.KEY_SET_VALUE |
wr.KEY_WOW64_32KEY
)
Typically you'd first try opening the path without either
KEY_WOW64_32KEY or KEY_WOW64_64KEY. The default view matches the
current process.
https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view
Remember to escape the backslash separators in string literals of key
paths, or use raw string literals as I used in the above example.
More information about the Python-list
mailing list