Пример #1
0
def EnumKey(space, w_hkey, index):
    """string = EnumKey(key, index) - Enumerates subkeys of an open registry key.

key is an already open key, or any one of the predefined 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 EnvironmentError exception is
raised, indicating no more values are available."""
    hkey = hkey_w(w_hkey, space)
    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)

    # The Windows docs claim that the max key name length is 255
    # characters, plus a terminating nul character.  However,
    # empirical testing demonstrates that it is possible to
    # create a 256 character key that is missing the terminating
    # nul.  RegEnumKeyEx requires a 257 character buffer to
    # retrieve such a key name.
    buf = ByteBuffer(257 * 2)
    bufP = rffi.cast(rwin32.LPWSTR, buf.get_raw_address())
    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as valueSize:
        valueSize[0] = r_uint(257)  # includes NULL terminator
        ret = rwinreg.RegEnumKeyExW(hkey, index, bufP, valueSize, null_dword,
                                    None, null_dword,
                                    lltype.nullptr(rwin32.PFILETIME.TO))
        if ret != 0:
            raiseWindowsError(space, ret, 'RegEnumKeyEx')
        vlen = intmask(valueSize[0]) * 2
        utf8, lgt = wbuf_to_utf8(space, buf[0:vlen])
        return space.newtext(utf8, lgt)
Пример #2
0
def QueryValue(space, w_hkey, w_subkey):
    """
string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.

key is an already open key, or any one of the predefined 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 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, DONT USE THIS!!!"""
    hkey = hkey_w(w_hkey, space)
    if space.is_w(w_subkey, space.w_None):
        subkey = None
    else:
        subkey = space.utf8_w(w_subkey).decode('utf8')
    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
        c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey)
        with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
            bufsize_p[0] = 0
            ret = rwinreg.RegQueryValueW(hkey, c_subkey, None, bufsize_p)
            if ret == 0 and intmask(bufsize_p[0]) == 0:
                return space.newtext('', 0)
            elif ret != 0 and ret != rwinreg.ERROR_MORE_DATA:
                raiseWindowsError(space, ret, 'RegQueryValue')
            # Add extra space for a NULL ending
            buf = ByteBuffer(intmask(bufsize_p[0]) * 2 + 2)
            bufP = rffi.cast(rwin32.LPWSTR, buf.get_raw_address())
            ret = rwinreg.RegQueryValueW(hkey, c_subkey, bufP, bufsize_p)
            if ret != 0:
                raiseWindowsError(space, ret, 'RegQueryValue')
            utf8, lgt = wbuf_to_utf8(space, buf[0:intmask(bufsize_p[0])])
            return space.newtext(utf8, lgt)
Пример #3
0
def QueryValueEx(space, w_hkey, w_subkey):
    """
value,type_id = 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 any one of the predefined HKEY_* constants.
value_name is a string indicating the value to query"""
    hkey = hkey_w(w_hkey, space)
    if space.is_w(w_subkey, space.w_None):
        subkey = None
    else:
        subkey = space.utf8_w(w_subkey).decode('utf8')
    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
        c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey)
        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as dataSize:
            ret = rwinreg.RegQueryValueExW(hkey, c_subkey, null_dword,
                                           null_dword, None, dataSize)
            bufSize = intmask(dataSize[0])
            if ret == rwinreg.ERROR_MORE_DATA:
                # Copy CPython behaviour, otherwise bufSize can be 0
                bufSize = 256
            elif ret != 0:
                raiseWindowsError(space, ret, 'RegQueryValue')
            while True:
                dataBuf = ByteBuffer(bufSize)
                dataBufP = rffi.cast(rffi.CWCHARP, dataBuf.get_raw_address())
                with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:

                    ret = rwinreg.RegQueryValueExW(hkey, c_subkey, null_dword,
                                                   retType, dataBufP, dataSize)
                    if ret == rwinreg.ERROR_MORE_DATA:
                        # Resize and retry
                        bufSize *= 2
                        dataSize[0] = rffi.cast(rwin32.DWORD, bufSize)
                        continue
                    if ret != 0:
                        raiseWindowsError(space, ret, 'RegQueryValueEx')
                    length = intmask(dataSize[0])
                    return space.newtuple([
                        convert_from_regdata(space, dataBuf, length,
                                             retType[0]),
                        space.newint(intmask(retType[0])),
                    ])
Пример #4
0
def read_console_wide(space, handle, maxlen):
    """ 
    Make a blocking call to ReadConsoleW, returns wchar-encoded bytes
    """
    err = 0
    sig = 0
    # Windows uses a 16-bit wchar_t, we mimic that with bytes
    buf = ByteBuffer((maxlen + 2) * 2)
    addr = buf.get_raw_address()
    off = 0  # offset from the beginning of buf, in wchar
    # readlen is in 16 bits, readlen_b is in 8-bit bytes
    readlen = readlen_b = 0
    bufsize = BUFSIZ
    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as n:
        while readlen_b < maxlen:
            neg_one = rffi.cast(rwin32.DWORD, -1)
            n[0] = neg_one
            length = min(maxlen - off, bufsize)
            rwin32.SetLastError_saved(0)
            res = rwin32.ReadConsoleW(
                handle, rffi.cast(rwin32.LPWSTR, rffi.ptradd(addr, readlen_b)),
                length, n, rffi.cast(rwin32.LPVOID, 0))
            nread = intmask(n[0])
            err = rwin32.GetLastError_saved()
            if not res:
                break

            if nread == -1 and err == rwin32.ERROR_OPERATION_ABORTED:
                break

            if nread == 0:
                if err != rwin32.ERROR_OPERATION_ABORTED:
                    break
                err = 0
                # This will only catch CTRL-C on the main thread
                sleep(space, space.newfloat(0.1))
                continue
            readlen += nread
            readlen_b = 2 * readlen

            # We didn't manage to read the whole buffer
            # don't try again as it will just block
            if nread < length:
                break

            if buf.getitem(readlen_b - 2) == '\n':
                # We read a new line
                break

            # If the buffer ends with a high surrogate, take an extra character.
            if (readlen_b + 1) >= maxlen:
                with lltype.scoped_alloc(rwin32.LPWORD.TO, 1) as char_type:
                    ptr = rffi.cast(rffi.CWCHARP, rffi.ptradd(addr, +1))
                    rwin32.GetStringTypeW(rwin32.CT_CTYPE3, ptr, 1, char_type)
                    if intmask(char_type[0]) == intmask(
                            rwin32.C3_HIGHSURROGATE):
                        readlen_b += 2
                break
    if err:
        raise OperationError(space.w_WindowsError, space.newint(err))
    if readlen_b <= 0 or buf.getitem(0) == '\x1a':
        return ''
    else:
        return buf.getslice(0, 1, readlen_b)
Пример #5
0
def EnumValue(space, w_hkey, index):
    """tuple = EnumValue(key, index) - Enumerates values of an open registry key.
key is an already open key, or any one of the predefined 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 EnvironmentError exception
is raised, indicating no more values.

The result is a tuple of 3 items:
value_name is a string that identifies the value.
value_data is an object that holds the value data, and whose type depends
 on the underlying registry type.
data_type is an integer that identifies the type of the value data."""
    hkey = hkey_w(w_hkey, space)
    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)

    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as valueSize:
        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as dataSize:
            ret = rwinreg.RegQueryInfoKeyW(hkey, None, null_dword, null_dword,
                                           null_dword, null_dword, null_dword,
                                           null_dword, valueSize, dataSize,
                                           null_dword,
                                           lltype.nullptr(rwin32.PFILETIME.TO))
            if ret != 0:
                raiseWindowsError(space, ret, 'RegQueryInfoKey')
            # include null terminators
            valueSize[0] += 1
            dataSize[0] += 1
            bufDataSize = intmask(dataSize[0])
            bufValueSize = intmask(valueSize[0] * 2)

            valueBuf = ByteBuffer(bufValueSize)
            valueBufP = rffi.cast(rffi.CWCHARP, valueBuf.get_raw_address())
            while True:
                dataBuf = ByteBuffer(bufDataSize)
                dataBufP = rffi.cast(rffi.CCHARP, dataBuf.get_raw_address())
                with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
                    ret = rwinreg.RegEnumValueW(hkey, index, valueBufP,
                                                valueSize, null_dword, retType,
                                                dataBufP, dataSize)
                    if ret == rwinreg.ERROR_MORE_DATA:
                        # Resize and retry. For dynamic keys, the value of
                        # dataSize[0] is useless (always 1) so do what CPython
                        # does, except they use 2 instead of 4
                        bufDataSize *= 4
                        dataSize[0] = rffi.cast(rwin32.DWORD, bufDataSize)
                        valueSize[0] = rffi.cast(rwin32.DWORD, bufValueSize)
                        continue

                    if ret != 0:
                        raiseWindowsError(space, ret, 'RegEnumValue')

                    length = intmask(dataSize[0])
                    vlen = (intmask(valueSize[0]) + 1) * 2
                    utf8v, lenv = wbuf_to_utf8(space, valueBuf[0:vlen])
                    return space.newtuple([
                        space.newtext(utf8v, lenv),
                        convert_from_regdata(space, dataBuf, length,
                                             retType[0]),
                        space.newint(intmask(retType[0])),
                    ])