[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