mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Implement #7347. Add CreateKeyEx, DeleteKeyEx, and update _winreg tests.
*ReflectionKey functions used to not be documented or tested, but they are now sufficiently documented and tested on platforms where they apply. Additionally, fixed a bug in QueryReflectionKey which was returning an incorrect value. All tests pass from XP through Windows 7, on 32 and 64-bit platforms.
This commit is contained in:
parent
ef253ac84e
commit
e33fa887d3
3 changed files with 386 additions and 38 deletions
119
PC/_winreg.c
119
PC/_winreg.c
|
@ -89,7 +89,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, an EnvironmentError exception is raised.");
|
||||
"If the function fails, a WindowsError exception is raised.");
|
||||
|
||||
PyDoc_STRVAR(CreateKey_doc,
|
||||
"key = CreateKey(key, sub_key) - Creates or opens the specified key.\n"
|
||||
|
@ -104,6 +104,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"
|
||||
|
@ -114,7 +129,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"
|
||||
|
@ -129,7 +159,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 an EnvironmentError exception is\n"
|
||||
"It is typically called repeatedly until a WindowsError exception is\n"
|
||||
"raised, indicating no more values are available.");
|
||||
|
||||
PyDoc_STRVAR(EnumValue_doc,
|
||||
|
@ -138,7 +168,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 an EnvironmentError exception\n"
|
||||
"It is typically called repeatedly, until a WindowsError exception\n"
|
||||
"is raised, indicating no more values.\n"
|
||||
"\n"
|
||||
"The result is a tuple of 3 items:\n"
|
||||
|
@ -192,7 +222,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, an EnvironmentError exception is raised.");
|
||||
"If the function fails, a WindowsError exception is raised.");
|
||||
|
||||
PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()");
|
||||
|
||||
|
@ -1013,6 +1043,29 @@ PyCreateKey(PyObject *self, PyObject *args)
|
|||
return PyHKEY_FromHKEY(retKey);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCreateKeyEx(PyObject *self, PyObject *args)
|
||||
{
|
||||
HKEY hKey;
|
||||
PyObject *obKey;
|
||||
char *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 = RegCreateKeyEx(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)
|
||||
{
|
||||
|
@ -1031,6 +1084,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 char*, REGSAM, int);
|
||||
RDKEFunc pfn = NULL;
|
||||
char *subKey;
|
||||
long rc;
|
||||
int res = 0;
|
||||
REGSAM sam = KEY_WOW64_64KEY;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Os|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,
|
||||
"RegDeleteKeyExA");
|
||||
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)
|
||||
{
|
||||
|
@ -1479,8 +1572,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,
|
||||
|
@ -1515,8 +1608,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,
|
||||
|
@ -1552,8 +1645,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,
|
||||
|
@ -1569,14 +1662,16 @@ PyQueryReflectionKey(PyObject *self, PyObject *args)
|
|||
if (rc != ERROR_SUCCESS)
|
||||
return PyErr_SetFromWindowsErrWithFunction(rc,
|
||||
"RegQueryReflectionKey");
|
||||
return PyBool_FromLong(rc);
|
||||
return PyBool_FromLong(result);
|
||||
}
|
||||
|
||||
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},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue