[pypy-svn] r62034 - in pypy/trunk/pypy: module/_winreg module/_winreg/test rlib

afa at codespeak.net afa at codespeak.net
Thu Feb 19 23:21:42 CET 2009


Author: afa
Date: Thu Feb 19 23:21:40 2009
New Revision: 62034

Modified:
   pypy/trunk/pypy/module/_winreg/__init__.py
   pypy/trunk/pypy/module/_winreg/interp_winreg.py
   pypy/trunk/pypy/module/_winreg/test/test_winreg.py
   pypy/trunk/pypy/rlib/rwin32.py
   pypy/trunk/pypy/rlib/rwinreg.py
Log:
Add the missing functions to _winreg,
not tested by CPython test suite.


Modified: pypy/trunk/pypy/module/_winreg/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/__init__.py	(original)
+++ pypy/trunk/pypy/module/_winreg/__init__.py	Thu Feb 19 23:21:40 2009
@@ -54,8 +54,11 @@
         'OpenKeyEx'      : 'interp_winreg.OpenKey',
         'EnumValue'      : 'interp_winreg.EnumValue',
         'EnumKey'        : 'interp_winreg.EnumKey',
+        'FlushKey'       : 'interp_winreg.FlushKey',
         'CloseKey'       : 'interp_winreg.CloseKey',
         'QueryInfoKey'   : 'interp_winreg.QueryInfoKey',
+        'LoadKey'        : 'interp_winreg.LoadKey',
+        'SaveKey'        : 'interp_winreg.SaveKey',
         'ConnectRegistry': 'interp_winreg.ConnectRegistry',
     }
 

Modified: pypy/trunk/pypy/module/_winreg/interp_winreg.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/interp_winreg.py	(original)
+++ pypy/trunk/pypy/module/_winreg/interp_winreg.py	Thu Feb 19 23:21:40 2009
@@ -36,6 +36,22 @@
         CloseKey(space, self)
     Close.unwrap_spec = ['self', ObjSpace]
 
+    def Detach(self, space):
+        """int = key.Detach() - Detaches the Windows handle from the handle object.
+
+The result is the value of the handle before it is detached.  If the
+handle is already detached, 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.
+On 64 bit windows, the result of this function is a long integer"""
+        hkey = self.hkey
+        self.hkey = 0
+        return space.wrap(hkey)
+    Detach.unwrap_spec = ['self', ObjSpace]
+
 def new_HKEY(space, w_subtype, hkey):
     return space.wrap(W_HKEY(hkey))
 descr_HKEY_new = interp2app(new_HKEY,
@@ -70,6 +86,7 @@
     __int__ = interp2app(W_HKEY.descr_int),
     __nonzero__ = interp2app(W_HKEY.descr_nonzero),
     Close = interp2app(W_HKEY.Close),
+    Detach = interp2app(W_HKEY.Detach),
     )
 
 def hkey_w(w_hkey, space):
@@ -97,9 +114,72 @@
     if hkey:
         ret = rwinreg.RegCloseKey(hkey)
         if ret != 0:
-            raiseWindowsError(space, ret, 'RegSetValue')
+            raiseWindowsError(space, ret, 'RegCloseKey')
 CloseKey.unwrap_spec = [ObjSpace, W_Root]
 
+def FlushKey(space, w_hkey):
+    """FlushKey(key) - Writes all the attributes of a key to the registry.
+
+key is an already open key, or any one of the predefined HKEY_* constants.
+
+It is not necessary to call RegFlushKey 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 CloseKey(), the FlushKey() method returns only when all the data has
+been written to the registry.
+An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.
+If you don't know whether a FlushKey() call is required, it probably isn't."""
+    hkey = hkey_w(w_hkey, space)
+    if hkey:
+        ret = rwinreg.RegFlushKey(hkey)
+        if ret != 0:
+            raiseWindowsError(space, ret, 'RegFlushKey')
+FlushKey.unwrap_spec = [ObjSpace, W_Root]
+
+def LoadKey(space, w_hkey, subkey, filename):
+    """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 one of the predefined 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 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
+SE_RESTORE_PRIVILEGE privilege.
+
+If key is a handle returned by ConnectRegistry(), then the path specified
+in fileName is relative to the remote computer.
+
+The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"""
+    hkey = hkey_w(w_hkey, space)
+    ret = rwinreg.RegLoadKey(hkey, subkey, filename)
+    if ret != 0:
+        raiseWindowsError(space, ret, 'RegLoadKey')
+LoadKey.unwrap_spec = [ObjSpace, W_Root, str, str]
+
+def SaveKey(space, w_hkey, filename):
+    """SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.
+
+key is an already open key, or any one of the predefined 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
+ LoadKey(), ReplaceKey() or 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 SeBackupPrivilege security privilege.
+This function passes NULL for security_attributes to the API."""
+    hkey = hkey_w(w_hkey, space)
+    pSA = 0
+    ret = rwinreg.RegSaveKey(hkey, filename, None)
+    if ret != 0:
+        raiseWindowsError(space, ret, 'RegSaveKey')
+SaveKey.unwrap_spec = [ObjSpace, W_Root, str]
+
 def SetValue(space, w_hkey, w_subkey, typ, value):
     """SetValue(key, sub_key, type, value) - Associates a value with a specified key.
 
@@ -584,78 +664,3 @@
     finally:
         lltype.free(rethkey, flavor='raw')
 ConnectRegistry.unwrap_spec = [ObjSpace, W_Root, W_Root]
-
-## XXX missing functions
-
-## "string = ExpandEnvironmentStrings(string) - Expand environment vars.\n");
-
-## "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.");
-
-## "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");
-
-## "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(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");
-
-## 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");

Modified: pypy/trunk/pypy/module/_winreg/test/test_winreg.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/test/test_winreg.py	(original)
+++ pypy/trunk/pypy/module/_winreg/test/test_winreg.py	Thu Feb 19 23:21:40 2009
@@ -1,10 +1,24 @@
 from pypy.conftest import gettestobjspace
+from pypy.tool.udir import udir
 
 import os, sys, py
 
 if sys.platform != 'win32':
     py.test.skip("_winreg is a win32 module")
 
+try:
+    # To call SaveKey, the process must have Backup Privileges
+    import win32api
+    import win32security
+    priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
+    hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess (), priv_flags)
+    privilege_id = win32security.LookupPrivilegeValue (None, "SeBackupPrivilege")
+    win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)])
+except:
+    canSaveKey = False
+else:
+    canSaveKey = True
+
 class AppTestHKey:
     def setup_class(cls):
         space = gettestobjspace(usemodules=('_winreg',))
@@ -24,6 +38,8 @@
         cls.test_key_name = "SOFTWARE\\Pypy Registry Test Key - Delete Me"
         cls.w_root_key = space.wrap(cls.root_key)
         cls.w_test_key_name = space.wrap(cls.test_key_name)
+        cls.w_canSaveKey = space.wrap(canSaveKey)
+        cls.w_tmpfilename = space.wrap(str(udir.join('winreg-temp')))
 
         test_data = [
             ("Int Value", 45, _winreg.REG_DWORD),
@@ -49,7 +65,7 @@
         assert QueryValue(self.root_key, self.test_key_name) == value
 
     def test_CreateKey(self):
-        from _winreg import CreateKey, CloseKey, QueryInfoKey
+        from _winreg import CreateKey, QueryInfoKey
         key = CreateKey(self.root_key, self.test_key_name)
         sub_key = CreateKey(key, "sub_key")
 
@@ -59,7 +75,13 @@
         nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
         assert nkeys == 0
 
+    def test_close(self):
+        from _winreg import OpenKey, CloseKey, FlushKey, QueryInfoKey
+        key = OpenKey(self.root_key, self.test_key_name)
+        sub_key = OpenKey(key, "sub_key")
+
         int_sub_key = int(sub_key)
+        FlushKey(sub_key)
         CloseKey(sub_key)
         raises(EnvironmentError, QueryInfoKey, int_sub_key)
 
@@ -67,6 +89,14 @@
         key.Close()
         raises(EnvironmentError, QueryInfoKey, int_key)
 
+        key = OpenKey(self.root_key, self.test_key_name)
+        int_key = key.Detach()
+        QueryInfoKey(int_key) # works
+        key.Close()
+        QueryInfoKey(int_key) # still works
+        CloseKey(int_key)
+        raises(EnvironmentError, QueryInfoKey, int_key) # now closed
+
     def test_exception(self):
         from _winreg import QueryInfoKey
         import errno
@@ -75,7 +105,9 @@
         except EnvironmentError, e:
             assert e.winerror == 6
             assert e.errno == errno.EBADF
-            assert "invalid" in e.strerror.lower()
+            # XXX translations...
+            assert ("invalid" in e.strerror.lower() or
+                    "non valide" in e.strerror.lower())
         else:
             assert 0, "Did not raise"
 
@@ -120,3 +152,16 @@
         from _winreg import ConnectRegistry, HKEY_LOCAL_MACHINE
         h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
         h.Close()
+
+    def test_savekey(self):
+        if not self.canSaveKey:
+            skip("CPython needs win32api to set the SeBackupPrivilege security privilege")
+        from _winreg import OpenKey, KEY_ALL_ACCESS, SaveKey
+        import os
+        try:
+            os.unlink(self.tmpfilename)
+        except:
+            pass
+
+        key = OpenKey(self.root_key, self.test_key_name, 0, KEY_ALL_ACCESS)
+        SaveKey(key, self.tmpfilename)

Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py	(original)
+++ pypy/trunk/pypy/rlib/rwin32.py	Thu Feb 19 23:21:40 2009
@@ -43,13 +43,16 @@
                                         [('dwLowDateTime', rffi.UINT),
                                          ('dwHighDateTime', rffi.UINT)])
 
+        LPSECURITY_ATTRIBUTES = rffi_platform.SimpleType(
+            "LPSECURITY_ATTRIBUTES", rffi.CCHARP)
+
         DEFAULT_LANGUAGE = rffi_platform.ConstantInteger(
             "MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)")
 
         for name in """FORMAT_MESSAGE_ALLOCATE_BUFFER FORMAT_MESSAGE_FROM_SYSTEM
               """.split():
             locals()[name] = rffi_platform.ConstantInteger(name)
-        
+
 
 for k, v in rffi_platform.configure(CConfig).items():
     globals()[k] = v

Modified: pypy/trunk/pypy/rlib/rwinreg.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwinreg.py	(original)
+++ pypy/trunk/pypy/rlib/rwinreg.py	Thu Feb 19 23:21:40 2009
@@ -113,6 +113,21 @@
     [HKEY],
     rffi.LONG)
 
+RegFlushKey = external(
+    'RegFlushKey',
+    [HKEY],
+    rffi.LONG)
+
+RegLoadKey = external(
+    'RegLoadKeyA',
+    [HKEY, rffi.CCHARP, rffi.CCHARP],
+    rffi.LONG)
+
+RegSaveKey = external(
+    'RegSaveKeyA',
+    [HKEY, rffi.CCHARP, rffi.VOIDP],
+    rffi.LONG)
+
 RegConnectRegistry = external(
     'RegConnectRegistryA',
     [rffi.CCHARP, HKEY, PHKEY],



More information about the Pypy-commit mailing list