Exemple #1
0
 def test_basic(self):
     buf = ByteBuffer(4)
     assert buf.getlength() == 4
     assert buf.getitem(2) == '\x00'
     buf.setitem(0, 'A')
     buf.setitem(3, 'Z')
     assert buf.as_str() == 'A\x00\x00Z'
Exemple #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)
Exemple #3
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)
Exemple #4
0
 def make_buffer(flag):
     if flag:
         buf = ByteBuffer(len(DATA))
         buf.setslice(0, DATA)
     else:
         buf = StringBuffer(DATA)
     return buf
    def _init(self, space):
        if self.buffer_size <= 0:
            raise oefmt(space.w_ValueError,
                        "buffer size must be strictly positive")

        self.buffer = ByteBuffer(self.buffer_size)

        self.lock = TryLock(space)

        try:
            self._raw_tell(space)
        except OperationError:
            pass
Exemple #6
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])),
                    ])
Exemple #7
0
    def _init(self, space):
        if self.buffer_size <= 0:
            raise oefmt(space.w_ValueError,
                        "buffer size must be strictly positive")

        if space.config.translation.split_gc_address_space:
            # When using split GC address space, it is not possible to get the
            # raw address of a GC buffer. Therefore we use a buffer backed by
            # raw memory.
            self.buffer = RawByteBuffer(self.buffer_size)
        else:
            # TODO: test whether using the raw buffer is faster
            self.buffer = ByteBuffer(self.buffer_size)

        self.lock = TryLock(space)

        try:
            self._raw_tell(space)
        except OperationError:
            pass
Exemple #8
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)
Exemple #9
0
def bytebuffer(space, length):
    return space.newbuffer(ByteBuffer(length))
Exemple #10
0
    def _read_generic(self, space, n):
        """Generic read function: read from the stream until enough bytes are
           read, or until an EOF occurs or until read() would block."""
        # Must run with the lock held!
        current_size = self._readahead()
        if n <= current_size:
            return self._read_fast(n)

        result_buffer = ByteBuffer(n)
        remaining = n
        written = 0
        if current_size:
            result_buffer.setslice(
                written, self.buffer[self.pos:self.pos + current_size])
            remaining -= current_size
            written += current_size
            self.pos += current_size

        # Flush the write buffer if necessary
        if self.writable:
            self._flush_and_rewind_unlocked(space)
        self._reader_reset_buf()

        # Read whole blocks, and don't buffer them
        while remaining > 0:
            r = self.buffer_size * (remaining // self.buffer_size)
            if r == 0:
                break
            try:
                size = self._raw_read(space, result_buffer, written, r)
            except BlockingIOError:
                if written == 0:
                    return None
                size = 0
            if size == 0:
                return result_buffer[0:written]
            remaining -= size
            written += size

        self.pos = 0
        self.raw_pos = 0
        self.read_end = 0

        while remaining > 0 and self.read_end < self.buffer_size:
            try:
                size = self._fill_buffer(space)
            except BlockingIOError:
                # EOF or read() would block
                if written == 0:
                    return None
                size = 0
            if size == 0:
                break

            if remaining > 0:
                if size > remaining:
                    size = remaining
                result_buffer.setslice(written,
                                       self.buffer[self.pos:self.pos + size])
                self.pos += size
                written += size
                remaining -= size

        return result_buffer[0:written]
Exemple #11
0
 def test_getslice_shortcut(self):
     buf = ByteBuffer(4)
     buf.setslice(0, b"data")
     buf.getitem = None
     assert buf.getslice(0, 2, 1, 2) == b"da" # no crash!
Exemple #12
0
 def test_typed_read(self):
     data = struct.pack('HH', 0x1234, 0x5678)
     buf = ByteBuffer(4)
     buf.setslice(0, data)
     assert buf.typed_read(rffi.USHORT, 0) == 0x1234
     assert buf.typed_read(rffi.USHORT, 2) == 0x5678
Exemple #13
0
 def test_typed_write(self):
     buf = ByteBuffer(4)
     buf.typed_write(rffi.USHORT, 0, 0x1234)
     buf.typed_write(rffi.USHORT, 2, 0x5678)
     expected = struct.pack('HH', 0x1234, 0x5678)
     assert buf.as_str() == expected
def bytebuffer(space, length):
    return SimpleView(ByteBuffer(length)).wrap(space)
Exemple #15
0
 def f(x):
     buf = ByteBuffer(8)
     return direct_write(buf), typed_write(buf)
Exemple #16
0
 def f(x):
     buf = ByteBuffer(8)
     return direct_read(buf), typed_read(buf)
Exemple #17
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])),
                    ])