From 38feaf0fef244879411f094a7e68f542a6771dea Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 25 May 2008 07:45:51 +0000 Subject: #2879: rename _winreg to winreg. --- Doc/library/_winreg.rst | 438 ---------- Doc/library/windows.rst | 2 +- Doc/library/winreg.rst | 437 ++++++++++ Lib/distutils/msvc9compiler.py | 18 +- Lib/distutils/msvccompiler.py | 14 +- Lib/platform.py | 18 +- Lib/test/test_winreg.py | 2 +- Lib/urllib.py | 24 +- Misc/NEWS | 4 +- Modules/posixmodule.c | 2 +- PC/VC6/pythoncore.dsp | 2 +- PC/VS7.1/python.iss | 4 +- PC/VS7.1/python20.wse | 8 +- PC/VS7.1/pythoncore.vcproj | 2 +- PC/VS8.0/pythoncore.vcproj | 2 +- PC/_winreg.c | 1645 ------------------------------------- PC/config.c | 4 +- PC/winreg.c | 1645 +++++++++++++++++++++++++++++++++++++ PCbuild/pythoncore.vcproj | 2 +- Tools/freeze/extensions_win32.ini | 2 +- Tools/msi/msilib.py | 8 +- Tools/scripts/win_add2path.py | 12 +- 22 files changed, 2148 insertions(+), 2147 deletions(-) delete mode 100644 Doc/library/_winreg.rst create mode 100644 Doc/library/winreg.rst delete mode 100644 PC/_winreg.c create mode 100644 PC/winreg.c diff --git a/Doc/library/_winreg.rst b/Doc/library/_winreg.rst deleted file mode 100644 index ba2994d..0000000 --- a/Doc/library/_winreg.rst +++ /dev/null @@ -1,438 +0,0 @@ - -:mod:`_winreg` -- Windows registry access -========================================= - -.. module:: _winreg - :platform: Windows - :synopsis: Routines and objects for manipulating the Windows registry. -.. sectionauthor:: Mark Hammond - - -These functions expose the Windows registry API to Python. Instead of using an -integer as the registry handle, a handle object is used to ensure that the -handles are closed correctly, even if the programmer neglects to explicitly -close them. - -This module exposes a very low-level interface to the Windows registry; it is -expected that in the future a new ``winreg`` module will be created offering a -higher-level interface to the registry API. - -This module offers the following functions: - - -.. function:: CloseKey(hkey) - - Closes a previously opened registry key. The hkey argument specifies a - previously opened key. - - Note that if *hkey* is not closed using this method (or via - :meth:`handle.Close`), it is closed when the *hkey* object is destroyed by - Python. - - -.. function:: ConnectRegistry(computer_name, key) - - Establishes a connection to a predefined registry handle on another computer, - and returns a :dfn:`handle object` - - *computer_name* is the name of the remote computer, of the form - ``r"\\computername"``. If ``None``, the local computer is used. - - *key* is the predefined handle to connect to. - - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. - - -.. function:: CreateKey(key, sub_key) - - 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. - - 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, an - :exc:`EnvironmentError` exception is raised. - - -.. function:: DeleteKey(key, sub_key) - - Deletes the specified key. - - *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. - - *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, an :exc:`EnvironmentError` exception is raised. - - -.. function:: DeleteValue(key, value) - - Removes a named value from a registry key. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *value* is a string that identifies the value to remove. - - -.. function:: EnumKey(key, index) - - Enumerates subkeys of an open registry key, returning a string. - - *key* is an already open key, or any one of the predefined :const:`HKEY_\*` - constants. - - *index* is an integer that identifies the index of the key to retrieve. - - The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly until an :exc:`EnvironmentError` exception is - raised, indicating, no more values are available. - - -.. function:: EnumValue(key, index) - - Enumerates values of an open registry key, returning a tuple. - - *key* is an already open key, or any one of the predefined :const:`HKEY_\*` - constants. - - *index* is an integer that identifies the index of the value to retrieve. - - The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly, until an :exc:`EnvironmentError` exception is - raised, indicating no more values. - - The result is a tuple of 3 items: - - +-------+--------------------------------------------+ - | Index | Meaning | - +=======+============================================+ - | ``0`` | A string that identifies the value name | - +-------+--------------------------------------------+ - | ``1`` | An object that holds the value data, and | - | | whose type depends on the underlying | - | | registry type | - +-------+--------------------------------------------+ - | ``2`` | An integer that identifies the type of the | - | | value data | - +-------+--------------------------------------------+ - - -.. function:: ExpandEnvironmentStrings(unicode) - - Expands environment strings %NAME% in unicode string like const:`REG_EXPAND_SZ`:: - - >>> ExpandEnvironmentStrings(u"%windir%") - u"C:\\Windows" - - -.. function:: FlushKey(key) - - Writes all the attributes of a key to the registry. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - It is not necessary to call :func:`FlushKey` to change a key. Registry changes are - flushed to disk by the registry using its lazy flusher. Registry changes are - also flushed to disk at system shutdown. Unlike :func:`CloseKey`, the - :func:`FlushKey` method returns only when all the data has been written to the - registry. An application should only call :func:`FlushKey` if it requires - absolute certainty that registry changes are on disk. - - .. note:: - - If you don't know whether a :func:`FlushKey` call is required, it probably - isn't. - - -.. function:: LoadKey(key, sub_key, file_name) - - Creates a subkey under the specified key and stores registration information - from a specified file into that subkey. - - *key* is an already open key, or any of the predefined :const:`HKEY_\*` - constants. - - *sub_key* is a string that identifies the sub_key to load. - - *file_name* is the name of the file to load registry data from. This file must - have been created with the :func:`SaveKey` function. Under the file allocation - table (FAT) file system, the filename may not have an extension. - - A call to LoadKey() fails if the calling process does not have the - :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different than - permissions - see the Win32 documentation for more details. - - If *key* is a handle returned by :func:`ConnectRegistry`, then the path - specified in *fileName* is relative to the remote computer. - - The Win32 documentation implies *key* must be in the :const:`HKEY_USER` or - :const:`HKEY_LOCAL_MACHINE` tree. This may or may not be true. - - -.. function:: OpenKey(key, sub_key[, res=0][, sam=KEY_READ]) - - Opens the specified key, returning a :dfn:`handle object` - - *key* is an already open key, or any one of the predefined :const:`HKEY_\*` - constants. - - *sub_key* is a string that identifies the sub_key to open. - - *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_READ` - - The result is a new handle to the specified key. - - If the function fails, :exc:`EnvironmentError` is raised. - - -.. function:: OpenKeyEx() - - The functionality of :func:`OpenKeyEx` is provided via :func:`OpenKey`, by the - use of default arguments. - - -.. function:: QueryInfoKey(key) - - Returns information about a key, as a tuple. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - The result is a tuple of 3 items: - - +-------+---------------------------------------------+ - | Index | Meaning | - +=======+=============================================+ - | ``0`` | An integer giving the number of sub keys | - | | this key has. | - +-------+---------------------------------------------+ - | ``1`` | An integer giving the number of values this | - | | key has. | - +-------+---------------------------------------------+ - | ``2`` | An integer giving when the key was last | - | | modified (if available) as 100's of | - | | nanoseconds since Jan 1, 1600. | - +-------+---------------------------------------------+ - - -.. function:: QueryValue(key, sub_key) - - Retrieves the unnamed value for a key, as a string - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *sub_key* is a string that holds the name of the subkey with which the value is - associated. If this parameter is ``None`` or empty, the function retrieves the - value set by the :func:`SetValue` method for the key identified by *key*. - - Values in the registry have name, type, and data components. This method - retrieves the data for a key's first value that has a NULL name. But the - underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! - - -.. function:: QueryValueEx(key, value_name) - - Retrieves the type and data for a specified value name associated with an open - registry key. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *value_name* is a string indicating the value to query. - - The result is a tuple of 2 items: - - +-------+-----------------------------------------+ - | Index | Meaning | - +=======+=========================================+ - | ``0`` | The value of the registry item. | - +-------+-----------------------------------------+ - | ``1`` | An integer giving the registry type for | - | | this value. | - +-------+-----------------------------------------+ - - -.. function:: SaveKey(key, file_name) - - Saves the specified key, and all its subkeys to the specified file. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *file_name* is the name of the file to save registry data to. This file cannot - already exist. If this filename includes an extension, it cannot be used on file - allocation table (FAT) file systems by the :meth:`LoadKey`, :meth:`ReplaceKey` - or :meth:`RestoreKey` methods. - - If *key* represents a key on a remote computer, the path described by - *file_name* is relative to the remote computer. The caller of this method must - possess the :const:`SeBackupPrivilege` security privilege. Note that - privileges are different than permissions - see the Win32 documentation for - more details. - - This function passes NULL for *security_attributes* to the API. - - -.. function:: SetValue(key, sub_key, type, value) - - Associates a value with a specified key. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *sub_key* is a string that names the subkey with which the value is associated. - - *type* is an integer that specifies the type of the data. Currently this must be - :const:`REG_SZ`, meaning only strings are supported. Use the :func:`SetValueEx` - function for support for other data types. - - *value* is a string that specifies the new value. - - If the key specified by the *sub_key* parameter does not exist, the SetValue - function creates it. - - Value lengths are limited by available memory. Long values (more than 2048 - bytes) should be stored as files with the filenames stored in the configuration - registry. This helps the registry perform efficiently. - - The key identified by the *key* parameter must have been opened with - :const:`KEY_SET_VALUE` access. - - -.. function:: SetValueEx(key, value_name, reserved, type, value) - - Stores data in the value field of an open registry key. - - *key* is an already open key, or one of the predefined :const:`HKEY_\*` - constants. - - *value_name* is a string that names the subkey with which the value is - associated. - - *type* is an integer that specifies the type of the data. This should be one - of the following constants defined in this module: - - +----------------------------------+---------------------------------------------+ - | Constant | Meaning | - +==================================+=============================================+ - | :const:`REG_BINARY` | Binary data in any form. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_DWORD` | A 32-bit number. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_DWORD_LITTLE_ENDIAN` | A 32-bit number in little-endian format. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_DWORD_BIG_ENDIAN` | A 32-bit number in big-endian format. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_EXPAND_SZ` | Null-terminated string containing | - | | references to environment variables | - | | (``%PATH%``). | - +----------------------------------+---------------------------------------------+ - | :const:`REG_LINK` | A Unicode symbolic link. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_MULTI_SZ` | A sequence of null-terminated strings, | - | | terminated by two null characters. (Python | - | | handles this termination automatically.) | - +----------------------------------+---------------------------------------------+ - | :const:`REG_NONE` | No defined value type. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_RESOURCE_LIST` | A device-driver resource list. | - +----------------------------------+---------------------------------------------+ - | :const:`REG_SZ` | A null-terminated string. | - +----------------------------------+---------------------------------------------+ - - *reserved* can be anything - zero is always passed to the API. - - *value* is a string that specifies the new value. - - This method can also set additional value and type information for the specified - key. The key identified by the key parameter must have been opened with - :const:`KEY_SET_VALUE` access. - - To open the key, use the :func:`CreateKeyEx` or :func:`OpenKey` methods. - - Value lengths are limited by available memory. Long values (more than 2048 - bytes) should be stored as files with the filenames stored in the configuration - registry. This helps the registry perform efficiently. - - -.. _handle-object: - -Registry Handle Objects ------------------------ - -This object wraps a Windows HKEY object, automatically closing it when the -object is destroyed. To guarantee cleanup, you can call either the -:meth:`Close` method on the object, or the :func:`CloseKey` function. - -All registry functions in this module return one of these objects. - -All registry functions in this module which accept a handle object also accept -an integer, however, use of the handle object is encouraged. - -Handle objects provide semantics for :meth:`__bool__` - thus :: - - if handle: - print("Yes") - -will print ``Yes`` if the handle is currently valid (has not been closed or -detached). - -The object also support comparison semantics, so handle objects will compare -true if they both reference the same underlying Windows handle value. - -Handle objects can be converted to an integer (e.g., using the builtin -:func:`int` function), in which case the underlying Windows handle value is -returned. You can also use the :meth:`Detach` method to return the integer -handle, and also disconnect the Windows handle from the handle object. - - -.. method:: PyHKEY.Close() - - Closes the underlying Windows handle. - - If the handle is already closed, no error is raised. - - -.. method:: PyHKEY.Detach() - - Detaches the Windows handle from the handle object. - - The result is an integer that holds the value of the handle before it is - detached. If the handle is already detached or closed, this will return - zero. - - After calling this function, the handle is effectively invalidated, but the - handle is not closed. You would call this function when you need the - underlying Win32 handle to exist beyond the lifetime of the handle object. - -.. method:: PyHKEY.__enter__() - PyHKEY.__exit__(\*exc_info) - - The HKEY object implements :meth:`__enter__` and :meth:`__exit__` and thus - supports the context protocol for the :keyword:`with` statement:: - - with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key: - # ... work with key ... - - will automatically close *key* when control leaves the :keyword:`with` block. - - diff --git a/Doc/library/windows.rst b/Doc/library/windows.rst index b09dd8b..b60d4e4 100644 --- a/Doc/library/windows.rst +++ b/Doc/library/windows.rst @@ -11,5 +11,5 @@ This chapter describes modules that are only available on MS Windows platforms. msilib.rst msvcrt.rst - _winreg.rst + winreg.rst winsound.rst diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst new file mode 100644 index 0000000..f349fdf --- /dev/null +++ b/Doc/library/winreg.rst @@ -0,0 +1,437 @@ +:mod:`winreg` -- Windows registry access +========================================= + +.. module:: winreg + :platform: Windows + :synopsis: Routines and objects for manipulating the Windows registry. +.. sectionauthor:: Mark Hammond + + +These functions expose the Windows registry API to Python. Instead of using an +integer as the registry handle, a handle object is used to ensure that the +handles are closed correctly, even if the programmer neglects to explicitly +close them. + +This module exposes a very low-level interface to the Windows registry; it is +expected that in the future a new ``winreg`` module will be created offering a +higher-level interface to the registry API. + +This module offers the following functions: + + +.. function:: CloseKey(hkey) + + Closes a previously opened registry key. The hkey argument specifies a + previously opened key. + + Note that if *hkey* is not closed using this method (or via + :meth:`handle.Close`), it is closed when the *hkey* object is destroyed by + Python. + + +.. function:: ConnectRegistry(computer_name, key) + + Establishes a connection to a predefined registry handle on another computer, + and returns a :dfn:`handle object` + + *computer_name* is the name of the remote computer, of the form + ``r"\\computername"``. If ``None``, the local computer is used. + + *key* is the predefined handle to connect to. + + The return value is the handle of the opened key. If the function fails, an + :exc:`EnvironmentError` exception is raised. + + +.. function:: CreateKey(key, sub_key) + + 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. + + 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, an + :exc:`EnvironmentError` exception is raised. + + +.. function:: DeleteKey(key, sub_key) + + Deletes the specified key. + + *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. + + *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, an :exc:`EnvironmentError` exception is raised. + + +.. function:: DeleteValue(key, value) + + Removes a named value from a registry key. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *value* is a string that identifies the value to remove. + + +.. function:: EnumKey(key, index) + + Enumerates subkeys of an open registry key, returning a string. + + *key* is an already open key, or any one of the predefined :const:`HKEY_\*` + constants. + + *index* is an integer that identifies the index of the key to retrieve. + + The function retrieves the name of one subkey each time it is called. It is + typically called repeatedly until an :exc:`EnvironmentError` exception is + raised, indicating, no more values are available. + + +.. function:: EnumValue(key, index) + + Enumerates values of an open registry key, returning a tuple. + + *key* is an already open key, or any one of the predefined :const:`HKEY_\*` + constants. + + *index* is an integer that identifies the index of the value to retrieve. + + The function retrieves the name of one subkey each time it is called. It is + typically called repeatedly, until an :exc:`EnvironmentError` exception is + raised, indicating no more values. + + The result is a tuple of 3 items: + + +-------+--------------------------------------------+ + | Index | Meaning | + +=======+============================================+ + | ``0`` | A string that identifies the value name | + +-------+--------------------------------------------+ + | ``1`` | An object that holds the value data, and | + | | whose type depends on the underlying | + | | registry type | + +-------+--------------------------------------------+ + | ``2`` | An integer that identifies the type of the | + | | value data | + +-------+--------------------------------------------+ + + +.. function:: ExpandEnvironmentStrings(unicode) + + Expands environment strings %NAME% in unicode string like const:`REG_EXPAND_SZ`:: + + >>> ExpandEnvironmentStrings(u"%windir%") + u"C:\\Windows" + + +.. function:: FlushKey(key) + + Writes all the attributes of a key to the registry. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + It is not necessary to call :func:`FlushKey` to change a key. Registry changes are + flushed to disk by the registry using its lazy flusher. Registry changes are + also flushed to disk at system shutdown. Unlike :func:`CloseKey`, the + :func:`FlushKey` method returns only when all the data has been written to the + registry. An application should only call :func:`FlushKey` if it requires + absolute certainty that registry changes are on disk. + + .. note:: + + If you don't know whether a :func:`FlushKey` call is required, it probably + isn't. + + +.. function:: LoadKey(key, sub_key, file_name) + + Creates a subkey under the specified key and stores registration information + from a specified file into that subkey. + + *key* is an already open key, or any of the predefined :const:`HKEY_\*` + constants. + + *sub_key* is a string that identifies the sub_key to load. + + *file_name* is the name of the file to load registry data from. This file must + have been created with the :func:`SaveKey` function. Under the file allocation + table (FAT) file system, the filename may not have an extension. + + A call to LoadKey() fails if the calling process does not have the + :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different than + permissions - see the Win32 documentation for more details. + + If *key* is a handle returned by :func:`ConnectRegistry`, then the path + specified in *fileName* is relative to the remote computer. + + The Win32 documentation implies *key* must be in the :const:`HKEY_USER` or + :const:`HKEY_LOCAL_MACHINE` tree. This may or may not be true. + + +.. function:: OpenKey(key, sub_key[, res=0][, sam=KEY_READ]) + + Opens the specified key, returning a :dfn:`handle object` + + *key* is an already open key, or any one of the predefined :const:`HKEY_\*` + constants. + + *sub_key* is a string that identifies the sub_key to open. + + *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_READ` + + The result is a new handle to the specified key. + + If the function fails, :exc:`EnvironmentError` is raised. + + +.. function:: OpenKeyEx() + + The functionality of :func:`OpenKeyEx` is provided via :func:`OpenKey`, by the + use of default arguments. + + +.. function:: QueryInfoKey(key) + + Returns information about a key, as a tuple. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + The result is a tuple of 3 items: + + +-------+---------------------------------------------+ + | Index | Meaning | + +=======+=============================================+ + | ``0`` | An integer giving the number of sub keys | + | | this key has. | + +-------+---------------------------------------------+ + | ``1`` | An integer giving the number of values this | + | | key has. | + +-------+---------------------------------------------+ + | ``2`` | An integer giving when the key was last | + | | modified (if available) as 100's of | + | | nanoseconds since Jan 1, 1600. | + +-------+---------------------------------------------+ + + +.. function:: QueryValue(key, sub_key) + + Retrieves the unnamed value for a key, as a string + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *sub_key* is a string that holds the name of the subkey with which the value is + associated. If this parameter is ``None`` or empty, the function retrieves the + value set by the :func:`SetValue` method for the key identified by *key*. + + Values in the registry have name, type, and data components. This method + retrieves the data for a key's first value that has a NULL name. But the + underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! + + +.. function:: QueryValueEx(key, value_name) + + Retrieves the type and data for a specified value name associated with an open + registry key. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *value_name* is a string indicating the value to query. + + The result is a tuple of 2 items: + + +-------+-----------------------------------------+ + | Index | Meaning | + +=======+=========================================+ + | ``0`` | The value of the registry item. | + +-------+-----------------------------------------+ + | ``1`` | An integer giving the registry type for | + | | this value. | + +-------+-----------------------------------------+ + + +.. function:: SaveKey(key, file_name) + + Saves the specified key, and all its subkeys to the specified file. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *file_name* is the name of the file to save registry data to. This file cannot + already exist. If this filename includes an extension, it cannot be used on file + allocation table (FAT) file systems by the :meth:`LoadKey`, :meth:`ReplaceKey` + or :meth:`RestoreKey` methods. + + If *key* represents a key on a remote computer, the path described by + *file_name* is relative to the remote computer. The caller of this method must + possess the :const:`SeBackupPrivilege` security privilege. Note that + privileges are different than permissions - see the Win32 documentation for + more details. + + This function passes NULL for *security_attributes* to the API. + + +.. function:: SetValue(key, sub_key, type, value) + + Associates a value with a specified key. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *sub_key* is a string that names the subkey with which the value is associated. + + *type* is an integer that specifies the type of the data. Currently this must be + :const:`REG_SZ`, meaning only strings are supported. Use the :func:`SetValueEx` + function for support for other data types. + + *value* is a string that specifies the new value. + + If the key specified by the *sub_key* parameter does not exist, the SetValue + function creates it. + + Value lengths are limited by available memory. Long values (more than 2048 + bytes) should be stored as files with the filenames stored in the configuration + registry. This helps the registry perform efficiently. + + The key identified by the *key* parameter must have been opened with + :const:`KEY_SET_VALUE` access. + + +.. function:: SetValueEx(key, value_name, reserved, type, value) + + Stores data in the value field of an open registry key. + + *key* is an already open key, or one of the predefined :const:`HKEY_\*` + constants. + + *value_name* is a string that names the subkey with which the value is + associated. + + *type* is an integer that specifies the type of the data. This should be one + of the following constants defined in this module: + + +----------------------------------+---------------------------------------------+ + | Constant | Meaning | + +==================================+=============================================+ + | :const:`REG_BINARY` | Binary data in any form. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_DWORD` | A 32-bit number. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_DWORD_LITTLE_ENDIAN` | A 32-bit number in little-endian format. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_DWORD_BIG_ENDIAN` | A 32-bit number in big-endian format. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_EXPAND_SZ` | Null-terminated string containing | + | | references to environment variables | + | | (``%PATH%``). | + +----------------------------------+---------------------------------------------+ + | :const:`REG_LINK` | A Unicode symbolic link. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_MULTI_SZ` | A sequence of null-terminated strings, | + | | terminated by two null characters. (Python | + | | handles this termination automatically.) | + +----------------------------------+---------------------------------------------+ + | :const:`REG_NONE` | No defined value type. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_RESOURCE_LIST` | A device-driver resource list. | + +----------------------------------+---------------------------------------------+ + | :const:`REG_SZ` | A null-terminated string. | + +----------------------------------+---------------------------------------------+ + + *reserved* can be anything - zero is always passed to the API. + + *value* is a string that specifies the new value. + + This method can also set additional value and type information for the specified + key. The key identified by the key parameter must have been opened with + :const:`KEY_SET_VALUE` access. + + To open the key, use the :func:`CreateKeyEx` or :func:`OpenKey` methods. + + Value lengths are limited by available memory. Long values (more than 2048 + bytes) should be stored as files with the filenames stored in the configuration + registry. This helps the registry perform efficiently. + + +.. _handle-object: + +Registry Handle Objects +----------------------- + +This object wraps a Windows HKEY object, automatically closing it when the +object is destroyed. To guarantee cleanup, you can call either the +:meth:`Close` method on the object, or the :func:`CloseKey` function. + +All registry functions in this module return one of these objects. + +All registry functions in this module which accept a handle object also accept +an integer, however, use of the handle object is encouraged. + +Handle objects provide semantics for :meth:`__bool__` - thus :: + + if handle: + print("Yes") + +will print ``Yes`` if the handle is currently valid (has not been closed or +detached). + +The object also support comparison semantics, so handle objects will compare +true if they both reference the same underlying Windows handle value. + +Handle objects can be converted to an integer (e.g., using the builtin +:func:`int` function), in which case the underlying Windows handle value is +returned. You can also use the :meth:`Detach` method to return the integer +handle, and also disconnect the Windows handle from the handle object. + + +.. method:: PyHKEY.Close() + + Closes the underlying Windows handle. + + If the handle is already closed, no error is raised. + + +.. method:: PyHKEY.Detach() + + Detaches the Windows handle from the handle object. + + The result is an integer that holds the value of the handle before it is + detached. If the handle is already detached or closed, this will return + zero. + + After calling this function, the handle is effectively invalidated, but the + handle is not closed. You would call this function when you need the + underlying Win32 handle to exist beyond the lifetime of the handle object. + +.. method:: PyHKEY.__enter__() + PyHKEY.__exit__(\*exc_info) + + The HKEY object implements :meth:`__enter__` and :meth:`__exit__` and thus + supports the context protocol for the :keyword:`with` statement:: + + with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key: + # ... work with key ... + + will automatically close *key* when control leaves the :keyword:`with` block. + + diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index c8d52c4..fdb74ae 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -24,17 +24,17 @@ from distutils.ccompiler import (CCompiler, gen_preprocess_options, from distutils import log from distutils.util import get_platform -import _winreg +import winreg -RegOpenKeyEx = _winreg.OpenKeyEx -RegEnumKey = _winreg.EnumKey -RegEnumValue = _winreg.EnumValue -RegError = _winreg.error +RegOpenKeyEx = winreg.OpenKeyEx +RegEnumKey = winreg.EnumKey +RegEnumValue = winreg.EnumValue +RegError = winreg.error -HKEYS = (_winreg.HKEY_USERS, - _winreg.HKEY_CURRENT_USER, - _winreg.HKEY_LOCAL_MACHINE, - _winreg.HKEY_CLASSES_ROOT) +HKEYS = (winreg.HKEY_USERS, + winreg.HKEY_CURRENT_USER, + winreg.HKEY_LOCAL_MACHINE, + winreg.HKEY_CLASSES_ROOT) VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f" WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows" diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index 71146dc..1cd0f91 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -20,15 +20,15 @@ from distutils import log _can_read_reg = False try: - import _winreg + import winreg _can_read_reg = True - hkey_mod = _winreg + hkey_mod = winreg - RegOpenKeyEx = _winreg.OpenKeyEx - RegEnumKey = _winreg.EnumKey - RegEnumValue = _winreg.EnumValue - RegError = _winreg.error + RegOpenKeyEx = winreg.OpenKeyEx + RegEnumKey = winreg.EnumKey + RegEnumValue = winreg.EnumValue + RegError = winreg.error except ImportError: try: @@ -44,7 +44,7 @@ except ImportError: except ImportError: log.info("Warning: Can't read registry to find the " "necessary compiler setting\n" - "Make sure that Python modules _winreg, " + "Make sure that Python modules winreg, " "win32api or win32con are installed.") pass diff --git a/Lib/platform.py b/Lib/platform.py index d5cf623..415d83f 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -529,9 +529,9 @@ def _win32_getvalue(key,name,default=''): # Use win32api if available from win32api import RegQueryValueEx except ImportError: - # On Python 2.0 and later, emulate using _winreg - import _winreg - RegQueryValueEx = _winreg.QueryValueEx + # On Python 2.0 and later, emulate using winreg + import winreg + RegQueryValueEx = winreg.QueryValueEx try: return RegQueryValueEx(key,name) except: @@ -579,14 +579,14 @@ def win32_ver(release='',version='',csd='',ptype=''): # No emulation possible, so return the defaults... return release,version,csd,ptype else: - # Emulation using _winreg (added in Python 2.0) and + # Emulation using winreg (added in Python 2.0) and # sys.getwindowsversion() (added in Python 2.3) - import _winreg + import winreg GetVersionEx = sys.getwindowsversion - RegQueryValueEx = _winreg.QueryValueEx - RegOpenKeyEx = _winreg.OpenKeyEx - RegCloseKey = _winreg.CloseKey - HKEY_LOCAL_MACHINE = _winreg.HKEY_LOCAL_MACHINE + RegQueryValueEx = winreg.QueryValueEx + RegOpenKeyEx = winreg.OpenKeyEx + RegCloseKey = winreg.CloseKey + HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE VER_PLATFORM_WIN32_WINDOWS = 1 VER_PLATFORM_WIN32_NT = 2 VER_NT_WORKSTATION = 1 diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index e852c69..3dbabc5 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -2,7 +2,7 @@ # Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey -from _winreg import * +from winreg import * import os, sys import unittest diff --git a/Lib/urllib.py b/Lib/urllib.py index 5cdfb46..a5171ef 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -1489,19 +1489,19 @@ elif os.name == 'nt': """ proxies = {} try: - import _winreg + import winreg except ImportError: # Std module, so should be around - but you never know! return proxies try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, - 'ProxyEnable')[0] + proxyEnable = winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] if proxyEnable: # Returned as Unicode but problems if not converted to ASCII - proxyServer = str(_winreg.QueryValueEx(internetSettings, - 'ProxyServer')[0]) + proxyServer = str(winreg.QueryValueEx(internetSettings, + 'ProxyServer')[0]) if '=' in proxyServer: # Per-protocol settings for p in proxyServer.split(';'): @@ -1537,18 +1537,18 @@ elif os.name == 'nt': def proxy_bypass_registry(host): try: - import _winreg + import winreg import re except ImportError: # Std modules, so should be around - but you never know! return 0 try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, - 'ProxyEnable')[0] - proxyOverride = str(_winreg.QueryValueEx(internetSettings, - 'ProxyOverride')[0]) + proxyEnable = winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] + proxyOverride = str(winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0]) # ^^^^ Returned as Unicode but problems if not converted to ASCII except WindowsError: return 0 diff --git a/Misc/NEWS b/Misc/NEWS index 161485f..f385560 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -39,11 +39,13 @@ Core and Builtins Extension Modules ----------------- +- Renamed ``_winreg`` module to ``winreg``. + - Support os.O_ASYNC and fcntl.FASYNC if the constants exist on the platform. - Support for Windows 9x has been removed from the winsound module. -- Fixed #2870: cmathmodule.c compile error +- Fixed #2870: cmathmodule.c compile error. Library ------- diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 33bcbd5..7020d8e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -476,7 +476,7 @@ static PyObject * win32_error(char* function, char* filename) { /* XXX We should pass the function name along in the future. - (_winreg.c also wants to pass the function name.) + (winreg.c also wants to pass the function name.) This would however require an additional param to the Windows error object, which is non-trivial. */ diff --git a/PC/VC6/pythoncore.dsp b/PC/VC6/pythoncore.dsp index 9a369f2..84a5bb5 100644 --- a/PC/VC6/pythoncore.dsp +++ b/PC/VC6/pythoncore.dsp @@ -177,7 +177,7 @@ SOURCE=..\..\Modules\_weakref.c # End Source File # Begin Source File -SOURCE=..\_winreg.c +SOURCE=..\winreg.c # End Source File # Begin Source File diff --git a/PC/VS7.1/python.iss b/PC/VS7.1/python.iss index 70c9bf3..2f6c8b7 100644 --- a/PC/VS7.1/python.iss +++ b/PC/VS7.1/python.iss @@ -155,8 +155,8 @@ Source: libs\select.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Compone Source: DLLs\unicodedata.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main Source: libs\unicodedata.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main -Source: DLLs\_winreg.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main -Source: libs\_winreg.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main +Source: DLLs\winreg.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main +Source: libs\winreg.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main Source: DLLs\winsound.pyd; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Components: main Source: libs\winsound.lib; DestDir: {app}\libs; CopyMode: alwaysoverwrite; Components: main diff --git a/PC/VS7.1/python20.wse b/PC/VS7.1/python20.wse index 6c1c387..8611b8e 100644 --- a/PC/VS7.1/python20.wse +++ b/PC/VS7.1/python20.wse @@ -1713,8 +1713,8 @@ item: Remark Text=Extension module DLLs (.pyd); keep in synch with libs directory next end item: Install File - Source=.\_winreg.pyd - Destination=%MAINDIR%\DLLs\_winreg.pyd + Source=.\winreg.pyd + Destination=%MAINDIR%\DLLs\winreg.pyd Description=Extension modules Flags=0000000000000010 end @@ -1809,8 +1809,8 @@ item: Remark Text=Link libraries (.lib); keep in synch with DLLs above, except that the Python lib lives here. end item: Install File - Source=.\_winreg.lib - Destination=%MAINDIR%\libs\_winreg.lib + Source=.\winreg.lib + Destination=%MAINDIR%\libs\winreg.lib Description=Link library files Flags=0000000000000010 end diff --git a/PC/VS7.1/pythoncore.vcproj b/PC/VS7.1/pythoncore.vcproj index f06d626..38982f4 100644 --- a/PC/VS7.1/pythoncore.vcproj +++ b/PC/VS7.1/pythoncore.vcproj @@ -401,7 +401,7 @@ RelativePath="..\..\Modules\_weakref.c"> + RelativePath="..\..\Pc\winreg.c"> diff --git a/PC/VS8.0/pythoncore.vcproj b/PC/VS8.0/pythoncore.vcproj index 8e59dae..75414ce 100644 --- a/PC/VS8.0/pythoncore.vcproj +++ b/PC/VS8.0/pythoncore.vcproj @@ -1559,7 +1559,7 @@ > \n" -"OpenKeyEx() - Opens the specified key.\n" -"QueryValue() - Retrieves the value associated with the unnamed value for a\n" -" specified key in the registry.\n" -"QueryValueEx() - Retrieves the type and data for a specified value name\n" -" associated with an open registry key.\n" -"QueryInfoKey() - Returns information about the specified key.\n" -"SaveKey() - Saves the specified key, and all its subkeys a file.\n" -"SetValue() - Associates a value with a specified key.\n" -"SetValueEx() - Stores data in the value field of an open registry key.\n" -"\n" -"Special objects:\n" -"\n" -"HKEYType -- type object for HKEY objects\n" -"error -- exception raised for Win32 errors\n" -"\n" -"Integer constants:\n" -"Many constants are defined - see the documentation for each function\n" -"to see what constants are used, and where."); - - -PyDoc_STRVAR(CloseKey_doc, -"CloseKey(hkey) - Closes a previously opened registry key.\n" -"\n" -"The hkey argument specifies a previously opened key.\n" -"\n" -"Note that if the key is not closed using this method, it will be\n" -"closed when the hkey object is destroyed by Python."); - -PyDoc_STRVAR(ConnectRegistry_doc, -"key = ConnectRegistry(computer_name, key) - " -"Establishes a connection to a predefined registry handle on another computer.\n" -"\n" -"computer_name is the name of the remote computer, of the form \\\\computername.\n" -" If None, the local computer is used.\n" -"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."); - -PyDoc_STRVAR(CreateKey_doc, -"key = CreateKey(key, sub_key) - 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" -" 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" -"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" -" 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, an EnvironmentError exception is raised."); - -PyDoc_STRVAR(DeleteValue_doc, -"DeleteValue(key, value) - Removes a named value from a registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value is a string that identifies the value to remove."); - -PyDoc_STRVAR(EnumKey_doc, -"string = EnumKey(key, index) - Enumerates subkeys of an open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"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" -"raised, indicating no more values are available."); - -PyDoc_STRVAR(EnumValue_doc, -"tuple = EnumValue(key, index) - Enumerates values of an open registry key.\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"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" -"is raised, indicating no more values.\n" -"\n" -"The result is a tuple of 3 items:\n" -"value_name is a string that identifies the value.\n" -"value_data is an object that holds the value data, and whose type depends\n" -" on the underlying registry type.\n" -"data_type is an integer that identifies the type of the value data."); - -PyDoc_STRVAR(ExpandEnvironmentStrings_doc, -"string = ExpandEnvironmentStrings(string) - Expand environment vars.\n"); - -PyDoc_STRVAR(FlushKey_doc, -"FlushKey(key) - Writes all the attributes of a key to the registry.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"\n" -"It is not necessary to call RegFlushKey to change a key.\n" -"Registry changes are flushed to disk by the registry using its lazy flusher.\n" -"Registry changes are also flushed to disk at system shutdown.\n" -"Unlike CloseKey(), the FlushKey() method returns only when all the data has\n" -"been written to the registry.\n" -"An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.\n" -"If you don't know whether a FlushKey() call is required, it probably isn't."); - -PyDoc_STRVAR(LoadKey_doc, -"LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key\n" -"and stores registration information from a specified file into that subkey.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that identifies the sub_key to load\n" -"file_name is the name of the file to load registry data from.\n" -" This file must have been created with the SaveKey() function.\n" -" Under the file allocation table (FAT) file system, the filename may not\n" -"have an extension.\n" -"\n" -"A call to LoadKey() fails if the calling process does not have the\n" -"SE_RESTORE_PRIVILEGE privilege.\n" -"\n" -"If key is a handle returned by ConnectRegistry(), then the path specified\n" -"in fileName is relative to the remote computer.\n" -"\n" -"The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"); - -PyDoc_STRVAR(OpenKey_doc, -"key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens 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 identifies the sub_key to open\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" -" 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."); - -PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()"); - -PyDoc_STRVAR(QueryInfoKey_doc, -"tuple = QueryInfoKey(key) - Returns information about a key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"\n" -"The result is a tuple of 3 items:" -"An integer that identifies the number of sub keys this key has.\n" -"An integer that identifies the number of values this key has.\n" -"A long integer that identifies when the key was last modified (if available)\n" -" as 100's of nanoseconds since Jan 1, 1600."); - -PyDoc_STRVAR(QueryValue_doc, -"string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that holds the name of the subkey with which the value\n" -" is associated. If this parameter is None or empty, the function retrieves\n" -" the value set by the SetValue() method for the key identified by key." -"\n" -"Values in the registry have name, type, and data components. This method\n" -"retrieves the data for a key's first value that has a NULL name.\n" -"But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!"); - -PyDoc_STRVAR(QueryValueEx_doc, -"value,type_id = QueryValueEx(key, value_name) - Retrieves the type and data for a specified value name associated with an open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value_name is a string indicating the value to query"); - -PyDoc_STRVAR(SaveKey_doc, -"SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"file_name is the name of the file to save registry data to.\n" -" This file cannot already exist. If this filename includes an extension,\n" -" it cannot be used on file allocation table (FAT) file systems by the\n" -" LoadKey(), ReplaceKey() or RestoreKey() methods.\n" -"\n" -"If key represents a key on a remote computer, the path described by\n" -"file_name is relative to the remote computer.\n" -"The caller of this method must possess the SeBackupPrivilege security privilege.\n" -"This function passes NULL for security_attributes to the API."); - -PyDoc_STRVAR(SetValue_doc, -"SetValue(key, sub_key, type, value) - Associates a value with a 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 names the subkey with which the value is associated.\n" -"type is an integer that specifies the type of the data. Currently this\n" -" must be REG_SZ, meaning only strings are supported.\n" -"value is a string that specifies the new value.\n" -"\n" -"If the key specified by the sub_key parameter does not exist, the SetValue\n" -"function creates it.\n" -"\n" -"Value lengths are limited by available memory. Long values (more than\n" -"2048 bytes) should be stored as files with the filenames stored in \n" -"the configuration registry. This helps the registry perform efficiently.\n" -"\n" -"The key identified by the key parameter must have been opened with\n" -"KEY_SET_VALUE access."); - -PyDoc_STRVAR(SetValueEx_doc, -"SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value_name is a string containing the name of the value to set, or None\n" -"type is an integer that specifies the type of the data. This should be one of:\n" -" REG_BINARY -- Binary data in any form.\n" -" REG_DWORD -- A 32-bit number.\n" -" REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n" -" REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n" -" REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references\n" -" to environment variables (for example, %PATH%).\n" -" REG_LINK -- A Unicode symbolic link.\n" -" REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by\n" -" two null characters. Note that Python handles this\n" -" termination automatically.\n" -" REG_NONE -- No defined value type.\n" -" REG_RESOURCE_LIST -- A device-driver resource list.\n" -" REG_SZ -- A null-terminated string.\n" -"reserved can be anything - zero is always passed to the API.\n" -"value is a string that specifies the new value.\n" -"\n" -"This method can also set additional value and type information for the\n" -"specified key. The key identified by the key parameter must have been\n" -"opened with KEY_SET_VALUE access.\n" -"\n" -"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n" -"\n" -"Value lengths are limited by available memory. Long values (more than\n" -"2048 bytes) should be stored as files with the filenames stored in \n" -"the configuration registry. This helps the registry perform efficiently."); - -PyDoc_STRVAR(DisableReflectionKey_doc, -"Disables registry reflection for 32-bit processes running on a 64-bit\n" -"Operating System. Will generally raise NotImplemented if executed on\n" -"a 32-bit Operating System.\n" -"If the key is not on the reflection list, the function succeeds but has no effect.\n" -"Disabling reflection for a key does not affect reflection of any subkeys."); - -PyDoc_STRVAR(EnableReflectionKey_doc, -"Restores registry reflection for the specified disabled key.\n" -"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n" -"Restoring reflection for a key does not affect reflection of any subkeys."); - -PyDoc_STRVAR(QueryReflectionKey_doc, -"bool = QueryReflectionKey(hkey) - Determines the reflection state for the specified key.\n" -"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n"); - -/* PyHKEY docstrings */ -PyDoc_STRVAR(PyHKEY_doc, -"PyHKEY Object - A Python object, representing a win32 registry key.\n" -"\n" -"This object wraps a Windows HKEY object, automatically closing it when\n" -"the object is destroyed. To guarantee cleanup, you can call either\n" -"the Close() method on the PyHKEY, or the CloseKey() method.\n" -"\n" -"All functions which accept a handle object also accept an integer - \n" -"however, use of the handle object is encouraged.\n" -"\n" -"Functions:\n" -"Close() - Closes the underlying handle.\n" -"Detach() - Returns the integer Win32 handle, detaching it from the object\n" -"\n" -"Properties:\n" -"handle - The integer Win32 handle.\n" -"\n" -"Operations:\n" -"__bool__ - Handles with an open object return true, otherwise false.\n" -"__int__ - Converting a handle to an integer returns the Win32 handle.\n" -"__cmp__ - Handle objects are compared using the handle value."); - - -PyDoc_STRVAR(PyHKEY_Close_doc, -"key.Close() - Closes the underlying Windows handle.\n" -"\n" -"If the handle is already closed, no error is raised."); - -PyDoc_STRVAR(PyHKEY_Detach_doc, -"int = key.Detach() - Detaches the Windows handle from the handle object.\n" -"\n" -"The result is the value of the handle before it is detached. If the\n" -"handle is already detached, this will return zero.\n" -"\n" -"After calling this function, the handle is effectively invalidated,\n" -"but the handle is not closed. You would call this function when you\n" -"need the underlying win32 handle to exist beyond the lifetime of the\n" -"handle object.\n" -"On 64 bit windows, the result of this function is a long integer"); - - -/************************************************************************ - - The PyHKEY object definition - -************************************************************************/ -typedef struct { - PyObject_VAR_HEAD - HKEY hkey; -} PyHKEYObject; - -#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type) - -static char *failMsg = "bad operand type"; - -static PyObject * -PyHKEY_unaryFailureFunc(PyObject *ob) -{ - PyErr_SetString(PyExc_TypeError, failMsg); - return NULL; -} -static PyObject * -PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2) -{ - PyErr_SetString(PyExc_TypeError, failMsg); - return NULL; -} -static PyObject * -PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3) -{ - PyErr_SetString(PyExc_TypeError, failMsg); - return NULL; -} - -static void -PyHKEY_deallocFunc(PyObject *ob) -{ - /* Can not call PyHKEY_Close, as the ob->tp_type - has already been cleared, thus causing the type - check to fail! - */ - PyHKEYObject *obkey = (PyHKEYObject *)ob; - if (obkey->hkey) - RegCloseKey((HKEY)obkey->hkey); - PyObject_DEL(ob); -} - -static int -PyHKEY_boolFunc(PyObject *ob) -{ - return ((PyHKEYObject *)ob)->hkey != 0; -} - -static PyObject * -PyHKEY_intFunc(PyObject *ob) -{ - PyHKEYObject *pyhkey = (PyHKEYObject *)ob; - return PyLong_FromVoidPtr(pyhkey->hkey); -} - -static PyObject * -PyHKEY_strFunc(PyObject *ob) -{ - PyHKEYObject *pyhkey = (PyHKEYObject *)ob; - return PyUnicode_FromFormat("", pyhkey->hkey); -} - -static int -PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2) -{ - PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1; - PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2; - return pyhkey1 == pyhkey2 ? 0 : - (pyhkey1 < pyhkey2 ? -1 : 1); -} - -static long -PyHKEY_hashFunc(PyObject *ob) -{ - /* Just use the address. - XXX - should we use the handle value? - */ - return _Py_HashPointer(ob); -} - - -static PyNumberMethods PyHKEY_NumberMethods = -{ - PyHKEY_binaryFailureFunc, /* nb_add */ - PyHKEY_binaryFailureFunc, /* nb_subtract */ - PyHKEY_binaryFailureFunc, /* nb_multiply */ - PyHKEY_binaryFailureFunc, /* nb_remainder */ - PyHKEY_binaryFailureFunc, /* nb_divmod */ - PyHKEY_ternaryFailureFunc, /* nb_power */ - PyHKEY_unaryFailureFunc, /* nb_negative */ - PyHKEY_unaryFailureFunc, /* nb_positive */ - PyHKEY_unaryFailureFunc, /* nb_absolute */ - PyHKEY_boolFunc, /* nb_bool */ - PyHKEY_unaryFailureFunc, /* nb_invert */ - PyHKEY_binaryFailureFunc, /* nb_lshift */ - PyHKEY_binaryFailureFunc, /* nb_rshift */ - PyHKEY_binaryFailureFunc, /* nb_and */ - PyHKEY_binaryFailureFunc, /* nb_xor */ - PyHKEY_binaryFailureFunc, /* nb_or */ - 0, /* nb_reserved */ - PyHKEY_intFunc, /* nb_int */ - PyHKEY_unaryFailureFunc, /* nb_long */ - PyHKEY_unaryFailureFunc, /* nb_float */ - PyHKEY_unaryFailureFunc, /* nb_oct */ - PyHKEY_unaryFailureFunc, /* nb_hex */ -}; - - -/* fwd declare __getattr__ */ -static PyObject *PyHKEY_getattr(PyObject *self, const char *name); - -/* The type itself */ -PyTypeObject PyHKEY_Type = -{ - PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */ - "PyHKEY", - sizeof(PyHKEYObject), - 0, - PyHKEY_deallocFunc, /* tp_dealloc */ - 0, /* tp_print */ - PyHKEY_getattr, /* tp_getattr */ - 0, /* tp_setattr */ - PyHKEY_compareFunc, /* tp_compare */ - 0, /* tp_repr */ - &PyHKEY_NumberMethods, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyHKEY_hashFunc, /* tp_hash */ - 0, /* tp_call */ - PyHKEY_strFunc, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - PyHKEY_doc, /* tp_doc */ -}; - -#define OFF(e) offsetof(PyHKEYObject, e) - -static PyMemberDef PyHKEY_memberlist[] = { - {"handle", T_INT, OFF(hkey), READONLY}, - {NULL} /* Sentinel */ -}; - -/************************************************************************ - - The PyHKEY object methods - -************************************************************************/ -static PyObject * -PyHKEY_CloseMethod(PyObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":Close")) - return NULL; - if (!PyHKEY_Close(self)) - return NULL; - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyHKEY_DetachMethod(PyObject *self, PyObject *args) -{ - void* ret; - PyHKEYObject *pThis = (PyHKEYObject *)self; - if (!PyArg_ParseTuple(args, ":Detach")) - return NULL; - ret = (void*)pThis->hkey; - pThis->hkey = 0; - return PyLong_FromVoidPtr(ret); -} - -static PyObject * -PyHKEY_Enter(PyObject *self) -{ - Py_XINCREF(self); - return self; -} - -static PyObject * -PyHKEY_Exit(PyObject *self, PyObject *args) -{ - if (!PyHKEY_Close(self)) - return NULL; - Py_RETURN_NONE; -} - - -static struct PyMethodDef PyHKEY_methods[] = { - {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, - {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, - {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, - {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, - {NULL} -}; - -/*static*/ PyObject * -PyHKEY_getattr(PyObject *self, const char *name) -{ - PyObject *res; - - res = Py_FindMethod(PyHKEY_methods, self, name); - if (res != NULL) - return res; - PyErr_Clear(); - if (strcmp(name, "handle") == 0) - return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey); - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", - Py_TYPE(self)->tp_name, name); - return NULL; -} - -/************************************************************************ - The public PyHKEY API (well, not public yet :-) -************************************************************************/ -PyObject * -PyHKEY_New(HKEY hInit) -{ - PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type); - if (key) - key->hkey = hInit; - return (PyObject *)key; -} - -BOOL -PyHKEY_Close(PyObject *ob_handle) -{ - LONG rc; - PyHKEYObject *key; - - if (!PyHKEY_Check(ob_handle)) { - PyErr_SetString(PyExc_TypeError, "bad operand type"); - return FALSE; - } - key = (PyHKEYObject *)ob_handle; - rc = key->hkey ? RegCloseKey((HKEY)key->hkey) : ERROR_SUCCESS; - key->hkey = 0; - if (rc != ERROR_SUCCESS) - PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); - return rc == ERROR_SUCCESS; -} - -BOOL -PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) -{ - if (ob == Py_None) { - if (!bNoneOK) { - PyErr_SetString( - PyExc_TypeError, - "None is not a valid HKEY in this context"); - return FALSE; - } - *pHANDLE = (HKEY)0; - } - else if (PyHKEY_Check(ob)) { - PyHKEYObject *pH = (PyHKEYObject *)ob; - *pHANDLE = pH->hkey; - } - else if (PyLong_Check(ob)) { - /* We also support integers */ - PyErr_Clear(); - *pHANDLE = (HKEY)PyLong_AsVoidPtr(ob); - if (PyErr_Occurred()) - return FALSE; - } - else { - PyErr_SetString( - PyExc_TypeError, - "The object is not a PyHKEY object"); - return FALSE; - } - return TRUE; -} - -PyObject * -PyHKEY_FromHKEY(HKEY h) -{ - PyHKEYObject *op; - - /* Inline PyObject_New */ - op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject)); - if (op == NULL) - return PyErr_NoMemory(); - PyObject_INIT(op, &PyHKEY_Type); - op->hkey = h; - return (PyObject *)op; -} - - -/************************************************************************ - The module methods -************************************************************************/ -BOOL -PyWinObject_CloseHKEY(PyObject *obHandle) -{ - BOOL ok; - if (PyHKEY_Check(obHandle)) { - ok = PyHKEY_Close(obHandle); - } -#if SIZEOF_LONG >= SIZEOF_HKEY - else if (PyLong_Check(obHandle)) { - long rc = RegCloseKey((HKEY)PyLong_AsLong(obHandle)); - ok = (rc == ERROR_SUCCESS); - if (!ok) - PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); - } -#else - else if (PyLong_Check(obHandle)) { - long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle)); - ok = (rc == ERROR_SUCCESS); - if (!ok) - PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); - } -#endif - else { - PyErr_SetString( - PyExc_TypeError, - "A handle must be a HKEY object or an integer"); - return FALSE; - } - return ok; -} - - -/* - Private Helper functions for the registry interfaces - -** Note that fixupMultiSZ and countString have both had changes -** made to support "incorrect strings". The registry specification -** calls for strings to be terminated with 2 null bytes. It seems -** some commercial packages install strings which dont conform, -** causing this code to fail - however, "regedit" etc still work -** with these strings (ie only we dont!). -*/ -static void -fixupMultiSZ(wchar_t **str, wchar_t *data, int len) -{ - wchar_t *P; - int i; - wchar_t *Q; - - Q = data + len; - for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) { - str[i] = P; - for(; *P != '\0'; P++) - ; - } -} - -static int -countStrings(wchar_t *data, int len) -{ - int strings; - wchar_t *P; - wchar_t *Q = data + len; - - for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++) - for (; P < Q && *P != '\0'; P++) - ; - return strings; -} - -/* Convert PyObject into Registry data. - Allocates space as needed. */ -static BOOL -Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) -{ - Py_ssize_t i,j; - switch (typ) { - case REG_DWORD: - if (value != Py_None && !PyLong_Check(value)) - return FALSE; - *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1); - if (*retDataBuf==NULL){ - PyErr_NoMemory(); - return FALSE; - } - *retDataSize = sizeof(DWORD); - if (value == Py_None) { - DWORD zero = 0; - memcpy(*retDataBuf, &zero, sizeof(DWORD)); - } - else { - DWORD d = PyLong_AsLong(value); - memcpy(*retDataBuf, &d, sizeof(DWORD)); - } - break; - case REG_SZ: - case REG_EXPAND_SZ: - { - if (value == Py_None) - *retDataSize = 1; - else { - if (!PyUnicode_Check(value)) - return FALSE; - - *retDataSize = 2 + PyUnicode_GET_DATA_SIZE(value); - } - *retDataBuf = (BYTE *)PyMem_NEW(DWORD, *retDataSize); - if (*retDataBuf==NULL){ - PyErr_NoMemory(); - return FALSE; - } - if (value == Py_None) - wcscpy((wchar_t *)*retDataBuf, L""); - else - wcscpy((wchar_t *)*retDataBuf, - PyUnicode_AS_UNICODE(value)); - break; - } - case REG_MULTI_SZ: - { - DWORD size = 0; - wchar_t *P; - - if (value == Py_None) - i = 0; - else { - if (!PyList_Check(value)) - return FALSE; - i = PyList_Size(value); - } - for (j = 0; j < i; j++) - { - PyObject *t; - t = PyList_GET_ITEM(value, j); - if (!PyUnicode_Check(t)) - return FALSE; - size += 2 + PyUnicode_GET_DATA_SIZE(t); - } - - *retDataSize = size + 2; - *retDataBuf = (BYTE *)PyMem_NEW(char, - *retDataSize); - if (*retDataBuf==NULL){ - PyErr_NoMemory(); - return FALSE; - } - P = (wchar_t *)*retDataBuf; - - for (j = 0; j < i; j++) - { - PyObject *t; - t = PyList_GET_ITEM(value, j); - wcscpy(P, PyUnicode_AS_UNICODE(t)); - P += 1 + wcslen( - PyUnicode_AS_UNICODE(t)); - } - /* And doubly-terminate the list... */ - *P = '\0'; - break; - } - case REG_BINARY: - /* ALSO handle ALL unknown data types here. Even if we can't - support it natively, we should handle the bits. */ - default: - if (value == Py_None) - *retDataSize = 0; - else { - Py_buffer view; - - if (!PyObject_CheckBuffer(value)) { - PyErr_Format(PyExc_TypeError, - "Objects of type '%s' can not " - "be used as binary registry values", - value->ob_type->tp_name); - return FALSE; - } - - if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) - return FALSE; - - *retDataBuf = (BYTE *)PyMem_NEW(char, view.len); - if (*retDataBuf==NULL){ - PyObject_ReleaseBuffer(value, &view); - PyErr_NoMemory(); - return FALSE; - } - *retDataSize = view.len; - memcpy(*retDataBuf, view.buf, view.len); - PyObject_ReleaseBuffer(value, &view); - } - break; - } - return TRUE; -} - -/* Convert Registry data into PyObject*/ -static PyObject * -Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) -{ - PyObject *obData; - - switch (typ) { - case REG_DWORD: - if (retDataSize == 0) - obData = PyLong_FromLong(0); - else - obData = PyLong_FromLong(*(int *)retDataBuf); - break; - case REG_SZ: - case REG_EXPAND_SZ: - { - /* the buffer may or may not have a trailing NULL */ - wchar_t *data = (wchar_t *)retDataBuf; - int len = retDataSize / 2; - if (retDataSize && data[len-1] == '\0') - retDataSize -= 2; - if (retDataSize <= 0) - data = L""; - obData = PyUnicode_FromUnicode(data, retDataSize/2); - break; - } - case REG_MULTI_SZ: - if (retDataSize == 0) - obData = PyList_New(0); - else - { - int index = 0; - wchar_t *data = (wchar_t *)retDataBuf; - int len = retDataSize / 2; - int s = countStrings(data, len); - wchar_t **str = (wchar_t **)malloc(sizeof(wchar_t *)*s); - if (str == NULL) - return PyErr_NoMemory(); - - fixupMultiSZ(str, data, len); - obData = PyList_New(s); - if (obData == NULL) - return NULL; - for (index = 0; index < s; index++) - { - size_t len = wcslen(str[index]); - if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "registry string is too long for a Python string"); - Py_DECREF(obData); - return NULL; - } - PyList_SetItem(obData, - index, - PyUnicode_FromUnicode(str[index], len)); - } - free(str); - - break; - } - case REG_BINARY: - /* ALSO handle ALL unknown data types here. Even if we can't - support it natively, we should handle the bits. */ - default: - if (retDataSize == 0) { - Py_INCREF(Py_None); - obData = Py_None; - } - else - obData = PyBytes_FromStringAndSize( - (char *)retDataBuf, retDataSize); - break; - } - return obData; -} - -/* The Python methods */ - -static PyObject * -PyCloseKey(PyObject *self, PyObject *args) -{ - PyObject *obKey; - if (!PyArg_ParseTuple(args, "O:CloseKey", &obKey)) - return NULL; - if (!PyHKEY_Close(obKey)) - return NULL; - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyConnectRegistry(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *szCompName = NULL; - HKEY retKey; - long rc; - if (!PyArg_ParseTuple(args, "ZO:ConnectRegistry", &szCompName, &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rc = RegConnectRegistryW(szCompName, hKey, &retKey); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "ConnectRegistry"); - return PyHKEY_FromHKEY(retKey); -} - -static PyObject * -PyCreateKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - HKEY retKey; - long rc; - if (!PyArg_ParseTuple(args, "OZ:CreateKey", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - rc = RegCreateKeyW(hKey, subKey, &retKey); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey"); - return PyHKEY_FromHKEY(retKey); -} - -static PyObject * -PyDeleteKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - long rc; - if (!PyArg_ParseTuple(args, "Ou:DeleteKey", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - rc = RegDeleteKeyW(hKey, subKey ); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyDeleteValue(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - long rc; - if (!PyArg_ParseTuple(args, "OZ:DeleteValue", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rc = RegDeleteValueW(hKey, subKey); - Py_END_ALLOW_THREADS - if (rc !=ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegDeleteValue"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyEnumKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - int index; - long rc; - PyObject *retStr; - wchar_t tmpbuf[256]; /* max key name length is 255 */ - DWORD len = sizeof(tmpbuf); /* includes NULL terminator */ - - if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - rc = RegEnumKeyExW(hKey, index, tmpbuf, &len, NULL, NULL, NULL, NULL); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx"); - - retStr = PyUnicode_FromUnicode(tmpbuf, len); - return retStr; /* can be NULL */ -} - -static PyObject * -PyEnumValue(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - int index; - long rc; - wchar_t *retValueBuf; - BYTE *retDataBuf; - DWORD retValueSize; - DWORD retDataSize; - DWORD typ; - PyObject *obData; - PyObject *retVal; - - if (!PyArg_ParseTuple(args, "Oi:EnumValue", &obKey, &index)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - if ((rc = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, - &retValueSize, &retDataSize, NULL, NULL)) - != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryInfoKey"); - ++retValueSize; /* include null terminators */ - ++retDataSize; - retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); - if (retValueBuf == NULL) - return PyErr_NoMemory(); - retDataBuf = (BYTE *)PyMem_Malloc(retDataSize); - if (retDataBuf == NULL) { - PyMem_Free(retValueBuf); - return PyErr_NoMemory(); - } - - Py_BEGIN_ALLOW_THREADS - rc = RegEnumValueW(hKey, - index, - retValueBuf, - &retValueSize, - NULL, - &typ, - retDataBuf, - &retDataSize); - Py_END_ALLOW_THREADS - - if (rc != ERROR_SUCCESS) { - retVal = PyErr_SetFromWindowsErrWithFunction(rc, - "PyRegEnumValue"); - goto fail; - } - obData = Reg2Py(retDataBuf, retDataSize, typ); - if (obData == NULL) { - retVal = NULL; - goto fail; - } - retVal = Py_BuildValue("uOi", retValueBuf, obData, typ); - Py_DECREF(obData); - fail: - PyMem_Free(retValueBuf); - PyMem_Free(retDataBuf); - return retVal; -} - -static PyObject * -PyExpandEnvironmentStrings(PyObject *self, PyObject *args) -{ - Py_UNICODE *retValue = NULL; - Py_UNICODE *src; - DWORD retValueSize; - DWORD rc; - PyObject *o; - - if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src)) - return NULL; - - retValueSize = ExpandEnvironmentStringsW(src, retValue, 0); - if (retValueSize == 0) { - return PyErr_SetFromWindowsErrWithFunction(retValueSize, - "ExpandEnvironmentStrings"); - } - retValue = (Py_UNICODE *)PyMem_Malloc(retValueSize * sizeof(Py_UNICODE)); - if (retValue == NULL) { - return PyErr_NoMemory(); - } - - rc = ExpandEnvironmentStringsW(src, retValue, retValueSize); - if (rc == 0) { - PyMem_Free(retValue); - return PyErr_SetFromWindowsErrWithFunction(retValueSize, - "ExpandEnvironmentStrings"); - } - o = PyUnicode_FromUnicode(retValue, wcslen(retValue)); - PyMem_Free(retValue); - return o; -} - -static PyObject * -PyFlushKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - long rc; - if (!PyArg_ParseTuple(args, "O:FlushKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rc = RegFlushKey(hKey); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey"); - Py_INCREF(Py_None); - return Py_None; -} -static PyObject * -PyLoadKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - wchar_t *fileName; - - long rc; - if (!PyArg_ParseTuple(args, "Ouu:LoadKey", &obKey, &subKey, &fileName)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rc = RegLoadKeyW(hKey, subKey, fileName ); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyOpenKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - - wchar_t *subKey; - int res = 0; - HKEY retKey; - long rc; - REGSAM sam = KEY_READ; - if (!PyArg_ParseTuple(args, "OZ|ii:OpenKey", &obKey, &subKey, - &res, &sam)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - rc = RegOpenKeyExW(hKey, subKey, res, sam, &retKey); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); - return PyHKEY_FromHKEY(retKey); -} - - -static PyObject * -PyQueryInfoKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - long rc; - DWORD nSubKeys, nValues; - FILETIME ft; - LARGE_INTEGER li; - PyObject *l; - PyObject *ret; - if (!PyArg_ParseTuple(args, "O:QueryInfoKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if ((rc = RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubKeys, NULL, NULL, - &nValues, NULL, NULL, NULL, &ft)) - != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey"); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - l = PyLong_FromLongLong(li.QuadPart); - if (l == NULL) - return NULL; - ret = Py_BuildValue("iiO", nSubKeys, nValues, l); - Py_DECREF(l); - return ret; -} - -static PyObject * -PyQueryValue(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - long rc; - PyObject *retStr; - wchar_t *retBuf; - long bufSize = 0; - - if (!PyArg_ParseTuple(args, "OZ:QueryValue", &obKey, &subKey)) - return NULL; - - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if ((rc = RegQueryValueW(hKey, subKey, NULL, &bufSize)) - != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryValue"); - retBuf = (wchar_t *)PyMem_Malloc(bufSize); - if (retBuf == NULL) - return PyErr_NoMemory(); - - if ((rc = RegQueryValueW(hKey, subKey, retBuf, &bufSize)) - != ERROR_SUCCESS) { - PyMem_Free(retBuf); - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryValue"); - } - - retStr = PyUnicode_FromUnicode(retBuf, wcslen(retBuf)); - PyMem_Free(retBuf); - return retStr; -} - -static PyObject * -PyQueryValueEx(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *valueName; - - long rc; - BYTE *retBuf; - DWORD bufSize = 0; - DWORD typ; - PyObject *obData; - PyObject *result; - - if (!PyArg_ParseTuple(args, "OZ:QueryValueEx", &obKey, &valueName)) - return NULL; - - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if ((rc = RegQueryValueExW(hKey, valueName, - NULL, NULL, NULL, - &bufSize)) - != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryValueEx"); - retBuf = (BYTE *)PyMem_Malloc(bufSize); - if (retBuf == NULL) - return PyErr_NoMemory(); - if ((rc = RegQueryValueExW(hKey, valueName, NULL, - &typ, retBuf, &bufSize)) - != ERROR_SUCCESS) { - PyMem_Free(retBuf); - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryValueEx"); - } - obData = Reg2Py(retBuf, bufSize, typ); - PyMem_Free(retBuf); - if (obData == NULL) - return NULL; - result = Py_BuildValue("Oi", obData, typ); - Py_DECREF(obData); - return result; -} - - -static PyObject * -PySaveKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *fileName; - LPSECURITY_ATTRIBUTES pSA = NULL; - - long rc; - if (!PyArg_ParseTuple(args, "Ou:SaveKey", &obKey, &fileName)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; -/* One day we may get security into the core? - if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE)) - return NULL; -*/ - Py_BEGIN_ALLOW_THREADS - rc = RegSaveKeyW(hKey, fileName, pSA ); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PySetValue(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - wchar_t *str; - DWORD typ; - DWORD len; - long rc; - if (!PyArg_ParseTuple(args, "OZiu#:SetValue", - &obKey, - &subKey, - &typ, - &str, - &len)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if (typ != REG_SZ) { - PyErr_SetString(PyExc_TypeError, - "Type must be _winreg.REG_SZ"); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - rc = RegSetValueW(hKey, subKey, REG_SZ, str, len+1); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PySetValueEx(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - Py_UNICODE *valueName; - PyObject *obRes; - PyObject *value; - BYTE *data; - DWORD len; - DWORD typ; - - LONG rc; - - if (!PyArg_ParseTuple(args, "OZOiO:SetValueEx", - &obKey, - &valueName, - &obRes, - &typ, - &value)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if (!Py2Reg(value, typ, &data, &len)) - { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, - "Could not convert the data to the specified type."); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = RegSetValueExW(hKey, valueName, 0, typ, data, len); - Py_END_ALLOW_THREADS - PyMem_DEL(data); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegSetValueEx"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyDisableReflectionKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - HMODULE hMod; - typedef LONG (WINAPI *RDRKFunc)(HKEY); - RDRKFunc pfn = NULL; - LONG rc; - - if (!PyArg_ParseTuple(args, "O:DisableReflectionKey", &obKey)) - 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 = (RDRKFunc)GetProcAddress(hMod, - "RegDisableReflectionKey"); - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegDisableReflectionKey"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyEnableReflectionKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - HMODULE hMod; - typedef LONG (WINAPI *RERKFunc)(HKEY); - RERKFunc pfn = NULL; - LONG rc; - - if (!PyArg_ParseTuple(args, "O:EnableReflectionKey", &obKey)) - 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 = (RERKFunc)GetProcAddress(hMod, - "RegEnableReflectionKey"); - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegEnableReflectionKey"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyQueryReflectionKey(PyObject *self, PyObject *args) -{ - HKEY hKey; - PyObject *obKey; - HMODULE hMod; - typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *); - RQRKFunc pfn = NULL; - BOOL result; - LONG rc; - - if (!PyArg_ParseTuple(args, "O:QueryReflectionKey", &obKey)) - 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 = (RQRKFunc)GetProcAddress(hMod, - "RegQueryReflectionKey"); - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey, &result); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryReflectionKey"); - return PyBool_FromLong(rc); -} - -static struct PyMethodDef winreg_methods[] = { - {"CloseKey", PyCloseKey, METH_VARARGS, CloseKey_doc}, - {"ConnectRegistry", PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc}, - {"CreateKey", PyCreateKey, METH_VARARGS, CreateKey_doc}, - {"DeleteKey", PyDeleteKey, METH_VARARGS, DeleteKey_doc}, - {"DeleteValue", PyDeleteValue, METH_VARARGS, DeleteValue_doc}, - {"DisableReflectionKey", PyDisableReflectionKey, METH_VARARGS, DisableReflectionKey_doc}, - {"EnableReflectionKey", PyEnableReflectionKey, METH_VARARGS, EnableReflectionKey_doc}, - {"EnumKey", PyEnumKey, METH_VARARGS, EnumKey_doc}, - {"EnumValue", PyEnumValue, METH_VARARGS, EnumValue_doc}, - {"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS, - ExpandEnvironmentStrings_doc }, - {"FlushKey", PyFlushKey, METH_VARARGS, FlushKey_doc}, - {"LoadKey", PyLoadKey, METH_VARARGS, LoadKey_doc}, - {"OpenKey", PyOpenKey, METH_VARARGS, OpenKey_doc}, - {"OpenKeyEx", PyOpenKey, METH_VARARGS, OpenKeyEx_doc}, - {"QueryValue", PyQueryValue, METH_VARARGS, QueryValue_doc}, - {"QueryValueEx", PyQueryValueEx, METH_VARARGS, QueryValueEx_doc}, - {"QueryInfoKey", PyQueryInfoKey, METH_VARARGS, QueryInfoKey_doc}, - {"QueryReflectionKey",PyQueryReflectionKey,METH_VARARGS, QueryReflectionKey_doc}, - {"SaveKey", PySaveKey, METH_VARARGS, SaveKey_doc}, - {"SetValue", PySetValue, METH_VARARGS, SetValue_doc}, - {"SetValueEx", PySetValueEx, METH_VARARGS, SetValueEx_doc}, - NULL, -}; - -static void -insint(PyObject * d, char * name, long value) -{ - PyObject *v = PyLong_FromLong(value); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - Py_XDECREF(v); -} - -#define ADD_INT(val) insint(d, #val, val) - -static void -inskey(PyObject * d, char * name, HKEY key) -{ - PyObject *v = PyLong_FromVoidPtr(key); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - Py_XDECREF(v); -} - -#define ADD_KEY(val) inskey(d, #val, val) - -PyMODINIT_FUNC init_winreg(void) -{ - PyObject *m, *d; - m = Py_InitModule3("_winreg", winreg_methods, module_doc); - if (m == NULL) - return; - d = PyModule_GetDict(m); - Py_TYPE(&PyHKEY_Type) = &PyType_Type; - PyHKEY_Type.tp_doc = PyHKEY_doc; - Py_INCREF(&PyHKEY_Type); - if (PyDict_SetItemString(d, "HKEYType", - (PyObject *)&PyHKEY_Type) != 0) - return; - Py_INCREF(PyExc_WindowsError); - if (PyDict_SetItemString(d, "error", - PyExc_WindowsError) != 0) - return; - - /* Add the relevant constants */ - ADD_KEY(HKEY_CLASSES_ROOT); - ADD_KEY(HKEY_CURRENT_USER); - ADD_KEY(HKEY_LOCAL_MACHINE); - ADD_KEY(HKEY_USERS); - ADD_KEY(HKEY_PERFORMANCE_DATA); -#ifdef HKEY_CURRENT_CONFIG - ADD_KEY(HKEY_CURRENT_CONFIG); -#endif -#ifdef HKEY_DYN_DATA - ADD_KEY(HKEY_DYN_DATA); -#endif - ADD_INT(KEY_QUERY_VALUE); - ADD_INT(KEY_SET_VALUE); - ADD_INT(KEY_CREATE_SUB_KEY); - ADD_INT(KEY_ENUMERATE_SUB_KEYS); - ADD_INT(KEY_NOTIFY); - ADD_INT(KEY_CREATE_LINK); - ADD_INT(KEY_READ); - ADD_INT(KEY_WRITE); - ADD_INT(KEY_EXECUTE); - ADD_INT(KEY_ALL_ACCESS); -#ifdef KEY_WOW64_64KEY - ADD_INT(KEY_WOW64_64KEY); -#endif -#ifdef KEY_WOW64_32KEY - ADD_INT(KEY_WOW64_32KEY); -#endif - ADD_INT(REG_OPTION_RESERVED); - ADD_INT(REG_OPTION_NON_VOLATILE); - ADD_INT(REG_OPTION_VOLATILE); - ADD_INT(REG_OPTION_CREATE_LINK); - ADD_INT(REG_OPTION_BACKUP_RESTORE); - ADD_INT(REG_OPTION_OPEN_LINK); - ADD_INT(REG_LEGAL_OPTION); - ADD_INT(REG_CREATED_NEW_KEY); - ADD_INT(REG_OPENED_EXISTING_KEY); - ADD_INT(REG_WHOLE_HIVE_VOLATILE); - ADD_INT(REG_REFRESH_HIVE); - ADD_INT(REG_NO_LAZY_FLUSH); - ADD_INT(REG_NOTIFY_CHANGE_NAME); - ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES); - ADD_INT(REG_NOTIFY_CHANGE_LAST_SET); - ADD_INT(REG_NOTIFY_CHANGE_SECURITY); - ADD_INT(REG_LEGAL_CHANGE_FILTER); - ADD_INT(REG_NONE); - ADD_INT(REG_SZ); - ADD_INT(REG_EXPAND_SZ); - ADD_INT(REG_BINARY); - ADD_INT(REG_DWORD); - ADD_INT(REG_DWORD_LITTLE_ENDIAN); - ADD_INT(REG_DWORD_BIG_ENDIAN); - ADD_INT(REG_LINK); - ADD_INT(REG_MULTI_SZ); - ADD_INT(REG_RESOURCE_LIST); - ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR); - ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST); -} - - diff --git a/PC/config.c b/PC/config.c index e3bbde7..1522533 100644 --- a/PC/config.c +++ b/PC/config.c @@ -42,7 +42,7 @@ extern void initmmap(void); extern void init_csv(void); extern void init_sre(void); extern void initparser(void); -extern void init_winreg(void); +extern void initwinreg(void); extern void init_struct(void); extern void initdatetime(void); extern void init_functools(void); @@ -116,7 +116,7 @@ struct _inittab _PyImport_Inittab[] = { {"_csv", init_csv}, {"_sre", init_sre}, {"parser", initparser}, - {"_winreg", init_winreg}, + {"winreg", initwinreg}, {"_struct", init_struct}, {"datetime", initdatetime}, {"_functools", init_functools}, diff --git a/PC/winreg.c b/PC/winreg.c new file mode 100644 index 0000000..1b141d3 --- /dev/null +++ b/PC/winreg.c @@ -0,0 +1,1645 @@ +/* + winreg.c + + Windows Registry access module for Python. + + * Simple registry access written by Mark Hammond in win32api + module circa 1995. + * Bill Tutt expanded the support significantly not long after. + * Numerous other people have submitted patches since then. + * Ripped from win32api module 03-Feb-2000 by Mark Hammond, and + basic Unicode support added. + +*/ + +#include "Python.h" +#include "structmember.h" +#include "windows.h" + +static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); +static PyObject *PyHKEY_FromHKEY(HKEY h); +static BOOL PyHKEY_Close(PyObject *obHandle); + +static char errNotAHandle[] = "Object is not a handle"; + +/* The win32api module reports the function name that failed, + but this concept is not in the Python core. + Hopefully it will one day, and in the meantime I dont + want to lose this info... +*/ +#define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \ + PyErr_SetFromWindowsErr(rc) + +/* Forward declares */ + +/* Doc strings */ +PyDoc_STRVAR(module_doc, +"This module provides access to the Windows registry API.\n" +"\n" +"Functions:\n" +"\n" +"CloseKey() - Closes a registry key.\n" +"ConnectRegistry() - Establishes a connection to a predefined registry handle\n" +" on another computer.\n" +"CreateKey() - Creates the specified key, or opens it if it already exists.\n" +"DeleteKey() - Deletes the specified key.\n" +"DeleteValue() - Removes a named value from the specified registry key.\n" +"EnumKey() - Enumerates subkeys of the specified open registry key.\n" +"EnumValue() - Enumerates values of the specified open registry key.\n" +"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ string.\n" +"FlushKey() - Writes all the attributes of the specified key to the registry.\n" +"LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n" +" registration information from a specified file into that subkey.\n" +"OpenKey() - Alias for \n" +"OpenKeyEx() - Opens the specified key.\n" +"QueryValue() - Retrieves the value associated with the unnamed value for a\n" +" specified key in the registry.\n" +"QueryValueEx() - Retrieves the type and data for a specified value name\n" +" associated with an open registry key.\n" +"QueryInfoKey() - Returns information about the specified key.\n" +"SaveKey() - Saves the specified key, and all its subkeys a file.\n" +"SetValue() - Associates a value with a specified key.\n" +"SetValueEx() - Stores data in the value field of an open registry key.\n" +"\n" +"Special objects:\n" +"\n" +"HKEYType -- type object for HKEY objects\n" +"error -- exception raised for Win32 errors\n" +"\n" +"Integer constants:\n" +"Many constants are defined - see the documentation for each function\n" +"to see what constants are used, and where."); + + +PyDoc_STRVAR(CloseKey_doc, +"CloseKey(hkey) - Closes a previously opened registry key.\n" +"\n" +"The hkey argument specifies a previously opened key.\n" +"\n" +"Note that if the key is not closed using this method, it will be\n" +"closed when the hkey object is destroyed by Python."); + +PyDoc_STRVAR(ConnectRegistry_doc, +"key = ConnectRegistry(computer_name, key) - " +"Establishes a connection to a predefined registry handle on another computer.\n" +"\n" +"computer_name is the name of the remote computer, of the form \\\\computername.\n" +" If None, the local computer is used.\n" +"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."); + +PyDoc_STRVAR(CreateKey_doc, +"key = CreateKey(key, sub_key) - 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" +" 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" +"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" +" 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, an EnvironmentError exception is raised."); + +PyDoc_STRVAR(DeleteValue_doc, +"DeleteValue(key, value) - Removes a named value from a registry key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"value is a string that identifies the value to remove."); + +PyDoc_STRVAR(EnumKey_doc, +"string = EnumKey(key, index) - Enumerates subkeys of an open registry key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"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" +"raised, indicating no more values are available."); + +PyDoc_STRVAR(EnumValue_doc, +"tuple = EnumValue(key, index) - Enumerates values of an open registry key.\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"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" +"is raised, indicating no more values.\n" +"\n" +"The result is a tuple of 3 items:\n" +"value_name is a string that identifies the value.\n" +"value_data is an object that holds the value data, and whose type depends\n" +" on the underlying registry type.\n" +"data_type is an integer that identifies the type of the value data."); + +PyDoc_STRVAR(ExpandEnvironmentStrings_doc, +"string = ExpandEnvironmentStrings(string) - Expand environment vars.\n"); + +PyDoc_STRVAR(FlushKey_doc, +"FlushKey(key) - Writes all the attributes of a key to the registry.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"It is not necessary to call RegFlushKey to change a key.\n" +"Registry changes are flushed to disk by the registry using its lazy flusher.\n" +"Registry changes are also flushed to disk at system shutdown.\n" +"Unlike CloseKey(), the FlushKey() method returns only when all the data has\n" +"been written to the registry.\n" +"An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.\n" +"If you don't know whether a FlushKey() call is required, it probably isn't."); + +PyDoc_STRVAR(LoadKey_doc, +"LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key\n" +"and stores registration information from a specified file into that subkey.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"sub_key is a string that identifies the sub_key to load\n" +"file_name is the name of the file to load registry data from.\n" +" This file must have been created with the SaveKey() function.\n" +" Under the file allocation table (FAT) file system, the filename may not\n" +"have an extension.\n" +"\n" +"A call to LoadKey() fails if the calling process does not have the\n" +"SE_RESTORE_PRIVILEGE privilege.\n" +"\n" +"If key is a handle returned by ConnectRegistry(), then the path specified\n" +"in fileName is relative to the remote computer.\n" +"\n" +"The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"); + +PyDoc_STRVAR(OpenKey_doc, +"key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens 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 identifies the sub_key to open\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" +" 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."); + +PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()"); + +PyDoc_STRVAR(QueryInfoKey_doc, +"tuple = QueryInfoKey(key) - Returns information about a key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"The result is a tuple of 3 items:" +"An integer that identifies the number of sub keys this key has.\n" +"An integer that identifies the number of values this key has.\n" +"A long integer that identifies when the key was last modified (if available)\n" +" as 100's of nanoseconds since Jan 1, 1600."); + +PyDoc_STRVAR(QueryValue_doc, +"string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"sub_key is a string that holds the name of the subkey with which the value\n" +" is associated. If this parameter is None or empty, the function retrieves\n" +" the value set by the SetValue() method for the key identified by key." +"\n" +"Values in the registry have name, type, and data components. This method\n" +"retrieves the data for a key's first value that has a NULL name.\n" +"But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!"); + +PyDoc_STRVAR(QueryValueEx_doc, +"value,type_id = QueryValueEx(key, value_name) - Retrieves the type and data for a specified value name associated with an open registry key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"value_name is a string indicating the value to query"); + +PyDoc_STRVAR(SaveKey_doc, +"SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"file_name is the name of the file to save registry data to.\n" +" This file cannot already exist. If this filename includes an extension,\n" +" it cannot be used on file allocation table (FAT) file systems by the\n" +" LoadKey(), ReplaceKey() or RestoreKey() methods.\n" +"\n" +"If key represents a key on a remote computer, the path described by\n" +"file_name is relative to the remote computer.\n" +"The caller of this method must possess the SeBackupPrivilege security privilege.\n" +"This function passes NULL for security_attributes to the API."); + +PyDoc_STRVAR(SetValue_doc, +"SetValue(key, sub_key, type, value) - Associates a value with a 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 names the subkey with which the value is associated.\n" +"type is an integer that specifies the type of the data. Currently this\n" +" must be REG_SZ, meaning only strings are supported.\n" +"value is a string that specifies the new value.\n" +"\n" +"If the key specified by the sub_key parameter does not exist, the SetValue\n" +"function creates it.\n" +"\n" +"Value lengths are limited by available memory. Long values (more than\n" +"2048 bytes) should be stored as files with the filenames stored in \n" +"the configuration registry. This helps the registry perform efficiently.\n" +"\n" +"The key identified by the key parameter must have been opened with\n" +"KEY_SET_VALUE access."); + +PyDoc_STRVAR(SetValueEx_doc, +"SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.\n" +"\n" +"key is an already open key, or any one of the predefined HKEY_* constants.\n" +"value_name is a string containing the name of the value to set, or None\n" +"type is an integer that specifies the type of the data. This should be one of:\n" +" REG_BINARY -- Binary data in any form.\n" +" REG_DWORD -- A 32-bit number.\n" +" REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n" +" REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n" +" REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references\n" +" to environment variables (for example, %PATH%).\n" +" REG_LINK -- A Unicode symbolic link.\n" +" REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by\n" +" two null characters. Note that Python handles this\n" +" termination automatically.\n" +" REG_NONE -- No defined value type.\n" +" REG_RESOURCE_LIST -- A device-driver resource list.\n" +" REG_SZ -- A null-terminated string.\n" +"reserved can be anything - zero is always passed to the API.\n" +"value is a string that specifies the new value.\n" +"\n" +"This method can also set additional value and type information for the\n" +"specified key. The key identified by the key parameter must have been\n" +"opened with KEY_SET_VALUE access.\n" +"\n" +"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n" +"\n" +"Value lengths are limited by available memory. Long values (more than\n" +"2048 bytes) should be stored as files with the filenames stored in \n" +"the configuration registry. This helps the registry perform efficiently."); + +PyDoc_STRVAR(DisableReflectionKey_doc, +"Disables registry reflection for 32-bit processes running on a 64-bit\n" +"Operating System. Will generally raise NotImplemented if executed on\n" +"a 32-bit Operating System.\n" +"If the key is not on the reflection list, the function succeeds but has no effect.\n" +"Disabling reflection for a key does not affect reflection of any subkeys."); + +PyDoc_STRVAR(EnableReflectionKey_doc, +"Restores registry reflection for the specified disabled key.\n" +"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n" +"Restoring reflection for a key does not affect reflection of any subkeys."); + +PyDoc_STRVAR(QueryReflectionKey_doc, +"bool = QueryReflectionKey(hkey) - Determines the reflection state for the specified key.\n" +"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n"); + +/* PyHKEY docstrings */ +PyDoc_STRVAR(PyHKEY_doc, +"PyHKEY Object - A Python object, representing a win32 registry key.\n" +"\n" +"This object wraps a Windows HKEY object, automatically closing it when\n" +"the object is destroyed. To guarantee cleanup, you can call either\n" +"the Close() method on the PyHKEY, or the CloseKey() method.\n" +"\n" +"All functions which accept a handle object also accept an integer - \n" +"however, use of the handle object is encouraged.\n" +"\n" +"Functions:\n" +"Close() - Closes the underlying handle.\n" +"Detach() - Returns the integer Win32 handle, detaching it from the object\n" +"\n" +"Properties:\n" +"handle - The integer Win32 handle.\n" +"\n" +"Operations:\n" +"__bool__ - Handles with an open object return true, otherwise false.\n" +"__int__ - Converting a handle to an integer returns the Win32 handle.\n" +"__cmp__ - Handle objects are compared using the handle value."); + + +PyDoc_STRVAR(PyHKEY_Close_doc, +"key.Close() - Closes the underlying Windows handle.\n" +"\n" +"If the handle is already closed, no error is raised."); + +PyDoc_STRVAR(PyHKEY_Detach_doc, +"int = key.Detach() - Detaches the Windows handle from the handle object.\n" +"\n" +"The result is the value of the handle before it is detached. If the\n" +"handle is already detached, this will return zero.\n" +"\n" +"After calling this function, the handle is effectively invalidated,\n" +"but the handle is not closed. You would call this function when you\n" +"need the underlying win32 handle to exist beyond the lifetime of the\n" +"handle object.\n" +"On 64 bit windows, the result of this function is a long integer"); + + +/************************************************************************ + + The PyHKEY object definition + +************************************************************************/ +typedef struct { + PyObject_VAR_HEAD + HKEY hkey; +} PyHKEYObject; + +#define PyHKEY_Check(op) ((op)->ob_type == &PyHKEY_Type) + +static char *failMsg = "bad operand type"; + +static PyObject * +PyHKEY_unaryFailureFunc(PyObject *ob) +{ + PyErr_SetString(PyExc_TypeError, failMsg); + return NULL; +} +static PyObject * +PyHKEY_binaryFailureFunc(PyObject *ob1, PyObject *ob2) +{ + PyErr_SetString(PyExc_TypeError, failMsg); + return NULL; +} +static PyObject * +PyHKEY_ternaryFailureFunc(PyObject *ob1, PyObject *ob2, PyObject *ob3) +{ + PyErr_SetString(PyExc_TypeError, failMsg); + return NULL; +} + +static void +PyHKEY_deallocFunc(PyObject *ob) +{ + /* Can not call PyHKEY_Close, as the ob->tp_type + has already been cleared, thus causing the type + check to fail! + */ + PyHKEYObject *obkey = (PyHKEYObject *)ob; + if (obkey->hkey) + RegCloseKey((HKEY)obkey->hkey); + PyObject_DEL(ob); +} + +static int +PyHKEY_boolFunc(PyObject *ob) +{ + return ((PyHKEYObject *)ob)->hkey != 0; +} + +static PyObject * +PyHKEY_intFunc(PyObject *ob) +{ + PyHKEYObject *pyhkey = (PyHKEYObject *)ob; + return PyLong_FromVoidPtr(pyhkey->hkey); +} + +static PyObject * +PyHKEY_strFunc(PyObject *ob) +{ + PyHKEYObject *pyhkey = (PyHKEYObject *)ob; + return PyUnicode_FromFormat("", pyhkey->hkey); +} + +static int +PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2) +{ + PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1; + PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2; + return pyhkey1 == pyhkey2 ? 0 : + (pyhkey1 < pyhkey2 ? -1 : 1); +} + +static long +PyHKEY_hashFunc(PyObject *ob) +{ + /* Just use the address. + XXX - should we use the handle value? + */ + return _Py_HashPointer(ob); +} + + +static PyNumberMethods PyHKEY_NumberMethods = +{ + PyHKEY_binaryFailureFunc, /* nb_add */ + PyHKEY_binaryFailureFunc, /* nb_subtract */ + PyHKEY_binaryFailureFunc, /* nb_multiply */ + PyHKEY_binaryFailureFunc, /* nb_remainder */ + PyHKEY_binaryFailureFunc, /* nb_divmod */ + PyHKEY_ternaryFailureFunc, /* nb_power */ + PyHKEY_unaryFailureFunc, /* nb_negative */ + PyHKEY_unaryFailureFunc, /* nb_positive */ + PyHKEY_unaryFailureFunc, /* nb_absolute */ + PyHKEY_boolFunc, /* nb_bool */ + PyHKEY_unaryFailureFunc, /* nb_invert */ + PyHKEY_binaryFailureFunc, /* nb_lshift */ + PyHKEY_binaryFailureFunc, /* nb_rshift */ + PyHKEY_binaryFailureFunc, /* nb_and */ + PyHKEY_binaryFailureFunc, /* nb_xor */ + PyHKEY_binaryFailureFunc, /* nb_or */ + 0, /* nb_reserved */ + PyHKEY_intFunc, /* nb_int */ + PyHKEY_unaryFailureFunc, /* nb_long */ + PyHKEY_unaryFailureFunc, /* nb_float */ + PyHKEY_unaryFailureFunc, /* nb_oct */ + PyHKEY_unaryFailureFunc, /* nb_hex */ +}; + + +/* fwd declare __getattr__ */ +static PyObject *PyHKEY_getattr(PyObject *self, const char *name); + +/* The type itself */ +PyTypeObject PyHKEY_Type = +{ + PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */ + "PyHKEY", + sizeof(PyHKEYObject), + 0, + PyHKEY_deallocFunc, /* tp_dealloc */ + 0, /* tp_print */ + PyHKEY_getattr, /* tp_getattr */ + 0, /* tp_setattr */ + PyHKEY_compareFunc, /* tp_compare */ + 0, /* tp_repr */ + &PyHKEY_NumberMethods, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + PyHKEY_hashFunc, /* tp_hash */ + 0, /* tp_call */ + PyHKEY_strFunc, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + PyHKEY_doc, /* tp_doc */ +}; + +#define OFF(e) offsetof(PyHKEYObject, e) + +static PyMemberDef PyHKEY_memberlist[] = { + {"handle", T_INT, OFF(hkey), READONLY}, + {NULL} /* Sentinel */ +}; + +/************************************************************************ + + The PyHKEY object methods + +************************************************************************/ +static PyObject * +PyHKEY_CloseMethod(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":Close")) + return NULL; + if (!PyHKEY_Close(self)) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyHKEY_DetachMethod(PyObject *self, PyObject *args) +{ + void* ret; + PyHKEYObject *pThis = (PyHKEYObject *)self; + if (!PyArg_ParseTuple(args, ":Detach")) + return NULL; + ret = (void*)pThis->hkey; + pThis->hkey = 0; + return PyLong_FromVoidPtr(ret); +} + +static PyObject * +PyHKEY_Enter(PyObject *self) +{ + Py_XINCREF(self); + return self; +} + +static PyObject * +PyHKEY_Exit(PyObject *self, PyObject *args) +{ + if (!PyHKEY_Close(self)) + return NULL; + Py_RETURN_NONE; +} + + +static struct PyMethodDef PyHKEY_methods[] = { + {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, + {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, + {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, + {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, + {NULL} +}; + +/*static*/ PyObject * +PyHKEY_getattr(PyObject *self, const char *name) +{ + PyObject *res; + + res = Py_FindMethod(PyHKEY_methods, self, name); + if (res != NULL) + return res; + PyErr_Clear(); + if (strcmp(name, "handle") == 0) + return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey); + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%.400s'", + Py_TYPE(self)->tp_name, name); + return NULL; +} + +/************************************************************************ + The public PyHKEY API (well, not public yet :-) +************************************************************************/ +PyObject * +PyHKEY_New(HKEY hInit) +{ + PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type); + if (key) + key->hkey = hInit; + return (PyObject *)key; +} + +BOOL +PyHKEY_Close(PyObject *ob_handle) +{ + LONG rc; + PyHKEYObject *key; + + if (!PyHKEY_Check(ob_handle)) { + PyErr_SetString(PyExc_TypeError, "bad operand type"); + return FALSE; + } + key = (PyHKEYObject *)ob_handle; + rc = key->hkey ? RegCloseKey((HKEY)key->hkey) : ERROR_SUCCESS; + key->hkey = 0; + if (rc != ERROR_SUCCESS) + PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); + return rc == ERROR_SUCCESS; +} + +BOOL +PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) +{ + if (ob == Py_None) { + if (!bNoneOK) { + PyErr_SetString( + PyExc_TypeError, + "None is not a valid HKEY in this context"); + return FALSE; + } + *pHANDLE = (HKEY)0; + } + else if (PyHKEY_Check(ob)) { + PyHKEYObject *pH = (PyHKEYObject *)ob; + *pHANDLE = pH->hkey; + } + else if (PyLong_Check(ob)) { + /* We also support integers */ + PyErr_Clear(); + *pHANDLE = (HKEY)PyLong_AsVoidPtr(ob); + if (PyErr_Occurred()) + return FALSE; + } + else { + PyErr_SetString( + PyExc_TypeError, + "The object is not a PyHKEY object"); + return FALSE; + } + return TRUE; +} + +PyObject * +PyHKEY_FromHKEY(HKEY h) +{ + PyHKEYObject *op; + + /* Inline PyObject_New */ + op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject)); + if (op == NULL) + return PyErr_NoMemory(); + PyObject_INIT(op, &PyHKEY_Type); + op->hkey = h; + return (PyObject *)op; +} + + +/************************************************************************ + The module methods +************************************************************************/ +BOOL +PyWinObject_CloseHKEY(PyObject *obHandle) +{ + BOOL ok; + if (PyHKEY_Check(obHandle)) { + ok = PyHKEY_Close(obHandle); + } +#if SIZEOF_LONG >= SIZEOF_HKEY + else if (PyLong_Check(obHandle)) { + long rc = RegCloseKey((HKEY)PyLong_AsLong(obHandle)); + ok = (rc == ERROR_SUCCESS); + if (!ok) + PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); + } +#else + else if (PyLong_Check(obHandle)) { + long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle)); + ok = (rc == ERROR_SUCCESS); + if (!ok) + PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey"); + } +#endif + else { + PyErr_SetString( + PyExc_TypeError, + "A handle must be a HKEY object or an integer"); + return FALSE; + } + return ok; +} + + +/* + Private Helper functions for the registry interfaces + +** Note that fixupMultiSZ and countString have both had changes +** made to support "incorrect strings". The registry specification +** calls for strings to be terminated with 2 null bytes. It seems +** some commercial packages install strings which dont conform, +** causing this code to fail - however, "regedit" etc still work +** with these strings (ie only we dont!). +*/ +static void +fixupMultiSZ(wchar_t **str, wchar_t *data, int len) +{ + wchar_t *P; + int i; + wchar_t *Q; + + Q = data + len; + for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) { + str[i] = P; + for(; *P != '\0'; P++) + ; + } +} + +static int +countStrings(wchar_t *data, int len) +{ + int strings; + wchar_t *P; + wchar_t *Q = data + len; + + for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++) + for (; P < Q && *P != '\0'; P++) + ; + return strings; +} + +/* Convert PyObject into Registry data. + Allocates space as needed. */ +static BOOL +Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) +{ + Py_ssize_t i,j; + switch (typ) { + case REG_DWORD: + if (value != Py_None && !PyLong_Check(value)) + return FALSE; + *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1); + if (*retDataBuf==NULL){ + PyErr_NoMemory(); + return FALSE; + } + *retDataSize = sizeof(DWORD); + if (value == Py_None) { + DWORD zero = 0; + memcpy(*retDataBuf, &zero, sizeof(DWORD)); + } + else { + DWORD d = PyLong_AsLong(value); + memcpy(*retDataBuf, &d, sizeof(DWORD)); + } + break; + case REG_SZ: + case REG_EXPAND_SZ: + { + if (value == Py_None) + *retDataSize = 1; + else { + if (!PyUnicode_Check(value)) + return FALSE; + + *retDataSize = 2 + PyUnicode_GET_DATA_SIZE(value); + } + *retDataBuf = (BYTE *)PyMem_NEW(DWORD, *retDataSize); + if (*retDataBuf==NULL){ + PyErr_NoMemory(); + return FALSE; + } + if (value == Py_None) + wcscpy((wchar_t *)*retDataBuf, L""); + else + wcscpy((wchar_t *)*retDataBuf, + PyUnicode_AS_UNICODE(value)); + break; + } + case REG_MULTI_SZ: + { + DWORD size = 0; + wchar_t *P; + + if (value == Py_None) + i = 0; + else { + if (!PyList_Check(value)) + return FALSE; + i = PyList_Size(value); + } + for (j = 0; j < i; j++) + { + PyObject *t; + t = PyList_GET_ITEM(value, j); + if (!PyUnicode_Check(t)) + return FALSE; + size += 2 + PyUnicode_GET_DATA_SIZE(t); + } + + *retDataSize = size + 2; + *retDataBuf = (BYTE *)PyMem_NEW(char, + *retDataSize); + if (*retDataBuf==NULL){ + PyErr_NoMemory(); + return FALSE; + } + P = (wchar_t *)*retDataBuf; + + for (j = 0; j < i; j++) + { + PyObject *t; + t = PyList_GET_ITEM(value, j); + wcscpy(P, PyUnicode_AS_UNICODE(t)); + P += 1 + wcslen( + PyUnicode_AS_UNICODE(t)); + } + /* And doubly-terminate the list... */ + *P = '\0'; + break; + } + case REG_BINARY: + /* ALSO handle ALL unknown data types here. Even if we can't + support it natively, we should handle the bits. */ + default: + if (value == Py_None) + *retDataSize = 0; + else { + Py_buffer view; + + if (!PyObject_CheckBuffer(value)) { + PyErr_Format(PyExc_TypeError, + "Objects of type '%s' can not " + "be used as binary registry values", + value->ob_type->tp_name); + return FALSE; + } + + if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) + return FALSE; + + *retDataBuf = (BYTE *)PyMem_NEW(char, view.len); + if (*retDataBuf==NULL){ + PyObject_ReleaseBuffer(value, &view); + PyErr_NoMemory(); + return FALSE; + } + *retDataSize = view.len; + memcpy(*retDataBuf, view.buf, view.len); + PyObject_ReleaseBuffer(value, &view); + } + break; + } + return TRUE; +} + +/* Convert Registry data into PyObject*/ +static PyObject * +Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) +{ + PyObject *obData; + + switch (typ) { + case REG_DWORD: + if (retDataSize == 0) + obData = PyLong_FromLong(0); + else + obData = PyLong_FromLong(*(int *)retDataBuf); + break; + case REG_SZ: + case REG_EXPAND_SZ: + { + /* the buffer may or may not have a trailing NULL */ + wchar_t *data = (wchar_t *)retDataBuf; + int len = retDataSize / 2; + if (retDataSize && data[len-1] == '\0') + retDataSize -= 2; + if (retDataSize <= 0) + data = L""; + obData = PyUnicode_FromUnicode(data, retDataSize/2); + break; + } + case REG_MULTI_SZ: + if (retDataSize == 0) + obData = PyList_New(0); + else + { + int index = 0; + wchar_t *data = (wchar_t *)retDataBuf; + int len = retDataSize / 2; + int s = countStrings(data, len); + wchar_t **str = (wchar_t **)malloc(sizeof(wchar_t *)*s); + if (str == NULL) + return PyErr_NoMemory(); + + fixupMultiSZ(str, data, len); + obData = PyList_New(s); + if (obData == NULL) + return NULL; + for (index = 0; index < s; index++) + { + size_t len = wcslen(str[index]); + if (len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "registry string is too long for a Python string"); + Py_DECREF(obData); + return NULL; + } + PyList_SetItem(obData, + index, + PyUnicode_FromUnicode(str[index], len)); + } + free(str); + + break; + } + case REG_BINARY: + /* ALSO handle ALL unknown data types here. Even if we can't + support it natively, we should handle the bits. */ + default: + if (retDataSize == 0) { + Py_INCREF(Py_None); + obData = Py_None; + } + else + obData = PyBytes_FromStringAndSize( + (char *)retDataBuf, retDataSize); + break; + } + return obData; +} + +/* The Python methods */ + +static PyObject * +PyCloseKey(PyObject *self, PyObject *args) +{ + PyObject *obKey; + if (!PyArg_ParseTuple(args, "O:CloseKey", &obKey)) + return NULL; + if (!PyHKEY_Close(obKey)) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyConnectRegistry(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *szCompName = NULL; + HKEY retKey; + long rc; + if (!PyArg_ParseTuple(args, "ZO:ConnectRegistry", &szCompName, &obKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + Py_BEGIN_ALLOW_THREADS + rc = RegConnectRegistryW(szCompName, hKey, &retKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "ConnectRegistry"); + return PyHKEY_FromHKEY(retKey); +} + +static PyObject * +PyCreateKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + HKEY retKey; + long rc; + if (!PyArg_ParseTuple(args, "OZ:CreateKey", &obKey, &subKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + rc = RegCreateKeyW(hKey, subKey, &retKey); + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey"); + return PyHKEY_FromHKEY(retKey); +} + +static PyObject * +PyDeleteKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + long rc; + if (!PyArg_ParseTuple(args, "Ou:DeleteKey", &obKey, &subKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + rc = RegDeleteKeyW(hKey, subKey ); + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyDeleteValue(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + long rc; + if (!PyArg_ParseTuple(args, "OZ:DeleteValue", &obKey, &subKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + Py_BEGIN_ALLOW_THREADS + rc = RegDeleteValueW(hKey, subKey); + Py_END_ALLOW_THREADS + if (rc !=ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegDeleteValue"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyEnumKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + int index; + long rc; + PyObject *retStr; + wchar_t tmpbuf[256]; /* max key name length is 255 */ + DWORD len = sizeof(tmpbuf); /* includes NULL terminator */ + + if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rc = RegEnumKeyExW(hKey, index, tmpbuf, &len, NULL, NULL, NULL, NULL); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx"); + + retStr = PyUnicode_FromUnicode(tmpbuf, len); + return retStr; /* can be NULL */ +} + +static PyObject * +PyEnumValue(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + int index; + long rc; + wchar_t *retValueBuf; + BYTE *retDataBuf; + DWORD retValueSize; + DWORD retDataSize; + DWORD typ; + PyObject *obData; + PyObject *retVal; + + if (!PyArg_ParseTuple(args, "Oi:EnumValue", &obKey, &index)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + + if ((rc = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, + &retValueSize, &retDataSize, NULL, NULL)) + != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryInfoKey"); + ++retValueSize; /* include null terminators */ + ++retDataSize; + retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); + if (retValueBuf == NULL) + return PyErr_NoMemory(); + retDataBuf = (BYTE *)PyMem_Malloc(retDataSize); + if (retDataBuf == NULL) { + PyMem_Free(retValueBuf); + return PyErr_NoMemory(); + } + + Py_BEGIN_ALLOW_THREADS + rc = RegEnumValueW(hKey, + index, + retValueBuf, + &retValueSize, + NULL, + &typ, + retDataBuf, + &retDataSize); + Py_END_ALLOW_THREADS + + if (rc != ERROR_SUCCESS) { + retVal = PyErr_SetFromWindowsErrWithFunction(rc, + "PyRegEnumValue"); + goto fail; + } + obData = Reg2Py(retDataBuf, retDataSize, typ); + if (obData == NULL) { + retVal = NULL; + goto fail; + } + retVal = Py_BuildValue("uOi", retValueBuf, obData, typ); + Py_DECREF(obData); + fail: + PyMem_Free(retValueBuf); + PyMem_Free(retDataBuf); + return retVal; +} + +static PyObject * +PyExpandEnvironmentStrings(PyObject *self, PyObject *args) +{ + Py_UNICODE *retValue = NULL; + Py_UNICODE *src; + DWORD retValueSize; + DWORD rc; + PyObject *o; + + if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src)) + return NULL; + + retValueSize = ExpandEnvironmentStringsW(src, retValue, 0); + if (retValueSize == 0) { + return PyErr_SetFromWindowsErrWithFunction(retValueSize, + "ExpandEnvironmentStrings"); + } + retValue = (Py_UNICODE *)PyMem_Malloc(retValueSize * sizeof(Py_UNICODE)); + if (retValue == NULL) { + return PyErr_NoMemory(); + } + + rc = ExpandEnvironmentStringsW(src, retValue, retValueSize); + if (rc == 0) { + PyMem_Free(retValue); + return PyErr_SetFromWindowsErrWithFunction(retValueSize, + "ExpandEnvironmentStrings"); + } + o = PyUnicode_FromUnicode(retValue, wcslen(retValue)); + PyMem_Free(retValue); + return o; +} + +static PyObject * +PyFlushKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + long rc; + if (!PyArg_ParseTuple(args, "O:FlushKey", &obKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + Py_BEGIN_ALLOW_THREADS + rc = RegFlushKey(hKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey"); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +PyLoadKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + wchar_t *fileName; + + long rc; + if (!PyArg_ParseTuple(args, "Ouu:LoadKey", &obKey, &subKey, &fileName)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + Py_BEGIN_ALLOW_THREADS + rc = RegLoadKeyW(hKey, subKey, fileName ); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyOpenKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + + wchar_t *subKey; + int res = 0; + HKEY retKey; + long rc; + REGSAM sam = KEY_READ; + if (!PyArg_ParseTuple(args, "OZ|ii:OpenKey", &obKey, &subKey, + &res, &sam)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rc = RegOpenKeyExW(hKey, subKey, res, sam, &retKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); + return PyHKEY_FromHKEY(retKey); +} + + +static PyObject * +PyQueryInfoKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + long rc; + DWORD nSubKeys, nValues; + FILETIME ft; + LARGE_INTEGER li; + PyObject *l; + PyObject *ret; + if (!PyArg_ParseTuple(args, "O:QueryInfoKey", &obKey)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + if ((rc = RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubKeys, NULL, NULL, + &nValues, NULL, NULL, NULL, &ft)) + != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey"); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + l = PyLong_FromLongLong(li.QuadPart); + if (l == NULL) + return NULL; + ret = Py_BuildValue("iiO", nSubKeys, nValues, l); + Py_DECREF(l); + return ret; +} + +static PyObject * +PyQueryValue(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + long rc; + PyObject *retStr; + wchar_t *retBuf; + long bufSize = 0; + + if (!PyArg_ParseTuple(args, "OZ:QueryValue", &obKey, &subKey)) + return NULL; + + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + if ((rc = RegQueryValueW(hKey, subKey, NULL, &bufSize)) + != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryValue"); + retBuf = (wchar_t *)PyMem_Malloc(bufSize); + if (retBuf == NULL) + return PyErr_NoMemory(); + + if ((rc = RegQueryValueW(hKey, subKey, retBuf, &bufSize)) + != ERROR_SUCCESS) { + PyMem_Free(retBuf); + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryValue"); + } + + retStr = PyUnicode_FromUnicode(retBuf, wcslen(retBuf)); + PyMem_Free(retBuf); + return retStr; +} + +static PyObject * +PyQueryValueEx(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *valueName; + + long rc; + BYTE *retBuf; + DWORD bufSize = 0; + DWORD typ; + PyObject *obData; + PyObject *result; + + if (!PyArg_ParseTuple(args, "OZ:QueryValueEx", &obKey, &valueName)) + return NULL; + + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + if ((rc = RegQueryValueExW(hKey, valueName, + NULL, NULL, NULL, + &bufSize)) + != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryValueEx"); + retBuf = (BYTE *)PyMem_Malloc(bufSize); + if (retBuf == NULL) + return PyErr_NoMemory(); + if ((rc = RegQueryValueExW(hKey, valueName, NULL, + &typ, retBuf, &bufSize)) + != ERROR_SUCCESS) { + PyMem_Free(retBuf); + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryValueEx"); + } + obData = Reg2Py(retBuf, bufSize, typ); + PyMem_Free(retBuf); + if (obData == NULL) + return NULL; + result = Py_BuildValue("Oi", obData, typ); + Py_DECREF(obData); + return result; +} + + +static PyObject * +PySaveKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *fileName; + LPSECURITY_ATTRIBUTES pSA = NULL; + + long rc; + if (!PyArg_ParseTuple(args, "Ou:SaveKey", &obKey, &fileName)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; +/* One day we may get security into the core? + if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE)) + return NULL; +*/ + Py_BEGIN_ALLOW_THREADS + rc = RegSaveKeyW(hKey, fileName, pSA ); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PySetValue(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + wchar_t *subKey; + wchar_t *str; + DWORD typ; + DWORD len; + long rc; + if (!PyArg_ParseTuple(args, "OZiu#:SetValue", + &obKey, + &subKey, + &typ, + &str, + &len)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + if (typ != REG_SZ) { + PyErr_SetString(PyExc_TypeError, + "Type must be winreg.REG_SZ"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + rc = RegSetValueW(hKey, subKey, REG_SZ, str, len+1); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PySetValueEx(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + Py_UNICODE *valueName; + PyObject *obRes; + PyObject *value; + BYTE *data; + DWORD len; + DWORD typ; + + LONG rc; + + if (!PyArg_ParseTuple(args, "OZOiO:SetValueEx", + &obKey, + &valueName, + &obRes, + &typ, + &value)) + return NULL; + if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + return NULL; + if (!Py2Reg(value, typ, &data, &len)) + { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_ValueError, + "Could not convert the data to the specified type."); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rc = RegSetValueExW(hKey, valueName, 0, typ, data, len); + Py_END_ALLOW_THREADS + PyMem_DEL(data); + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegSetValueEx"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyDisableReflectionKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + HMODULE hMod; + typedef LONG (WINAPI *RDRKFunc)(HKEY); + RDRKFunc pfn = NULL; + LONG rc; + + if (!PyArg_ParseTuple(args, "O:DisableReflectionKey", &obKey)) + 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 = (RDRKFunc)GetProcAddress(hMod, + "RegDisableReflectionKey"); + if (!pfn) { + PyErr_SetString(PyExc_NotImplementedError, + "not implemented on this platform"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rc = (*pfn)(hKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegDisableReflectionKey"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyEnableReflectionKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + HMODULE hMod; + typedef LONG (WINAPI *RERKFunc)(HKEY); + RERKFunc pfn = NULL; + LONG rc; + + if (!PyArg_ParseTuple(args, "O:EnableReflectionKey", &obKey)) + 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 = (RERKFunc)GetProcAddress(hMod, + "RegEnableReflectionKey"); + if (!pfn) { + PyErr_SetString(PyExc_NotImplementedError, + "not implemented on this platform"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rc = (*pfn)(hKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegEnableReflectionKey"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PyQueryReflectionKey(PyObject *self, PyObject *args) +{ + HKEY hKey; + PyObject *obKey; + HMODULE hMod; + typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *); + RQRKFunc pfn = NULL; + BOOL result; + LONG rc; + + if (!PyArg_ParseTuple(args, "O:QueryReflectionKey", &obKey)) + 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 = (RQRKFunc)GetProcAddress(hMod, + "RegQueryReflectionKey"); + if (!pfn) { + PyErr_SetString(PyExc_NotImplementedError, + "not implemented on this platform"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rc = (*pfn)(hKey, &result); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) + return PyErr_SetFromWindowsErrWithFunction(rc, + "RegQueryReflectionKey"); + return PyBool_FromLong(rc); +} + +static struct PyMethodDef winreg_methods[] = { + {"CloseKey", PyCloseKey, METH_VARARGS, CloseKey_doc}, + {"ConnectRegistry", PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc}, + {"CreateKey", PyCreateKey, METH_VARARGS, CreateKey_doc}, + {"DeleteKey", PyDeleteKey, METH_VARARGS, DeleteKey_doc}, + {"DeleteValue", PyDeleteValue, METH_VARARGS, DeleteValue_doc}, + {"DisableReflectionKey", PyDisableReflectionKey, METH_VARARGS, DisableReflectionKey_doc}, + {"EnableReflectionKey", PyEnableReflectionKey, METH_VARARGS, EnableReflectionKey_doc}, + {"EnumKey", PyEnumKey, METH_VARARGS, EnumKey_doc}, + {"EnumValue", PyEnumValue, METH_VARARGS, EnumValue_doc}, + {"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS, + ExpandEnvironmentStrings_doc }, + {"FlushKey", PyFlushKey, METH_VARARGS, FlushKey_doc}, + {"LoadKey", PyLoadKey, METH_VARARGS, LoadKey_doc}, + {"OpenKey", PyOpenKey, METH_VARARGS, OpenKey_doc}, + {"OpenKeyEx", PyOpenKey, METH_VARARGS, OpenKeyEx_doc}, + {"QueryValue", PyQueryValue, METH_VARARGS, QueryValue_doc}, + {"QueryValueEx", PyQueryValueEx, METH_VARARGS, QueryValueEx_doc}, + {"QueryInfoKey", PyQueryInfoKey, METH_VARARGS, QueryInfoKey_doc}, + {"QueryReflectionKey",PyQueryReflectionKey,METH_VARARGS, QueryReflectionKey_doc}, + {"SaveKey", PySaveKey, METH_VARARGS, SaveKey_doc}, + {"SetValue", PySetValue, METH_VARARGS, SetValue_doc}, + {"SetValueEx", PySetValueEx, METH_VARARGS, SetValueEx_doc}, + NULL, +}; + +static void +insint(PyObject * d, char * name, long value) +{ + PyObject *v = PyLong_FromLong(value); + if (!v || PyDict_SetItemString(d, name, v)) + PyErr_Clear(); + Py_XDECREF(v); +} + +#define ADD_INT(val) insint(d, #val, val) + +static void +inskey(PyObject * d, char * name, HKEY key) +{ + PyObject *v = PyLong_FromVoidPtr(key); + if (!v || PyDict_SetItemString(d, name, v)) + PyErr_Clear(); + Py_XDECREF(v); +} + +#define ADD_KEY(val) inskey(d, #val, val) + +PyMODINIT_FUNC initwinreg(void) +{ + PyObject *m, *d; + m = Py_InitModule3("winreg", winreg_methods, module_doc); + if (m == NULL) + return; + d = PyModule_GetDict(m); + Py_TYPE(&PyHKEY_Type) = &PyType_Type; + PyHKEY_Type.tp_doc = PyHKEY_doc; + Py_INCREF(&PyHKEY_Type); + if (PyDict_SetItemString(d, "HKEYType", + (PyObject *)&PyHKEY_Type) != 0) + return; + Py_INCREF(PyExc_WindowsError); + if (PyDict_SetItemString(d, "error", + PyExc_WindowsError) != 0) + return; + + /* Add the relevant constants */ + ADD_KEY(HKEY_CLASSES_ROOT); + ADD_KEY(HKEY_CURRENT_USER); + ADD_KEY(HKEY_LOCAL_MACHINE); + ADD_KEY(HKEY_USERS); + ADD_KEY(HKEY_PERFORMANCE_DATA); +#ifdef HKEY_CURRENT_CONFIG + ADD_KEY(HKEY_CURRENT_CONFIG); +#endif +#ifdef HKEY_DYN_DATA + ADD_KEY(HKEY_DYN_DATA); +#endif + ADD_INT(KEY_QUERY_VALUE); + ADD_INT(KEY_SET_VALUE); + ADD_INT(KEY_CREATE_SUB_KEY); + ADD_INT(KEY_ENUMERATE_SUB_KEYS); + ADD_INT(KEY_NOTIFY); + ADD_INT(KEY_CREATE_LINK); + ADD_INT(KEY_READ); + ADD_INT(KEY_WRITE); + ADD_INT(KEY_EXECUTE); + ADD_INT(KEY_ALL_ACCESS); +#ifdef KEY_WOW64_64KEY + ADD_INT(KEY_WOW64_64KEY); +#endif +#ifdef KEY_WOW64_32KEY + ADD_INT(KEY_WOW64_32KEY); +#endif + ADD_INT(REG_OPTION_RESERVED); + ADD_INT(REG_OPTION_NON_VOLATILE); + ADD_INT(REG_OPTION_VOLATILE); + ADD_INT(REG_OPTION_CREATE_LINK); + ADD_INT(REG_OPTION_BACKUP_RESTORE); + ADD_INT(REG_OPTION_OPEN_LINK); + ADD_INT(REG_LEGAL_OPTION); + ADD_INT(REG_CREATED_NEW_KEY); + ADD_INT(REG_OPENED_EXISTING_KEY); + ADD_INT(REG_WHOLE_HIVE_VOLATILE); + ADD_INT(REG_REFRESH_HIVE); + ADD_INT(REG_NO_LAZY_FLUSH); + ADD_INT(REG_NOTIFY_CHANGE_NAME); + ADD_INT(REG_NOTIFY_CHANGE_ATTRIBUTES); + ADD_INT(REG_NOTIFY_CHANGE_LAST_SET); + ADD_INT(REG_NOTIFY_CHANGE_SECURITY); + ADD_INT(REG_LEGAL_CHANGE_FILTER); + ADD_INT(REG_NONE); + ADD_INT(REG_SZ); + ADD_INT(REG_EXPAND_SZ); + ADD_INT(REG_BINARY); + ADD_INT(REG_DWORD); + ADD_INT(REG_DWORD_LITTLE_ENDIAN); + ADD_INT(REG_DWORD_BIG_ENDIAN); + ADD_INT(REG_LINK); + ADD_INT(REG_MULTI_SZ); + ADD_INT(REG_RESOURCE_LIST); + ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR); + ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST); +} + + diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj index c2a3b9a..143a178 100644 --- a/PCbuild/pythoncore.vcproj +++ b/PCbuild/pythoncore.vcproj @@ -1563,7 +1563,7 @@ >