PageRenderTime 220ms CodeModel.GetById 70ms app.highlight 127ms RepoModel.GetById 14ms app.codeStats 0ms

/pypy/module/_winreg/interp_winreg.py

https://bitbucket.org/pypy/pypy/
Python | 740 lines | 714 code | 14 blank | 12 comment | 5 complexity | 0dca3dd597d92e2f692d15b8f55fc041 MD5 | raw file
  1from __future__ import with_statement
  2from pypy.interpreter.baseobjspace import W_Root, BufferInterfaceNotFound
  3from pypy.interpreter.gateway import interp2app, unwrap_spec
  4from pypy.interpreter.typedef import TypeDef, GetSetProperty
  5from pypy.interpreter.error import OperationError, oefmt, wrap_windowserror
  6from rpython.rtyper.lltypesystem import rffi, lltype
  7from rpython.rlib import rwinreg, rwin32
  8from rpython.rlib.rarithmetic import r_uint, intmask
  9
 10def raiseWindowsError(space, errcode, context):
 11    message = rwin32.FormatError(errcode)
 12    raise OperationError(space.w_WindowsError,
 13                         space.newtuple([space.wrap(errcode),
 14                                         space.wrap(message)]))
 15
 16class W_HKEY(W_Root):
 17    def __init__(self, space, hkey):
 18        self.hkey = hkey
 19        self.space = space
 20        self.register_finalizer(space)
 21
 22    def _finalize_(self):
 23        self.Close(self.space)
 24
 25    def as_int(self):
 26        return rffi.cast(rffi.SIZE_T, self.hkey)
 27
 28    def descr_nonzero(self, space):
 29        return space.wrap(self.as_int() != 0)
 30
 31    def descr_handle_get(self, space):
 32        return space.wrap(self.as_int())
 33
 34    def descr_repr(self, space):
 35        return space.wrap("<PyHKEY:0x%x>" % (self.as_int(),))
 36
 37    def descr_int(self, space):
 38        return space.wrap(self.as_int())
 39
 40    def descr__enter__(self, space):
 41        return self
 42
 43    def descr__exit__(self, space, __args__):
 44        CloseKey(space, self)
 45
 46    def Close(self, space):
 47        """key.Close() - Closes the underlying Windows handle.
 48If the handle is already closed, no error is raised."""
 49        CloseKey(space, self)
 50
 51    def Detach(self, space):
 52        """int = key.Detach() - Detaches the Windows handle from the handle object.
 53
 54The result is the value of the handle before it is detached.  If the
 55handle is already detached, this will return zero.
 56
 57After calling this function, the handle is effectively invalidated,
 58but the handle is not closed.  You would call this function when you
 59need the underlying win32 handle to exist beyond the lifetime of the
 60handle object.
 61On 64 bit windows, the result of this function is a long integer"""
 62        key = self.as_int()
 63        self.hkey = rwin32.NULL_HANDLE
 64        return space.wrap(key)
 65
 66@unwrap_spec(key=int)
 67def new_HKEY(space, w_subtype, key):
 68    hkey = rffi.cast(rwinreg.HKEY, key)
 69    return space.wrap(W_HKEY(space, hkey))
 70descr_HKEY_new = interp2app(new_HKEY)
 71
 72W_HKEY.typedef = TypeDef(
 73    "_winreg.HKEYType",
 74    __doc__ = """\
 75PyHKEY Object - A Python object, representing a win32 registry key.
 76
 77This object wraps a Windows HKEY object, automatically closing it when
 78the object is destroyed.  To guarantee cleanup, you can call either
 79the Close() method on the PyHKEY, or the CloseKey() method.
 80
 81All functions which accept a handle object also accept an integer -
 82however, use of the handle object is encouraged.
 83
 84Functions:
 85Close() - Closes the underlying handle.
 86Detach() - Returns the integer Win32 handle, detaching it from the object
 87
 88Properties:
 89handle - The integer Win32 handle.
 90
 91Operations:
 92__nonzero__ - Handles with an open object return true, otherwise false.
 93__int__ - Converting a handle to an integer returns the Win32 handle.
 94__cmp__ - Handle objects are compared using the handle value.""",
 95    __new__ = descr_HKEY_new,
 96    __repr__ = interp2app(W_HKEY.descr_repr),
 97    __int__ = interp2app(W_HKEY.descr_int),
 98    __nonzero__ = interp2app(W_HKEY.descr_nonzero),
 99    __enter__ = interp2app(W_HKEY.descr__enter__),
100    __exit__ = interp2app(W_HKEY.descr__exit__),
101    handle = GetSetProperty(W_HKEY.descr_handle_get),
102    Close = interp2app(W_HKEY.Close),
103    Detach = interp2app(W_HKEY.Detach),
104    )
105
106def hkey_w(w_hkey, space):
107    if space.is_w(w_hkey, space.w_None):
108        raise oefmt(space.w_TypeError,
109                    "None is not a valid HKEY in this context")
110    elif isinstance(w_hkey, W_HKEY):
111        return w_hkey.hkey
112    elif space.isinstance_w(w_hkey, space.w_int):
113        return rffi.cast(rwinreg.HKEY, space.int_w(w_hkey))
114    elif space.isinstance_w(w_hkey, space.w_long):
115        return rffi.cast(rwinreg.HKEY, space.uint_w(w_hkey))
116    else:
117        raise oefmt(space.w_TypeError, "The object is not a PyHKEY object")
118
119def CloseKey(space, w_hkey):
120    """CloseKey(hkey) - Closes a previously opened registry key.
121
122The hkey argument specifies a previously opened key.
123
124Note that if the key is not closed using this method, it will be
125closed when the hkey object is destroyed by Python."""
126    hkey = hkey_w(w_hkey, space)
127    if hkey:
128        ret = rwinreg.RegCloseKey(hkey)
129        if ret != 0:
130            raiseWindowsError(space, ret, 'RegCloseKey')
131    if isinstance(w_hkey, W_HKEY):
132        space.interp_w(W_HKEY, w_hkey).hkey = rwin32.NULL_HANDLE
133
134def FlushKey(space, w_hkey):
135    """FlushKey(key) - Writes all the attributes of a key to the registry.
136
137key is an already open key, or any one of the predefined HKEY_* constants.
138
139It is not necessary to call RegFlushKey to change a key.
140Registry changes are flushed to disk by the registry using its lazy flusher.
141Registry changes are also flushed to disk at system shutdown.
142Unlike CloseKey(), the FlushKey() method returns only when all the data has
143been written to the registry.
144An application should only call FlushKey() if it requires absolute certainty that registry changes are on disk.
145If you don't know whether a FlushKey() call is required, it probably isn't."""
146    hkey = hkey_w(w_hkey, space)
147    if hkey:
148        ret = rwinreg.RegFlushKey(hkey)
149        if ret != 0:
150            raiseWindowsError(space, ret, 'RegFlushKey')
151
152@unwrap_spec(subkey=str, filename=str)
153def LoadKey(space, w_hkey, subkey, filename):
154    """LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key
155and stores registration information from a specified file into that subkey.
156
157key is an already open key, or any one of the predefined HKEY_* constants.
158sub_key is a string that identifies the sub_key to load
159file_name is the name of the file to load registry data from.
160 This file must have been created with the SaveKey() function.
161 Under the file allocation table (FAT) file system, the filename may not
162have an extension.
163
164A call to LoadKey() fails if the calling process does not have the
165SE_RESTORE_PRIVILEGE privilege.
166
167If key is a handle returned by ConnectRegistry(), then the path specified
168in fileName is relative to the remote computer.
169
170The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"""
171    hkey = hkey_w(w_hkey, space)
172    ret = rwinreg.RegLoadKey(hkey, subkey, filename)
173    if ret != 0:
174        raiseWindowsError(space, ret, 'RegLoadKey')
175
176@unwrap_spec(filename=str)
177def SaveKey(space, w_hkey, filename):
178    """SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.
179
180key is an already open key, or any one of the predefined HKEY_* constants.
181file_name is the name of the file to save registry data to.
182 This file cannot already exist. If this filename includes an extension,
183 it cannot be used on file allocation table (FAT) file systems by the
184 LoadKey(), ReplaceKey() or RestoreKey() methods.
185
186If key represents a key on a remote computer, the path described by
187file_name is relative to the remote computer.
188The caller of this method must possess the SeBackupPrivilege security privilege.
189This function passes NULL for security_attributes to the API."""
190    hkey = hkey_w(w_hkey, space)
191    ret = rwinreg.RegSaveKey(hkey, filename, None)
192    if ret != 0:
193        raiseWindowsError(space, ret, 'RegSaveKey')
194
195@unwrap_spec(typ=int, value=str)
196def SetValue(space, w_hkey, w_subkey, typ, value):
197    """SetValue(key, sub_key, type, value) - Associates a value with a specified key.
198
199key is an already open key, or any one of the predefined HKEY_* constants.
200sub_key is a string that names the subkey with which the value is associated.
201type is an integer that specifies the type of the data.  Currently this
202 must be REG_SZ, meaning only strings are supported.
203value is a string that specifies the new value.
204
205If the key specified by the sub_key parameter does not exist, the SetValue
206function creates it.
207
208Value lengths are limited by available memory. Long values (more than
2092048 bytes) should be stored as files with the filenames stored in
210the configuration registry.  This helps the registry perform efficiently.
211
212The key identified by the key parameter must have been opened with
213KEY_SET_VALUE access."""
214    if typ != rwinreg.REG_SZ:
215        raise oefmt(space.w_ValueError, "Type must be _winreg.REG_SZ")
216    hkey = hkey_w(w_hkey, space)
217    if space.is_w(w_subkey, space.w_None):
218        subkey = None
219    else:
220        subkey = space.str_w(w_subkey)
221    with rffi.scoped_str2charp(value) as dataptr:
222        ret = rwinreg.RegSetValue(hkey, subkey, rwinreg.REG_SZ, dataptr, len(value))
223        if ret != 0:
224            raiseWindowsError(space, ret, 'RegSetValue')
225
226def QueryValue(space, w_hkey, w_subkey):
227    """string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.
228
229key is an already open key, or any one of the predefined HKEY_* constants.
230sub_key is a string that holds the name of the subkey with which the value
231 is associated.  If this parameter is None or empty, the function retrieves
232 the value set by the SetValue() method for the key identified by key.
233
234Values in the registry have name, type, and data components. This method
235retrieves the data for a key's first value that has a NULL name.
236But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!"""
237    hkey = hkey_w(w_hkey, space)
238    if space.is_w(w_subkey, space.w_None):
239        subkey = None
240    else:
241        subkey = space.str_w(w_subkey)
242    with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
243        ret = rwinreg.RegQueryValue(hkey, subkey, None, bufsize_p)
244        bufSize = intmask(bufsize_p[0])
245        if ret == rwinreg.ERROR_MORE_DATA:
246            bufSize = 256
247        elif ret != 0:
248            raiseWindowsError(space, ret, 'RegQueryValue')
249
250        while True:
251            with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as buf:
252                ret = rwinreg.RegQueryValue(hkey, subkey, buf, bufsize_p)
253                if ret == rwinreg.ERROR_MORE_DATA:
254                    # Resize and retry
255                    bufSize *= 2
256                    bufsize_p[0] = bufSize
257                    continue
258
259                if ret != 0:
260                    raiseWindowsError(space, ret, 'RegQueryValue')
261                length = intmask(bufsize_p[0] - 1)
262                return space.wrap(rffi.charp2strn(buf, length))
263
264def convert_to_regdata(space, w_value, typ):
265    buf = None
266
267    if typ == rwinreg.REG_DWORD:
268        if space.is_none(w_value) or (
269                space.isinstance_w(w_value, space.w_int) or
270                space.isinstance_w(w_value, space.w_long)):
271            if space.is_none(w_value):
272                value = r_uint(0)
273            else:
274                value = space.c_uint_w(w_value)
275            buflen = rffi.sizeof(rwin32.DWORD)
276            buf1 = lltype.malloc(rffi.CArray(rwin32.DWORD), 1, flavor='raw')
277            buf1[0] = value
278            buf = rffi.cast(rffi.CCHARP, buf1)
279
280    elif typ == rwinreg.REG_SZ or typ == rwinreg.REG_EXPAND_SZ:
281        if space.is_w(w_value, space.w_None):
282            buflen = 1
283            buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
284            buf[0] = '\0'
285        else:
286            if space.isinstance_w(w_value, space.w_unicode):
287                w_value = space.call_method(w_value, 'encode',
288                                            space.wrap('mbcs'))
289            buf = rffi.str2charp(space.str_w(w_value))
290            buflen = space.len_w(w_value) + 1
291
292    elif typ == rwinreg.REG_MULTI_SZ:
293        if space.is_w(w_value, space.w_None):
294            buflen = 1
295            buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
296            buf[0] = '\0'
297        elif space.isinstance_w(w_value, space.w_list):
298            strings = []
299            buflen = 0
300
301            # unwrap strings and compute total size
302            w_iter = space.iter(w_value)
303            while True:
304                try:
305                    w_item = space.next(w_iter)
306                    if space.isinstance_w(w_item, space.w_unicode):
307                        w_item = space.call_method(w_item, 'encode',
308                                                   space.wrap('mbcs'))
309                    item = space.str_w(w_item)
310                    strings.append(item)
311                    buflen += len(item) + 1
312                except OperationError as e:
313                    if not e.match(space, space.w_StopIteration):
314                        raise       # re-raise other app-level exceptions
315                    break
316            buflen += 1
317            buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
318
319            # Now copy data
320            buflen = 0
321            for string in strings:
322                for i in range(len(string)):
323                    buf[buflen + i] = string[i]
324                buflen += len(string) + 1
325                buf[buflen - 1] = '\0'
326            buflen += 1
327            buf[buflen - 1] = '\0'
328
329    else: # REG_BINARY and ALL unknown data types.
330        if space.is_w(w_value, space.w_None):
331            buflen = 0
332            buf = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw')
333            buf[0] = '\0'
334        else:
335            try:
336                value = w_value.readbuf_w(space)
337            except BufferInterfaceNotFound:
338                raise oefmt(space.w_TypeError,
339                            "Objects of type '%T' can not be used as binary "
340                            "registry values", w_value)
341            else:
342                value = value.as_str()
343            buflen = len(value)
344            buf = rffi.str2charp(value)
345
346    if buf is not None:
347        return rffi.cast(rffi.CCHARP, buf), buflen
348
349    raise oefmt(space.w_ValueError,
350                "Could not convert the data to the specified type")
351
352def convert_from_regdata(space, buf, buflen, typ):
353    if typ == rwinreg.REG_DWORD:
354        if not buflen:
355            return space.wrap(0)
356        d = rffi.cast(rwin32.LPDWORD, buf)[0]
357        return space.wrap(d)
358
359    elif typ == rwinreg.REG_SZ or typ == rwinreg.REG_EXPAND_SZ:
360        if not buflen:
361            return space.wrap("")
362        s = rffi.charp2strn(rffi.cast(rffi.CCHARP, buf), buflen)
363        return space.wrap(s)
364
365    elif typ == rwinreg.REG_MULTI_SZ:
366        if not buflen:
367            return space.newlist([])
368        i = 0
369        l = []
370        while i < buflen and buf[i]:
371            s = []
372            while i < buflen and buf[i] != '\0':
373                s.append(buf[i])
374                i += 1
375            if len(s) == 0:
376                break
377            s = ''.join(s)
378            l.append(space.wrap(s))
379            i += 1
380        return space.newlist(l)
381
382    else: # REG_BINARY and all other types
383        return space.newbytes(rffi.charpsize2str(buf, buflen))
384
385@unwrap_spec(value_name=str, typ=int)
386def SetValueEx(space, w_hkey, value_name, w_reserved, typ, w_value):
387    """SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.
388
389key is an already open key, or any one of the predefined HKEY_* constants.
390value_name is a string containing the name of the value to set, or None
391type is an integer that specifies the type of the data.  This should be one of:
392  REG_BINARY -- Binary data in any form.
393  REG_DWORD -- A 32-bit number.
394  REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.
395  REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.
396  REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references
397                   to environment variables (for example, %PATH%).
398  REG_LINK -- A Unicode symbolic link.
399  REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by
400                  two null characters.  Note that Python handles this
401                  termination automatically.
402  REG_NONE -- No defined value type.
403  REG_RESOURCE_LIST -- A device-driver resource list.
404  REG_SZ -- A null-terminated string.
405reserved can be anything - zero is always passed to the API.
406value is a string that specifies the new value.
407
408This method can also set additional value and type information for the
409specified key.  The key identified by the key parameter must have been
410opened with KEY_SET_VALUE access.
411
412To open the key, use the CreateKeyEx() or OpenKeyEx() methods.
413
414Value lengths are limited by available memory. Long values (more than
4152048 bytes) should be stored as files with the filenames stored in
416the configuration registry.  This helps the registry perform efficiently."""
417    hkey = hkey_w(w_hkey, space)
418    buf, buflen = convert_to_regdata(space, w_value, typ)
419    try:
420        ret = rwinreg.RegSetValueEx(hkey, value_name, 0, typ, buf, buflen)
421    finally:
422        lltype.free(buf, flavor='raw')
423    if ret != 0:
424        raiseWindowsError(space, ret, 'RegSetValueEx')
425
426def QueryValueEx(space, w_hkey, w_subkey):
427    """value,type_id = QueryValueEx(key, value_name) - Retrieves the type and data for a specified value name associated with an open registry key.
428
429key is an already open key, or any one of the predefined HKEY_* constants.
430value_name is a string indicating the value to query"""
431    hkey = hkey_w(w_hkey, space)
432    if space.is_w(w_subkey, space.w_None):
433        subkey = None
434    else:
435        subkey = space.str_w(w_subkey)
436    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
437    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
438        ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword, null_dword,
439                                      None, retDataSize)
440        bufSize = intmask(retDataSize[0])
441        if ret == rwinreg.ERROR_MORE_DATA:
442            bufSize = 256
443        elif ret != 0:
444            raiseWindowsError(space, ret, 'RegQueryValueEx')
445
446        while True:
447            with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as databuf:
448                with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
449
450                    ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword,
451                                                  retType, databuf, retDataSize)
452                    if ret == rwinreg.ERROR_MORE_DATA:
453                        # Resize and retry
454                        bufSize *= 2
455                        retDataSize[0] = rffi.cast(rwin32.DWORD, bufSize)
456                        continue
457                    if ret != 0:
458                        raiseWindowsError(space, ret, 'RegQueryValueEx')
459                    length = intmask(retDataSize[0])
460                    return space.newtuple([
461                        convert_from_regdata(space, databuf,
462                                             length, retType[0]),
463                        space.wrap(retType[0]),
464                        ])
465
466@unwrap_spec(subkey=str)
467def CreateKey(space, w_hkey, subkey):
468    """key = CreateKey(key, sub_key) - Creates or opens the specified key.
469
470key is an already open key, or one of the predefined HKEY_* constants
471sub_key is a string that names the key this method opens or creates.
472 If key is one of the predefined keys, sub_key may be None. In that case,
473 the handle returned is the same key handle passed in to the function.
474
475If the key already exists, this function opens the existing key
476
477The return value is the handle of the opened key.
478If the function fails, an exception is raised."""
479    hkey = hkey_w(w_hkey, space)
480    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
481        ret = rwinreg.RegCreateKey(hkey, subkey, rethkey)
482        if ret != 0:
483            raiseWindowsError(space, ret, 'CreateKey')
484        return space.wrap(W_HKEY(space, rethkey[0]))
485
486@unwrap_spec(subkey=str, res=int, sam=rffi.r_uint)
487def CreateKeyEx(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_WRITE):
488    """key = CreateKey(key, sub_key) - Creates or opens the specified key.
489
490key is an already open key, or one of the predefined HKEY_* constants
491sub_key is a string that names the key this method opens or creates.
492 If key is one of the predefined keys, sub_key may be None. In that case,
493 the handle returned is the same key handle passed in to the function.
494
495If the key already exists, this function opens the existing key
496
497The return value is the handle of the opened key.
498If the function fails, an exception is raised."""
499    hkey = hkey_w(w_hkey, space)
500    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
501        ret = rwinreg.RegCreateKeyEx(hkey, subkey, res, None, 0,
502                                     sam, None, rethkey,
503                                     lltype.nullptr(rwin32.LPDWORD.TO))
504        if ret != 0:
505            raiseWindowsError(space, ret, 'CreateKeyEx')
506        return space.wrap(W_HKEY(space, rethkey[0]))
507
508@unwrap_spec(subkey=str)
509def DeleteKey(space, w_hkey, subkey):
510    """DeleteKey(key, sub_key) - Deletes the specified key.
511
512key is an already open key, or any one of the predefined HKEY_* constants.
513sub_key is a string that must be a subkey of the key identified by the key parameter.
514 This value must not be None, and the key may not have subkeys.
515
516This method can not delete keys with subkeys.
517
518If the method succeeds, the entire key, including all of its values,
519is removed.  If the method fails, an EnvironmentError exception is raised."""
520    hkey = hkey_w(w_hkey, space)
521    ret = rwinreg.RegDeleteKey(hkey, subkey)
522    if ret != 0:
523        raiseWindowsError(space, ret, 'RegDeleteKey')
524
525@unwrap_spec(subkey=str)
526def DeleteValue(space, w_hkey, subkey):
527    """DeleteValue(key, value) - Removes a named value from a registry key.
528
529key is an already open key, or any one of the predefined HKEY_* constants.
530value is a string that identifies the value to remove."""
531    hkey = hkey_w(w_hkey, space)
532    ret = rwinreg.RegDeleteValue(hkey, subkey)
533    if ret != 0:
534        raiseWindowsError(space, ret, 'RegDeleteValue')
535
536@unwrap_spec(subkey=str, res=int, sam=rffi.r_uint)
537def OpenKey(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_READ):
538    """key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens the specified key.
539
540key is an already open key, or any one of the predefined HKEY_* constants.
541sub_key is a string that identifies the sub_key to open
542res is a reserved integer, and must be zero.  Default is zero.
543sam is an integer that specifies an access mask that describes the desired
544 security access for the key.  Default is KEY_READ
545
546The result is a new handle to the specified key
547If the function fails, an EnvironmentError exception is raised."""
548    hkey = hkey_w(w_hkey, space)
549    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
550        ret = rwinreg.RegOpenKeyEx(hkey, subkey, res, sam, rethkey)
551        if ret != 0:
552            raiseWindowsError(space, ret, 'RegOpenKeyEx')
553        return space.wrap(W_HKEY(space, rethkey[0]))
554
555@unwrap_spec(index=int)
556def EnumValue(space, w_hkey, index):
557    """tuple = EnumValue(key, index) - Enumerates values of an open registry key.
558key is an already open key, or any one of the predefined HKEY_* constants.
559index is an integer that identifies the index of the value to retrieve.
560
561The function retrieves the name of one subkey each time it is called.
562It is typically called repeatedly, until an EnvironmentError exception
563is raised, indicating no more values.
564
565The result is a tuple of 3 items:
566value_name is a string that identifies the value.
567value_data is an object that holds the value data, and whose type depends
568 on the underlying registry type.
569data_type is an integer that identifies the type of the value data."""
570    hkey = hkey_w(w_hkey, space)
571    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
572
573    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retValueSize:
574        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
575            ret = rwinreg.RegQueryInfoKey(
576                hkey, None, null_dword, null_dword,
577                null_dword, null_dword, null_dword,
578                null_dword, retValueSize, retDataSize,
579                null_dword, lltype.nullptr(rwin32.PFILETIME.TO))
580            if ret != 0:
581                raiseWindowsError(space, ret, 'RegQueryInfoKey')
582            # include null terminators
583            retValueSize[0] += 1
584            retDataSize[0] += 1
585            bufDataSize = intmask(retDataSize[0])
586            bufValueSize = intmask(retValueSize[0])
587
588            with lltype.scoped_alloc(rffi.CCHARP.TO,
589                                     intmask(retValueSize[0])) as valuebuf:
590                while True:
591                    with lltype.scoped_alloc(rffi.CCHARP.TO,
592                                             bufDataSize) as databuf:
593                        with lltype.scoped_alloc(rwin32.LPDWORD.TO,
594                                                 1) as retType:
595                            ret = rwinreg.RegEnumValue(
596                                hkey, index, valuebuf, retValueSize,
597                                null_dword, retType, databuf, retDataSize)
598                            if ret == rwinreg.ERROR_MORE_DATA:
599                                # Resize and retry
600                                bufDataSize *= 2
601                                retDataSize[0] = rffi.cast(rwin32.DWORD,
602                                                           bufDataSize)
603                                retValueSize[0] = rffi.cast(rwin32.DWORD,
604                                                            bufValueSize)
605                                continue
606
607                            if ret != 0:
608                                raiseWindowsError(space, ret, 'RegEnumValue')
609
610                            length = intmask(retDataSize[0])
611                            return space.newtuple([
612                                space.wrap(rffi.charp2str(valuebuf)),
613                                convert_from_regdata(space, databuf,
614                                                     length, retType[0]),
615                                space.wrap(retType[0]),
616                                ])
617
618@unwrap_spec(index=int)
619def EnumKey(space, w_hkey, index):
620    """string = EnumKey(key, index) - Enumerates subkeys of an open registry key.
621
622key is an already open key, or any one of the predefined HKEY_* constants.
623index is an integer that identifies the index of the key to retrieve.
624
625The function retrieves the name of one subkey each time it is called.
626It is typically called repeatedly until an EnvironmentError exception is
627raised, indicating no more values are available."""
628    hkey = hkey_w(w_hkey, space)
629    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
630
631    # The Windows docs claim that the max key name length is 255
632    # characters, plus a terminating nul character.  However,
633    # empirical testing demonstrates that it is possible to
634    # create a 256 character key that is missing the terminating
635    # nul.  RegEnumKeyEx requires a 257 character buffer to
636    # retrieve such a key name.
637    with lltype.scoped_alloc(rffi.CCHARP.TO, 257) as buf:
638        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retValueSize:
639            retValueSize[0] = r_uint(257) # includes NULL terminator
640            ret = rwinreg.RegEnumKeyEx(hkey, index, buf, retValueSize,
641                                       null_dword, None, null_dword,
642                                       lltype.nullptr(rwin32.PFILETIME.TO))
643            if ret != 0:
644                raiseWindowsError(space, ret, 'RegEnumKeyEx')
645            return space.wrap(rffi.charp2str(buf))
646
647def QueryInfoKey(space, w_hkey):
648    """tuple = QueryInfoKey(key) - Returns information about a key.
649
650key is an already open key, or any one of the predefined HKEY_* constants.
651
652The result is a tuple of 3 items:
653An integer that identifies the number of sub keys this key has.
654An integer that identifies the number of values this key has.
655A long integer that identifies when the key was last modified (if available)
656 as 100's of nanoseconds since Jan 1, 1600."""
657    hkey = hkey_w(w_hkey, space)
658    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as nSubKeys:
659        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as nValues:
660            with lltype.scoped_alloc(rwin32.PFILETIME.TO, 1) as ft:
661                null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
662                ret = rwinreg.RegQueryInfoKey(
663                    hkey, None, null_dword, null_dword,
664                    nSubKeys, null_dword, null_dword,
665                    nValues, null_dword, null_dword,
666                    null_dword, ft)
667                if ret != 0:
668                    raiseWindowsError(space, ret, 'RegQueryInfoKey')
669                l = ((lltype.r_longlong(ft[0].c_dwHighDateTime) << 32) +
670                     lltype.r_longlong(ft[0].c_dwLowDateTime))
671                return space.newtuple([space.wrap(nSubKeys[0]),
672                                       space.wrap(nValues[0]),
673                                       space.wrap(l)])
674
675def ConnectRegistry(space, w_machine, w_hkey):
676    """key = ConnectRegistry(computer_name, key)
677
678Establishes a connection to a predefined registry handle on another computer.
679
680computer_name is the name of the remote computer, of the form \\\\computername.
681 If None, the local computer is used.
682key is the predefined handle to connect to.
683
684The return value is the handle of the opened key.
685If the function fails, an EnvironmentError exception is raised."""
686    machine = space.str_or_None_w(w_machine)
687    hkey = hkey_w(w_hkey, space)
688    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
689        ret = rwinreg.RegConnectRegistry(machine, hkey, rethkey)
690        if ret != 0:
691            raiseWindowsError(space, ret, 'RegConnectRegistry')
692        return space.wrap(W_HKEY(space, rethkey[0]))
693
694@unwrap_spec(source=unicode)
695def ExpandEnvironmentStrings(space, source):
696    "string = ExpandEnvironmentStrings(string) - Expand environment vars."
697    try:
698        return space.wrap(rwinreg.ExpandEnvironmentStrings(source))
699    except WindowsError as e:
700        raise wrap_windowserror(space, e)
701
702def DisableReflectionKey(space, w_key):
703    """Disables registry reflection for 32-bit processes running on a 64-bit
704    Operating System.  Will generally raise NotImplemented if executed on
705    a 32-bit Operating System.
706    If the key is not on the reflection list, the function succeeds but has no effect.
707    Disabling reflection for a key does not affect reflection of any subkeys."""
708    raise oefmt(space.w_NotImplementedError,
709                "not implemented on this platform")
710
711def EnableReflectionKey(space, w_key):
712    """Restores registry reflection for the specified disabled key.
713    Will generally raise NotImplemented if executed on a 32-bit Operating System.
714    Restoring reflection for a key does not affect reflection of any subkeys."""
715    raise oefmt(space.w_NotImplementedError,
716                "not implemented on this platform")
717
718def QueryReflectionKey(space, w_key):
719    """bool = QueryReflectionKey(hkey) - Determines the reflection state for the specified key.
720    Will generally raise NotImplemented if executed on a 32-bit Operating System."""
721    raise oefmt(space.w_NotImplementedError,
722                "not implemented on this platform")
723
724@unwrap_spec(subkey=str)
725def DeleteKeyEx(space, w_key, subkey):
726    """DeleteKeyEx(key, sub_key, sam, res) - Deletes the specified key.
727
728    key is an already open key, or any one of the predefined HKEY_* constants.
729    sub_key is a string that must be a subkey of the key identified by the key parameter.
730    res is a reserved integer, and must be zero.  Default is zero.
731    sam is an integer that specifies an access mask that describes the desired
732     This value must not be None, and the key may not have subkeys.
733
734    This method can not delete keys with subkeys.
735
736    If the method succeeds, the entire key, including all of its values,
737    is removed.  If the method fails, a WindowsError exception is raised.
738    On unsupported Windows versions, NotImplementedError is raised."""
739    raise oefmt(space.w_NotImplementedError,
740                "not implemented on this platform")