Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
3035c392
Commit
3035c392
authored
Apr 21, 2010
by
Brian Curtin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Port #7347 to py3k.
Add CreateKeyEx and DeleteKeyEx, along with test improvements.
parent
2f67fa29
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
390 additions
and
38 deletions
+390
-38
Doc/library/winreg.rst
Doc/library/winreg.rst
+101
-3
Lib/test/test_winreg.py
Lib/test/test_winreg.py
+182
-23
PC/winreg.c
PC/winreg.c
+107
-12
No files found.
Doc/library/winreg.rst
View file @
3035c392
...
...
@@ -61,15 +61,40 @@ This module offers the following functions:
:exc:`WindowsError` exception is raised.
.. function:: CreateKeyEx(key, sub_key, res=0, sam=KEY_ALL_ACCESS)
Creates or opens the specified key, returning a :dfn:`handle object`
*key* is an already open key, or one of the predefined :const:`HKEY_\*`
constants.
*sub_key* is a string that names the key this method opens or creates.
*res* is a reserved integer, and must be zero. The default is zero.
*sam* is an integer that specifies an access mask that describes the desired
security access for the key. Default is :const:`KEY_ALL_ACCESS`
If *key* is one of the predefined keys, *sub_key* may be ``None``. In that
case, the handle returned is the same key handle passed in to the function.
If the key already exists, this function opens the existing key.
The return value is the handle of the opened key. If the function fails, a
:exc:`WindowsError` exception is raised.
.. versionadded:: 3.2
.. function:: DeleteKey(key, sub_key)
Deletes the specified key.
*key* is an already open key, or any one of the predefined
:const:`HKEY_\*`
*key* is an already open key, or any one of the predefined :const:`HKEY_\*`
constants.
*sub_key* is a string that must be a subkey of the key
identified by the *key*
parameter. This value must not be
``None``, and the key may not have subkeys.
*sub_key* is a string that must be a subkey of the key identified by the *key*
parameter. This value must not be ``None``, and the key may not have subkeys.
*This method can not delete keys with subkeys.*
...
...
@@ -77,6 +102,37 @@ This module offers the following functions:
If the method fails, a :exc:`WindowsError` exception is raised.
.. function:: DeleteKeyEx(key, sub_key, sam=KEY_WOW64_64KEY, res=0)
Deletes the specified key.
.. note::
The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx
Windows API function, which is specific to 64-bit versions of Windows.
See http://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx
*key* is an already open key, or any one of the predefined :const:`HKEY_\*`
constants.
*sub_key* is a string that must be a subkey of the key identified by the
*key* parameter. This value must not be ``None``, and the key may not have
subkeys.
*res* is a reserved integer, and must be zero. The default is zero.
*sam* is an integer that specifies an access mask that describes the
desired security access for the key. Default is :const:`KEY_WOW64_64KEY`
*This method can not delete keys with subkeys.*
If the method succeeds, the entire key, including all of its values, is
removed. If the method fails, a :exc:`WindowsError` exception is raised.
On unsupported Windows versions, :exc:`NotImplementedError` is raised.
.. versionadded:: 3.2
.. function:: DeleteValue(key, value)
Removes a named value from a registry key.
...
...
@@ -374,6 +430,48 @@ This module offers the following functions:
registry. This helps the registry perform efficiently.
.. function:: DisableReflectionKey(key)
Disables registry reflection for 32-bit processes running on a 64-bit
Operating System.
*key* is an already open key, or one of the predefined :const:`HKEY_\*`
constants.
Will generally raise :exc:`NotImplemented` if executed on a 32-bit
Operating System.
If the key is not on the reflection list, the function succeeds but has no
effect. Disabling reflection for a key does not affect reflection of any
subkeys.
.. function:: EnableReflectionKey(key)
Restores registry reflection for the specified disabled key.
*key* is an already open key, or one of the predefined :const:`HKEY_\*`
constants.
Will generally raise :exc:`NotImplemented` if executed on a 32-bit
Operating System.
Restoring reflection for a key does not affect reflection of any subkeys.
.. function:: QueryReflectionKey(key)
Determines the reflection state for the specified key.
*key* is an already open key, or one of the predefined :const:`HKEY_\*`
constants.
Returns ``True`` if reflection is disabled.
Will generally raise :exc:`NotImplemented` if executed on a 32-bit
Operating System.
.. _handle-object:
Registry Handle Objects
...
...
Lib/test/test_winreg.py
View file @
3035c392
...
...
@@ -5,13 +5,32 @@
import
os
,
sys
import
unittest
from
test
import
support
from
platform
import
machine
# Do this first so test will be skipped if module doesn't exist
support
.
import_module
(
'winreg'
)
# Now import everything
from
winreg
import
*
try
:
REMOTE_NAME
=
sys
.
argv
[
sys
.
argv
.
index
(
"--remote"
)
+
1
]
except
(
IndexError
,
ValueError
):
REMOTE_NAME
=
None
# tuple of (major, minor)
WIN_VER
=
sys
.
getwindowsversion
()[:
2
]
# Some tests should only run on 64-bit architectures where WOW64 will be.
WIN64_MACHINE
=
True
if
machine
()
==
"AMD64"
else
False
# Starting with Windows 7 and Windows Server 2008 R2, WOW64 no longer uses
# registry reflection and formerly reflected keys are shared instead.
# Windows 7 and Windows Server 2008 R2 are version 6.1. Due to this, some
# tests are only valid up until 6.1
HAS_REFLECTION
=
True
if
WIN_VER
<
(
6
,
1
)
else
False
test_key_name
=
"SOFTWARE
\
\
Python Registry Test Key - Delete Me"
# On OS'es that support reflection we should test with a reflected key
test_reflect_key_name
=
"SOFTWARE
\
\
Classes
\
\
Python Test Key - Delete Me"
test_data
=
[
(
"Int Value"
,
45
,
REG_DWORD
),
...
...
@@ -25,8 +44,7 @@ test_data = [
(
"Japanese 日本"
,
"日本語"
,
REG_SZ
),
]
class
WinregTests
(
unittest
.
TestCase
):
remote_name
=
None
class
BaseWinregTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
# Make sure that the test key is absent when the test
...
...
@@ -49,7 +67,8 @@ class WinregTests(unittest.TestCase):
CloseKey
(
hkey
)
DeleteKey
(
root
,
subkey
)
def
WriteTestData
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
def
_write_test_data
(
self
,
root_key
,
subkeystr
=
"sub_key"
,
CreateKey
=
CreateKey
):
# Set the default value for this key.
SetValue
(
root_key
,
test_key_name
,
REG_SZ
,
"Default value"
)
key
=
CreateKey
(
root_key
,
test_key_name
)
...
...
@@ -90,7 +109,7 @@ class WinregTests(unittest.TestCase):
except
EnvironmentError
:
pass
def
ReadTestData
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
def
_read_test_data
(
self
,
root_key
,
subkeystr
=
"sub_key"
,
OpenKey
=
OpenKey
):
# Check we can get default value for this key.
val
=
QueryValue
(
root_key
,
test_key_name
)
self
.
assertEquals
(
val
,
"Default value"
,
...
...
@@ -130,7 +149,7 @@ class WinregTests(unittest.TestCase):
key
.
Close
()
def
DeleteTestD
ata
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
def
_delete_test_d
ata
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
key
=
OpenKey
(
root_key
,
test_key_name
,
0
,
KEY_ALL_ACCESS
)
sub_key
=
OpenKey
(
key
,
subkeystr
,
0
,
KEY_ALL_ACCESS
)
# It is not necessary to delete the values before deleting
...
...
@@ -160,39 +179,179 @@ class WinregTests(unittest.TestCase):
except
WindowsError
:
# Use this error name this time
pass
def
TestAll
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
self
.
WriteTestData
(
root_key
,
subkeystr
)
self
.
ReadTestData
(
root_key
,
subkeystr
)
self
.
DeleteTestData
(
root_key
,
subkeystr
)
def
_test_all
(
self
,
root_key
,
subkeystr
=
"sub_key"
):
self
.
_write_test_data
(
root_key
,
subkeystr
)
self
.
_read_test_data
(
root_key
,
subkeystr
)
self
.
_delete_test_data
(
root_key
,
subkeystr
)
class
LocalWinregTests
(
BaseWinregTests
):
def
test_registry_works
(
self
):
self
.
_test_all
(
HKEY_CURRENT_USER
)
self
.
_test_all
(
HKEY_CURRENT_USER
,
"日本-subkey"
)
def
testLocalMachineRegistryWorks
(
self
):
self
.
TestAll
(
HKEY_CURRENT_USER
)
self
.
TestAll
(
HKEY_CURRENT_USER
,
"日本-subkey"
)
def
test_registry_works_extended_functions
(
self
):
# Substitute the regular CreateKey and OpenKey calls with their
# extended counterparts.
# Note: DeleteKeyEx is not used here because it is platform dependent
cke
=
lambda
key
,
sub_key
:
CreateKeyEx
(
key
,
sub_key
,
0
,
KEY_ALL_ACCESS
)
self
.
_write_test_data
(
HKEY_CURRENT_USER
,
CreateKey
=
cke
)
def
testConnectRegistryToLocalMachineWorks
(
self
):
oke
=
lambda
key
,
sub_key
:
OpenKeyEx
(
key
,
sub_key
,
0
,
KEY_READ
)
self
.
_read_test_data
(
HKEY_CURRENT_USER
,
OpenKey
=
oke
)
self
.
_delete_test_data
(
HKEY_CURRENT_USER
)
def
test_connect_registry_to_local_machine_works
(
self
):
# perform minimal ConnectRegistry test which just invokes it
h
=
ConnectRegistry
(
None
,
HKEY_LOCAL_MACHINE
)
self
.
assertNotEqual
(
h
.
handle
,
0
)
h
.
Close
()
self
.
assertEqual
(
h
.
handle
,
0
)
def
testRemoteMachineRegistryWorks
(
self
):
if
not
self
.
remote_name
:
return
# remote machine name not specified
remote_key
=
ConnectRegistry
(
self
.
remote_name
,
HKEY_CURRENT_USER
)
self
.
TestAll
(
remote_key
)
def
test_inexistant_remote_registry
(
self
):
connect
=
lambda
:
ConnectRegistry
(
"abcdefghijkl"
,
HKEY_CURRENT_USER
)
self
.
assertRaises
(
WindowsError
,
connect
)
def
testExpandEnvironmentStrings
(
self
):
r
=
ExpandEnvironmentStrings
(
"%windir%
\
\
test"
)
self
.
assertEqual
(
type
(
r
),
str
)
self
.
assertEqual
(
r
,
os
.
environ
[
"windir"
]
+
"
\
\
test"
)
def
test_context_manager
(
self
):
# ensure that the handle is closed if an exception occurs
try
:
with
ConnectRegistry
(
None
,
HKEY_LOCAL_MACHINE
)
as
h
:
self
.
assertNotEqual
(
h
.
handle
,
0
)
raise
WindowsError
except
WindowsError
:
self
.
assertEqual
(
h
.
handle
,
0
)
# Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff
# or DeleteKeyEx so make sure their use raises NotImplementedError
@
unittest
.
skipUnless
(
WIN_VER
<
(
5
,
2
),
"Requires Windows XP"
)
def
test_reflection_unsupported
(
self
):
try
:
with
CreateKey
(
HKEY_CURRENT_USER
,
test_key_name
)
as
ck
:
self
.
assertNotEqual
(
ck
.
handle
,
0
)
key
=
OpenKey
(
HKEY_CURRENT_USER
,
test_key_name
)
self
.
assertNotEqual
(
key
.
handle
,
0
)
with
self
.
assertRaises
(
NotImplementedError
):
DisableReflectionKey
(
key
)
with
self
.
assertRaises
(
NotImplementedError
):
EnableReflectionKey
(
key
)
with
self
.
assertRaises
(
NotImplementedError
):
QueryReflectionKey
(
key
)
with
self
.
assertRaises
(
NotImplementedError
):
DeleteKeyEx
(
HKEY_CURRENT_USER
,
test_key_name
)
finally
:
DeleteKey
(
HKEY_CURRENT_USER
,
test_key_name
)
@
unittest
.
skipUnless
(
REMOTE_NAME
,
"Skipping remote registry tests"
)
class
RemoteWinregTests
(
BaseWinregTests
):
def
test_remote_registry_works
(
self
):
remote_key
=
ConnectRegistry
(
REMOTE_NAME
,
HKEY_CURRENT_USER
)
self
.
_test_all
(
remote_key
)
@
unittest
.
skipUnless
(
WIN64_MACHINE
,
"x64 specific registry tests"
)
class
Win64WinregTests
(
BaseWinregTests
):
def
test_reflection_functions
(
self
):
# Test that we can call the query, enable, and disable functions
# on a key which isn't on the reflection list with no consequences.
with
OpenKey
(
HKEY_LOCAL_MACHINE
,
"Software"
)
as
key
:
# HKLM\Software is redirected but not reflected in all OSes
self
.
assertTrue
(
QueryReflectionKey
(
key
))
self
.
assertEquals
(
None
,
EnableReflectionKey
(
key
))
self
.
assertEquals
(
None
,
DisableReflectionKey
(
key
))
self
.
assertTrue
(
QueryReflectionKey
(
key
))
@
unittest
.
skipUnless
(
HAS_REFLECTION
,
"OS doesn't support reflection"
)
def
test_reflection
(
self
):
# Test that we can create, open, and delete keys in the 32-bit
# area. Because we are doing this in a key which gets reflected,
# test the differences of 32 and 64-bit keys before and after the
# reflection occurs (ie. when the created key is closed).
try
:
with
CreateKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_ALL_ACCESS
|
KEY_WOW64_32KEY
)
as
created_key
:
self
.
assertNotEqual
(
created_key
.
handle
,
0
)
# The key should now be available in the 32-bit area
with
OpenKey
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_ALL_ACCESS
|
KEY_WOW64_32KEY
)
as
key
:
self
.
assertNotEqual
(
key
.
handle
,
0
)
# Write a value to what currently is only in the 32-bit area
SetValueEx
(
created_key
,
""
,
0
,
REG_SZ
,
"32KEY"
)
# The key is not reflected until created_key is closed.
# The 64-bit version of the key should not be available yet.
open_fail
=
lambda
:
OpenKey
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
)
self
.
assertRaises
(
WindowsError
,
open_fail
)
# Now explicitly open the 64-bit version of the key
with
OpenKey
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_ALL_ACCESS
|
KEY_WOW64_64KEY
)
as
key
:
self
.
assertNotEqual
(
key
.
handle
,
0
)
# Make sure the original value we set is there
self
.
assertEqual
(
"32KEY"
,
QueryValue
(
key
,
""
))
# Set a new value, which will get reflected to 32-bit
SetValueEx
(
key
,
""
,
0
,
REG_SZ
,
"64KEY"
)
# Reflection uses a "last-writer wins policy, so the value we set
# on the 64-bit key should be the same on 32-bit
with
OpenKey
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_READ
|
KEY_WOW64_32KEY
)
as
key
:
self
.
assertEqual
(
"64KEY"
,
QueryValue
(
key
,
""
))
finally
:
DeleteKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
KEY_WOW64_32KEY
,
0
)
@
unittest
.
skipUnless
(
HAS_REFLECTION
,
"OS doesn't support reflection"
)
def
test_disable_reflection
(
self
):
# Make use of a key which gets redirected and reflected
try
:
with
CreateKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_ALL_ACCESS
|
KEY_WOW64_32KEY
)
as
created_key
:
# QueryReflectionKey returns whether or not the key is disabled
disabled
=
QueryReflectionKey
(
created_key
)
self
.
assertEqual
(
type
(
disabled
),
bool
)
# HKCU\Software\Classes is reflected by default
self
.
assertFalse
(
disabled
)
DisableReflectionKey
(
created_key
)
self
.
assertTrue
(
QueryReflectionKey
(
created_key
))
# The key is now closed and would normally be reflected to the
# 64-bit area, but let's make sure that didn't happen.
open_fail
=
lambda
:
OpenKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_READ
|
KEY_WOW64_64KEY
)
self
.
assertRaises
(
WindowsError
,
open_fail
)
# Make sure the 32-bit key is actually there
with
OpenKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
0
,
KEY_READ
|
KEY_WOW64_32KEY
)
as
key
:
self
.
assertNotEqual
(
key
.
handle
,
0
)
finally
:
DeleteKeyEx
(
HKEY_CURRENT_USER
,
test_reflect_key_name
,
KEY_WOW64_32KEY
,
0
)
def
test_main
():
support
.
run_unittest
(
WinregTests
)
support
.
run_unittest
(
LocalWinregTests
,
RemoteWinregTests
,
Win64WinregTests
)
if
__name__
==
"__main__"
:
try
:
WinregTests
.
remote_name
=
sys
.
argv
[
sys
.
argv
.
index
(
"--remote"
)
+
1
]
except
(
IndexError
,
ValueError
):
if
not
REMOTE_NAME
:
print
(
"Remote registry calls can be tested using"
,
"'test_winreg.py --remote
\
\
\
\
machine_name'"
)
WinregTests
.
remote_name
=
None
test_main
()
PC/winreg.c
View file @
3035c392
...
...
@@ -88,7 +88,7 @@ PyDoc_STRVAR(ConnectRegistry_doc,
"key is the predefined handle to connect to.
\n
"
"
\n
"
"The return value is the handle of the opened key.
\n
"
"If the function fails, a
n Environment
Error exception is raised."
);
"If the function fails, a
Windows
Error exception is raised."
);
PyDoc_STRVAR
(
CreateKey_doc
,
"key = CreateKey(key, sub_key) - Creates or opens the specified key.
\n
"
...
...
@@ -103,6 +103,21 @@ PyDoc_STRVAR(CreateKey_doc,
"The return value is the handle of the opened key.
\n
"
"If the function fails, an exception is raised."
);
PyDoc_STRVAR
(
CreateKeyEx_doc
,
"key = CreateKeyEx(key, sub_key, res, sam) - Creates or opens the specified key.
\n
"
"
\n
"
"key is an already open key, or one of the predefined HKEY_* constants
\n
"
"sub_key is a string that names the key this method opens or creates.
\n
"
"res is a reserved integer, and must be zero. Default is zero.
\n
"
"sam is an integer that specifies an access mask that describes the desired
\n
"
" If key is one of the predefined keys, sub_key may be None. In that case,
\n
"
" the handle returned is the same key handle passed in to the function.
\n
"
"
\n
"
"If the key already exists, this function opens the existing key
\n
"
"
\n
"
"The return value is the handle of the opened key.
\n
"
"If the function fails, an exception is raised."
);
PyDoc_STRVAR
(
DeleteKey_doc
,
"DeleteKey(key, sub_key) - Deletes the specified key.
\n
"
"
\n
"
...
...
@@ -113,7 +128,22 @@ PyDoc_STRVAR(DeleteKey_doc,
"This method can not delete keys with subkeys.
\n
"
"
\n
"
"If the method succeeds, the entire key, including all of its values,
\n
"
"is removed. If the method fails, an EnvironmentError exception is raised."
);
"is removed. If the method fails, a WindowsError exception is raised."
);
PyDoc_STRVAR
(
DeleteKeyEx_doc
,
"DeleteKeyEx(key, sub_key, sam, res) - Deletes the specified key.
\n
"
"
\n
"
"key is an already open key, or any one of the predefined HKEY_* constants.
\n
"
"sub_key is a string that must be a subkey of the key identified by the key parameter.
\n
"
"res is a reserved integer, and must be zero. Default is zero.
\n
"
"sam is an integer that specifies an access mask that describes the desired
\n
"
" This value must not be None, and the key may not have subkeys.
\n
"
"
\n
"
"This method can not delete keys with subkeys.
\n
"
"
\n
"
"If the method succeeds, the entire key, including all of its values,
\n
"
"is removed. If the method fails, a WindowsError exception is raised.
\n
"
"On unsupported Windows versions, NotImplementedError is raised."
);
PyDoc_STRVAR
(
DeleteValue_doc
,
"DeleteValue(key, value) - Removes a named value from a registry key.
\n
"
...
...
@@ -128,7 +158,7 @@ PyDoc_STRVAR(EnumKey_doc,
"index is an integer that identifies the index of the key to retrieve.
\n
"
"
\n
"
"The function retrieves the name of one subkey each time it is called.
\n
"
"It is typically called repeatedly until a
n Environment
Error exception is
\n
"
"It is typically called repeatedly until a
Windows
Error exception is
\n
"
"raised, indicating no more values are available."
);
PyDoc_STRVAR
(
EnumValue_doc
,
...
...
@@ -137,7 +167,7 @@ PyDoc_STRVAR(EnumValue_doc,
"index is an integer that identifies the index of the value to retrieve.
\n
"
"
\n
"
"The function retrieves the name of one subkey each time it is called.
\n
"
"It is typically called repeatedly, until a
n Environment
Error exception
\n
"
"It is typically called repeatedly, until a
Windows
Error exception
\n
"
"is raised, indicating no more values.
\n
"
"
\n
"
"The result is a tuple of 3 items:
\n
"
...
...
@@ -191,7 +221,7 @@ PyDoc_STRVAR(OpenKey_doc,
" security access for the key. Default is KEY_READ
\n
"
"
\n
"
"The result is a new handle to the specified key
\n
"
"If the function fails, a
n Environment
Error exception is raised."
);
"If the function fails, a
Windows
Error exception is raised."
);
PyDoc_STRVAR
(
OpenKeyEx_doc
,
"See OpenKey()"
);
...
...
@@ -956,6 +986,29 @@ PyCreateKey(PyObject *self, PyObject *args)
return
PyHKEY_FromHKEY
(
retKey
);
}
static
PyObject
*
PyCreateKeyEx
(
PyObject
*
self
,
PyObject
*
args
)
{
HKEY
hKey
;
PyObject
*
obKey
;
wchar_t
*
subKey
;
HKEY
retKey
;
int
res
=
0
;
REGSAM
sam
=
KEY_WRITE
;
long
rc
;
if
(
!
PyArg_ParseTuple
(
args
,
"OZ|ii:CreateKeyEx"
,
&
obKey
,
&
subKey
,
&
res
,
&
sam
))
return
NULL
;
if
(
!
PyHKEY_AsHKEY
(
obKey
,
&
hKey
,
FALSE
))
return
NULL
;
rc
=
RegCreateKeyExW
(
hKey
,
subKey
,
res
,
NULL
,
(
DWORD
)
NULL
,
sam
,
NULL
,
&
retKey
,
NULL
);
if
(
rc
!=
ERROR_SUCCESS
)
return
PyErr_SetFromWindowsErrWithFunction
(
rc
,
"CreateKeyEx"
);
return
PyHKEY_FromHKEY
(
retKey
);
}
static
PyObject
*
PyDeleteKey
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
@@ -974,6 +1027,46 @@ PyDeleteKey(PyObject *self, PyObject *args)
return
Py_None
;
}
static
PyObject
*
PyDeleteKeyEx
(
PyObject
*
self
,
PyObject
*
args
)
{
HKEY
hKey
;
PyObject
*
obKey
;
HMODULE
hMod
;
typedef
LONG
(
WINAPI
*
RDKEFunc
)(
HKEY
,
const
wchar_t
*
,
REGSAM
,
int
);
RDKEFunc
pfn
=
NULL
;
wchar_t
*
subKey
;
long
rc
;
int
res
=
0
;
REGSAM
sam
=
KEY_WOW64_64KEY
;
if
(
!
PyArg_ParseTuple
(
args
,
"Ou|ii:DeleteKeyEx"
,
&
obKey
,
&
subKey
,
&
sam
,
&
res
))
return
NULL
;
if
(
!
PyHKEY_AsHKEY
(
obKey
,
&
hKey
,
FALSE
))
return
NULL
;
/* Only available on 64bit platforms, so we must load it
dynamically. */
hMod
=
GetModuleHandle
(
"advapi32.dll"
);
if
(
hMod
)
pfn
=
(
RDKEFunc
)
GetProcAddress
(
hMod
,
"RegDeleteKeyExW"
);
if
(
!
pfn
)
{
PyErr_SetString
(
PyExc_NotImplementedError
,
"not implemented on this platform"
);
return
NULL
;
}
Py_BEGIN_ALLOW_THREADS
rc
=
(
*
pfn
)(
hKey
,
subKey
,
sam
,
res
);
Py_END_ALLOW_THREADS
if
(
rc
!=
ERROR_SUCCESS
)
return
PyErr_SetFromWindowsErrWithFunction
(
rc
,
"RegDeleteKeyEx"
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
PyDeleteValue
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
@@ -1412,8 +1505,8 @@ PyDisableReflectionKey(PyObject *self, PyObject *args)
if
(
!
PyHKEY_AsHKEY
(
obKey
,
&
hKey
,
FALSE
))
return
NULL
;
/
/
Only available on 64bit platforms, so we must load it
// dynamically.
/
*
Only available on 64bit platforms, so we must load it
dynamically.*/
hMod
=
GetModuleHandle
(
"advapi32.dll"
);
if
(
hMod
)
pfn
=
(
RDRKFunc
)
GetProcAddress
(
hMod
,
...
...
@@ -1448,8 +1541,8 @@ PyEnableReflectionKey(PyObject *self, PyObject *args)
if
(
!
PyHKEY_AsHKEY
(
obKey
,
&
hKey
,
FALSE
))
return
NULL
;
/
/
Only available on 64bit platforms, so we must load it
// dynamically.
/
*
Only available on 64bit platforms, so we must load it
dynamically.*/
hMod
=
GetModuleHandle
(
"advapi32.dll"
);
if
(
hMod
)
pfn
=
(
RERKFunc
)
GetProcAddress
(
hMod
,
...
...
@@ -1485,8 +1578,8 @@ PyQueryReflectionKey(PyObject *self, PyObject *args)
if
(
!
PyHKEY_AsHKEY
(
obKey
,
&
hKey
,
FALSE
))
return
NULL
;
/
/
Only available on 64bit platforms, so we must load it
// dynamically.
/
*
Only available on 64bit platforms, so we must load it
dynamically.*/
hMod
=
GetModuleHandle
(
"advapi32.dll"
);
if
(
hMod
)
pfn
=
(
RQRKFunc
)
GetProcAddress
(
hMod
,
...
...
@@ -1502,14 +1595,16 @@ PyQueryReflectionKey(PyObject *self, PyObject *args)
if
(
rc
!=
ERROR_SUCCESS
)
return
PyErr_SetFromWindowsErrWithFunction
(
rc
,
"RegQueryReflectionKey"
);
return
PyBool_FromLong
(
r
c
);
return
PyBool_FromLong
(
r
esult
);
}
static
struct
PyMethodDef
winreg_methods
[]
=
{
{
"CloseKey"
,
PyCloseKey
,
METH_VARARGS
,
CloseKey_doc
},
{
"ConnectRegistry"
,
PyConnectRegistry
,
METH_VARARGS
,
ConnectRegistry_doc
},
{
"CreateKey"
,
PyCreateKey
,
METH_VARARGS
,
CreateKey_doc
},
{
"CreateKeyEx"
,
PyCreateKeyEx
,
METH_VARARGS
,
CreateKeyEx_doc
},
{
"DeleteKey"
,
PyDeleteKey
,
METH_VARARGS
,
DeleteKey_doc
},
{
"DeleteKeyEx"
,
PyDeleteKeyEx
,
METH_VARARGS
,
DeleteKeyEx_doc
},
{
"DeleteValue"
,
PyDeleteValue
,
METH_VARARGS
,
DeleteValue_doc
},
{
"DisableReflectionKey"
,
PyDisableReflectionKey
,
METH_VARARGS
,
DisableReflectionKey_doc
},
{
"EnableReflectionKey"
,
PyEnableReflectionKey
,
METH_VARARGS
,
EnableReflectionKey_doc
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment